From 1798d51da67835618079f034d0b552be342af5d2 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 25 Nov 2018 11:35:38 -0500 Subject: [PATCH 0001/1064] Add grammar for {f32,f64}::from_str, mention known bug. - Original bug about documenting grammar - https://github.com/rust-lang/rust/issues/32243 - Known bug with parsing - https://github.com/rust-lang/rust/issues/31407 --- src/libcore/num/dec2flt/mod.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index f93564c2849f5..64ac69946d10d 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -122,11 +122,35 @@ macro_rules! from_str_float_impl { /// * '2.5E10', or equivalently, '2.5e10' /// * '2.5E-10' /// * '5.' - /// * '.5', or, equivalently, '0.5' + /// * '.5', or, equivalently, '0.5' /// * 'inf', '-inf', 'NaN' /// /// Leading and trailing whitespace represent an error. /// + /// # Grammar + /// + /// All strings that adhere to the following regular expression + /// will result in an [`Ok`] being returned: + /// + /// ```txt + /// (\+|-)? + /// (inf| + /// NaN| + /// ([0-9]+| + /// [0-9]+\.[0-9]*| + /// [0-9]*\.[0-9]+) + /// ((e|E) + /// (\+|-)? + /// [0-9]+)?) + /// ``` + /// + /// # Known bugs + /// + /// * [#31407]: Some strings that adhere to the regular expression + /// above will incorrectly return an [`Err`]. + /// + /// [#31407]: https://github.com/rust-lang/rust/issues/31407 + /// /// # Arguments /// /// * src - A string From 694b18d973e3c45d0dcc0221813fd0daefaf367f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 3 Dec 2018 12:28:56 -0800 Subject: [PATCH 0002/1064] tweak 'known issues' wording --- src/libcore/num/dec2flt/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 64ac69946d10d..759c2e8c953e0 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -146,8 +146,8 @@ macro_rules! from_str_float_impl { /// /// # Known bugs /// - /// * [#31407]: Some strings that adhere to the regular expression - /// above will incorrectly return an [`Err`]. + /// In some situations, some strings that should create a valid float + /// instead return an error. See [issue #31407] for details. /// /// [#31407]: https://github.com/rust-lang/rust/issues/31407 /// From 15f79d890522028e88a60992b76c0fce26024a8f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 3 Dec 2018 12:29:28 -0800 Subject: [PATCH 0003/1064] ...and fix a link --- src/libcore/num/dec2flt/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 759c2e8c953e0..1926d84d0439f 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -149,7 +149,7 @@ macro_rules! from_str_float_impl { /// In some situations, some strings that should create a valid float /// instead return an error. See [issue #31407] for details. /// - /// [#31407]: https://github.com/rust-lang/rust/issues/31407 + /// [issue #31407]: https://github.com/rust-lang/rust/issues/31407 /// /// # Arguments /// From 5eafae22ceb0e4fae835a5eb7518a55e75061e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 7 Dec 2018 16:18:38 +0200 Subject: [PATCH 0004/1064] Remove confusing comment about ideally using `!` for `c_void` Using `!` for `c_void` would have the problem that pointers and potentially references to an uninhabited type would be created, and at least for references this is UB. Also document in addition that newtype wrappers around `c_void` are not recommended for representing opaque types (as a workaround for `extern type` not being stable) but instead refer to the Nomicon. --- src/libcore/ffi.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index d7a112eb90df8..02e92af853452 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -13,11 +13,12 @@ use ::fmt; /// and `*mut c_void` is equivalent to C's `void*`. That said, this is /// *not* the same as C's `void` return type, which is Rust's `()` type. /// -/// Ideally, this type would be equivalent to [`!`], but currently it may -/// be more ideal to use `c_void` for FFI purposes. +/// To model pointers to opaque types in FFI, until `extern type` is +/// stabilized, it is recommended to use a newtype wrapper around an empty +/// byte array. See the [Nomicon] for details. /// -/// [`!`]: ../../std/primitive.never.html /// [pointer]: ../../std/primitive.pointer.html +/// [Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs // N.B., for LLVM to recognize the void pointer type and by extension // functions like malloc(), we need to have it represented as i8* in // LLVM bitcode. The enum used here ensures this and prevents misuse From 8de8880b7b74cb0294c6d8c75c24656130278509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 10 Dec 2018 10:10:42 +0200 Subject: [PATCH 0005/1064] Update code comments of `c_void` to explain the reasoning for its current implementation We need at least two variants of the enum as otherwise the compiler complains about the #[repr(u8)] attribute and we also need at least one variant as otherwise the enum would be uninhabitated and dereferencing pointers to it would be UB. As such, mark the variants not unstable because they should not actually exist but because they are temporary implementation details until `extern type` is stable and can be used instead. --- src/libcore/ffi.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 02e92af853452..22e219d51f41f 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -22,16 +22,18 @@ use ::fmt; // N.B., for LLVM to recognize the void pointer type and by extension // functions like malloc(), we need to have it represented as i8* in // LLVM bitcode. The enum used here ensures this and prevents misuse -// of the "raw" type by only having private variants.. We need two +// of the "raw" type by only having private variants. We need two // variants, because the compiler complains about the repr attribute -// otherwise. +// otherwise and we need at least one variant as otherwise the enum +// would be uninhabited and at least dereferencing such pointers would +// be UB. #[repr(u8)] #[stable(feature = "raw_os", since = "1.1.0")] pub enum c_void { - #[unstable(feature = "c_void_variant", reason = "should not have to exist", + #[unstable(feature = "c_void_variant", reason = "temporary implementation detail", issue = "0")] #[doc(hidden)] __variant1, - #[unstable(feature = "c_void_variant", reason = "should not have to exist", + #[unstable(feature = "c_void_variant", reason = "temporary implementation detail", issue = "0")] #[doc(hidden)] __variant2, } From f8bd80a830509d4356b76bc44a50c798db1bb3ea Mon Sep 17 00:00:00 2001 From: Ozaren Date: Thu, 13 Dec 2018 16:53:50 -0500 Subject: [PATCH 0006/1064] Change bounds on `TryFrom` blanket impl to use `Into` instead of `From` --- src/libcore/convert.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 2d4813718f41a..18ead0877fe85 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -476,11 +476,11 @@ impl TryInto for T where U: TryFrom // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[unstable(feature = "try_from", issue = "33417")] -impl TryFrom for T where T: From { +impl TryFrom for T where U: Into { type Error = !; fn try_from(value: U) -> Result { - Ok(T::from(value)) + Ok(U::into(value)) } } From 7a25a7ce8df3ba8b41915e240fedd8bf94867137 Mon Sep 17 00:00:00 2001 From: Ozaren Date: Sun, 16 Dec 2018 13:01:26 -0500 Subject: [PATCH 0007/1064] Changed expected error message for TryFrom Reason: Due to changes in bounds of `TryFrom` from `From` to `Into` --- src/test/ui/e0119/conflict-with-std.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr index e8b2c84c0df0b..8ca085c3a4bbf 100644 --- a/src/test/ui/e0119/conflict-with-std.stderr +++ b/src/test/ui/e0119/conflict-with-std.stderr @@ -25,7 +25,7 @@ LL | impl TryFrom for X { //~ ERROR conflicting implementations | = note: conflicting implementation in crate `core`: - impl std::convert::TryFrom for T - where T: std::convert::From; + where T: std::convert::Into; error: aborting due to 3 previous errors From a1be81300fdc6906dc3cb19019747e622901badc Mon Sep 17 00:00:00 2001 From: Ozaren Date: Sun, 16 Dec 2018 13:59:12 -0500 Subject: [PATCH 0008/1064] Fixed `Into` bound on `TryFrom` error. fix to last commit --- src/test/ui/e0119/conflict-with-std.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr index 8ca085c3a4bbf..fd016941d258e 100644 --- a/src/test/ui/e0119/conflict-with-std.stderr +++ b/src/test/ui/e0119/conflict-with-std.stderr @@ -25,7 +25,7 @@ LL | impl TryFrom for X { //~ ERROR conflicting implementations | = note: conflicting implementation in crate `core`: - impl std::convert::TryFrom for T - where T: std::convert::Into; + where U: std::convert::Into; error: aborting due to 3 previous errors From 5a3abffc77f11aa66b75874b446fbbf257758f91 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 18 Dec 2018 13:33:02 +0100 Subject: [PATCH 0009/1064] Automatically open an issue when a tool breaks --- src/tools/publish_toolstate.py | 42 +++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 4ade87f5d65bd..b863b9dde0d79 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -45,11 +45,41 @@ def read_current_status(current_commit, path): return json.loads(status) return {} +def issue( + title, + tool, + maintainers, + relevant_pr_number, + relevant_pr_user, +): + # Open an issue about the toolstate failure. + gh_url = 'https://api.github.com/repos/rust-lang/rust/issues' + assignees = [x.strip() for x in maintainers.split('@') if x != ''] + assignees.append(relevant_pr_user) + response = urllib2.urlopen(urllib2.Request( + gh_url, + json.dumps({ + 'body': '''\ + @{}: your PR ({}) broke {} + + If you have the time it would be great if you could open a PR against {} that + fixes the fallout from your PR. + '''.format(relevant_pr_user, relevant_pr_number, tool, tool), + 'title': title, + 'assignees': assignees, + }), + { + 'Authorization': 'token ' + github_token, + 'Content-Type': 'application/json', + } + )) + response.read() def update_latest( current_commit, relevant_pr_number, relevant_pr_url, + relevant_pr_user, current_datetime ): '''Updates `_data/latest.json` to match build result of the given commit. @@ -85,8 +115,11 @@ def update_latest( .format(tool, os, old, new, MAINTAINERS.get(tool)) elif new < old: changed = True - message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \ - .format(tool, os, old, new, MAINTAINERS.get(tool)) + title = '💔 {} on {}: {} → {}' \ + .format(tool, os, old, new) + message += '{} (cc {}, @rust-lang/infra).\n' \ + .format(title, MAINTAINERS.get(tool)) + issue(title, tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user) if changed: status['commit'] = current_commit @@ -109,13 +142,15 @@ def update_latest( save_message_to_path = sys.argv[3] github_token = sys.argv[4] - relevant_pr_match = re.search('#([0-9]+)', cur_commit_msg) + relevant_pr_match = re.search('Auto merge of #([0-9]+) - ([^:]+)', cur_commit_msg) if relevant_pr_match: number = relevant_pr_match.group(1) + relevant_pr_user = relevant_pr_match.group(2) relevant_pr_number = 'rust-lang/rust#' + number relevant_pr_url = 'https://github.com/rust-lang/rust/pull/' + number else: number = '-1' + relevant_pr_user = '' relevant_pr_number = '' relevant_pr_url = '' @@ -123,6 +158,7 @@ def update_latest( cur_commit, relevant_pr_number, relevant_pr_url, + relevant_pr_user, cur_datetime ) if not message: From 46a8fcdf3cf0eb64b5ac70b4847f1facbdd12be1 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 18 Dec 2018 16:30:40 +0100 Subject: [PATCH 0010/1064] Automatically tag as nominated for T-compiler --- src/tools/publish_toolstate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index b863b9dde0d79..c05cd912991ca 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -67,6 +67,7 @@ def issue( '''.format(relevant_pr_user, relevant_pr_number, tool, tool), 'title': title, 'assignees': assignees, + 'labels': ['T-compiler', 'I-nominated'], }), { 'Authorization': 'token ' + github_token, From db9fe1c86ea3c45a459f2ff63db2aef658ee3b7f Mon Sep 17 00:00:00 2001 From: Ozaren Date: Tue, 18 Dec 2018 23:18:20 -0500 Subject: [PATCH 0011/1064] added test to show motivation for modified TryFrom impl --- src/test/run-pass/try_from.rs | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/run-pass/try_from.rs diff --git a/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs new file mode 100644 index 0000000000000..3f2eb98f861a0 --- /dev/null +++ b/src/test/run-pass/try_from.rs @@ -0,0 +1,43 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test relies on `TryFrom` being auto impl for all `T: Into` +// and `TryInto` being auto impl for all `U: TryFrom` + +// This test was added to show the motivation for doing this +// over `TryFrom` being auto impl for all `T: From` + +#![feature(try_from, never_type)] + +use std::convert::TryInto; + +struct Foo { + t: T +} + +/* +// This fails to compile due to coherence restrictions +// as of rust version 1.32.x +impl From> for Box { + fn from(foo: Foo) -> Box { + Box::new(foo.t) + } +} +*/ + +impl Into> for Foo { + fn into(self) -> Box { + Box::new(self.t) + } +} + +pub fn main() { + let _: Result, !> = Foo { t: 10 }.try_into(); +} From 7dd078f53f4e1817207b089fb08d6a00121ca05b Mon Sep 17 00:00:00 2001 From: Ozaren Date: Wed, 19 Dec 2018 00:19:07 -0500 Subject: [PATCH 0012/1064] fixed test, now it doesn't use a fundemental type i.e. `Box`, instead it now uses `Vec` --- src/test/run-pass/try_from.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs index 3f2eb98f861a0..767c2b9147174 100644 --- a/src/test/run-pass/try_from.rs +++ b/src/test/run-pass/try_from.rs @@ -32,12 +32,13 @@ impl From> for Box { } */ -impl Into> for Foo { - fn into(self) -> Box { - Box::new(self.t) +impl Into> for Foo { + fn into(self) -> Vec { + vec![self.t] } } pub fn main() { - let _: Result, !> = Foo { t: 10 }.try_into(); + let _: Result, !> = Foo { t: 10 }.try_into(); } + From c485acb27c248d36c847ef4602770dcaa76b286d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Dec 2018 15:54:51 +0100 Subject: [PATCH 0013/1064] Only open one issue per tool --- src/tools/publish_toolstate.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index c05cd912991ca..5cacdb7ef0b57 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -46,11 +46,11 @@ def read_current_status(current_commit, path): return {} def issue( - title, tool, maintainers, relevant_pr_number, relevant_pr_user, + msg, ): # Open an issue about the toolstate failure. gh_url = 'https://api.github.com/repos/rust-lang/rust/issues' @@ -64,8 +64,11 @@ def issue( If you have the time it would be great if you could open a PR against {} that fixes the fallout from your PR. - '''.format(relevant_pr_user, relevant_pr_number, tool, tool), - 'title': title, + + {} + + '''.format(relevant_pr_user, relevant_pr_number, tool, tool, msg), + 'title': '💔 {}'.format(tool), 'assignees': assignees, 'labels': ['T-compiler', 'I-nominated'], }), @@ -105,6 +108,7 @@ def update_latest( for status in latest: tool = status['tool'] changed = False + failures = '' for os, s in current_status.items(): old = status[os] @@ -120,7 +124,11 @@ def update_latest( .format(tool, os, old, new) message += '{} (cc {}, @rust-lang/infra).\n' \ .format(title, MAINTAINERS.get(tool)) - issue(title, tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user) + failures += title + failures += '\n' + + if failures != '': + issue(tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user, failures) if changed: status['commit'] = current_commit From ab5fc7fb5b2028323ac30a0f67bf13202071936c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Dec 2018 16:37:16 +0100 Subject: [PATCH 0014/1064] Only emit issues for build failures to supress spurious failures --- src/tools/publish_toolstate.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 5cacdb7ef0b57..095ef0df496e6 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -115,17 +115,21 @@ def update_latest( new = s.get(tool, old) status[os] = new if new > old: + # things got fixed or at least the status quo improved changed = True message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \ .format(tool, os, old, new, MAINTAINERS.get(tool)) elif new < old: + # tests or builds are failing and were not failing before changed = True title = '💔 {} on {}: {} → {}' \ .format(tool, os, old, new) message += '{} (cc {}, @rust-lang/infra).\n' \ .format(title, MAINTAINERS.get(tool)) - failures += title - failures += '\n' + # only create issues for build failures. Other failures can be spurious + if new == 'build-fail': + failures += title + failures += '\n' if failures != '': issue(tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user, failures) @@ -151,6 +155,7 @@ def update_latest( save_message_to_path = sys.argv[3] github_token = sys.argv[4] + # assume that PR authors are also owners of the repo where the branch lives relevant_pr_match = re.search('Auto merge of #([0-9]+) - ([^:]+)', cur_commit_msg) if relevant_pr_match: number = relevant_pr_match.group(1) From a4c317ef980a8c0ef443937c78143535781e791c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Dec 2018 17:44:46 +0100 Subject: [PATCH 0015/1064] Be more cheerful and helpful --- src/tools/publish_toolstate.py | 41 +++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 095ef0df496e6..fbb3bc9a75154 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -34,6 +34,17 @@ 'rust-by-example': '@steveklabnik @marioidival @projektir', } +REPOS = { + 'miri': 'https://github.com/solson/miri', + 'clippy-driver': 'https://github.com/rust-lang/rust-clippy', + 'rls': 'https://github.com/rust-lang/rls', + 'rustfmt': 'https://github.com/rust-lang/rustfmt', + 'book': 'https://github.com/rust-lang/book', + 'nomicon': 'https://github.com/rust-lang-nursery/nomicon', + 'reference': 'https://github.com/rust-lang-nursery/reference', + 'rust-by-example': 'https://github.com/rust-lang/rust-by-example', +} + def read_current_status(current_commit, path): '''Reads build status of `current_commit` from content of `history/*.tsv` @@ -50,7 +61,7 @@ def issue( maintainers, relevant_pr_number, relevant_pr_user, - msg, + pr_reviewer, ): # Open an issue about the toolstate failure. gh_url = 'https://api.github.com/repos/rust-lang/rust/issues' @@ -60,15 +71,16 @@ def issue( gh_url, json.dumps({ 'body': '''\ - @{}: your PR ({}) broke {} + Hello, this is your friendly neighborhood mergebot. + After merging PR {}, I observed that the tool {} no longer builds. + A follow-up PR to the repository {} is needed to fix the fallout. - If you have the time it would be great if you could open a PR against {} that - fixes the fallout from your PR. + cc @{}, do you think you would have time to do the follow-up work? If so, that would be great! - {} + cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. - '''.format(relevant_pr_user, relevant_pr_number, tool, tool, msg), - 'title': '💔 {}'.format(tool), + '''.format(relevant_pr_number, tool, REPOS[tool], relevant_pr_user, pr_reviewer), + 'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number), 'assignees': assignees, 'labels': ['T-compiler', 'I-nominated'], }), @@ -84,6 +96,7 @@ def update_latest( relevant_pr_number, relevant_pr_url, relevant_pr_user, + pr_reviewer, current_datetime ): '''Updates `_data/latest.json` to match build result of the given commit. @@ -108,7 +121,7 @@ def update_latest( for status in latest: tool = status['tool'] changed = False - failures = '' + build_failed = False for os, s in current_status.items(): old = status[os] @@ -128,11 +141,10 @@ def update_latest( .format(title, MAINTAINERS.get(tool)) # only create issues for build failures. Other failures can be spurious if new == 'build-fail': - failures += title - failures += '\n' + build_failed = True - if failures != '': - issue(tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user, failures) + if build_failed: + issue(tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user, pr_reviewer) if changed: status['commit'] = current_commit @@ -156,23 +168,26 @@ def update_latest( github_token = sys.argv[4] # assume that PR authors are also owners of the repo where the branch lives - relevant_pr_match = re.search('Auto merge of #([0-9]+) - ([^:]+)', cur_commit_msg) + relevant_pr_match = re.search('Auto merge of #([0-9]+) - ([^:]+):[^,]+ r=([^\s]+)', cur_commit_msg) if relevant_pr_match: number = relevant_pr_match.group(1) relevant_pr_user = relevant_pr_match.group(2) relevant_pr_number = 'rust-lang/rust#' + number relevant_pr_url = 'https://github.com/rust-lang/rust/pull/' + number + pr_reviewer = relevant_pr_match.group(3) else: number = '-1' relevant_pr_user = '' relevant_pr_number = '' relevant_pr_url = '' + pr_reviewer = '' message = update_latest( cur_commit, relevant_pr_number, relevant_pr_url, relevant_pr_user, + pr_reviewer, cur_datetime ) if not message: From b454474c84ed96a8af55ed76e68e428cc11e69c6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 20 Dec 2018 14:29:42 +0100 Subject: [PATCH 0016/1064] Tidy --- src/tools/publish_toolstate.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index fbb3bc9a75154..3bf40e336d352 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -75,7 +75,8 @@ def issue( After merging PR {}, I observed that the tool {} no longer builds. A follow-up PR to the repository {} is needed to fix the fallout. - cc @{}, do you think you would have time to do the follow-up work? If so, that would be great! + cc @{}, do you think you would have time to do the follow-up work? + If so, that would be great! cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. @@ -144,7 +145,10 @@ def update_latest( build_failed = True if build_failed: - issue(tool, MAINTAINERS.get(tool), relevant_pr_number, relevant_pr_user, pr_reviewer) + issue( + tool, MAINTAINERS.get(tool), + relevant_pr_number, relevant_pr_user, pr_reviewer, + ) if changed: status['commit'] = current_commit @@ -168,7 +172,10 @@ def update_latest( github_token = sys.argv[4] # assume that PR authors are also owners of the repo where the branch lives - relevant_pr_match = re.search('Auto merge of #([0-9]+) - ([^:]+):[^,]+ r=([^\s]+)', cur_commit_msg) + relevant_pr_match = re.search( + 'Auto merge of #([0-9]+) - ([^:]+):[^,]+ r=([^\s]+)', + cur_commit_msg, + ) if relevant_pr_match: number = relevant_pr_match.group(1) relevant_pr_user = relevant_pr_match.group(2) From 1027dc16b941e04611213c7b7e2a6e9de523868a Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 22 Dec 2018 09:34:22 -0500 Subject: [PATCH 0017/1064] Update regex to EBNF --- src/libcore/num/dec2flt/mod.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 1926d84d0439f..804e5f5e52158 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -129,19 +129,17 @@ macro_rules! from_str_float_impl { /// /// # Grammar /// - /// All strings that adhere to the following regular expression + /// All strings that adhere to the following EBNF grammar /// will result in an [`Ok`] being returned: /// /// ```txt - /// (\+|-)? - /// (inf| - /// NaN| - /// ([0-9]+| - /// [0-9]+\.[0-9]*| - /// [0-9]*\.[0-9]+) - /// ((e|E) - /// (\+|-)? - /// [0-9]+)?) + /// Float ::= Sign? ( 'inf' | 'NaN' | Number ) + /// Number ::= ( Digit+ | + /// Digit+ '.' Digit* | + /// Digit* '.' Digit+ ) Exp? + /// Exp ::= [eE] Sign? Digit+ + /// Sign ::= [+-] + /// Digit ::= [0-9] /// ``` /// /// # Known bugs From 55be692eb8c2facf78892cdafbb898c375be0b94 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 22 Dec 2018 09:43:47 -0500 Subject: [PATCH 0018/1064] Update src/libcore/num/dec2flt/mod.rs Co-Authored-By: frewsxcv --- src/libcore/num/dec2flt/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 804e5f5e52158..8bde41fefd5b1 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -129,7 +129,9 @@ macro_rules! from_str_float_impl { /// /// # Grammar /// - /// All strings that adhere to the following EBNF grammar + /// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation + /// + /// All strings that adhere to the following [EBNF] grammar /// will result in an [`Ok`] being returned: /// /// ```txt From 488f16a85041e57ce5934df44ed64ffe5303be03 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 23 Dec 2018 13:27:37 +0100 Subject: [PATCH 0019/1064] Dedent mergebot message --- src/tools/publish_toolstate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 3bf40e336d352..18d447bcdb684 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -70,7 +70,7 @@ def issue( response = urllib2.urlopen(urllib2.Request( gh_url, json.dumps({ - 'body': '''\ + 'body': textwrap.dedent('''\ Hello, this is your friendly neighborhood mergebot. After merging PR {}, I observed that the tool {} no longer builds. A follow-up PR to the repository {} is needed to fix the fallout. @@ -80,7 +80,7 @@ def issue( cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. - '''.format(relevant_pr_number, tool, REPOS[tool], relevant_pr_user, pr_reviewer), + ''').format(relevant_pr_number, tool, REPOS[tool], relevant_pr_user, pr_reviewer), 'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number), 'assignees': assignees, 'labels': ['T-compiler', 'I-nominated'], From 284f0d364588821ba7e2ea0c42845fcbbf722290 Mon Sep 17 00:00:00 2001 From: daxpedda <1645124+daxpedda@users.noreply.github.com> Date: Wed, 26 Dec 2018 18:19:46 +0100 Subject: [PATCH 0020/1064] Document that `-C opt-level=0` implies `-C debug-assertions`. --- src/doc/rustc/src/codegen-options/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 94f21042c8fdd..a616409d9a400 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -187,7 +187,7 @@ This flag lets you control debug information: This flag lets you control the optimization level. -* `0`: no optimizations +* `0`: no optimizations, also turn on `cfg(debug_assertions)`. * `1`: basic optimizations * `2`: some optimizations * `3`: all optimizations From 809a1a86e04d03619642ab9074b9c95a24cbf82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 24 Dec 2018 21:43:51 +0100 Subject: [PATCH 0021/1064] mark str::string::String.trim.* functions as #[must_use]. The functions return a reference to a new object and do not modify in-place as the following code shows: ```` let s = String::from(" hello "); s.trim(); assert_eq!(s, " hello "); ```` The new reference should be bound to a variable as now indicated by #[must_use]. --- src/libcore/str/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 689d456d41246..a8b8b44413e13 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3544,6 +3544,8 @@ impl str { /// /// assert_eq!("Hello\tworld", s.trim()); /// ``` + #[must_use = "this returns the trimmed string as a new allocation, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] pub fn trim(&self) -> &str { self.trim_matches(|c: char| c.is_whitespace()) @@ -3579,6 +3581,8 @@ impl str { /// let s = " עברית "; /// assert!(Some('ע') == s.trim_start().chars().next()); /// ``` + #[must_use = "this returns the trimmed string as a new allocation, \ + without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_start(&self) -> &str { self.trim_start_matches(|c: char| c.is_whitespace()) @@ -3614,6 +3618,8 @@ impl str { /// let s = " עברית "; /// assert!(Some('ת') == s.trim_end().chars().rev().next()); /// ``` + #[must_use = "this returns the trimmed string as a new allocation, \ + without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_end(&self) -> &str { self.trim_end_matches(|c: char| c.is_whitespace()) @@ -3716,6 +3722,8 @@ impl str { /// ``` /// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar"); /// ``` + #[must_use = "this returns the trimmed string as a new allocation, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str where P::Searcher: DoubleEndedSearcher<'a> @@ -3761,6 +3769,8 @@ impl str { /// let x: &[_] = &['1', '2']; /// assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12"); /// ``` + #[must_use = "this returns the trimmed string as a new allocation, \ + without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { let mut i = self.len(); @@ -3804,6 +3814,8 @@ impl str { /// ``` /// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` + #[must_use = "this returns the trimmed string as a new allocation, \ + without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str where P::Searcher: ReverseSearcher<'a> From e7ce868f8e7ba2df728451bcbeafe387d393a1bc Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Tue, 25 Dec 2018 20:28:20 +0100 Subject: [PATCH 0022/1064] Update src/libcore/str/mod.rs, tweak must_use message trimmed string is returned as a slice instead of a new allocation Co-Authored-By: matthiaskrgr --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index a8b8b44413e13..9e724f117ff6e 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3544,7 +3544,7 @@ impl str { /// /// assert_eq!("Hello\tworld", s.trim()); /// ``` - #[must_use = "this returns the trimmed string as a new allocation, \ + #[must_use = "this returns the trimmed string as a slice, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] pub fn trim(&self) -> &str { From 74e9057905c3c24303245a4a2c5671d80a9503b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 26 Dec 2018 22:03:04 +0100 Subject: [PATCH 0023/1064] modify remaining #[must_use[ messages --- src/libcore/str/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 9e724f117ff6e..e58320ebf569e 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3581,7 +3581,7 @@ impl str { /// let s = " עברית "; /// assert!(Some('ע') == s.trim_start().chars().next()); /// ``` - #[must_use = "this returns the trimmed string as a new allocation, \ + #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_start(&self) -> &str { @@ -3618,7 +3618,7 @@ impl str { /// let s = " עברית "; /// assert!(Some('ת') == s.trim_end().chars().rev().next()); /// ``` - #[must_use = "this returns the trimmed string as a new allocation, \ + #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_end(&self) -> &str { @@ -3722,7 +3722,7 @@ impl str { /// ``` /// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar"); /// ``` - #[must_use = "this returns the trimmed string as a new allocation, \ + #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str @@ -3769,7 +3769,7 @@ impl str { /// let x: &[_] = &['1', '2']; /// assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12"); /// ``` - #[must_use = "this returns the trimmed string as a new allocation, \ + #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { @@ -3814,7 +3814,7 @@ impl str { /// ``` /// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` - #[must_use = "this returns the trimmed string as a new allocation, \ + #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str From eed140792d2a32e665e8fc8fb7863aa1da01ab8e Mon Sep 17 00:00:00 2001 From: Jacob Kiesel Date: Fri, 28 Dec 2018 14:15:55 -0700 Subject: [PATCH 0024/1064] Update std/lib.rs docs to reflect Rust 2018 usage --- src/libstd/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index aa4278a879981..5a33f3e7a37df 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -7,11 +7,9 @@ //! primitives](#primitives), [standard macros](#macros), [I/O] and //! [multithreading], among [many other things][other]. //! -//! `std` is available to all Rust crates by default, just as if each one -//! contained an `extern crate std;` import at the [crate root]. Therefore the +//! `std` is available to all Rust crates by default. Therefore the //! standard library can be accessed in [`use`] statements through the path -//! `std`, as in [`use std::env`], or in expressions through the absolute path -//! `::std`, as in [`::std::env::args`]. +//! `std`, as in [`use std::env`]. //! //! # How to read this documentation //! From 11b0fa21a66789c05471e2bc7ab58f5e40f4e6bd Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 30 Dec 2018 12:23:24 +0100 Subject: [PATCH 0025/1064] docs(rustc): Link to the book's source in rustc --- src/doc/rustc/src/contributing.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md index 3a1cafe8a6153..25a5c97b0a120 100644 --- a/src/doc/rustc/src/contributing.md +++ b/src/doc/rustc/src/contributing.md @@ -1,6 +1,12 @@ # Contributing to rustc We'd love to have your help improving `rustc`! To that end, we've written [a -whole book](https://rust-lang.github.io/rustc-guide/) on its +whole book][rustc_guide] on its internals, how it works, and how to get started working on it. To learn more, you'll want to check that out. + +If you would like to contribute to _this_ book, you can find its source in the +rustc source at [src/doc/rustc][rustc_book]. + +[rustc_guide]: https://rust-lang.github.io/rustc-guide/ +[rustc_book]: https://github.com/rust-lang/rust/tree/master/src/doc/rustc From ea68b3ff3dd5a49c5984c476570fb5404c342079 Mon Sep 17 00:00:00 2001 From: Ozaren Date: Wed, 2 Jan 2019 20:38:50 -0500 Subject: [PATCH 0026/1064] update to reflect changes recommended by @shepmaster his review --- src/test/run-pass/try_from.rs | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs index 767c2b9147174..4522ce3a8d617 100644 --- a/src/test/run-pass/try_from.rs +++ b/src/test/run-pass/try_from.rs @@ -1,30 +1,23 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This test relies on `TryFrom` being auto impl for all `T: Into` -// and `TryInto` being auto impl for all `U: TryFrom` +// This test relies on `TryFrom` being blanket impl for all `T: Into` +// and `TryInto` being blanket impl for all `U: TryFrom` // This test was added to show the motivation for doing this -// over `TryFrom` being auto impl for all `T: From` +// over `TryFrom` being blanket impl for all `T: From` #![feature(try_from, never_type)] use std::convert::TryInto; struct Foo { - t: T + t: T, } -/* // This fails to compile due to coherence restrictions -// as of rust version 1.32.x +// as of Rust version 1.32.x, therefore it could not be used +// instead of the `Into` version of the impl, and serves as +// motivation for a blanket impl for all `T: Into`, instead +// of a blanket impl for all `T: From` +/* impl From> for Box { fn from(foo: Foo) -> Box { Box::new(foo.t) From 6bae4a763df95c436ce9f1286b1d593e67218932 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 3 Jan 2019 21:49:56 +0900 Subject: [PATCH 0027/1064] Fix unused_assignments false positive Make `continue` jump to the loop condition's `LiveNode` instead of one of the loop body. --- src/librustc/middle/liveness.rs | 11 ++++++----- src/test/ui/liveness/liveness-dead.rs | 9 +++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a78cf1a471b4b..71a104ba6e761 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -911,7 +911,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn compute(&mut self, body: &hir::Expr) -> LiveNode { - // if there is a `break` or `again` at the top level, then it's + // if there is a `break` or `continue` at the top level, then it's // effectively a return---this only occurs in `for` loops, // where the body is really a closure. @@ -1407,15 +1407,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { debug!("propagate_through_loop: using id for loop body {} {}", expr.id, self.ir.tcx.hir().node_to_pretty_string(body.id)); - let break_ln = succ; - let cont_ln = ln; - self.break_ln.insert(expr.id, break_ln); - self.cont_ln.insert(expr.id, cont_ln); + + self.break_ln.insert(expr.id, succ); let cond_ln = match kind { LoopLoop => ln, WhileLoop(ref cond) => self.propagate_through_expr(&cond, ln), }; + + self.cont_ln.insert(expr.id, cond_ln); + let body_ln = self.propagate_through_block(body, cond_ln); // repeat until fixed point is reached: diff --git a/src/test/ui/liveness/liveness-dead.rs b/src/test/ui/liveness/liveness-dead.rs index 7d420afde4b72..004663c85ee50 100644 --- a/src/test/ui/liveness/liveness-dead.rs +++ b/src/test/ui/liveness/liveness-dead.rs @@ -27,4 +27,13 @@ fn f5(mut x: i32) { x = 4; //~ ERROR: value assigned to `x` is never read } +// #22630 +fn f6() { + let mut done = false; + while !done { + done = true; // no error + continue; + } +} + fn main() {} From 069b0c410808c1d1d33b495e048b1186e9f8d57f Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 3 Jan 2019 23:20:44 +0900 Subject: [PATCH 0028/1064] Cleanup `for` loops are no longer closures. --- src/librustc/middle/liveness.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 71a104ba6e761..2ca823929fd38 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -911,17 +911,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn compute(&mut self, body: &hir::Expr) -> LiveNode { - // if there is a `break` or `continue` at the top level, then it's - // effectively a return---this only occurs in `for` loops, - // where the body is really a closure. - debug!("compute: using id for body, {}", self.ir.tcx.hir().node_to_pretty_string(body.id)); - let exit_ln = self.s.exit_ln; - - self.break_ln.insert(body.id, exit_ln); - self.cont_ln.insert(body.id, exit_ln); - // the fallthrough exit is only for those cases where we do not // explicitly return: let s = self.s; @@ -1024,19 +1015,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&e, succ) } - hir::ExprKind::Closure(.., blk_id, _, _) => { + hir::ExprKind::Closure(..) => { debug!("{} is an ExprKind::Closure", self.ir.tcx.hir().node_to_pretty_string(expr.id)); - // The next-node for a break is the successor of the entire - // loop. The next-node for a continue is the top of this loop. - let node = self.live_node(expr.hir_id, expr.span); - - let break_ln = succ; - let cont_ln = node; - self.break_ln.insert(blk_id.node_id, break_ln); - self.cont_ln.insert(blk_id.node_id, cont_ln); - // the construction of a closure itself is not important, // but we have to consider the closed over variables. let caps = self.ir.capture_info_map.get(&expr.id).cloned().unwrap_or_else(|| From c738e6042d2925bbfb045982fabe1f902f8b7c72 Mon Sep 17 00:00:00 2001 From: purple-ice Date: Thu, 3 Jan 2019 20:15:01 +0200 Subject: [PATCH 0029/1064] Extend E0106, E0261 Added an example that points out hardly obvious mistake one could make when writing impl for a new type. --- src/librustc/diagnostics.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 4bc52e82f9be1..50beacf3e8cbb 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -362,6 +362,10 @@ struct Foo1 { x: &bool } // ^ expected lifetime parameter struct Foo2<'a> { x: &'a bool } // correct +impl Foo2 { ... } + // ^ expected lifetime parameter +impl<'a> Foo2<'a> { ... } // correct + struct Bar1 { x: Foo2 } // ^^^^ expected lifetime parameter struct Bar2<'a> { x: Foo2<'a> } // correct @@ -772,6 +776,24 @@ struct Foo<'a> { x: &'a str, } ``` + +Implementations need their own lifetime declarations: + +``` +// error, undeclared lifetime +impl Foo<'a> { + ... +} +``` + +Which are declared like this: + +``` +// correct +impl<'a> Foo<'a> { + ... +} +``` "##, E0262: r##" From 6d54672acf431ceae0b057f45e0351e84793d9f2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 11 Dec 2018 14:18:30 -0500 Subject: [PATCH 0030/1064] Fix stack overflow when finding blanket impls Currently, SelectionContext tries to prevent stack overflow by keeping track of the current recursion depth. However, this depth tracking is only used when performing normal section (which includes confirmation). No such tracking is performed for evaluate_obligation_recursively, which can allow a stack overflow to occur. To fix this, this commit tracks the current predicate evaluation depth. This is done separately from the existing obligation depth tracking: an obligation overflow can occur across multiple calls to 'select' (e.g. when fulfilling a trait), while a predicate evaluation overflow can only happen as a result of a deep recursive call stack. Fixes #56701 --- src/librustc/traits/select.rs | 101 ++++++++++++++++++++++---------- src/test/rustdoc/issue-56701.rs | 34 +++++++++++ 2 files changed, 104 insertions(+), 31 deletions(-) create mode 100644 src/test/rustdoc/issue-56701.rs diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 373ec2d5e490f..ea5f199de2950 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -42,7 +42,7 @@ use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; use std::cmp; -use std::fmt; +use std::fmt::{self, Display}; use std::iter; use std::rc::Rc; use util::nodemap::{FxHashMap, FxHashSet}; @@ -573,7 +573,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let stack = self.push_stack(TraitObligationStackList::empty(), obligation); - let candidate = match self.candidate_from_obligation(&stack) { + // 'select' is an entry point into SelectionContext - we never call it recursively + // from within SelectionContext. Therefore, we start our recursion depth at 0 + let candidate = match self.candidate_from_obligation(&stack, 0) { Err(SelectionError::Overflow) => { // In standard mode, overflow must have been caught and reported // earlier. @@ -629,7 +631,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result { self.evaluation_probe(|this| { - this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation) + // Like 'select', 'evaluate_obligation_recursively' is an entry point into + // SelectionContext, so our recursion depth is 0 + this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation, 0) }) } @@ -653,6 +657,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: TraitObligationStackList<'o, 'tcx>, predicates: I, + recursion_depth: usize ) -> Result where I: IntoIterator>, @@ -660,7 +665,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { { let mut result = EvaluatedToOk; for obligation in predicates { - let eval = self.evaluate_predicate_recursively(stack, obligation)?; + let eval = self.evaluate_predicate_recursively(stack, obligation, recursion_depth)?; debug!( "evaluate_predicate_recursively({:?}) = {:?}", obligation, eval @@ -680,14 +685,30 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &PredicateObligation<'tcx>, + mut recursion_depth: usize ) -> Result { - debug!("evaluate_predicate_recursively({:?})", obligation); + debug!("evaluate_predicate_recursively({:?}, recursion_depth={:?})", obligation, + recursion_depth); + + // We need to check for overflow here, since the normal + // recursion check uses the obligation from the stack. + // This is insufficient for two reasions: + // 1. That recursion depth is only incremented when a candidate is confirmed + // Since evaluation skips candidate confirmation, this will never happen + // 2. It relies on the trait obligation stack. However, it's possible for overflow + // to happen without involving the trait obligation stack. For example, + // we might end up trying to infinitely recurse with a projection predicate, + // which will never push anything onto the stack. + self.check_recursion_limit(recursion_depth, obligation)?; + + // Now that we know that the recursion check has passed, increment our depth + recursion_depth += 1; match obligation.predicate { ty::Predicate::Trait(ref t) => { debug_assert!(!t.has_escaping_bound_vars()); let obligation = obligation.with(t.clone()); - self.evaluate_trait_predicate_recursively(previous_stack, obligation) + self.evaluate_trait_predicate_recursively(previous_stack, obligation, recursion_depth) } ty::Predicate::Subtype(ref p) => { @@ -696,7 +717,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .subtype_predicate(&obligation.cause, obligation.param_env, p) { Some(Ok(InferOk { obligations, .. })) => { - self.evaluate_predicates_recursively(previous_stack, &obligations) + self.evaluate_predicates_recursively(previous_stack, &obligations, recursion_depth) } Some(Err(_)) => Ok(EvaluatedToErr), None => Ok(EvaluatedToAmbig), @@ -711,7 +732,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.cause.span, ) { Some(obligations) => { - self.evaluate_predicates_recursively(previous_stack, obligations.iter()) + self.evaluate_predicates_recursively(previous_stack, obligations.iter(), recursion_depth) } None => Ok(EvaluatedToAmbig), }, @@ -737,6 +758,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let result = self.evaluate_predicates_recursively( previous_stack, subobligations.iter(), + recursion_depth ); if let Some(key) = ProjectionCacheKey::from_poly_projection_predicate(self, data) @@ -795,6 +817,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: TraitObligation<'tcx>, + recursion_depth: usize ) -> Result { debug!("evaluate_trait_predicate_recursively({:?})", obligation); @@ -822,7 +845,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Ok(result); } - let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack)); + let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack, recursion_depth)); let result = result?; debug!("CACHE MISS: EVAL({:?})={:?}", fresh_trait_ref, result); @@ -834,6 +857,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn evaluate_stack<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, + recursion_depth: usize ) -> Result { // In intercrate mode, whenever any of the types are unbound, // there can always be an impl. Even if there are no impls in @@ -874,7 +898,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Heuristics: show the diagnostics when there are no candidates in crate. if self.intercrate_ambiguity_causes.is_some() { debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - if let Ok(candidate_set) = self.assemble_candidates(stack) { + if let Ok(candidate_set) = self.assemble_candidates(stack, recursion_depth) { if !candidate_set.ambiguous && candidate_set.vec.is_empty() { let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; let self_ty = trait_ref.self_ty(); @@ -955,8 +979,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } } - match self.candidate_from_obligation(stack) { - Ok(Some(c)) => self.evaluate_candidate(stack, &c), + match self.candidate_from_obligation(stack, recursion_depth) { + Ok(Some(c)) => self.evaluate_candidate(stack, &c, recursion_depth), Ok(None) => Ok(EvaluatedToAmbig), Err(Overflow) => Err(OverflowError), Err(..) => Ok(EvaluatedToErr), @@ -995,6 +1019,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidate: &SelectionCandidate<'tcx>, + recursion_depth: usize ) -> Result { debug!( "evaluate_candidate: depth={} candidate={:?}", @@ -1006,6 +1031,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Ok(selection) => this.evaluate_predicates_recursively( stack.list(), selection.nested_obligations().iter(), + recursion_depth ), Err(..) => Ok(EvaluatedToErr), } @@ -1080,6 +1106,24 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .insert(trait_ref, WithDepNode::new(dep_node, result)); } + // The weird return type of this function allows it to be used with the 'try' (?) + // operator within certain functions + fn check_recursion_limit>(&self, recursion_depth: usize, obligation: &Obligation<'tcx, T>, + ) -> Result<(), OverflowError> { + let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); + if recursion_depth >= recursion_limit { + match self.query_mode { + TraitQueryMode::Standard => { + self.infcx().report_overflow_error(obligation, true); + } + TraitQueryMode::Canonical => { + return Err(OverflowError); + } + } + } + Ok(()) + } + /////////////////////////////////////////////////////////////////////////// // CANDIDATE ASSEMBLY // @@ -1093,20 +1137,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn candidate_from_obligation<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, + recursion_depth: usize ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { // Watch out for overflow. This intentionally bypasses (and does // not update) the cache. - let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); - if stack.obligation.recursion_depth >= recursion_limit { - match self.query_mode { - TraitQueryMode::Standard => { - self.infcx().report_overflow_error(&stack.obligation, true); - } - TraitQueryMode::Canonical => { - return Err(Overflow); - } - } - } + self.check_recursion_limit(stack.obligation.recursion_depth, &stack.obligation)?; // Check the cache. Note that we freshen the trait-ref // separately rather than using `stack.fresh_trait_ref` -- @@ -1128,7 +1163,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // If no match, compute result and insert into cache. let (candidate, dep_node) = - self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); + self.in_task(|this| this.candidate_from_obligation_no_cache(stack, recursion_depth)); debug!( "CACHE MISS: SELECT({:?})={:?}", @@ -1172,6 +1207,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn candidate_from_obligation_no_cache<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, + recursion_depth: usize ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { if stack.obligation.predicate.references_error() { // If we encounter a `Error`, we generally prefer the @@ -1189,13 +1225,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { if self.intercrate_ambiguity_causes.is_some() { debug!("evaluate_stack: intercrate_ambiguity_causes is some"); // Heuristics: show the diagnostics when there are no candidates in crate. - if let Ok(candidate_set) = self.assemble_candidates(stack) { + if let Ok(candidate_set) = self.assemble_candidates(stack, recursion_depth) { let mut no_candidates_apply = true; { let evaluated_candidates = candidate_set .vec .iter() - .map(|c| self.evaluate_candidate(stack, &c)); + .map(|c| self.evaluate_candidate(stack, &c, recursion_depth)); for ec in evaluated_candidates { match ec { @@ -1241,7 +1277,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Ok(None); } - let candidate_set = self.assemble_candidates(stack)?; + let candidate_set = self.assemble_candidates(stack, recursion_depth)?; if candidate_set.ambiguous { debug!("candidate set contains ambig"); @@ -1288,7 +1324,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // is needed for specialization. Propagate overflow if it occurs. let mut candidates = candidates .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c) { + .map(|c| match self.evaluate_candidate(stack, &c, recursion_depth) { Ok(eval) if eval.may_apply() => Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval, @@ -1526,6 +1562,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn assemble_candidates<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, + recursion_depth: usize ) -> Result, SelectionError<'tcx>> { let TraitObligationStack { obligation, .. } = *stack; let ref obligation = Obligation { @@ -1601,7 +1638,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } self.assemble_candidates_from_projected_tys(obligation, &mut candidates); - self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?; + self.assemble_candidates_from_caller_bounds(stack, &mut candidates, recursion_depth)?; // Auto implementations have lower priority, so we only // consider triggering a default if there is no other impl that can apply. if candidates.vec.is_empty() { @@ -1734,6 +1771,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, + recursion_depth: usize ) -> Result<(), SelectionError<'tcx>> { debug!( "assemble_candidates_from_caller_bounds({:?})", @@ -1755,7 +1793,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // keep only those bounds which may apply, and propagate overflow if it occurs let mut param_candidates = vec![]; for bound in matching_bounds { - let wc = self.evaluate_where_clause(stack, bound.clone())?; + let wc = self.evaluate_where_clause(stack, bound.clone(), recursion_depth)?; if wc.may_apply() { param_candidates.push(ParamCandidate(bound)); } @@ -1770,11 +1808,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, + recursion_depth: usize ) -> Result { self.evaluation_probe(|this| { match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => { - this.evaluate_predicates_recursively(stack.list(), obligations.iter()) + this.evaluate_predicates_recursively(stack.list(), obligations.iter(), recursion_depth) } Err(()) => Ok(EvaluatedToErr), } diff --git a/src/test/rustdoc/issue-56701.rs b/src/test/rustdoc/issue-56701.rs new file mode 100644 index 0000000000000..6fb30a4ff4c30 --- /dev/null +++ b/src/test/rustdoc/issue-56701.rs @@ -0,0 +1,34 @@ +// This shouldn't cause a stack overflow when rustdoc is run + +use std::ops::Deref; +use std::ops::DerefMut; + +pub trait SimpleTrait { + type SimpleT; +} + +impl> SimpleTrait for Outer { + type SimpleT = Inner::SimpleT; +} + +pub trait AnotherTrait { + type AnotherT; +} + +impl>> AnotherTrait for Simple { + type AnotherT = T; +} + +pub struct Unrelated>>(UnrelatedT); + +impl>> Deref for Unrelated { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + + +pub fn main() { } + From c55c312c1721c80289915d8741d7f05d7c33de70 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 11 Dec 2018 14:48:12 -0500 Subject: [PATCH 0031/1064] Fix tidy errors --- src/librustc/traits/select.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ea5f199de2950..54e015d1b37a5 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -657,7 +657,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: TraitObligationStackList<'o, 'tcx>, predicates: I, - recursion_depth: usize + recursion_depth: usize ) -> Result where I: IntoIterator>, @@ -708,7 +708,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::Predicate::Trait(ref t) => { debug_assert!(!t.has_escaping_bound_vars()); let obligation = obligation.with(t.clone()); - self.evaluate_trait_predicate_recursively(previous_stack, obligation, recursion_depth) + self.evaluate_trait_predicate_recursively(previous_stack, obligation, + recursion_depth) } ty::Predicate::Subtype(ref p) => { @@ -717,7 +718,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .subtype_predicate(&obligation.cause, obligation.param_env, p) { Some(Ok(InferOk { obligations, .. })) => { - self.evaluate_predicates_recursively(previous_stack, &obligations, recursion_depth) + self.evaluate_predicates_recursively(previous_stack, &obligations, + recursion_depth) } Some(Err(_)) => Ok(EvaluatedToErr), None => Ok(EvaluatedToAmbig), @@ -732,7 +734,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.cause.span, ) { Some(obligations) => { - self.evaluate_predicates_recursively(previous_stack, obligations.iter(), recursion_depth) + self.evaluate_predicates_recursively(previous_stack, obligations.iter(), + recursion_depth) } None => Ok(EvaluatedToAmbig), }, @@ -1108,7 +1111,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // The weird return type of this function allows it to be used with the 'try' (?) // operator within certain functions - fn check_recursion_limit>(&self, recursion_depth: usize, obligation: &Obligation<'tcx, T>, + fn check_recursion_limit>(&self, recursion_depth: usize, + obligation: &Obligation<'tcx, T>, ) -> Result<(), OverflowError> { let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); if recursion_depth >= recursion_limit { @@ -1813,7 +1817,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.evaluation_probe(|this| { match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => { - this.evaluate_predicates_recursively(stack.list(), obligations.iter(), recursion_depth) + this.evaluate_predicates_recursively(stack.list(), obligations.iter(), + recursion_depth) } Err(()) => Ok(EvaluatedToErr), } From 54fd8caddc980a6ad47069d9674b4f59b1cd7da0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Dec 2018 23:38:00 -0500 Subject: [PATCH 0032/1064] Remove extra recursion_depth tracking --- src/librustc/traits/select.rs | 104 ++++++++++++++-------------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 54e015d1b37a5..7931943c90959 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -42,7 +42,7 @@ use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; use std::cmp; -use std::fmt::{self, Display}; +use std::fmt; use std::iter; use std::rc::Rc; use util::nodemap::{FxHashMap, FxHashSet}; @@ -573,9 +573,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let stack = self.push_stack(TraitObligationStackList::empty(), obligation); - // 'select' is an entry point into SelectionContext - we never call it recursively - // from within SelectionContext. Therefore, we start our recursion depth at 0 - let candidate = match self.candidate_from_obligation(&stack, 0) { + let candidate = match self.candidate_from_obligation(&stack) { Err(SelectionError::Overflow) => { // In standard mode, overflow must have been caught and reported // earlier. @@ -631,9 +629,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result { self.evaluation_probe(|this| { - // Like 'select', 'evaluate_obligation_recursively' is an entry point into - // SelectionContext, so our recursion depth is 0 - this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation, 0) + this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation.clone()) }) } @@ -657,15 +653,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: TraitObligationStackList<'o, 'tcx>, predicates: I, - recursion_depth: usize ) -> Result where - I: IntoIterator>, + I: IntoIterator>, 'tcx: 'a, { let mut result = EvaluatedToOk; for obligation in predicates { - let eval = self.evaluate_predicate_recursively(stack, obligation, recursion_depth)?; + let eval = self.evaluate_predicate_recursively(stack, obligation)?; debug!( "evaluate_predicate_recursively({:?}) = {:?}", obligation, eval @@ -684,32 +679,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn evaluate_predicate_recursively<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, - obligation: &PredicateObligation<'tcx>, - mut recursion_depth: usize + obligation: PredicateObligation<'tcx>, ) -> Result { - debug!("evaluate_predicate_recursively({:?}, recursion_depth={:?})", obligation, - recursion_depth); - - // We need to check for overflow here, since the normal - // recursion check uses the obligation from the stack. - // This is insufficient for two reasions: - // 1. That recursion depth is only incremented when a candidate is confirmed - // Since evaluation skips candidate confirmation, this will never happen - // 2. It relies on the trait obligation stack. However, it's possible for overflow - // to happen without involving the trait obligation stack. For example, - // we might end up trying to infinitely recurse with a projection predicate, - // which will never push anything onto the stack. - self.check_recursion_limit(recursion_depth, obligation)?; - - // Now that we know that the recursion check has passed, increment our depth - recursion_depth += 1; + debug!("evaluate_predicate_recursively({:?})", obligation); + self.check_recursion_limit(obligation)?; match obligation.predicate { ty::Predicate::Trait(ref t) => { debug_assert!(!t.has_escaping_bound_vars()); - let obligation = obligation.with(t.clone()); - self.evaluate_trait_predicate_recursively(previous_stack, obligation, - recursion_depth) + let mut obligation = obligation.with(t.clone()); + obligation.recursion_depth += 1 + self.evaluate_trait_predicate_recursively(previous_stack, obligation) } ty::Predicate::Subtype(ref p) => { @@ -718,8 +698,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .subtype_predicate(&obligation.cause, obligation.param_env, p) { Some(Ok(InferOk { obligations, .. })) => { - self.evaluate_predicates_recursively(previous_stack, &obligations, - recursion_depth) + for o in obligations.iter_mut() { + o.recursion_depth += 1 + } + self.evaluate_predicates_recursively(previous_stack, obligation.into_iter()) } Some(Err(_)) => Ok(EvaluatedToErr), None => Ok(EvaluatedToAmbig), @@ -734,8 +716,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.cause.span, ) { Some(obligations) => { - self.evaluate_predicates_recursively(previous_stack, obligations.iter(), - recursion_depth) + for o in obligations.iter_mut() { + o.recursion_depth += 1 + } + self.evaluate_predicates_recursively(previous_stack, obligations.iter()) } None => Ok(EvaluatedToAmbig), }, @@ -758,10 +742,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let project_obligation = obligation.with(data.clone()); match project::poly_project_and_unify_type(self, &project_obligation) { Ok(Some(subobligations)) => { + for o in subobligations.iter_mut() { + o.recursion_depth += 1 + } let result = self.evaluate_predicates_recursively( previous_stack, - subobligations.iter(), - recursion_depth + subobligations.into_iter(), ); if let Some(key) = ProjectionCacheKey::from_poly_projection_predicate(self, data) @@ -820,7 +806,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: TraitObligation<'tcx>, - recursion_depth: usize ) -> Result { debug!("evaluate_trait_predicate_recursively({:?})", obligation); @@ -848,7 +833,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Ok(result); } - let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack, recursion_depth)); + let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack)); let result = result?; debug!("CACHE MISS: EVAL({:?})={:?}", fresh_trait_ref, result); @@ -860,7 +845,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn evaluate_stack<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, - recursion_depth: usize ) -> Result { // In intercrate mode, whenever any of the types are unbound, // there can always be an impl. Even if there are no impls in @@ -901,7 +885,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Heuristics: show the diagnostics when there are no candidates in crate. if self.intercrate_ambiguity_causes.is_some() { debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - if let Ok(candidate_set) = self.assemble_candidates(stack, recursion_depth) { + if let Ok(candidate_set) = self.assemble_candidates(stack) { if !candidate_set.ambiguous && candidate_set.vec.is_empty() { let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; let self_ty = trait_ref.self_ty(); @@ -982,8 +966,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } } - match self.candidate_from_obligation(stack, recursion_depth) { - Ok(Some(c)) => self.evaluate_candidate(stack, &c, recursion_depth), + match self.candidate_from_obligation(stack) { + Ok(Some(c)) => self.evaluate_candidate(stack, &c), Ok(None) => Ok(EvaluatedToAmbig), Err(Overflow) => Err(OverflowError), Err(..) => Ok(EvaluatedToErr), @@ -1022,7 +1006,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidate: &SelectionCandidate<'tcx>, - recursion_depth: usize ) -> Result { debug!( "evaluate_candidate: depth={} candidate={:?}", @@ -1034,7 +1017,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Ok(selection) => this.evaluate_predicates_recursively( stack.list(), selection.nested_obligations().iter(), - recursion_depth ), Err(..) => Ok(EvaluatedToErr), } @@ -1109,13 +1091,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .insert(trait_ref, WithDepNode::new(dep_node, result)); } + // Check that the recursion limit has not been exceeded. + // // The weird return type of this function allows it to be used with the 'try' (?) // operator within certain functions - fn check_recursion_limit>(&self, recursion_depth: usize, - obligation: &Obligation<'tcx, T>, + fn check_recursion_limit>(&self, obligation: &Obligation<'tcx, T>, ) -> Result<(), OverflowError> { let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); - if recursion_depth >= recursion_limit { + if obligaton.recursion_depth >= recursion_limit { match self.query_mode { TraitQueryMode::Standard => { self.infcx().report_overflow_error(obligation, true); @@ -1141,11 +1124,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn candidate_from_obligation<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, - recursion_depth: usize ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { // Watch out for overflow. This intentionally bypasses (and does // not update) the cache. - self.check_recursion_limit(stack.obligation.recursion_depth, &stack.obligation)?; + self.check_recursion_limit(&stack.obligation)?; + // Check the cache. Note that we freshen the trait-ref // separately rather than using `stack.fresh_trait_ref` -- @@ -1167,7 +1150,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // If no match, compute result and insert into cache. let (candidate, dep_node) = - self.in_task(|this| this.candidate_from_obligation_no_cache(stack, recursion_depth)); + self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); debug!( "CACHE MISS: SELECT({:?})={:?}", @@ -1211,7 +1194,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn candidate_from_obligation_no_cache<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, - recursion_depth: usize ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { if stack.obligation.predicate.references_error() { // If we encounter a `Error`, we generally prefer the @@ -1229,13 +1211,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { if self.intercrate_ambiguity_causes.is_some() { debug!("evaluate_stack: intercrate_ambiguity_causes is some"); // Heuristics: show the diagnostics when there are no candidates in crate. - if let Ok(candidate_set) = self.assemble_candidates(stack, recursion_depth) { + if let Ok(candidate_set) = self.assemble_candidates(stack) { let mut no_candidates_apply = true; { let evaluated_candidates = candidate_set .vec .iter() - .map(|c| self.evaluate_candidate(stack, &c, recursion_depth)); + .map(|c| self.evaluate_candidate(stack, &c)); for ec in evaluated_candidates { match ec { @@ -1281,7 +1263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Ok(None); } - let candidate_set = self.assemble_candidates(stack, recursion_depth)?; + let candidate_set = self.assemble_candidates(stack)?; if candidate_set.ambiguous { debug!("candidate set contains ambig"); @@ -1328,7 +1310,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // is needed for specialization. Propagate overflow if it occurs. let mut candidates = candidates .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c, recursion_depth) { + .map(|c| match self.evaluate_candidate(stack, &c) { Ok(eval) if eval.may_apply() => Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval, @@ -1566,7 +1548,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn assemble_candidates<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, - recursion_depth: usize ) -> Result, SelectionError<'tcx>> { let TraitObligationStack { obligation, .. } = *stack; let ref obligation = Obligation { @@ -1642,7 +1623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } self.assemble_candidates_from_projected_tys(obligation, &mut candidates); - self.assemble_candidates_from_caller_bounds(stack, &mut candidates, recursion_depth)?; + self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?; // Auto implementations have lower priority, so we only // consider triggering a default if there is no other impl that can apply. if candidates.vec.is_empty() { @@ -1775,7 +1756,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, - recursion_depth: usize ) -> Result<(), SelectionError<'tcx>> { debug!( "assemble_candidates_from_caller_bounds({:?})", @@ -1797,7 +1777,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // keep only those bounds which may apply, and propagate overflow if it occurs let mut param_candidates = vec![]; for bound in matching_bounds { - let wc = self.evaluate_where_clause(stack, bound.clone(), recursion_depth)?; + let wc = self.evaluate_where_clause(stack, bound.clone())?; if wc.may_apply() { param_candidates.push(ParamCandidate(bound)); } @@ -1812,13 +1792,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, - recursion_depth: usize ) -> Result { self.evaluation_probe(|this| { match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => { - this.evaluate_predicates_recursively(stack.list(), obligations.iter(), - recursion_depth) + this.evaluate_predicates_recursively(stack.list(), obligations.iter()) } Err(()) => Ok(EvaluatedToErr), } From 03cd934ba9f7ceb1a1b048b6ed9caa0956a1bd8d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 20 Dec 2018 04:02:12 -0500 Subject: [PATCH 0033/1064] Ensure that we properly increment obligation depth --- src/librustc/traits/select.rs | 45 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7931943c90959..2eb717c7c7f5f 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -42,7 +42,7 @@ use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; use std::cmp; -use std::fmt; +use std::fmt::{self, Display}; use std::iter; use std::rc::Rc; use util::nodemap::{FxHashMap, FxHashSet}; @@ -660,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { { let mut result = EvaluatedToOk; for obligation in predicates { - let eval = self.evaluate_predicate_recursively(stack, obligation)?; + let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?; debug!( "evaluate_predicate_recursively({:?}) = {:?}", obligation, eval @@ -682,13 +682,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: PredicateObligation<'tcx>, ) -> Result { debug!("evaluate_predicate_recursively({:?})", obligation); - self.check_recursion_limit(obligation)?; + self.check_recursion_limit(&obligation)?; match obligation.predicate { ty::Predicate::Trait(ref t) => { debug_assert!(!t.has_escaping_bound_vars()); let mut obligation = obligation.with(t.clone()); - obligation.recursion_depth += 1 + obligation.recursion_depth += 1; self.evaluate_trait_predicate_recursively(previous_stack, obligation) } @@ -697,11 +697,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match self.infcx .subtype_predicate(&obligation.cause, obligation.param_env, p) { - Some(Ok(InferOk { obligations, .. })) => { - for o in obligations.iter_mut() { - o.recursion_depth += 1 - } - self.evaluate_predicates_recursively(previous_stack, obligation.into_iter()) + Some(Ok(InferOk { mut obligations, .. })) => { + self.add_depth(obligations.iter_mut(), obligation.recursion_depth); + self.evaluate_predicates_recursively(previous_stack, obligations.into_iter()) } Some(Err(_)) => Ok(EvaluatedToErr), None => Ok(EvaluatedToAmbig), @@ -715,11 +713,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty, obligation.cause.span, ) { - Some(obligations) => { - for o in obligations.iter_mut() { - o.recursion_depth += 1 - } - self.evaluate_predicates_recursively(previous_stack, obligations.iter()) + Some(mut obligations) => { + self.add_depth(obligations.iter_mut(), obligation.recursion_depth); + self.evaluate_predicates_recursively(previous_stack, obligations.into_iter()) } None => Ok(EvaluatedToAmbig), }, @@ -741,10 +737,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::Predicate::Projection(ref data) => { let project_obligation = obligation.with(data.clone()); match project::poly_project_and_unify_type(self, &project_obligation) { - Ok(Some(subobligations)) => { - for o in subobligations.iter_mut() { - o.recursion_depth += 1 - } + Ok(Some(mut subobligations)) => { + self.add_depth(subobligations.iter_mut(), obligation.recursion_depth); let result = self.evaluate_predicates_recursively( previous_stack, subobligations.into_iter(), @@ -1016,7 +1010,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match this.confirm_candidate(stack.obligation, candidate) { Ok(selection) => this.evaluate_predicates_recursively( stack.list(), - selection.nested_obligations().iter(), + selection.nested_obligations().into_iter(), ), Err(..) => Ok(EvaluatedToErr), } @@ -1091,6 +1085,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .insert(trait_ref, WithDepNode::new(dep_node, result)); } + // Due to caching of projection results, it's possible for a subobligation + // to have a *lower* recursion_depth than the obligation used to create it. + // To ensure that obligation_depth never decreasees, we force all subobligations + // to have at least the depth of the original obligation. + fn add_depth>>(&self, it: I, + min_depth: usize) { + it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1); + } + // Check that the recursion limit has not been exceeded. // // The weird return type of this function allows it to be used with the 'try' (?) @@ -1098,7 +1101,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn check_recursion_limit>(&self, obligation: &Obligation<'tcx, T>, ) -> Result<(), OverflowError> { let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); - if obligaton.recursion_depth >= recursion_limit { + if obligation.recursion_depth >= recursion_limit { match self.query_mode { TraitQueryMode::Standard => { self.infcx().report_overflow_error(obligation, true); @@ -1796,7 +1799,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.evaluation_probe(|this| { match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => { - this.evaluate_predicates_recursively(stack.list(), obligations.iter()) + this.evaluate_predicates_recursively(stack.list(), obligations.into_iter()) } Err(()) => Ok(EvaluatedToErr), } From 1f08280555aa07a3070806049b0e270dde6fc483 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 20 Dec 2018 04:03:40 -0500 Subject: [PATCH 0034/1064] More tidy fixes --- src/librustc/traits/select.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 2eb717c7c7f5f..0c0d68c9b36b1 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -629,7 +629,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result { self.evaluation_probe(|this| { - this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation.clone()) + this.evaluate_predicate_recursively(TraitObligationStackList::empty(), + obligation.clone()) }) } @@ -699,7 +700,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { { Some(Ok(InferOk { mut obligations, .. })) => { self.add_depth(obligations.iter_mut(), obligation.recursion_depth); - self.evaluate_predicates_recursively(previous_stack, obligations.into_iter()) + self.evaluate_predicates_recursively(previous_stack,obligations.into_iter()) } Some(Err(_)) => Ok(EvaluatedToErr), None => Ok(EvaluatedToAmbig), @@ -1098,7 +1099,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // // The weird return type of this function allows it to be used with the 'try' (?) // operator within certain functions - fn check_recursion_limit>(&self, obligation: &Obligation<'tcx, T>, + fn check_recursion_limit>(&self,obligation:&Obligation<'tcx, T>, ) -> Result<(), OverflowError> { let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); if obligation.recursion_depth >= recursion_limit { From b1a8da6e6170ce3749d917e614bb28ad8dcb9ac0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 2 Jan 2019 21:19:03 -0500 Subject: [PATCH 0035/1064] Improve error generation, fixup recursion limits --- src/librustc/traits/select.rs | 34 +++++++++++++++---- src/test/run-pass/weird-exprs.rs | 2 +- .../ui/did_you_mean/recursion_limit.stderr | 8 +---- src/test/ui/error-codes/E0055.rs | 4 +-- src/test/ui/error-codes/E0055.stderr | 2 +- src/test/ui/error-codes/E0275.stderr | 34 +------------------ src/test/ui/issues/issue-20413.stderr | 34 +------------------ 7 files changed, 35 insertions(+), 83 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 0c0d68c9b36b1..75ed8ddcefea4 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -682,8 +682,20 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: PredicateObligation<'tcx>, ) -> Result { - debug!("evaluate_predicate_recursively({:?})", obligation); - self.check_recursion_limit(&obligation)?; + debug!("evaluate_predicate_recursively(previous_stack={:?}, obligation={:?})", + previous_stack.head(), obligation); + + // Previous_stack stores a TraitObligatiom, while 'obligation' is + // a PredicateObligation. These are distinct types, so we can't + // use any Option combinator method that would force them to be + // the same + match previous_stack.head() { + Some(h) => self.check_recursion_limit(&obligation, h.obligation)?, + None => self.check_recursion_limit(&obligation, &obligation)? + } + + //self.check_recursion_limit(&obligation, previous_stack.head() + // .map_or(&obligation, |s| s.obligation))?; match obligation.predicate { ty::Predicate::Trait(ref t) => { @@ -1011,7 +1023,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match this.confirm_candidate(stack.obligation, candidate) { Ok(selection) => this.evaluate_predicates_recursively( stack.list(), - selection.nested_obligations().into_iter(), + selection.nested_obligations().into_iter().map(|o| { + //o.recursion_depth = 0; + o + }) ), Err(..) => Ok(EvaluatedToErr), } @@ -1099,13 +1114,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // // The weird return type of this function allows it to be used with the 'try' (?) // operator within certain functions - fn check_recursion_limit>(&self,obligation:&Obligation<'tcx, T>, + fn check_recursion_limit, V: Display + TypeFoldable<'tcx>>( + &self, + obligation: &Obligation<'tcx, T>, + error_obligation: &Obligation<'tcx, V> ) -> Result<(), OverflowError> { let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); if obligation.recursion_depth >= recursion_limit { match self.query_mode { TraitQueryMode::Standard => { - self.infcx().report_overflow_error(obligation, true); + self.infcx().report_overflow_error(error_obligation, true); } TraitQueryMode::Canonical => { return Err(OverflowError); @@ -1131,7 +1149,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { // Watch out for overflow. This intentionally bypasses (and does // not update) the cache. - self.check_recursion_limit(&stack.obligation)?; + self.check_recursion_limit(&stack.obligation, &stack.obligation)?; // Check the cache. Note that we freshen the trait-ref @@ -3826,6 +3844,10 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> { fn with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx> { TraitObligationStackList { head: Some(r) } } + + fn head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>> { + self.head + } } impl<'o, 'tcx> Iterator for TraitObligationStackList<'o, 'tcx> { diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index 6d0c5c11732f2..7ce7e29e87235 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -4,7 +4,7 @@ #![allow(unused_parens)] // compile-flags: -Z borrowck=compare -#![recursion_limit = "128"] +#![recursion_limit = "256"] use std::cell::Cell; use std::mem::swap; diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index 08947fd7fdcba..292a80faa7420 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -1,16 +1,10 @@ -error[E0275]: overflow evaluating the requirement `K: std::marker::Send` +error[E0275]: overflow evaluating the requirement `E: std::marker::Send` --> $DIR/recursion_limit.rs:34:5 | LL | is_send::(); //~ ERROR overflow evaluating the requirement | ^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate - = note: required because it appears within the type `J` - = note: required because it appears within the type `I` - = note: required because it appears within the type `H` - = note: required because it appears within the type `G` - = note: required because it appears within the type `F` - = note: required because it appears within the type `E` = note: required because it appears within the type `D` = note: required because it appears within the type `C` = note: required because it appears within the type `B` diff --git a/src/test/ui/error-codes/E0055.rs b/src/test/ui/error-codes/E0055.rs index a3ade92d24f4c..b525575d98d46 100644 --- a/src/test/ui/error-codes/E0055.rs +++ b/src/test/ui/error-codes/E0055.rs @@ -1,4 +1,4 @@ -#![recursion_limit="2"] +#![recursion_limit="5"] struct Foo; impl Foo { @@ -7,7 +7,7 @@ impl Foo { fn main() { let foo = Foo; - let ref_foo = &&Foo; + let ref_foo = &&&&&Foo; ref_foo.foo(); //~^ ERROR E0055 } diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr index cd2bd923d5a0f..d06566ffbe9a9 100644 --- a/src/test/ui/error-codes/E0055.stderr +++ b/src/test/ui/error-codes/E0055.stderr @@ -4,7 +4,7 @@ error[E0055]: reached the recursion limit while auto-dereferencing `Foo` LL | ref_foo.foo(); | ^^^ deref recursion limit reached | - = help: consider adding a `#![recursion_limit="4"]` attribute to your crate + = help: consider adding a `#![recursion_limit="10"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index 817b4828cc4ab..df3b362f82401 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -1,42 +1,10 @@ -error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: std::marker::Sized` +error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: std::marker::Sized` --> $DIR/E0275.rs:5:1 | LL | impl Foo for T where Bar: Foo {} //~ ERROR E0275 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 20e57583f1daa..043df0e392b45 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -6,7 +6,7 @@ LL | struct NoData; | = help: consider removing `T` or using a marker such as `std::marker::PhantomData` -error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: std::marker::Sized` +error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: std::marker::Sized` --> $DIR/issue-20413.rs:8:1 | LL | / impl Foo for T where NoData: Foo { @@ -18,38 +18,6 @@ LL | | } | |_^ | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` From 9a64d79365fb0eaa52afb0be9265c86d9fe3e490 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 2 Jan 2019 21:21:47 -0500 Subject: [PATCH 0036/1064] Cleanup code --- src/librustc/traits/select.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 75ed8ddcefea4..e5eb8e24a427d 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -694,9 +694,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { None => self.check_recursion_limit(&obligation, &obligation)? } - //self.check_recursion_limit(&obligation, previous_stack.head() - // .map_or(&obligation, |s| s.obligation))?; - match obligation.predicate { ty::Predicate::Trait(ref t) => { debug_assert!(!t.has_escaping_bound_vars()); @@ -1023,10 +1020,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match this.confirm_candidate(stack.obligation, candidate) { Ok(selection) => this.evaluate_predicates_recursively( stack.list(), - selection.nested_obligations().into_iter().map(|o| { - //o.recursion_depth = 0; - o - }) + selection.nested_obligations().into_iter() ), Err(..) => Ok(EvaluatedToErr), } From dadd7bb6f46b1d646abedcb327b4da111caf042e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 3 Jan 2019 01:30:30 -0500 Subject: [PATCH 0037/1064] Fix diagnostic error --- src/librustc_typeck/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 5910a8b3110d0..0645db66c69f6 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -516,7 +516,7 @@ recursion limit (which can be set via the `recursion_limit` attribute). For a somewhat artificial example: ```compile_fail,E0055 -#![recursion_limit="2"] +#![recursion_limit="5"] struct Foo; @@ -526,9 +526,9 @@ impl Foo { fn main() { let foo = Foo; - let ref_foo = &&Foo; + let ref_foo = &&&&&Foo; - // error, reached the recursion limit while auto-dereferencing `&&Foo` + // error, reached the recursion limit while auto-dereferencing `&&&&&Foo` ref_foo.foo(); } ``` From 726bdec60f8ef8c9dbb57a87cc5f2a03763b1f70 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 3 Jan 2019 22:15:38 -0500 Subject: [PATCH 0038/1064] Improve comment --- src/librustc/traits/select.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e5eb8e24a427d..8b9863fa27879 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1095,8 +1095,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .insert(trait_ref, WithDepNode::new(dep_node, result)); } - // Due to caching of projection results, it's possible for a subobligation + // For various reasons, it's possible for a subobligation // to have a *lower* recursion_depth than the obligation used to create it. + // Projection sub-obligations may be returned from the projection cache, + // which results in obligations with an 'old' recursion_depth. + // Additionally, methods like ty::wf::obligations and + // InferCtxt.subtype_predicate produce subobligations without + // taking in a 'parent' depth, causing the generated subobligations + // to have a recursion_depth of 0 + // // To ensure that obligation_depth never decreasees, we force all subobligations // to have at least the depth of the original obligation. fn add_depth>>(&self, it: I, From adadefd8741d84ebfb5884fbd12f3202cd6fdb4f Mon Sep 17 00:00:00 2001 From: purple-ice Date: Fri, 4 Jan 2019 13:00:26 +0200 Subject: [PATCH 0039/1064] Fix changes for E0106, E0261 Replaced impl block dock with suggested one and made sure that blocks compile. --- src/librustc/diagnostics.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 50beacf3e8cbb..dd5144b1568fb 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -362,9 +362,9 @@ struct Foo1 { x: &bool } // ^ expected lifetime parameter struct Foo2<'a> { x: &'a bool } // correct -impl Foo2 { ... } +impl Foo2 {} // ^ expected lifetime parameter -impl<'a> Foo2<'a> { ... } // correct +impl<'a> Foo2<'a> {} // correct struct Bar1 { x: Foo2 } // ^^^^ expected lifetime parameter @@ -777,21 +777,32 @@ struct Foo<'a> { } ``` -Implementations need their own lifetime declarations: +Impl blocks declare lifetime parameters separately. You need to add lifetime +parameters to an impl block if you're implementing a type that has a lifetime +parameter of its own. +For example: -``` -// error, undeclared lifetime +```compile_fail,E0261 +// error, use of undeclared lifetime name `'a` impl Foo<'a> { - ... + fn foo<'a>(x: &'a str) {} +} + +struct Foo<'a> { + x: &'a str, } ``` -Which are declared like this: +This is fixed by declaring impl block like this: ``` // correct impl<'a> Foo<'a> { - ... + fn foo(x: &'a str) {} +} + +struct Foo<'a> { + x: &'a str, } ``` "##, From c120199116439827a89a0ac0f24f91f99dbed60f Mon Sep 17 00:00:00 2001 From: folex <0xdxdy@gmail.com> Date: Sat, 5 Jan 2019 05:56:23 +0300 Subject: [PATCH 0040/1064] Show suggestion to use .char().nth() and link to The Book on unimplemented Index trait --- src/libcore/ops/index.rs | 30 ++++++++++++++++++++++++++++++ src/test/ui/str/str-idx.stderr | 2 ++ src/test/ui/str/str-mut-idx.stderr | 2 ++ 3 files changed, 34 insertions(+) diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index 4f55c68ecd4ae..6cfa36741d0ca 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -51,6 +51,21 @@ /// ``` #[lang = "index"] #[rustc_on_unimplemented( + on( + _Self="&str", + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), + on( + _Self="str", + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), + on( + _Self="std::string::String", + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), message="the type `{Self}` cannot be indexed by `{Idx}`", label="`{Self}` cannot be indexed by `{Idx}`", )] @@ -141,6 +156,21 @@ pub trait Index { /// ``` #[lang = "index_mut"] #[rustc_on_unimplemented( + on( + _Self="&str", + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), + on( + _Self="str", + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), + on( + _Self="std::string::String", + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), message="the type `{Self}` cannot be mutably indexed by `{Idx}`", label="`{Self}` cannot be mutably indexed by `{Idx}`", )] diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 108096df9c41c..71b1747492329 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -5,6 +5,8 @@ LL | let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integ | ^^^^ `str` cannot be indexed by `{integer}` | = help: the trait `std::ops::Index<{integer}>` is not implemented for `str` + = note: you can use `.chars().nth()` or `.bytes().nth()` + see chapter in The Book error: aborting due to previous error diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index a8ab38e5ab6a5..f1e969696b458 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -29,6 +29,8 @@ LL | s[1usize] = bot(); | ^^^^^^^^^ `str` cannot be mutably indexed by `usize` | = help: the trait `std::ops::IndexMut` is not implemented for `str` + = note: you can use `.chars().nth()` or `.bytes().nth()` + see chapter in The Book error: aborting due to 3 previous errors From 96678df83821407f2112028cc0099866cb548c49 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 5 Jan 2019 12:41:12 -0500 Subject: [PATCH 0041/1064] Cleanup PartialEq docs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cleanup the `impl PartialEq for Book` implementation - Implement `impl PartialEq for BookFormat` so it’s symmetric - Fixes https://github.com/rust-lang/rust/issues/53844. - Removes the last example since it appears to be redundant with the previous two examples. --- src/libcore/cmp.rs | 56 ++++++++-------------------------------------- 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index f420d0d00a401..cf24e08e2e706 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -107,67 +107,29 @@ use self::Ordering::*; /// format: BookFormat, /// } /// +/// // Implement == comparisons /// impl PartialEq for Book { /// fn eq(&self, other: &BookFormat) -> bool { -/// match (&self.format, other) { -/// (BookFormat::Paperback, BookFormat::Paperback) => true, -/// (BookFormat::Hardback, BookFormat::Hardback) => true, -/// (BookFormat::Ebook, BookFormat::Ebook) => true, -/// (_, _) => false, -/// } +/// self.format == *other /// } /// } /// -/// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; -/// -/// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); -/// ``` -/// -/// By changing `impl PartialEq for Book` to `impl PartialEq for Book`, -/// we've changed what type we can use on the right side of the `==` operator. -/// This lets us use it in the `assert!` statements at the bottom. -/// -/// You can also combine these implementations to let the `==` operator work with -/// two different types: -/// -/// ``` -/// enum BookFormat { -/// Paperback, -/// Hardback, -/// Ebook, -/// } -/// -/// struct Book { -/// isbn: i32, -/// format: BookFormat, -/// } -/// -/// impl PartialEq for Book { -/// fn eq(&self, other: &BookFormat) -> bool { -/// match (&self.format, other) { -/// (&BookFormat::Paperback, &BookFormat::Paperback) => true, -/// (&BookFormat::Hardback, &BookFormat::Hardback) => true, -/// (&BookFormat::Ebook, &BookFormat::Ebook) => true, -/// (_, _) => false, -/// } -/// } -/// } -/// -/// impl PartialEq for Book { +/// // Implement == comparisons +/// impl PartialEq for BookFormat { /// fn eq(&self, other: &Book) -> bool { -/// self.isbn == other.isbn +/// *other == self.format /// } /// } /// /// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; -/// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; /// /// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); -/// assert!(b1 == b2); +/// assert!(BookFormat::Ebook != b1); /// ``` /// +/// By changing `impl PartialEq for Book` to `impl PartialEq for Book`, +/// we allow `BookFormat`s to be compared with `Book`s. +/// /// # Examples /// /// ``` From b91d211b40300a3c026b330e50a6e3e19d71351c Mon Sep 17 00:00:00 2001 From: Peter Jin Date: Mon, 31 Dec 2018 10:58:13 -0800 Subject: [PATCH 0042/1064] Add a target option "merge-functions" taking values in ("disabled", "trampolines", or "aliases (the default)) to allow targets to opt out of the MergeFunctions LLVM pass. Also add a corresponding -Z option with the same name and values. This works around: https://github.com/rust-lang/rust/issues/57356 Motivation: Basically, the problem is that the MergeFunctions pass, which rustc currently enables by default at -O2 and -O3, and `extern "ptx-kernel"` functions (specific to the NVPTX target) are currently not compatible with each other. If the MergeFunctions pass is allowed to run, rustc can generate invalid PTX assembly (i.e. a PTX file that is not accepted by the native PTX assembler ptxas). Therefore we would like a way to opt out of the MergeFunctions pass, which is what our target option does. Related work: The current behavior of rustc is to enable MergeFunctions at -O2 and -O3, and also to enable the use of function aliases within MergeFunctions. MergeFunctions both with and without function aliases is incompatible with the NVPTX target. clang's "solution" is to have a "-fmerge-functions" flag that opts in to the MergeFunctions pass, but it is not enabled by default. --- src/librustc/session/config.rs | 28 +++++++++-- src/librustc_codegen_llvm/llvm_util.rs | 10 +++- src/librustc_codegen_ssa/back/write.rs | 21 +++++++- src/librustc_target/spec/mod.rs | 66 +++++++++++++++++++++++++- 4 files changed, 117 insertions(+), 8 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 33409f9b4a74f..ca4ab15d79b1d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -6,7 +6,7 @@ use std::str::FromStr; use session::{early_error, early_warn, Session}; use session::search_paths::SearchPath; -use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; +use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel}; use rustc_target::spec::{Target, TargetTriple}; use lint; use middle::cstore; @@ -808,13 +808,16 @@ macro_rules! options { pub const parse_cross_lang_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \ or the path to the linker plugin"); + pub const parse_merge_functions: Option<&str> = + Some("one of: `disabled`, `trampolines`, or `aliases`"); } #[allow(dead_code)] mod $mod_set { use super::{$struct_name, Passes, Sanitizer, LtoCli, CrossLangLto}; - use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; + use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel}; use std::path::PathBuf; + use std::str::FromStr; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -1046,6 +1049,14 @@ macro_rules! options { }; true } + + fn parse_merge_functions(slot: &mut Option, v: Option<&str>) -> bool { + match v.and_then(|s| MergeFunctions::from_str(s).ok()) { + Some(mergefunc) => *slot = Some(mergefunc), + _ => return false, + } + true + } } ) } @@ -1380,6 +1391,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "whether to use the PLT when calling into shared libraries; only has effect for PIC code on systems with ELF binaries (default: PLT is disabled if full relro is enabled)"), + merge_functions: Option = (None, parse_merge_functions, [TRACKED], + "control the operation of the MergeFunctions LLVM pass, taking + the same values as the target option of the same name"), } pub fn default_lib_output() -> CrateType { @@ -2398,7 +2412,7 @@ mod dep_tracking { use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes, Passes, Sanitizer, LtoCli, CrossLangLto}; use syntax::feature_gate::UnstableFeatures; - use rustc_target::spec::{PanicStrategy, RelroLevel, TargetTriple}; + use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple}; use syntax::edition::Edition; pub trait DepTrackingHash { @@ -2441,12 +2455,14 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option<(String, u64)>); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(CrateType); + impl_dep_tracking_hash_via_hash!(MergeFunctions); impl_dep_tracking_hash_via_hash!(PanicStrategy); impl_dep_tracking_hash_via_hash!(RelroLevel); impl_dep_tracking_hash_via_hash!(Passes); @@ -2532,7 +2548,7 @@ mod tests { use std::iter::FromIterator; use std::path::PathBuf; use super::{Externs, OutputType, OutputTypes}; - use rustc_target::spec::{PanicStrategy, RelroLevel}; + use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; use syntax::edition::{Edition, DEFAULT_EDITION}; use syntax; @@ -3187,6 +3203,10 @@ mod tests { opts = reference.clone(); opts.debugging_opts.cross_lang_lto = CrossLangLto::LinkerPluginAuto; assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index ad9ebbcde8ab9..dc70ebcf943a5 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -3,6 +3,7 @@ use back::write::create_target_machine; use llvm; use rustc::session::Session; use rustc::session::config::PrintRequest; +use rustc_target::spec::MergeFunctions; use libc::c_int; use std::ffi::CString; use syntax::feature_gate::UnstableFeatures; @@ -61,7 +62,14 @@ unsafe fn configure_llvm(sess: &Session) { add("-disable-preinline"); } if llvm::LLVMRustIsRustLLVM() { - add("-mergefunc-use-aliases"); + match sess.opts.debugging_opts.merge_functions + .unwrap_or(sess.target.target.options.merge_functions) { + MergeFunctions::Disabled | + MergeFunctions::Trampolines => {} + MergeFunctions::Aliases => { + add("-mergefunc-use-aliases"); + } + } } // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index fb3e7ea696363..39bdc70f8322e 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -24,6 +24,7 @@ use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; use rustc_errors::emitter::{Emitter}; +use rustc_target::spec::MergeFunctions; use syntax::attr; use syntax::ext::hygiene::Mark; use syntax_pos::MultiSpan; @@ -152,8 +153,24 @@ impl ModuleConfig { sess.opts.optimize == config::OptLevel::Aggressive && !sess.target.target.options.is_like_emscripten; - self.merge_functions = sess.opts.optimize == config::OptLevel::Default || - sess.opts.optimize == config::OptLevel::Aggressive; + // Some targets (namely, NVPTX) interact badly with the MergeFunctions + // pass. This is because MergeFunctions can generate new function calls + // which may interfere with the target calling convention; e.g. for the + // NVPTX target, PTX kernels should not call other PTX kernels. + // MergeFunctions can also be configured to generate aliases instead, + // but aliases are not supported by some backends (again, NVPTX). + // Therefore, allow targets to opt out of the MergeFunctions pass, + // but otherwise keep the pass enabled (at O2 and O3) since it can be + // useful for reducing code size. + self.merge_functions = match sess.opts.debugging_opts.merge_functions + .unwrap_or(sess.target.target.options.merge_functions) { + MergeFunctions::Disabled => false, + MergeFunctions::Trampolines | + MergeFunctions::Aliases => { + sess.opts.optimize == config::OptLevel::Default || + sess.opts.optimize == config::OptLevel::Aggressive + } + }; } pub fn bitcode_needed(&self) -> bool { diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index f42b0a1c3c958..3a21ca19b176b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -217,6 +217,46 @@ impl ToJson for RelroLevel { } } +#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] +pub enum MergeFunctions { + Disabled, + Trampolines, + Aliases +} + +impl MergeFunctions { + pub fn desc(&self) -> &str { + match *self { + MergeFunctions::Disabled => "disabled", + MergeFunctions::Trampolines => "trampolines", + MergeFunctions::Aliases => "aliases", + } + } +} + +impl FromStr for MergeFunctions { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "disabled" => Ok(MergeFunctions::Disabled), + "trampolines" => Ok(MergeFunctions::Trampolines), + "aliases" => Ok(MergeFunctions::Aliases), + _ => Err(()), + } + } +} + +impl ToJson for MergeFunctions { + fn to_json(&self) -> Json { + match *self { + MergeFunctions::Disabled => "disabled".to_json(), + MergeFunctions::Trampolines => "trampolines".to_json(), + MergeFunctions::Aliases => "aliases".to_json(), + } + } +} + pub type LinkArgs = BTreeMap>; pub type TargetResult = Result; @@ -690,7 +730,15 @@ pub struct TargetOptions { /// If set, have the linker export exactly these symbols, instead of using /// the usual logic to figure this out from the crate itself. - pub override_export_symbols: Option> + pub override_export_symbols: Option>, + + /// Determines how or whether the MergeFunctions LLVM pass should run for + /// this target. Either "disabled", "trampolines", or "aliases". + /// The MergeFunctions pass is generally useful, but some targets may need + /// to opt out. The default is "aliases". + /// + /// Workaround for: https://github.com/rust-lang/rust/issues/57356 + pub merge_functions: MergeFunctions } impl Default for TargetOptions { @@ -773,6 +821,7 @@ impl Default for TargetOptions { requires_uwtable: false, simd_types_indirect: true, override_export_symbols: None, + merge_functions: MergeFunctions::Aliases, } } } @@ -875,6 +924,19 @@ impl Target { .map(|o| o.as_u64() .map(|s| base.options.$key_name = Some(s))); } ); + ($key_name:ident, MergeFunctions) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { + match s.parse::() { + Ok(mergefunc) => base.options.$key_name = mergefunc, + _ => return Some(Err(format!("'{}' is not a valid value for \ + merge-functions. Use 'disabled', \ + 'trampolines', or 'aliases'.", + s))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); ($key_name:ident, PanicStrategy) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { @@ -1064,6 +1126,7 @@ impl Target { key!(requires_uwtable, bool); key!(simd_types_indirect, bool); key!(override_export_symbols, opt_list); + key!(merge_functions, MergeFunctions)?; if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1275,6 +1338,7 @@ impl ToJson for Target { target_option_val!(requires_uwtable); target_option_val!(simd_types_indirect); target_option_val!(override_export_symbols); + target_option_val!(merge_functions); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() From 0d3dfdf6aadd7dd241956fa234bdd01de7291e5f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 5 Jan 2019 22:52:13 -0500 Subject: [PATCH 0043/1064] Fix compile error --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index cf24e08e2e706..89afe7057b17b 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -117,7 +117,7 @@ use self::Ordering::*; /// // Implement == comparisons /// impl PartialEq for BookFormat { /// fn eq(&self, other: &Book) -> bool { -/// *other == self.format +/// *self == other.format /// } /// } /// From 319a2c1cc2a4d99d5b1d6fb424c77963fd668f24 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 6 Jan 2019 11:08:34 -0500 Subject: [PATCH 0044/1064] add missing derive to fix compile error --- src/libcore/cmp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 89afe7057b17b..5b78aa632d17f 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -65,6 +65,7 @@ use self::Ordering::*; /// the same book if their ISBN matches, even if the formats differ: /// /// ``` +/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, From bbbabdfc52eaa897c965bf10f50af4fc1512d4f0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 6 Jan 2019 15:18:22 -0500 Subject: [PATCH 0045/1064] Update cmp.rs --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 5b78aa632d17f..64e37ec5a56cb 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -65,7 +65,6 @@ use self::Ordering::*; /// the same book if their ISBN matches, even if the formats differ: /// /// ``` -/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, @@ -97,6 +96,7 @@ use self::Ordering::*; /// For example, let's tweak our previous code a bit: /// /// ``` +/// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, /// Hardback, From 6c60662b26847a0d8670d298d6a5e95fade576df Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Fri, 4 Jan 2019 11:12:54 -0600 Subject: [PATCH 0046/1064] Use correct tracking issue for c_variadic Fixes #57306 --- src/libcore/ffi.rs | 22 +++++++++++----------- src/libstd/ffi/mod.rs | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 0717a88b6b8f3..8a35051434dd4 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -49,7 +49,7 @@ impl fmt::Debug for c_void { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] extern { type VaListImpl; } @@ -74,7 +74,7 @@ impl fmt::Debug for VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] struct VaListImpl { stack: *mut (), gr_top: *mut (), @@ -90,7 +90,7 @@ struct VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] struct VaListImpl { gpr: u8, fpr: u8, @@ -106,7 +106,7 @@ struct VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] struct VaListImpl { gp_offset: i32, fp_offset: i32, @@ -120,7 +120,7 @@ struct VaListImpl { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] #[repr(transparent)] pub struct VaList<'a>(&'a mut VaListImpl); @@ -140,7 +140,7 @@ mod sealed_trait { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub trait VaArgSafe {} } @@ -150,7 +150,7 @@ macro_rules! impl_va_arg_safe { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] impl sealed_trait::VaArgSafe for $t {} )+ } @@ -163,12 +163,12 @@ impl_va_arg_safe!{f64} #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] impl sealed_trait::VaArgSafe for *mut T {} #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] impl sealed_trait::VaArgSafe for *const T {} impl<'a> VaList<'a> { @@ -176,7 +176,7 @@ impl<'a> VaList<'a> { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub unsafe fn arg(&mut self) -> T { va_arg(self) } @@ -185,7 +185,7 @@ impl<'a> VaList<'a> { #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub unsafe fn copy(&self, f: F) -> R where F: for<'copy> FnOnce(VaList<'copy>) -> R { #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 62081e713f139..7a38f0ebd5a57 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -169,7 +169,7 @@ pub use core::ffi::c_void; #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", - issue = "27745")] + issue = "44930")] pub use core::ffi::VaList; mod c_str; From 7cdcdb5dc0b282d5926f0edd7f05b13fbf239197 Mon Sep 17 00:00:00 2001 From: king6cong Date: Wed, 2 Jan 2019 15:18:13 +0800 Subject: [PATCH 0047/1064] Update reference of rlibc crate to compiler-builtins crate --- src/libcore/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index b2cafc4cede2e..c94f0ab03014d 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -24,7 +24,7 @@ //! often generated by LLVM. Additionally, this library can make explicit //! calls to these functions. Their signatures are the same as found in C. //! These functions are often provided by the system libc, but can also be -//! provided by the [rlibc crate](https://crates.io/crates/rlibc). +//! provided by the [compiler-builtins crate](https://crates.io/crates/compiler_builtins). //! //! * `rust_begin_panic` - This function takes four arguments, a //! `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments From 5581207182d69a03f09d48c38e279cd7b99e422b Mon Sep 17 00:00:00 2001 From: king6cong Date: Wed, 9 Jan 2019 19:42:25 +0800 Subject: [PATCH 0048/1064] Remove outdated comment --- config.toml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.toml.example b/config.toml.example index c68d358b6a67e..23943d34b7ca8 100644 --- a/config.toml.example +++ b/config.toml.example @@ -288,7 +288,7 @@ #codegen-units-std = 1 # Whether or not debug assertions are enabled for the compiler and standard -# library. Also enables compilation of debug! and trace! logging macros. +# library. #debug-assertions = false # Whether or not debuginfo is emitted From 5fc6fc3d90b32c504b3ffe1802e48987cb7a7e64 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 8 Jan 2019 15:44:57 -0500 Subject: [PATCH 0049/1064] Improve docs for Formatter --- src/libcore/fmt/mod.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index ec1aeb8a7d1e9..06cb1b02fcf4c 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -232,9 +232,18 @@ impl Write for &mut W { } } -/// A struct to represent both where to emit formatting strings to and how they -/// should be formatted. A mutable version of this is passed to all formatting -/// traits. +/// Configuration for formatting. +/// +/// A `Formatter` represents various options related to formatting. Users do not +/// construct `Formatter`s directly; a mutable reference to one is passed to +/// the `fmt` method of all formatting traits, like [`Debug`] and [`Display`]. +/// +/// To interact with a `Formatter`, you'll call various methods to change the +/// various options related to formatting. For examples, please see the +/// documentation of the methods defined on `Formatter` below. +/// +/// [`Debug`]: trait.Debug.html +/// [`Display`]: trait.Display.html #[allow(missing_debug_implementations)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Formatter<'a> { From 430553bc7766ecdbdb04113ef0137e6174e0dba2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 8 Jan 2019 10:50:24 -0500 Subject: [PATCH 0050/1064] introduce `trait_def_id` method Co-Authored-By: Alexander Regueiro --- src/librustc/hir/mod.rs | 15 +++++++++++++++ src/librustc_typeck/astconv.rs | 22 ++++------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7e87171a5edf7..03a61dd03a9f5 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -10,6 +10,7 @@ pub use self::PrimTy::*; pub use self::UnOp::*; pub use self::UnsafeSource::*; +use errors::FatalError; use hir::def::Def; use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; use util::nodemap::{NodeMap, FxHashSet}; @@ -2053,6 +2054,20 @@ pub struct TraitRef { pub hir_ref_id: HirId, } +impl TraitRef { + /// Get the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias. + pub fn trait_def_id(&self) -> DefId { + match self.path.def { + Def::Trait(did) => did, + Def::TraitAlias(did) => did, + Def::Err => { + FatalError.raise(); + } + _ => unreachable!(), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct PolyTraitRef { /// The `'a` in `<'a> Foo<&'a T>` diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8e5eaa18b9de0..a841bbab5867b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2,7 +2,7 @@ //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an //! instance of `AstConv`. -use errors::{Applicability, FatalError, DiagnosticId}; +use errors::{Applicability, DiagnosticId}; use hir::{self, GenericArg, GenericArgs}; use hir::def::Def; use hir::def_id::DefId; @@ -689,27 +689,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); - let trait_def_id = self.trait_def_id(trait_ref); self.ast_path_to_mono_trait_ref(trait_ref.path.span, - trait_def_id, + trait_ref.trait_def_id(), self_ty, trait_ref.path.segments.last().unwrap()) } - /// Get the `DefId` of the given trait ref. It _must_ actually be a trait. - fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId { - let path = &trait_ref.path; - match path.def { - Def::Trait(trait_def_id) => trait_def_id, - Def::TraitAlias(alias_def_id) => alias_def_id, - Def::Err => { - FatalError.raise(); - } - _ => unreachable!(), - } - } - - /// The given trait ref must actually be a trait. + /// The given trait-ref must actually be a trait. pub(super) fn instantiate_poly_trait_ref_inner(&self, trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>, @@ -717,7 +703,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { speculative: bool) -> (ty::PolyTraitRef<'tcx>, Option>) { - let trait_def_id = self.trait_def_id(trait_ref); + let trait_def_id = trait_ref.trait_def_id(); debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); From 1336b8e8c7417fdde5384119a588a11ef0818cf3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 8 Jan 2019 10:55:18 -0500 Subject: [PATCH 0051/1064] integrate trait aliases into def-paths / metadata Co-authored-by: Alexander Regueiro --- src/librustc/hir/map/def_collector.rs | 6 +-- src/librustc/hir/map/definitions.rs | 6 ++- src/librustc/traits/select.rs | 2 +- src/librustc/ty/item_path.rs | 1 + src/librustc/ty/mod.rs | 12 ------ src/librustc/ty/util.rs | 9 ++++ src/librustc/util/ppaux.rs | 1 + src/librustc_metadata/decoder.rs | 46 ++++++++++++++------- src/librustc_metadata/encoder.rs | 17 ++++++-- src/librustc_metadata/schema.rs | 13 ++++++ src/librustc_resolve/build_reduced_graph.rs | 3 ++ src/librustc_traits/lowering/mod.rs | 3 +- src/librustc_typeck/collect.rs | 2 +- 13 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index bc0a64ae7c5d8..c9b4b2bb99717 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -120,10 +120,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { let def_data = match i.node { ItemKind::Impl(..) => DefPathData::Impl, ItemKind::Trait(..) => DefPathData::Trait(i.ident.as_interned_str()), + ItemKind::TraitAlias(..) => DefPathData::TraitAlias(i.ident.as_interned_str()), ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | - ItemKind::TraitAlias(..) | ItemKind::Existential(..) | - ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) => - DefPathData::TypeNs(i.ident.as_interned_str()), + ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | + ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()), ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => { return visit::walk_item(self, i); } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 6b707dd2dcc80..1b7445199475c 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -373,7 +373,9 @@ pub enum DefPathData { /// GlobalMetaData identifies a piece of crate metadata that is global to /// a whole crate (as opposed to just one item). GlobalMetaData components /// are only supposed to show up right below the crate root. - GlobalMetaData(InternedString) + GlobalMetaData(InternedString), + /// A trait alias. + TraitAlias(InternedString), } #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, @@ -615,6 +617,7 @@ impl DefPathData { match *self { TypeNs(name) | Trait(name) | + TraitAlias(name) | AssocTypeInTrait(name) | AssocTypeInImpl(name) | AssocExistentialInImpl(name) | @@ -642,6 +645,7 @@ impl DefPathData { let s = match *self { TypeNs(name) | Trait(name) | + TraitAlias(name) | AssocTypeInTrait(name) | AssocTypeInImpl(name) | AssocExistentialInImpl(name) | diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 6db6fe31fba70..4d478365e7276 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2154,7 +2154,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let def_id = obligation.predicate.def_id(); - if ty::is_trait_alias(self.tcx(), def_id) { + if self.tcx().is_trait_alias(def_id) { candidates.vec.push(TraitAliasCandidate(def_id.clone())); } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 417e14054d24f..9328de4f6a0a1 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -311,6 +311,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::Misc | data @ DefPathData::TypeNs(..) | data @ DefPathData::Trait(..) | + data @ DefPathData::TraitAlias(..) | data @ DefPathData::AssocTypeInTrait(..) | data @ DefPathData::AssocTypeInImpl(..) | data @ DefPathData::AssocExistentialInImpl(..) | diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a2c96e7cf9f66..e2f696b0974a7 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3178,18 +3178,6 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option, def_id: DefId) -> bool { - if let Some(node_id) = tcx.hir().as_local_node_id(def_id) { - if let Node::Item(item) = tcx.hir().get(node_id) { - if let hir::ItemKind::TraitAlias(..) = item.node { - return true; - } - } - } - false -} - /// See `ParamEnv` struct definition for details. fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index e989ef823e979..75fc0f716a2f6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -526,6 +526,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + /// True if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`). + pub fn is_trait_alias(self, def_id: DefId) -> bool { + if let DefPathData::TraitAlias(_) = self.def_key(def_id).disambiguated_data.data { + true + } else { + false + } + } + /// True if this def-id refers to the implicit constructor for /// a tuple struct like `struct Foo(u32)`. pub fn is_struct_constructor(self, def_id: DefId) -> bool { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 04e571863d42f..51e9192cd290d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -409,6 +409,7 @@ impl PrintContext { DefPathData::AssocTypeInImpl(_) | DefPathData::AssocExistentialInImpl(_) | DefPathData::Trait(_) | + DefPathData::TraitAlias(_) | DefPathData::Impl | DefPathData::TypeNs(_) => { break; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index dc8db5be5820a..1f07e8f478b5a 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -418,6 +418,7 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Mod(_) => Def::Mod(did), EntryKind::Variant(_) => Def::Variant(did), EntryKind::Trait(_) => Def::Trait(did), + EntryKind::TraitAlias(_) => Def::TraitAlias(did), EntryKind::Enum(..) => Def::Enum(did), EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang), EntryKind::ForeignType => Def::ForeignTy(did), @@ -520,17 +521,26 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { - let data = match self.entry(item_id).kind { - EntryKind::Trait(data) => data.decode((self, sess)), - _ => bug!(), - }; - - ty::TraitDef::new(self.local_def_id(item_id), - data.unsafety, - data.paren_sugar, - data.has_auto_impl, - data.is_marker, - self.def_path_table.def_path_hash(item_id)) + match self.entry(item_id).kind { + EntryKind::Trait(data) => { + let data = data.decode((self, sess)); + ty::TraitDef::new(self.local_def_id(item_id), + data.unsafety, + data.paren_sugar, + data.has_auto_impl, + data.is_marker, + self.def_path_table.def_path_hash(item_id)) + }, + EntryKind::TraitAlias(_) => { + ty::TraitDef::new(self.local_def_id(item_id), + hir::Unsafety::Normal, + false, + false, + false, + self.def_path_table.def_path_hash(item_id)) + }, + _ => bug!("def-index does not refer to trait or trait alias"), + } } fn get_variant(&self, @@ -615,10 +625,13 @@ impl<'a, 'tcx> CrateMetadata { item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::GenericPredicates<'tcx> { - match self.entry(item_id).kind { - EntryKind::Trait(data) => data.decode(self).super_predicates.decode((self, tcx)), - _ => bug!(), - } + let super_predicates = match self.entry(item_id).kind { + EntryKind::Trait(data) => data.decode(self).super_predicates, + EntryKind::TraitAlias(data) => data.decode(self).super_predicates, + _ => bug!("def-index does not refer to trait or trait alias"), + }; + + super_predicates.decode((self, tcx)) } pub fn get_generics(&self, @@ -1014,7 +1027,8 @@ impl<'a, 'tcx> CrateMetadata { } def_key.parent.and_then(|parent_index| { match self.entry(parent_index).kind { - EntryKind::Trait(_) => Some(self.local_def_id(parent_index)), + EntryKind::Trait(_) | + EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)), _ => None, } }) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 032a4656efcda..2522469086f67 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1131,8 +1131,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { EntryKind::Impl(self.lazy(&data)) } - hir::ItemKind::Trait(..) | - hir::ItemKind::TraitAlias(..) => { + hir::ItemKind::Trait(..) => { let trait_def = tcx.trait_def(def_id); let data = TraitData { unsafety: trait_def.unsafety, @@ -1144,6 +1143,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { EntryKind::Trait(self.lazy(&data)) } + hir::ItemKind::TraitAlias(..) => { + let data = TraitAliasData { + super_predicates: self.lazy(&tcx.super_predicates_of(def_id)), + }; + + EntryKind::TraitAlias(self.lazy(&data)) + } hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), }; @@ -1217,6 +1223,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { hir::ItemKind::Impl(..) | hir::ItemKind::Existential(..) | hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)), + hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)), _ => None, }, predicates: match item.node { @@ -1229,7 +1236,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { hir::ItemKind::Union(..) | hir::ItemKind::Impl(..) | hir::ItemKind::Existential(..) | - hir::ItemKind::Trait(..) => Some(self.encode_predicates(def_id)), + hir::ItemKind::Trait(..) | + hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)), _ => None, }, @@ -1239,7 +1247,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { // hack. (No reason not to expand it in the future if // necessary.) predicates_defined_on: match item.node { - hir::ItemKind::Trait(..) => Some(self.encode_predicates_defined_on(def_id)), + hir::ItemKind::Trait(..) | + hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates_defined_on(def_id)), _ => None, // not *wrong* for other kinds of items, but not needed }, diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 25f499bc31984..f3ff9747625f5 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -316,6 +316,7 @@ pub enum EntryKind<'tcx> { AssociatedType(AssociatedContainer), AssociatedExistential(AssociatedContainer), AssociatedConst(AssociatedContainer, ConstQualif, Lazy), + TraitAlias(Lazy>), } impl<'a, 'gcx> HashStable> for EntryKind<'gcx> { @@ -370,6 +371,9 @@ impl<'a, 'gcx> HashStable> for EntryKind<'gcx> { EntryKind::Trait(ref trait_data) => { trait_data.hash_stable(hcx, hasher); } + EntryKind::TraitAlias(ref trait_alias_data) => { + trait_alias_data.hash_stable(hcx, hasher); + } EntryKind::Impl(ref impl_data) => { impl_data.hash_stable(hcx, hasher); } @@ -474,6 +478,15 @@ impl_stable_hash_for!(struct TraitData<'tcx> { super_predicates }); +#[derive(RustcEncodable, RustcDecodable)] +pub struct TraitAliasData<'tcx> { + pub super_predicates: Lazy>, +} + +impl_stable_hash_for!(struct TraitAliasData<'tcx> { + super_predicates +}); + #[derive(RustcEncodable, RustcDecodable)] pub struct ImplData<'tcx> { pub polarity: hir::ImplPolarity, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a452bbf0c9d54..28b80fe3aaf29 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -673,6 +673,9 @@ impl<'a> Resolver<'a> { } module.populated.set(true); } + Def::TraitAlias(..) => { + self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); + } Def::Struct(..) | Def::Union(..) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 5502a1d186eee..9bdef3051e589 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -158,7 +158,8 @@ crate fn program_clauses_for<'a, 'tcx>( def_id: DefId, ) -> Clauses<'tcx> { match tcx.def_key(def_id).disambiguated_data.data { - DefPathData::Trait(_) => program_clauses_for_trait(tcx, def_id), + DefPathData::Trait(_) | + DefPathData::TraitAlias(_) => program_clauses_for_trait(tcx, def_id), DefPathData::Impl => program_clauses_for_impl(tcx, def_id), DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id), DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id), diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e0e173901ef38..66b2443af413a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -706,7 +706,7 @@ fn super_predicates_of<'a, 'tcx>( // In the case of trait aliases, however, we include all bounds in the where clause, // so e.g., `trait Foo = where u32: PartialEq` would include `u32: PartialEq` // as one of its "superpredicates". - let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id); + let is_trait_alias = tcx.is_trait_alias(trait_def_id); let superbounds2 = icx.type_parameter_bounds_in_generics( generics, item.id, self_param_ty, OnlySelfBounds(!is_trait_alias)); From b411994b3b9a571db486cb7de9ea06b071a22b6c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 10 Jan 2019 16:56:05 -0500 Subject: [PATCH 0052/1064] new trait alias tests Co-authored-by: Alexander Regueiro --- src/test/ui/issues/issue-56488.rs | 13 +++++++ .../lint-incoherent-auto-trait-objects.rs | 21 ++++++++++ .../lint-incoherent-auto-trait-objects.stderr | 39 +++++++++++++++++++ src/test/ui/traits/auxiliary/trait_alias.rs | 3 ++ src/test/ui/traits/trait-alias-cross-crate.rs | 17 ++++++++ .../ui/traits/trait-alias-cross-crate.stderr | 29 ++++++++++++++ 6 files changed, 122 insertions(+) create mode 100644 src/test/ui/issues/issue-56488.rs create mode 100644 src/test/ui/lint/lint-incoherent-auto-trait-objects.rs create mode 100644 src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr create mode 100644 src/test/ui/traits/auxiliary/trait_alias.rs create mode 100644 src/test/ui/traits/trait-alias-cross-crate.rs create mode 100644 src/test/ui/traits/trait-alias-cross-crate.stderr diff --git a/src/test/ui/issues/issue-56488.rs b/src/test/ui/issues/issue-56488.rs new file mode 100644 index 0000000000000..e2f3996927b7f --- /dev/null +++ b/src/test/ui/issues/issue-56488.rs @@ -0,0 +1,13 @@ +// run-pass + +#![feature(trait_alias)] + +mod alpha { + pub trait A {} + pub trait C = A; +} + +#[allow(unused_imports)] +use alpha::C; + +fn main() {} diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.rs b/src/test/ui/lint/lint-incoherent-auto-trait-objects.rs new file mode 100644 index 0000000000000..0d18965ee7338 --- /dev/null +++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.rs @@ -0,0 +1,21 @@ +// ignore-tidy-linelength + +trait Foo {} + +impl Foo for dyn Send {} + +impl Foo for dyn Send + Send {} +//~^ ERROR conflicting implementations +//~| hard error + +impl Foo for dyn Send + Sync {} + +impl Foo for dyn Sync + Send {} +//~^ ERROR conflicting implementations +//~| hard error + +impl Foo for dyn Send + Sync + Send {} +//~^ ERROR conflicting implementations +//~| hard error + +fn main() {} diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr new file mode 100644 index 0000000000000..928c92ef91655 --- /dev/null +++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr @@ -0,0 +1,39 @@ +error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119) + --> $DIR/lint-incoherent-auto-trait-objects.rs:7:1 + | +LL | impl Foo for dyn Send {} + | --------------------- first implementation here +LL | +LL | impl Foo for dyn Send + Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` + | + = note: #[deny(order_dependent_trait_objects)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56484 + +error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) + --> $DIR/lint-incoherent-auto-trait-objects.rs:13:1 + | +LL | impl Foo for dyn Send + Sync {} + | ---------------------------- first implementation here +LL | +LL | impl Foo for dyn Sync + Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56484 + +error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) + --> $DIR/lint-incoherent-auto-trait-objects.rs:17:1 + | +LL | impl Foo for dyn Sync + Send {} + | ---------------------------- first implementation here +... +LL | impl Foo for dyn Send + Sync + Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56484 + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/traits/auxiliary/trait_alias.rs b/src/test/ui/traits/auxiliary/trait_alias.rs new file mode 100644 index 0000000000000..9e56b87e08813 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_alias.rs @@ -0,0 +1,3 @@ +#![feature(trait_alias)] + +pub trait SendSync = Send + Sync; diff --git a/src/test/ui/traits/trait-alias-cross-crate.rs b/src/test/ui/traits/trait-alias-cross-crate.rs new file mode 100644 index 0000000000000..259fc4fa5d1ce --- /dev/null +++ b/src/test/ui/traits/trait-alias-cross-crate.rs @@ -0,0 +1,17 @@ +// aux-build:trait_alias.rs + +#![feature(trait_alias)] + +extern crate trait_alias; + +use std::rc::Rc; +use trait_alias::SendSync; + +fn use_alias() {} + +fn main() { + use_alias::(); + use_alias::>(); + //~^ ERROR `std::rc::Rc` cannot be sent between threads safely [E0277] + //~^^ ERROR `std::rc::Rc` cannot be shared between threads safely [E0277] +} diff --git a/src/test/ui/traits/trait-alias-cross-crate.stderr b/src/test/ui/traits/trait-alias-cross-crate.stderr new file mode 100644 index 0000000000000..972d213ac8f8f --- /dev/null +++ b/src/test/ui/traits/trait-alias-cross-crate.stderr @@ -0,0 +1,29 @@ +error[E0277]: `std::rc::Rc` cannot be sent between threads safely + --> $DIR/trait-alias-cross-crate.rs:14:5 + | +LL | use_alias::>(); + | ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `std::rc::Rc` +note: required by `use_alias` + --> $DIR/trait-alias-cross-crate.rs:10:1 + | +LL | fn use_alias() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `std::rc::Rc` cannot be shared between threads safely + --> $DIR/trait-alias-cross-crate.rs:14:5 + | +LL | use_alias::>(); + | ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `std::rc::Rc` +note: required by `use_alias` + --> $DIR/trait-alias-cross-crate.rs:10:1 + | +LL | fn use_alias() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 830b3b8c75a5b7476de7ce07ee53c590f09f82f1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Jan 2019 23:59:42 +0100 Subject: [PATCH 0053/1064] Re-enable history api on file:// protocol --- src/librustdoc/html/static/main.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 75b0f5df0d8b3..250e4a466fc96 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -150,8 +150,7 @@ if (!DOMTokenList.prototype.remove) { } function browserSupportsHistoryApi() { - return document.location.protocol != "file:" && - window.history && typeof window.history.pushState === "function"; + return window.history && typeof window.history.pushState === "function"; } var main = document.getElementById("main"); From 0f34e0dabb1251de6769576105a0cd34d6a1db44 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Sat, 12 Jan 2019 01:53:47 +0900 Subject: [PATCH 0054/1064] Add fmt benchmarks --- src/libcore/benches/fmt.rs | 110 +++++++++++++++++++++++++++++++++++++ src/libcore/benches/lib.rs | 1 + 2 files changed, 111 insertions(+) create mode 100644 src/libcore/benches/fmt.rs diff --git a/src/libcore/benches/fmt.rs b/src/libcore/benches/fmt.rs new file mode 100644 index 0000000000000..92f10c760c6d2 --- /dev/null +++ b/src/libcore/benches/fmt.rs @@ -0,0 +1,110 @@ +use std::io::{self, Write as IoWrite}; +use std::fmt::{self, Write as FmtWrite}; +use test::Bencher; + +#[bench] +fn write_vec_value(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = Vec::new(); + for _ in 0..1000 { + mem.write_all("abc".as_bytes()).unwrap(); + } + }); +} + +#[bench] +fn write_vec_ref(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = Vec::new(); + let wr = &mut mem as &mut dyn io::Write; + for _ in 0..1000 { + wr.write_all("abc".as_bytes()).unwrap(); + } + }); +} + +#[bench] +fn write_vec_macro1(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = Vec::new(); + let wr = &mut mem as &mut dyn io::Write; + for _ in 0..1000 { + write!(wr, "abc").unwrap(); + } + }); +} + +#[bench] +fn write_vec_macro2(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = Vec::new(); + let wr = &mut mem as &mut dyn io::Write; + for _ in 0..1000 { + write!(wr, "{}", "abc").unwrap(); + } + }); +} + +#[bench] +fn write_vec_macro_debug(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = Vec::new(); + let wr = &mut mem as &mut dyn io::Write; + for _ in 0..1000 { + write!(wr, "{:?}", "☃").unwrap(); + } + }); +} + +#[bench] +fn write_str_value(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = String::new(); + for _ in 0..1000 { + mem.write_str("abc").unwrap(); + } + }); +} + +#[bench] +fn write_str_ref(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = String::new(); + let wr = &mut mem as &mut dyn fmt::Write; + for _ in 0..1000 { + wr.write_str("abc").unwrap(); + } + }); +} + +#[bench] +fn write_str_macro1(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = String::new(); + for _ in 0..1000 { + write!(mem, "abc").unwrap(); + } + }); +} + +#[bench] +fn write_str_macro2(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = String::new(); + let wr = &mut mem as &mut dyn fmt::Write; + for _ in 0..1000 { + write!(wr, "{}", "abc").unwrap(); + } + }); +} + +#[bench] +fn write_str_macro_debug(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = String::new(); + let wr = &mut mem as &mut dyn fmt::Write; + for _ in 0..1000 { + write!(wr, "{:?}", "☃").unwrap(); + } + }); +} diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs index 5b4971c81dd92..48572af611a5b 100644 --- a/src/libcore/benches/lib.rs +++ b/src/libcore/benches/lib.rs @@ -11,3 +11,4 @@ mod iter; mod num; mod ops; mod slice; +mod fmt; From d7a7ce9edd487dc151426dcb6d89911cc741e605 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Sat, 12 Jan 2019 01:53:59 +0900 Subject: [PATCH 0055/1064] Utilize specialized zip iterator impl name old ns/iter new ns/iter diff ns/iter diff % speedup fmt::write_str_macro1 13,927 12,489 -1,438 -10.33% x 1.12 fmt::write_str_macro2 24,633 23,418 -1,215 -4.93% x 1.05 fmt::write_str_macro_debug 234,633 233,092 -1,541 -0.66% x 1.01 fmt::write_str_ref 5,819 5,823 4 0.07% x 1.00 fmt::write_str_value 6,012 5,828 -184 -3.06% x 1.03 fmt::write_vec_macro1 18,550 17,143 -1,407 -7.58% x 1.08 fmt::write_vec_macro2 30,369 28,920 -1,449 -4.77% x 1.05 fmt::write_vec_macro_debug 244,338 244,901 563 0.23% x 1.00 fmt::write_vec_ref 5,952 5,885 -67 -1.13% x 1.01 fmt::write_vec_value 5,944 5,894 -50 -0.84% x 1.01 --- src/libcore/fmt/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index ec1aeb8a7d1e9..306a715f02d6e 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1026,28 +1026,30 @@ pub fn write(output: &mut dyn Write, args: Arguments) -> Result { curarg: args.args.iter(), }; - let mut pieces = args.pieces.iter(); + let mut idx = 0; match args.fmt { None => { // We can use default formatting parameters for all arguments. - for (arg, piece) in args.args.iter().zip(pieces.by_ref()) { + for (arg, piece) in args.args.iter().zip(args.pieces.iter()) { formatter.buf.write_str(*piece)?; (arg.formatter)(arg.value, &mut formatter)?; + idx += 1; } } Some(fmt) => { // Every spec has a corresponding argument that is preceded by // a string piece. - for (arg, piece) in fmt.iter().zip(pieces.by_ref()) { + for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { formatter.buf.write_str(*piece)?; formatter.run(arg)?; + idx += 1; } } } // There can be only one trailing string piece left. - if let Some(piece) = pieces.next() { + if let Some(piece) = args.pieces.get(idx) { formatter.buf.write_str(*piece)?; } From 038d8372244ab088ea186e10704e2bfc4e83f477 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Sat, 12 Jan 2019 13:30:03 +0900 Subject: [PATCH 0056/1064] Fix simple formatting optimization name old2 ns/iter new2 ns/iter diff ns/iter diff % speedup fmt::write_str_macro1 12,295 12,308 13 0.11% x 1.00 fmt::write_str_macro2 24,079 21,451 -2,628 -10.91% x 1.12 fmt::write_str_macro_debug 238,363 230,807 -7,556 -3.17% x 1.03 fmt::write_str_ref 6,203 6,064 -139 -2.24% x 1.02 fmt::write_str_value 6,225 6,075 -150 -2.41% x 1.02 fmt::write_vec_macro1 17,144 17,121 -23 -0.13% x 1.00 fmt::write_vec_macro2 29,845 26,703 -3,142 -10.53% x 1.12 fmt::write_vec_macro_debug 248,840 242,117 -6,723 -2.70% x 1.03 fmt::write_vec_ref 5,954 6,438 484 8.13% x 0.92 fmt::write_vec_value 5,959 6,439 480 8.06% x 0.93 --- src/libfmt_macros/lib.rs | 9 +++++++++ src/libsyntax_ext/format.rs | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 32ae878909f30..da440cdd72f80 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -72,6 +72,15 @@ pub enum Position<'a> { ArgumentNamed(&'a str), } +impl Position<'_> { + pub fn index(&self) -> Option { + match self { + ArgumentIs(i) | ArgumentImplicitlyIs(i) => Some(*i), + _ => None, + } + } +} + /// Enum of alignments which are supported. #[derive(Copy, Clone, PartialEq)] pub enum Alignment { diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 61722ba551653..0613c78e49590 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -493,7 +493,10 @@ impl<'a, 'b> Context<'a, 'b> { let fill = arg.format.fill.unwrap_or(' '); - if *arg != simple_arg || fill != ' ' { + let pos_simple = + arg.position.index() == simple_arg.position.index(); + + if !pos_simple || arg.format != simple_arg.format || fill != ' ' { self.all_pieces_simple = false; } From 423a5bb5c437c2ce81d4150490d0cccfdbc33a4c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 12 Jan 2019 11:00:14 -0500 Subject: [PATCH 0057/1064] add comment explaining what the derive does --- src/libcore/cmp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 64e37ec5a56cb..72ff9cca9fd86 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -96,6 +96,7 @@ use self::Ordering::*; /// For example, let's tweak our previous code a bit: /// /// ``` +/// // The derive implements == comparisons /// #[derive(PartialEq)] /// enum BookFormat { /// Paperback, From 1445a065ded1bc7e73e7a358f9bc971e908e9181 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 12 Jan 2019 11:17:49 -0500 Subject: [PATCH 0058/1064] bring back the example i removed, also add symmetry and simplify impl --- src/libcore/cmp.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 72ff9cca9fd86..db72b7bb9d2da 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -132,6 +132,48 @@ use self::Ordering::*; /// By changing `impl PartialEq for Book` to `impl PartialEq for Book`, /// we allow `BookFormat`s to be compared with `Book`s. /// +/// You can also combine these implementations to let the `==` operator work with +/// two different types: +/// +/// ``` +/// #[derive(PartialEq)] +/// enum BookFormat { +/// Paperback, +/// Hardback, +/// Ebook, +/// } +/// +/// struct Book { +/// isbn: i32, +/// format: BookFormat, +/// } +/// +/// impl PartialEq for Book { +/// fn eq(&self, other: &BookFormat) -> bool { +/// self.format == *other +/// } +/// } +/// +/// impl PartialEq for BookFormat { +/// fn eq(&self, other: &Book) -> bool { +/// *self == other.format +/// } +/// } +/// +/// impl PartialEq for Book { +/// fn eq(&self, other: &Book) -> bool { +/// self.isbn == other.isbn +/// } +/// } +/// +/// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; +/// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; +/// +/// assert!(b1 == BookFormat::Paperback); +/// assert!(b1 != BookFormat::Ebook); +/// assert!(b1 == b2); +/// ``` +/// /// # Examples /// /// ``` From 0394dce7884562651906a84e3a32dc8ad2a50ac8 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 12 Jan 2019 11:19:02 -0500 Subject: [PATCH 0059/1064] whitespace --- src/libcore/cmp.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index db72b7bb9d2da..65792607a2824 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -142,33 +142,33 @@ use self::Ordering::*; /// Hardback, /// Ebook, /// } -/// +/// /// struct Book { /// isbn: i32, /// format: BookFormat, /// } -/// +/// /// impl PartialEq for Book { /// fn eq(&self, other: &BookFormat) -> bool { /// self.format == *other /// } /// } -/// +/// /// impl PartialEq for BookFormat { /// fn eq(&self, other: &Book) -> bool { /// *self == other.format /// } /// } -/// +/// /// impl PartialEq for Book { /// fn eq(&self, other: &Book) -> bool { /// self.isbn == other.isbn /// } /// } -/// +/// /// let b1 = Book { isbn: 3, format: BookFormat::Paperback }; /// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; -/// +/// /// assert!(b1 == BookFormat::Paperback); /// assert!(b1 != BookFormat::Ebook); /// assert!(b1 == b2); From ebdd072e3b1d4b3eb39048c27be4e9b2ccc849a8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 13 Jan 2019 00:04:47 +0300 Subject: [PATCH 0060/1064] resolve: Add a test for issue #57539 --- src/test/ui/imports/issue-57539.rs | 8 ++++++++ src/test/ui/imports/issue-57539.stderr | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/imports/issue-57539.rs create mode 100644 src/test/ui/imports/issue-57539.stderr diff --git a/src/test/ui/imports/issue-57539.rs b/src/test/ui/imports/issue-57539.rs new file mode 100644 index 0000000000000..90b74eb464779 --- /dev/null +++ b/src/test/ui/imports/issue-57539.rs @@ -0,0 +1,8 @@ +// edition:2018 + +mod core { + use core; //~ ERROR `core` is ambiguous + use crate::*; +} + +fn main() {} diff --git a/src/test/ui/imports/issue-57539.stderr b/src/test/ui/imports/issue-57539.stderr new file mode 100644 index 0000000000000..3f745fd8204bf --- /dev/null +++ b/src/test/ui/imports/issue-57539.stderr @@ -0,0 +1,18 @@ +error[E0659]: `core` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-57539.rs:4:9 + | +LL | use core; //~ ERROR `core` is ambiguous + | ^^^^ ambiguous name + | + = note: `core` could refer to a built-in extern crate + = help: use `::core` to refer to this extern crate unambiguously +note: `core` could also refer to the module imported here + --> $DIR/issue-57539.rs:5:9 + | +LL | use crate::*; + | ^^^^^^^^ + = help: use `self::core` to refer to this module unambiguously + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`. From 28966e1a7ac509cebac4595e96f8d053b30fb946 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 9 Jan 2019 15:20:56 +1100 Subject: [PATCH 0061/1064] Remove `TokenStream::Tree` variant. `TokenStream::Stream` can represent a token stream containing any number of token trees. `TokenStream::Tree` is the special case representing a single token tree. The latter doesn't occur all that often dynamically, so this commit removes it, which simplifies the code quite a bit. This change has mixed performance effects. - The size of `TokenStream` drops from 32 bytes to 8 bytes, and there is one less case for all the match statements. - The conversion of a `TokenTree` to a `TokenStream` now requires two allocations, for the creation of a single element Lrc>. (But a subsequent commit in this PR will reduce the main source of such conversions.) --- src/libsyntax/tokenstream.rs | 45 +++----------------------- src/libsyntax_ext/proc_macro_server.rs | 2 +- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index fb72ef9c956ce..95ff7728897e5 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -113,7 +113,7 @@ impl TokenTree { } pub fn joint(self) -> TokenStream { - TokenStream::Tree(self, Joint) + TokenStream::new(vec![(self, Joint)]) } /// Returns the opening delimiter as a token tree. @@ -146,7 +146,6 @@ impl TokenTree { #[derive(Clone, Debug)] pub enum TokenStream { Empty, - Tree(TokenTree, IsJoint), Stream(Lrc>), } @@ -154,7 +153,7 @@ pub type TreeAndJoint = (TokenTree, IsJoint); // `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -static_assert!(MEM_SIZE_OF_TOKEN_STREAM: mem::size_of::() == 32); +static_assert!(MEM_SIZE_OF_TOKEN_STREAM: mem::size_of::() == 8); #[derive(Clone, Copy, Debug, PartialEq)] pub enum IsJoint { @@ -201,7 +200,7 @@ impl TokenStream { impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { - TokenStream::Tree(tree, NonJoint) + TokenStream::new(vec![(tree, NonJoint)]) } } @@ -260,7 +259,6 @@ impl TokenStream { for stream in streams { match stream { TokenStream::Empty => {}, - TokenStream::Tree(tree, is_joint) => vec.push((tree, is_joint)), TokenStream::Stream(stream2) => vec.extend(stream2.iter().cloned()), } } @@ -269,13 +267,9 @@ impl TokenStream { } } - pub fn new(mut streams: Vec) -> TokenStream { + pub fn new(streams: Vec) -> TokenStream { match streams.len() { 0 => TokenStream::empty(), - 1 => { - let (tree, is_joint) = streams.pop().unwrap(); - TokenStream::Tree(tree, is_joint) - } _ => TokenStream::Stream(Lrc::new(streams)), } } @@ -283,7 +277,6 @@ impl TokenStream { pub fn append_to_tree_and_joint_vec(self, vec: &mut Vec) { match self { TokenStream::Empty => {} - TokenStream::Tree(tree, is_joint) => vec.push((tree, is_joint)), TokenStream::Stream(stream) => vec.extend(stream.iter().cloned()), } } @@ -351,7 +344,6 @@ impl TokenStream { pub fn map_enumerated TokenTree>(self, mut f: F) -> TokenStream { match self { TokenStream::Empty => TokenStream::Empty, - TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(0, tree), is_joint), TokenStream::Stream(stream) => TokenStream::Stream(Lrc::new( stream .iter() @@ -365,7 +357,6 @@ impl TokenStream { pub fn map TokenTree>(self, mut f: F) -> TokenStream { match self { TokenStream::Empty => TokenStream::Empty, - TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(tree), is_joint), TokenStream::Stream(stream) => TokenStream::Stream(Lrc::new( stream .iter() @@ -378,7 +369,6 @@ impl TokenStream { fn first_tree_and_joint(&self) -> Option<(TokenTree, IsJoint)> { match self { TokenStream::Empty => None, - TokenStream::Tree(ref tree, is_joint) => Some((tree.clone(), *is_joint)), TokenStream::Stream(ref stream) => Some(stream.first().unwrap().clone()) } } @@ -386,13 +376,6 @@ impl TokenStream { fn last_tree_if_joint(&self) -> Option { match self { TokenStream::Empty => None, - TokenStream::Tree(ref tree, is_joint) => { - if *is_joint == Joint { - Some(tree.clone()) - } else { - None - } - } TokenStream::Stream(ref stream) => { if let (tree, Joint) = stream.last().unwrap() { Some(tree.clone()) @@ -422,7 +405,7 @@ impl TokenStreamBuilder { self.push_all_but_last_tree(&last_stream); let glued_span = last_span.to(span); let glued_tt = TokenTree::Token(glued_span, glued_tok); - let glued_tokenstream = TokenStream::Tree(glued_tt, is_joint); + let glued_tokenstream = TokenStream::new(vec![(glued_tt, is_joint)]); self.0.push(glued_tokenstream); self.push_all_but_first_tree(&stream); return @@ -441,7 +424,6 @@ impl TokenStreamBuilder { let len = streams.len(); match len { 1 => {} - 2 => self.0.push(TokenStream::Tree(streams[0].0.clone(), streams[0].1)), _ => self.0.push(TokenStream::Stream(Lrc::new(streams[0 .. len - 1].to_vec()))), } } @@ -452,7 +434,6 @@ impl TokenStreamBuilder { let len = streams.len(); match len { 1 => {} - 2 => self.0.push(TokenStream::Tree(streams[1].0.clone(), streams[1].1)), _ => self.0.push(TokenStream::Stream(Lrc::new(streams[1 .. len].to_vec()))), } } @@ -481,14 +462,6 @@ impl Cursor { pub fn next_with_joint(&mut self) -> Option { match self.stream { TokenStream::Empty => None, - TokenStream::Tree(ref tree, ref is_joint) => { - if self.index == 0 { - self.index = 1; - Some((tree.clone(), *is_joint)) - } else { - None - } - } TokenStream::Stream(ref stream) => { if self.index < stream.len() { self.index += 1; @@ -513,13 +486,6 @@ impl Cursor { pub fn look_ahead(&self, n: usize) -> Option { match self.stream { TokenStream::Empty => None, - TokenStream::Tree(ref tree, _) => { - if n == 0 && self.index == 0 { - Some(tree.clone()) - } else { - None - } - } TokenStream::Stream(ref stream) => stream[self.index ..].get(n).map(|(tree, _)| tree.clone()), } @@ -542,7 +508,6 @@ impl From for ThinTokenStream { fn from(stream: TokenStream) -> ThinTokenStream { ThinTokenStream(match stream { TokenStream::Empty => None, - TokenStream::Tree(tree, is_joint) => Some(Lrc::new(vec![(tree, is_joint)])), TokenStream::Stream(stream) => Some(stream), }) } diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index 158cbc791ef50..7de9b9343a8fa 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -269,7 +269,7 @@ impl ToInternal for TokenTree { }; let tree = tokenstream::TokenTree::Token(span, token); - TokenStream::Tree(tree, if joint { Joint } else { NonJoint }) + TokenStream::new(vec![(tree, if joint { Joint } else { NonJoint })]) } } From ce0d9949b817267e88e8d366a8cee929abf1e4ba Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 9 Jan 2019 16:53:14 +1100 Subject: [PATCH 0062/1064] Remove `ThinTokenStream`. `TokenStream` is now almost identical to `ThinTokenStream`. This commit removes the latter, replacing it with the former. --- src/librustc/ich/impls_syntax.rs | 2 +- src/librustc_lint/builtin.rs | 2 +- src/libsyntax/ast.rs | 8 ++--- src/libsyntax/attr/mod.rs | 2 +- src/libsyntax/ext/quote.rs | 2 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/mod.rs | 6 ++-- src/libsyntax/parse/parser.rs | 12 +++---- src/libsyntax/print/pprust.rs | 2 +- src/libsyntax/tokenstream.rs | 55 ++------------------------------ src/libsyntax/visit.rs | 2 +- 11 files changed, 23 insertions(+), 72 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 70ec72d73bc6c..de567183a3c05 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -258,7 +258,7 @@ for tokenstream::TokenTree { tokenstream::TokenTree::Delimited(span, delim, ref tts) => { span.hash_stable(hcx, hasher); std_hash::Hash::hash(&delim, hasher); - for sub_tt in tts.stream().trees() { + for sub_tt in tts.trees() { sub_tt.hash_stable(hcx, hasher); } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5678f30dabccd..0fce166d828b0 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1540,7 +1540,7 @@ impl KeywordIdents { _ => {}, } TokenTree::Delimited(_, _, tts) => { - self.check_tokens(cx, tts.stream()) + self.check_tokens(cx, tts) }, } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e3a8980a975c1..1e91f4adc36d7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -15,7 +15,7 @@ use rustc_target::spec::abi::Abi; use source_map::{dummy_spanned, respan, Spanned}; use symbol::{keywords, Symbol}; use syntax_pos::{Span, DUMMY_SP}; -use tokenstream::{ThinTokenStream, TokenStream}; +use tokenstream::TokenStream; use ThinVec; use rustc_data_structures::fx::FxHashSet; @@ -1216,7 +1216,7 @@ pub type Mac = Spanned; pub struct Mac_ { pub path: Path, pub delim: MacDelimiter, - pub tts: ThinTokenStream, + pub tts: TokenStream, } #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] @@ -1228,13 +1228,13 @@ pub enum MacDelimiter { impl Mac_ { pub fn stream(&self) -> TokenStream { - self.tts.stream() + self.tts.clone() } } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct MacroDef { - pub tokens: ThinTokenStream, + pub tokens: TokenStream, pub legacy: bool, } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index d03563f8891aa..0f8ca5e7b9982 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -565,7 +565,7 @@ impl MetaItemKind { } Some(TokenTree::Delimited(_, delim, ref tts)) if delim == token::Paren => { tokens.next(); - tts.stream() + tts.clone() } _ => return Some(MetaItemKind::Word), }; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index c3124144009ab..c01e7f538b90d 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -748,7 +748,7 @@ fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, quoted: bool) -> Vec { let mut stmts = statements_mk_tt(cx, &TokenTree::open_tt(span.open, delim), false); - stmts.extend(statements_mk_tts(cx, tts.stream())); + stmts.extend(statements_mk_tts(cx, tts.clone())); stmts.extend(statements_mk_tt(cx, &TokenTree::close_tt(span.close, delim), false)); stmts } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 8ac103856dcd1..a4c3b38f691ed 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -598,7 +598,7 @@ pub fn noop_fold_tt(tt: TokenTree, fld: &mut T) -> TokenTree { TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited( DelimSpan::from_pair(fld.new_span(span.open), fld.new_span(span.close)), delim, - fld.fold_tts(tts.stream()).into(), + fld.fold_tts(tts).into(), ), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ba5676a65d7eb..759de578847a9 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -811,7 +811,7 @@ mod tests { ) if name_macro_rules.name == "macro_rules" && name_zip.name == "zip" => { - let tts = ¯o_tts.stream().trees().collect::>(); + let tts = ¯o_tts.trees().collect::>(); match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) { ( 3, @@ -820,7 +820,7 @@ mod tests { Some(&TokenTree::Delimited(_, second_delim, ref second_tts)), ) if macro_delim == token::Paren => { - let tts = &first_tts.stream().trees().collect::>(); + let tts = &first_tts.trees().collect::>(); match (tts.len(), tts.get(0), tts.get(1)) { ( 2, @@ -830,7 +830,7 @@ mod tests { if first_delim == token::Paren && ident.name == "a" => {}, _ => panic!("value 3: {:?} {:?}", first_delim, first_tts), } - let tts = &second_tts.stream().trees().collect::>(); + let tts = &second_tts.trees().collect::>(); match (tts.len(), tts.get(0), tts.get(1)) { ( 2, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5c8ed94731afb..6df95d539affb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -46,7 +46,7 @@ use print::pprust; use ptr::P; use parse::PResult; use ThinVec; -use tokenstream::{self, DelimSpan, ThinTokenStream, TokenTree, TokenStream}; +use tokenstream::{self, DelimSpan, TokenTree, TokenStream}; use symbol::{Symbol, keywords}; use std::borrow::Cow; @@ -285,12 +285,12 @@ enum LastToken { } impl TokenCursorFrame { - fn new(sp: DelimSpan, delim: DelimToken, tts: &ThinTokenStream) -> Self { + fn new(sp: DelimSpan, delim: DelimToken, tts: &TokenStream) -> Self { TokenCursorFrame { delim: delim, span: sp, open_delim: delim == token::NoDelim, - tree_cursor: tts.stream().into_trees(), + tree_cursor: tts.clone().into_trees(), close_delim: delim == token::NoDelim, last_token: LastToken::Was(None), } @@ -2325,7 +2325,7 @@ impl<'a> Parser<'a> { }) } - fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, ThinTokenStream)> { + fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, TokenStream)> { let delim = match self.token { token::OpenDelim(delim) => delim, _ => { @@ -2345,7 +2345,7 @@ impl<'a> Parser<'a> { token::Brace => MacDelimiter::Brace, token::NoDelim => self.bug("unexpected no delimiter"), }; - Ok((delim, tts.stream().into())) + Ok((delim, tts.into())) } /// At the bottom (top?) of the precedence hierarchy, @@ -4633,7 +4633,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let tokens = if self.check(&token::OpenDelim(token::Brace)) { match self.parse_token_tree() { - TokenTree::Delimited(_, _, tts) => tts.stream(), + TokenTree::Delimited(_, _, tts) => tts, _ => unreachable!(), } } else if self.check(&token::OpenDelim(token::Paren)) { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 2ad3d3a6d6487..c53594032a00a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -807,7 +807,7 @@ pub trait PrintState<'a> { TokenTree::Delimited(_, delim, tts) => { self.writer().word(token_to_string(&token::OpenDelim(delim)))?; self.writer().space()?; - self.print_tts(tts.stream())?; + self.print_tts(tts)?; self.writer().space()?; self.writer().word(token_to_string(&token::CloseDelim(delim))) }, diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 95ff7728897e5..d5c362490ca6a 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -41,7 +41,7 @@ pub enum TokenTree { /// A single token Token(Span, token::Token), /// A delimited sequence of token trees - Delimited(DelimSpan, DelimToken, ThinTokenStream), + Delimited(DelimSpan, DelimToken, TokenStream), } impl TokenTree { @@ -62,8 +62,7 @@ impl TokenTree { (&TokenTree::Token(_, ref tk), &TokenTree::Token(_, ref tk2)) => tk == tk2, (&TokenTree::Delimited(_, delim, ref tts), &TokenTree::Delimited(_, delim2, ref tts2)) => { - delim == delim2 && - tts.stream().eq_unspanned(&tts2.stream()) + delim == delim2 && tts.eq_unspanned(&tts2) } (_, _) => false, } @@ -81,8 +80,7 @@ impl TokenTree { } (&TokenTree::Delimited(_, delim, ref tts), &TokenTree::Delimited(_, delim2, ref tts2)) => { - delim == delim2 && - tts.stream().probably_equal_for_proc_macro(&tts2.stream()) + delim == delim2 && tts.probably_equal_for_proc_macro(&tts2) } (_, _) => false, } @@ -492,41 +490,6 @@ impl Cursor { } } -/// The `TokenStream` type is large enough to represent a single `TokenTree` without allocation. -/// `ThinTokenStream` is smaller, but needs to allocate to represent a single `TokenTree`. -/// We must use `ThinTokenStream` in `TokenTree::Delimited` to avoid infinite size due to recursion. -#[derive(Debug, Clone)] -pub struct ThinTokenStream(Option>>); - -impl ThinTokenStream { - pub fn stream(&self) -> TokenStream { - self.clone().into() - } -} - -impl From for ThinTokenStream { - fn from(stream: TokenStream) -> ThinTokenStream { - ThinTokenStream(match stream { - TokenStream::Empty => None, - TokenStream::Stream(stream) => Some(stream), - }) - } -} - -impl From for TokenStream { - fn from(stream: ThinTokenStream) -> TokenStream { - stream.0.map(TokenStream::Stream).unwrap_or_else(TokenStream::empty) - } -} - -impl Eq for ThinTokenStream {} - -impl PartialEq for ThinTokenStream { - fn eq(&self, other: &ThinTokenStream) -> bool { - TokenStream::from(self.clone()) == TokenStream::from(other.clone()) - } -} - impl fmt::Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&pprust::tokens_to_string(self.clone())) @@ -545,18 +508,6 @@ impl Decodable for TokenStream { } } -impl Encodable for ThinTokenStream { - fn encode(&self, encoder: &mut E) -> Result<(), E::Error> { - TokenStream::from(self.clone()).encode(encoder) - } -} - -impl Decodable for ThinTokenStream { - fn decode(decoder: &mut D) -> Result { - TokenStream::decode(decoder).map(Into::into) - } -} - #[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] pub struct DelimSpan { pub open: Span, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 156546bbba94a..8cbd47ca70fde 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -832,7 +832,7 @@ pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) { match tt { TokenTree::Token(_, tok) => visitor.visit_token(tok), - TokenTree::Delimited(_, _, tts) => visitor.visit_tts(tts.stream()), + TokenTree::Delimited(_, _, tts) => visitor.visit_tts(tts), } } From ba31d83adc839768ed8fab7dea79d9f6bd6c58ac Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Jan 2019 11:58:38 +1100 Subject: [PATCH 0063/1064] Avoid some `TokenTree`-to-`TokenStream` conversions. This avoids some allocations. --- src/libsyntax/parse/parser.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6df95d539affb..537d536ec62c1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -46,7 +46,7 @@ use print::pprust; use ptr::P; use parse::PResult; use ThinVec; -use tokenstream::{self, DelimSpan, TokenTree, TokenStream}; +use tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use symbol::{Symbol, keywords}; use std::borrow::Cow; @@ -280,8 +280,8 @@ struct TokenCursorFrame { /// on the parser. #[derive(Clone)] enum LastToken { - Collecting(Vec), - Was(Option), + Collecting(Vec), + Was(Option), } impl TokenCursorFrame { @@ -7677,7 +7677,7 @@ impl<'a> Parser<'a> { &mut self.token_cursor.stack[prev].last_token }; - // Pull our the toekns that we've collected from the call to `f` above + // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()), LastToken::Was(_) => panic!("our vector went away?"), @@ -7696,10 +7696,9 @@ impl<'a> Parser<'a> { // call. In that case we need to record all the tokens we collected in // our parent list as well. To do that we push a clone of our stream // onto the previous list. - let stream = collected_tokens.into_iter().collect::(); match prev_collecting { Some(mut list) => { - list.push(stream.clone()); + list.extend(collected_tokens.iter().cloned()); list.extend(extra_token); *last_token = LastToken::Collecting(list); } @@ -7708,7 +7707,7 @@ impl<'a> Parser<'a> { } } - Ok((ret?, stream)) + Ok((ret?, TokenStream::new(collected_tokens))) } pub fn parse_item(&mut self) -> PResult<'a, Option>> { From 728572440171d8d9c0557c89c3d71cc8d7cf6c2e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Jan 2019 10:36:54 +1100 Subject: [PATCH 0064/1064] Make `TokenStream` use `Option`. Because that's the more typical way of representing an all-or-nothing type. --- src/libsyntax/tokenstream.rs | 95 +++++++++++++++++------------------- 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index d5c362490ca6a..f5d2d6f18ee87 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -141,11 +141,13 @@ impl TokenTree { /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s /// instead of a representation of the abstract syntax tree. /// Today's `TokenTree`s can still contain AST via `Token::Interpolated` for back-compat. +/// +/// The use of `Option` is an optimization that avoids the need for an +/// allocation when the stream is empty. However, it is not guaranteed that an +/// empty stream is represented with `None`; it may be represented as a `Some` +/// around an empty `Vec`. #[derive(Clone, Debug)] -pub enum TokenStream { - Empty, - Stream(Lrc>), -} +pub struct TokenStream(Option>>); pub type TreeAndJoint = (TokenTree, IsJoint); @@ -166,7 +168,7 @@ impl TokenStream { /// separating the two arguments with a comma for diagnostic suggestions. pub(crate) fn add_comma(&self) -> Option<(TokenStream, Span)> { // Used to suggest if a user writes `foo!(a b);` - if let TokenStream::Stream(ref stream) = self { + if let Some(ref stream) = self.0 { let mut suggestion = None; let mut iter = stream.iter().enumerate().peekable(); while let Some((pos, ts)) = iter.next() { @@ -230,7 +232,7 @@ impl PartialEq for TokenStream { impl TokenStream { pub fn len(&self) -> usize { - if let TokenStream::Stream(ref slice) = self { + if let Some(ref slice) = self.0 { slice.len() } else { 0 @@ -238,13 +240,13 @@ impl TokenStream { } pub fn empty() -> TokenStream { - TokenStream::Empty + TokenStream(None) } pub fn is_empty(&self) -> bool { - match self { - TokenStream::Empty => true, - _ => false, + match self.0 { + None => true, + Some(ref stream) => stream.is_empty(), } } @@ -255,9 +257,9 @@ impl TokenStream { _ => { let mut vec = vec![]; for stream in streams { - match stream { - TokenStream::Empty => {}, - TokenStream::Stream(stream2) => vec.extend(stream2.iter().cloned()), + match stream.0 { + None => {}, + Some(stream2) => vec.extend(stream2.iter().cloned()), } } TokenStream::new(vec) @@ -267,15 +269,14 @@ impl TokenStream { pub fn new(streams: Vec) -> TokenStream { match streams.len() { - 0 => TokenStream::empty(), - _ => TokenStream::Stream(Lrc::new(streams)), + 0 => TokenStream(None), + _ => TokenStream(Some(Lrc::new(streams))), } } pub fn append_to_tree_and_joint_vec(self, vec: &mut Vec) { - match self { - TokenStream::Empty => {} - TokenStream::Stream(stream) => vec.extend(stream.iter().cloned()), + if let Some(stream) = self.0 { + vec.extend(stream.iter().cloned()); } } @@ -340,41 +341,36 @@ impl TokenStream { } pub fn map_enumerated TokenTree>(self, mut f: F) -> TokenStream { - match self { - TokenStream::Empty => TokenStream::Empty, - TokenStream::Stream(stream) => TokenStream::Stream(Lrc::new( + TokenStream(self.0.map(|stream| { + Lrc::new( stream .iter() .enumerate() .map(|(i, (tree, is_joint))| (f(i, tree.clone()), *is_joint)) - .collect() - )), - } + .collect()) + })) } pub fn map TokenTree>(self, mut f: F) -> TokenStream { - match self { - TokenStream::Empty => TokenStream::Empty, - TokenStream::Stream(stream) => TokenStream::Stream(Lrc::new( + TokenStream(self.0.map(|stream| { + Lrc::new( stream .iter() .map(|(tree, is_joint)| (f(tree.clone()), *is_joint)) - .collect() - )), - } + .collect()) + })) } - fn first_tree_and_joint(&self) -> Option<(TokenTree, IsJoint)> { - match self { - TokenStream::Empty => None, - TokenStream::Stream(ref stream) => Some(stream.first().unwrap().clone()) - } + fn first_tree_and_joint(&self) -> Option { + self.0.as_ref().map(|stream| { + stream.first().unwrap().clone() + }) } fn last_tree_if_joint(&self) -> Option { - match self { - TokenStream::Empty => None, - TokenStream::Stream(ref stream) => { + match self.0 { + None => None, + Some(ref stream) => { if let (tree, Joint) = stream.last().unwrap() { Some(tree.clone()) } else { @@ -418,21 +414,21 @@ impl TokenStreamBuilder { } fn push_all_but_last_tree(&mut self, stream: &TokenStream) { - if let TokenStream::Stream(ref streams) = stream { + if let Some(ref streams) = stream.0 { let len = streams.len(); match len { 1 => {} - _ => self.0.push(TokenStream::Stream(Lrc::new(streams[0 .. len - 1].to_vec()))), + _ => self.0.push(TokenStream(Some(Lrc::new(streams[0 .. len - 1].to_vec())))), } } } fn push_all_but_first_tree(&mut self, stream: &TokenStream) { - if let TokenStream::Stream(ref streams) = stream { + if let Some(ref streams) = stream.0 { let len = streams.len(); match len { 1 => {} - _ => self.0.push(TokenStream::Stream(Lrc::new(streams[1 .. len].to_vec()))), + _ => self.0.push(TokenStream(Some(Lrc::new(streams[1 .. len].to_vec())))), } } } @@ -458,9 +454,9 @@ impl Cursor { } pub fn next_with_joint(&mut self) -> Option { - match self.stream { - TokenStream::Empty => None, - TokenStream::Stream(ref stream) => { + match self.stream.0 { + None => None, + Some(ref stream) => { if self.index < stream.len() { self.index += 1; Some(stream[self.index - 1].clone()) @@ -476,16 +472,15 @@ impl Cursor { return; } let index = self.index; - let stream = mem::replace(&mut self.stream, TokenStream::Empty); + let stream = mem::replace(&mut self.stream, TokenStream(None)); *self = TokenStream::from_streams(vec![stream, new_stream]).into_trees(); self.index = index; } pub fn look_ahead(&self, n: usize) -> Option { - match self.stream { - TokenStream::Empty => None, - TokenStream::Stream(ref stream) => - stream[self.index ..].get(n).map(|(tree, _)| tree.clone()), + match self.stream.0 { + None => None, + Some(ref stream) => stream[self.index ..].get(n).map(|(tree, _)| tree.clone()), } } } From c6632725c1c72569eb8f017461809648fd9e9c93 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Tue, 13 Nov 2018 16:25:51 -0800 Subject: [PATCH 0065/1064] Support passing cflags/cxxflags/ldflags to LLVM build This may be needed with some host compilers. --- config.toml.example | 5 +++++ src/bootstrap/config.rs | 10 ++++++++++ src/bootstrap/configure.py | 4 ++++ src/bootstrap/native.rs | 15 ++++++++++++++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/config.toml.example b/config.toml.example index 23943d34b7ca8..24293fc864c5f 100644 --- a/config.toml.example +++ b/config.toml.example @@ -90,6 +90,11 @@ # with clang-cl, so this is special in that it only compiles LLVM with clang-cl #clang-cl = '/path/to/clang-cl.exe' +# Pass extra compiler and linker flags to the LLVM CMake build. +#cflags = "-fextra-flag" +#cxxflags = "-fextra-flag" +#ldflags = "-Wl,extra-flag" + # Use libc++ when building LLVM instead of libstdc++. This is the default on # platforms already use libc++ as the default C++ library, but this option # allows you to use libc++ even on platforms when it's not. You need to ensure diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9421817ae6d8e..a2989f0cffa6e 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -82,6 +82,9 @@ pub struct Config { pub lldb_enabled: bool, pub llvm_tools_enabled: bool, + pub llvm_cflags: Option, + pub llvm_cxxflags: Option, + pub llvm_ldflags: Option, pub llvm_use_libcxx: bool, // rust codegen options @@ -254,6 +257,9 @@ struct Llvm { link_shared: Option, version_suffix: Option, clang_cl: Option, + cflags: Option, + cxxflags: Option, + ldflags: Option, use_libcxx: Option, } @@ -516,6 +522,10 @@ impl Config { config.llvm_link_jobs = llvm.link_jobs; config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); + + config.llvm_cflags = llvm.cflags.clone(); + config.llvm_cxxflags = llvm.cxxflags.clone(); + config.llvm_ldflags = llvm.ldflags.clone(); set(&mut config.llvm_use_libcxx, llvm.use_libcxx); } diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index b0c3c9702498d..7b70236dfe8e6 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -64,6 +64,10 @@ def v(*args): o("missing-tools", "dist.missing-tools", "allow failures when building tools") o("use-libcxx", "llvm.use_libcxx", "build LLVM with libc++") +o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags") +o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") +o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") + # Optimization and debugging options. These may be overridden by the release # channel, etc. o("optimize", "rust.optimize", "build optimized rust code") diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index cb9c86df55080..f5bacd63e6803 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -358,7 +358,11 @@ fn configure_cmake(builder: &Builder, } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); - cfg.define("CMAKE_C_FLAGS", builder.cflags(target, GitRepo::Llvm).join(" ")); + let mut cflags = builder.cflags(target, GitRepo::Llvm).join(" "); + if let Some(ref s) = builder.config.llvm_cxxflags { + cflags.push_str(&format!(" {}", s)); + } + cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" "); if builder.config.llvm_static_stdcpp && !target.contains("windows") && @@ -366,6 +370,9 @@ fn configure_cmake(builder: &Builder, { cxxflags.push_str(" -static-libstdc++"); } + if let Some(ref s) = builder.config.llvm_cxxflags { + cxxflags.push_str(&format!(" {}", s)); + } cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) { if ar.is_absolute() { @@ -383,6 +390,12 @@ fn configure_cmake(builder: &Builder, } } + if let Some(ref s) = builder.config.llvm_ldflags { + cfg.define("CMAKE_SHARED_LINKER_FLAGS", s); + cfg.define("CMAKE_MODULE_LINKER_FLAGS", s); + cfg.define("CMAKE_EXE_LINKER_FLAGS", s); + } + if env::var_os("SCCACHE_ERROR_LOG").is_some() { cfg.env("RUST_LOG", "sccache=warn"); } From f4ded5b5591b3ec1446422dd9d62d404d4335753 Mon Sep 17 00:00:00 2001 From: Michael Bradshaw Date: Mon, 24 Dec 2018 16:07:10 -0700 Subject: [PATCH 0066/1064] Add a regression test for mutating a non-mut #[thread_local] --- src/test/ui/thread-local-mutation.nll.stderr | 9 +++++++++ src/test/ui/thread-local-mutation.rs | 18 ++++++++++++++++++ src/test/ui/thread-local-mutation.stderr | 9 +++++++++ 3 files changed, 36 insertions(+) create mode 100644 src/test/ui/thread-local-mutation.nll.stderr create mode 100644 src/test/ui/thread-local-mutation.rs create mode 100644 src/test/ui/thread-local-mutation.stderr diff --git a/src/test/ui/thread-local-mutation.nll.stderr b/src/test/ui/thread-local-mutation.nll.stderr new file mode 100644 index 0000000000000..0a3664b0d9d40 --- /dev/null +++ b/src/test/ui/thread-local-mutation.nll.stderr @@ -0,0 +1,9 @@ +error[E0594]: cannot assign to immutable static item `S` + --> $DIR/thread-local-mutation.rs:11:5 + | +LL | S = "after"; //~ ERROR cannot assign to immutable + | ^^^^^^^^^^^ cannot assign + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/thread-local-mutation.rs b/src/test/ui/thread-local-mutation.rs new file mode 100644 index 0000000000000..e738225ce2a48 --- /dev/null +++ b/src/test/ui/thread-local-mutation.rs @@ -0,0 +1,18 @@ +// Regression test for #54901: immutable thread locals could be mutated. See: +// https://github.com/rust-lang/rust/issues/29594#issuecomment-328177697 +// https://github.com/rust-lang/rust/issues/54901 + +#![feature(thread_local)] + +#[thread_local] +static S: &str = "before"; + +fn set_s() { + S = "after"; //~ ERROR cannot assign to immutable +} + +fn main() { + println!("{}", S); + set_s(); + println!("{}", S); +} diff --git a/src/test/ui/thread-local-mutation.stderr b/src/test/ui/thread-local-mutation.stderr new file mode 100644 index 0000000000000..bf298523e1b73 --- /dev/null +++ b/src/test/ui/thread-local-mutation.stderr @@ -0,0 +1,9 @@ +error[E0594]: cannot assign to immutable thread-local static item + --> $DIR/thread-local-mutation.rs:11:5 + | +LL | S = "after"; //~ ERROR cannot assign to immutable + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. From 3638f0e4778bc9ecac206811941db9b1df98fe63 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 14 Jan 2019 09:23:49 -0800 Subject: [PATCH 0067/1064] Remove GCE cloud setting from AppVeyor config AppVeyor has informed us that this may no longer be necessary after some infrastructure upgrades on their side, so let's see how this goes! --- appveyor.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f043b8bfefca7..d70ad54b1c812 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,12 +5,6 @@ environment: # server goes down presumably. See #43333 for more info CARGO_HTTP_CHECK_REVOKE: false - # Recommended by AppVeyor this moves our builds to GCE which incurs a 3-4 - # minute startup overhead, but that's paltry compared to our overall build - # times so we're will to eat the cost. This is intended to give us better - # performance I believe! - appveyor_build_worker_cloud: gce - matrix: # 32/64 bit MSVC tests - MSYS_BITS: 64 From e459000bc1509805e18a74c402fd78e2881d0248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 8 Jun 2018 19:14:03 +0200 Subject: [PATCH 0068/1064] Make privacy checking, intrinsic checking and liveness checking incremental --- src/librustc/dep_graph/dep_node.rs | 3 ++ src/librustc/hir/map/mod.rs | 15 ++++++++++ src/librustc/middle/intrinsicck.rs | 20 ++++++++++++-- src/librustc/middle/liveness.rs | 19 +++++++++++-- src/librustc/ty/query/config.rs | 27 ++++++++++++++++++ src/librustc/ty/query/mod.rs | 6 ++++ src/librustc/ty/query/plumbing.rs | 3 ++ src/librustc_driver/driver.rs | 2 ++ src/librustc_privacy/lib.rs | 44 +++++++++++++++++++++--------- 9 files changed, 121 insertions(+), 18 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 427fe51e6ff9c..d1067b70778ee 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -476,6 +476,9 @@ define_dep_nodes!( <'tcx> [] CheckModLoops(DefId), [] CheckModUnstableApiUsage(DefId), [] CheckModItemTypes(DefId), + [] CheckModPrivacy(DefId), + [] CheckModIntrinsics(DefId), + [] CheckModLiveness(DefId), [] CollectModItemTypes(DefId), [] Reachability, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 869baef1f5afc..d9ca37c937bc7 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -509,6 +509,21 @@ impl<'hir> Map<'hir> { &self.forest.krate.attrs } + pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId) + { + let node_id = self.as_local_node_id(module).unwrap(); + self.read(node_id); + match self.find_entry(node_id).unwrap().node { + Node::Item(&Item { + span, + node: ItemKind::Mod(ref m), + .. + }) => (m, span, node_id), + Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id), + _ => panic!("not a module") + } + } + pub fn visit_item_likes_in_module(&self, module: DefId, visitor: &mut V) where V: ItemLikeVisitor<'hir> { diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 1716daaa107c4..a0f7954eb0c55 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -2,6 +2,7 @@ use hir::def::Def; use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; +use ty::query::{Providers, queries}; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_data_structures::indexed_vec::Idx; @@ -10,10 +11,23 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut visitor = ItemVisitor { - tcx, + for &module in tcx.hir().krate().modules.keys() { + queries::check_mod_intrinsics::ensure(tcx, tcx.hir().local_def_id(module)); + } +} + +fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + tcx.hir().visit_item_likes_in_module( + module_def_id, + &mut ItemVisitor { tcx }.as_deep_visitor() + ); +} + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_intrinsics, + ..*providers }; - tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); } struct ItemVisitor<'a, 'tcx: 'a> { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a78cf1a471b4b..0a1802a4e12c9 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -100,6 +100,7 @@ use self::VarKind::*; use hir::def::*; use hir::Node; use ty::{self, TyCtxt}; +use ty::query::{Providers, queries}; use lint; use errors::Applicability; use util::nodemap::{NodeMap, HirIdMap, HirIdSet}; @@ -114,8 +115,9 @@ use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::Span; -use hir::{Expr, HirId}; use hir; +use hir::{Expr, HirId}; +use hir::def_id::DefId; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; /// For use with `propagate_through_loop`. @@ -179,11 +181,24 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> { fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); } } +fn check_mod_liveness<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + tcx.hir().visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx).as_deep_visitor()); +} + pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir().krate().visit_all_item_likes(&mut IrMaps::new(tcx).as_deep_visitor()); + for &module in tcx.hir().krate().modules.keys() { + queries::check_mod_liveness::ensure(tcx, tcx.hir().local_def_id(module)); + } tcx.sess.abort_if_errors(); } +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_liveness, + ..*providers + }; +} + impl fmt::Debug for LiveNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ln({})", self.get()) diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index ca5d1f6bd3203..c20846aebb877 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -109,6 +109,33 @@ impl<'tcx> QueryDescription<'tcx> for queries::check_mod_item_types<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_privacy<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking privacy in {}", key.describe_as_module(tcx)).into() + } +} + +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_intrinsics<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking intrinsics in {}", key.describe_as_module(tcx)).into() + } +} + +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_liveness<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking liveness of variables in {}", key.describe_as_module(tcx)).into() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::collect_mod_item_types<'tcx> { fn describe( tcx: TyCtxt<'_, '_, '_>, diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 39d76ceed9507..88c20547a2108 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -264,6 +264,12 @@ define_queries! { <'tcx> [] fn check_mod_item_types: CheckModItemTypes(DefId) -> (), + [] fn check_mod_privacy: CheckModPrivacy(DefId) -> (), + + [] fn check_mod_intrinsics: CheckModIntrinsics(DefId) -> (), + + [] fn check_mod_liveness: CheckModLiveness(DefId) -> (), + [] fn collect_mod_item_types: CollectModItemTypes(DefId) -> (), /// Caches CoerceUnsized kinds for impls on custom types. diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 32d4070dfed2a..5fb6d33ded914 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1280,6 +1280,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); } DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); } DepKind::CheckModItemTypes => { force!(check_mod_item_types, def_id!()); } + DepKind::CheckModPrivacy => { force!(check_mod_privacy, def_id!()); } + DepKind::CheckModIntrinsics => { force!(check_mod_intrinsics, def_id!()); } + DepKind::CheckModLiveness => { force!(check_mod_liveness, def_id!()); } DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); } DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); } DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 380f9afd68de6..95c0facb6fd42 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1168,6 +1168,8 @@ pub fn default_provide(providers: &mut ty::query::Providers) { ty::provide(providers); traits::provide(providers); stability::provide(providers); + middle::intrinsicck::provide(providers); + middle::liveness::provide(providers); reachable::provide(providers); rustc_passes::provide(providers); rustc_traits::provide(providers); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4890369e13f20..10ac1caa692ca 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -22,12 +22,12 @@ use rustc::lint; use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::ty::{self, TyCtxt, Ty, TraitRef, TypeFoldable, GenericParamDefKind}; use rustc::ty::fold::TypeVisitor; -use rustc::ty::query::Providers; +use rustc::ty::query::{Providers, queries}; use rustc::ty::subst::Substs; use rustc::util::nodemap::NodeSet; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; -use syntax::ast::{self, CRATE_NODE_ID, Ident}; +use syntax::ast::{self, DUMMY_NODE_ID, Ident}; use syntax::attr; use syntax::symbol::keywords; use syntax_pos::Span; @@ -782,6 +782,10 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { NestedVisitorMap::All(&self.tcx.hir()) } + fn visit_mod(&mut self, _m: &'tcx hir::Mod, _s: Span, _n: ast::NodeId) { + // Don't visit modules inside + } + fn visit_nested_body(&mut self, body: hir::BodyId) { let orig_tables = mem::replace(&mut self.tables, self.tcx.body_tables(body)); let body = self.tcx.hir().body(body); @@ -917,6 +921,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { NestedVisitorMap::All(&self.tcx.hir()) } + fn visit_mod(&mut self, _m: &'tcx hir::Mod, _s: Span, _n: ast::NodeId) { + // Don't visit modules inside + } + fn visit_nested_body(&mut self, body: hir::BodyId) { let orig_tables = mem::replace(&mut self.tables, self.tcx.body_tables(body)); let orig_in_body = mem::replace(&mut self.in_body, true); @@ -1659,6 +1667,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> pub fn provide(providers: &mut Providers) { *providers = Providers { privacy_access_levels, + check_mod_privacy, ..*providers }; } @@ -1667,34 +1676,43 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc { tcx.privacy_access_levels(LOCAL_CRATE) } -fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - krate: CrateNum) - -> Lrc { - assert_eq!(krate, LOCAL_CRATE); - - let krate = tcx.hir().krate(); +fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { tcx, tables: &empty_tables, - current_item: CRATE_NODE_ID, + current_item: DUMMY_NODE_ID, empty_tables: &empty_tables, }; - intravisit::walk_crate(&mut visitor, krate); + let (module, span, node_id) = tcx.hir().get_module(module_def_id); + intravisit::walk_mod(&mut visitor, module, node_id); // Check privacy of explicitly written types and traits as well as // inferred types of expressions and patterns. let mut visitor = TypePrivacyVisitor { tcx, tables: &empty_tables, - current_item: DefId::local(CRATE_DEF_INDEX), + current_item: module_def_id, in_body: false, - span: krate.span, + span, empty_tables: &empty_tables, }; - intravisit::walk_crate(&mut visitor, krate); + intravisit::walk_mod(&mut visitor, module, node_id); +} + +fn privacy_access_levels<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + krate: CrateNum, +) -> Lrc { + assert_eq!(krate, LOCAL_CRATE); + + let krate = tcx.hir().krate(); + + for &module in tcx.hir().krate().modules.keys() { + queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); + } // Build up a set of all exported items in the AST. This is a set of all // items which are reachable from external crates based on visibility. From e301f90f227ee2719cffa36b423d97360bfb3db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 15 Jan 2019 00:54:56 +0100 Subject: [PATCH 0069/1064] Address comments --- src/librustc_privacy/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 10ac1caa692ca..698037e237101 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -783,7 +783,8 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { } fn visit_mod(&mut self, _m: &'tcx hir::Mod, _s: Span, _n: ast::NodeId) { - // Don't visit modules inside + // Don't visit nested modules, since we run a separate visitor walk + // for each module in `privacy_access_levels` } fn visit_nested_body(&mut self, body: hir::BodyId) { @@ -922,7 +923,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { } fn visit_mod(&mut self, _m: &'tcx hir::Mod, _s: Span, _n: ast::NodeId) { - // Don't visit modules inside + // Don't visit nested modules, since we run a separate visitor walk + // for each module in `privacy_access_levels` } fn visit_nested_body(&mut self, body: hir::BodyId) { @@ -1710,7 +1712,7 @@ fn privacy_access_levels<'tcx>( let krate = tcx.hir().krate(); - for &module in tcx.hir().krate().modules.keys() { + for &module in krate.modules.keys() { queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } From ee10d99b9a44c57f450678310b16e651d08075cd Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 15 Dec 2018 12:56:45 -0500 Subject: [PATCH 0070/1064] generalize markdown to source span calculation --- .../passes/collect_intra_doc_links.rs | 63 +------------- src/librustdoc/passes/mod.rs | 83 +++++++++++++++++++ 2 files changed, 87 insertions(+), 59 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fdc1c0616187a..56d6671266065 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -451,17 +451,9 @@ pub fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { /// Reports a resolution failure diagnostic. /// -/// Ideally we can report the diagnostic with the actual span in the source where the link failure -/// occurred. However, there's a mismatch between the span in the source code and the span in the -/// markdown, so we have to do a bit of work to figure out the correspondence. -/// -/// It's not too hard to find the span for sugared doc comments (`///` and `/**`), because the -/// source will match the markdown exactly, excluding the comment markers. However, it's much more -/// difficult to calculate the spans for unsugared docs, because we have to deal with escaping and -/// other source features. So, we attempt to find the exact source span of the resolution failure -/// in sugared docs, but use the span of the documentation attributes themselves for unsugared -/// docs. Because this span might be overly large, we display the markdown line containing the -/// failure as a note. +/// If we cannot find the exact source span of the resolution failure, we use the span of the +/// documentation attributes themselves. This is a little heavy-handed, so we display the markdown +/// line containing the failure as a note as well. fn resolution_failure( cx: &DocContext, attrs: &Attributes, @@ -473,54 +465,7 @@ fn resolution_failure( let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str); let mut diag = if let Some(link_range) = link_range { - let src = cx.sess().source_map().span_to_snippet(sp); - let is_all_sugared_doc = attrs.doc_strings.iter().all(|frag| match frag { - DocFragment::SugaredDoc(..) => true, - _ => false, - }); - - if let (Ok(src), true) = (src, is_all_sugared_doc) { - // The number of markdown lines up to and including the resolution failure. - let num_lines = dox[..link_range.start].lines().count(); - - // We use `split_terminator('\n')` instead of `lines()` when counting bytes to ensure - // that DOS-style line endings do not cause the spans to be calculated incorrectly. - let mut src_lines = src.split_terminator('\n'); - let mut md_lines = dox.split_terminator('\n').take(num_lines).peekable(); - - // The number of bytes from the start of the source span to the resolution failure that - // are *not* part of the markdown, like comment markers. - let mut extra_src_bytes = 0; - - while let Some(md_line) = md_lines.next() { - loop { - let source_line = src_lines - .next() - .expect("could not find markdown line in source"); - - match source_line.find(md_line) { - Some(offset) => { - extra_src_bytes += if md_lines.peek().is_some() { - source_line.len() - md_line.len() - } else { - offset - }; - break; - } - None => { - // Since this is a source line that doesn't include a markdown line, - // we have to count the newline that we split from earlier. - extra_src_bytes += source_line.len() + 1; - } - } - } - } - - let sp = sp.from_inner_byte_pos( - link_range.start + extra_src_bytes, - link_range.end + extra_src_bytes, - ); - + if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs) { let mut diag = cx.tcx.struct_span_lint_node( lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, NodeId::from_u32(0), diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index e897b9a7de58e..23581d0051166 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -8,6 +8,8 @@ use rustc::util::nodemap::DefIdSet; use std::mem; use std::fmt; use syntax::ast::NodeId; +use syntax_pos::Span; +use std::ops::Range; use clean::{self, GetDefId, Item}; use core::{DocContext, DocAccessLevels}; @@ -396,3 +398,84 @@ pub fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a>( } } } + +/// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. +/// +/// This method will return `None` if we cannot construct a span from the source map or if the +/// attributes are not all sugared doc comments. It's difficult to calculate the correct span in +/// that case due to escaping and other source features. +crate fn source_span_for_markdown_range( + cx: &DocContext, + markdown: &str, + md_range: &Range, + attrs: &clean::Attributes, +) -> Option { + let is_all_sugared_doc = attrs.doc_strings.iter().all(|frag| match frag { + clean::DocFragment::SugaredDoc(..) => true, + _ => false, + }); + + if !is_all_sugared_doc { + return None; + } + + let snippet = cx + .sess() + .source_map() + .span_to_snippet(span_of_attrs(attrs)) + .ok()?; + + let starting_line = markdown[..md_range.start].lines().count() - 1; + let ending_line = markdown[..md_range.end].lines().count() - 1; + + // We use `split_terminator('\n')` instead of `lines()` when counting bytes so that we only + // we can treat CRLF and LF line endings the same way. + let mut src_lines = snippet.split_terminator('\n'); + let md_lines = markdown.split_terminator('\n'); + + // The number of bytes from the source span to the markdown span that are not part + // of the markdown, like comment markers. + let mut start_bytes = 0; + let mut end_bytes = 0; + + 'outer: for (line_no, md_line) in md_lines.enumerate() { + loop { + let source_line = src_lines.next().expect("could not find markdown in source"); + match source_line.find(md_line) { + Some(offset) => { + if line_no == starting_line { + start_bytes += offset; + + if starting_line == ending_line { + break 'outer; + } + } else if line_no == ending_line { + end_bytes += offset; + break 'outer; + } else if line_no < starting_line { + start_bytes += source_line.len() - md_line.len(); + } else { + end_bytes += source_line.len() - md_line.len(); + } + break; + } + None => { + // Since this is a source line that doesn't include a markdown line, + // we have to count the newline that we split from earlier. + if line_no <= starting_line { + start_bytes += source_line.len() + 1; + } else { + end_bytes += source_line.len() + 1; + } + } + } + } + } + + let sp = span_of_attrs(attrs).from_inner_byte_pos( + md_range.start + start_bytes, + md_range.end + start_bytes + end_bytes, + ); + + Some(sp) +} From 8c93798e9f80d6d6ed9a2ab4b01af06a8fea23b7 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 15 Dec 2018 16:25:50 -0500 Subject: [PATCH 0071/1064] rustdoc: check code block syntax in early pass --- src/librustdoc/html/highlight.rs | 92 +++++++++------ src/librustdoc/html/markdown.rs | 109 ++++++++++++++++++ src/librustdoc/lib.rs | 1 + .../passes/check_code_block_syntax.rs | 109 ++++++++++++++++++ .../passes/collect_intra_doc_links.rs | 12 +- src/librustdoc/passes/mod.rs | 20 +++- src/libsyntax/parse/lexer/mod.rs | 13 --- src/test/rustdoc-ui/invalid-syntax.rs | 61 +++++++++- src/test/rustdoc-ui/invalid-syntax.stderr | 105 +++++++++++++++-- src/test/rustdoc/bad-codeblock-syntax.rs | 27 +++++ 10 files changed, 476 insertions(+), 73 deletions(-) create mode 100644 src/librustdoc/passes/check_code_block_syntax.rs create mode 100644 src/test/rustdoc/bad-codeblock-syntax.rs diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 87e979b93e9ef..29a41384edcda 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -25,40 +25,51 @@ pub fn render_with_highlighting( tooltip: Option<(&str, &str)>, ) -> String { debug!("highlighting: ================\n{}\n==============", src); - let sess = parse::ParseSess::new(FilePathMapping::empty()); - let fm = sess.source_map().new_source_file(FileName::Custom("stdin".to_string()), - src.to_string()); - let mut out = Vec::new(); if let Some((tooltip, class)) = tooltip { write!(out, "
{}
", class, tooltip).unwrap(); } - write_header(class, &mut out).unwrap(); - - let lexer = match lexer::StringReader::new_without_err(&sess, fm, None, "Output from rustc:") { - Ok(l) => l, - Err(_) => { - let first_line = src.lines().next().unwrap_or_else(|| ""); - let mut err = sess.span_diagnostic - .struct_warn(&format!("Invalid doc comment starting with: `{}`\n\ - (Ignoring this codeblock)", - first_line)); - err.emit(); - return String::new(); + + let sess = parse::ParseSess::new(FilePathMapping::empty()); + let fm = sess.source_map().new_source_file( + FileName::Custom(String::from("rustdoc-highlighting")), + src.to_owned(), + ); + let highlight_result = + lexer::StringReader::new_or_buffered_errs(&sess, fm, None).and_then(|lexer| { + let mut classifier = Classifier::new(lexer, sess.source_map()); + + let mut highlighted_source = vec![]; + if classifier.write_source(&mut highlighted_source).is_err() { + Err(classifier.lexer.buffer_fatal_errors()) + } else { + Ok(String::from_utf8_lossy(&highlighted_source).into_owned()) + } + }); + + match highlight_result { + Ok(highlighted_source) => { + write_header(class, &mut out).unwrap(); + write!(out, "{}", highlighted_source).unwrap(); + if let Some(extension) = extension { + write!(out, "{}", extension).unwrap(); + } + write_footer(&mut out).unwrap(); } - }; - let mut classifier = Classifier::new(lexer, sess.source_map()); - if classifier.write_source(&mut out).is_err() { - classifier.lexer.emit_fatal_errors(); - return format!("
{}
", src); - } + Err(errors) => { + // If errors are encountered while trying to highlight, cancel the errors and just emit + // the unhighlighted source. The errors will have already been reported in the + // `check-code-block-syntax` pass. + for mut error in errors { + error.cancel(); + } - if let Some(extension) = extension { - write!(out, "{}", extension).unwrap(); + write!(out, "
{}
", src).unwrap(); + } } - write_footer(&mut out).unwrap(); + String::from_utf8_lossy(&out[..]).into_owned() } @@ -151,6 +162,17 @@ impl Writer for U { } } +enum HighlightError { + LexError, + IoError(io::Error), +} + +impl From for HighlightError { + fn from(err: io::Error) -> Self { + HighlightError::IoError(err) + } +} + impl<'a> Classifier<'a> { fn new(lexer: lexer::StringReader<'a>, source_map: &'a SourceMap) -> Classifier<'a> { Classifier { @@ -162,17 +184,11 @@ impl<'a> Classifier<'a> { } } - /// Gets the next token out of the lexer, emitting fatal errors if lexing fails. - fn try_next_token(&mut self) -> io::Result { + /// Gets the next token out of the lexer. + fn try_next_token(&mut self) -> Result { match self.lexer.try_next_token() { Ok(tas) => Ok(tas), - Err(_) => { - let mut err = self.lexer.sess.span_diagnostic - .struct_warn("Backing out of syntax highlighting"); - err.note("You probably did not intend to render this as a rust code-block"); - err.emit(); - Err(io::Error::new(io::ErrorKind::Other, "")) - } + Err(_) => Err(HighlightError::LexError), } } @@ -185,7 +201,7 @@ impl<'a> Classifier<'a> { /// source. fn write_source(&mut self, out: &mut W) - -> io::Result<()> { + -> Result<(), HighlightError> { loop { let next = self.try_next_token()?; if next.tok == token::Eof { @@ -202,7 +218,7 @@ impl<'a> Classifier<'a> { fn write_token(&mut self, out: &mut W, tas: TokenAndSpan) - -> io::Result<()> { + -> Result<(), HighlightError> { let klass = match tas.tok { token::Shebang(s) => { out.string(Escape(&s.as_str()), Class::None)?; @@ -341,7 +357,9 @@ impl<'a> Classifier<'a> { // Anything that didn't return above is the simple case where we the // class just spans a single token, so we can use the `string` method. - out.string(Escape(&self.snip(tas.sp)), klass) + out.string(Escape(&self.snip(tas.sp)), klass)?; + + Ok(()) } // Helper function to get a snippet from the source_map. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 05a9a2d1312ae..6b7f54044ca1d 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -919,6 +919,115 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option>)> { links } +#[derive(Debug)] +crate struct RustCodeBlock { + /// The range in the markdown that the code block occupies. Note that this includes the fences + /// for fenced code blocks. + pub range: Range, + /// The range in the markdown that the code within the code block occupies. + pub code: Range, + pub is_fenced: bool, + pub syntax: Option, +} + +/// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or +/// untagged (and assumed to be rust). +crate fn rust_code_blocks(md: &str) -> Vec { + let mut code_blocks = vec![]; + + if md.is_empty() { + return code_blocks; + } + + let mut opts = Options::empty(); + opts.insert(OPTION_ENABLE_TABLES); + opts.insert(OPTION_ENABLE_FOOTNOTES); + let mut p = Parser::new_ext(md, opts); + + let mut code_block_start = 0; + let mut code_start = 0; + let mut is_fenced = false; + let mut previous_offset = 0; + let mut in_rust_code_block = false; + while let Some(event) = p.next() { + let offset = p.get_offset(); + + match event { + Event::Start(Tag::CodeBlock(syntax)) => { + let lang_string = if syntax.is_empty() { + LangString::all_false() + } else { + LangString::parse(&*syntax, ErrorCodes::Yes) + }; + + if lang_string.rust { + in_rust_code_block = true; + + code_start = offset; + code_block_start = match md[previous_offset..offset].find("```") { + Some(fence_idx) => { + is_fenced = true; + previous_offset + fence_idx + } + None => offset, + }; + } + } + Event::End(Tag::CodeBlock(syntax)) if in_rust_code_block => { + in_rust_code_block = false; + + let code_block_end = if is_fenced { + let fence_str = &md[previous_offset..offset] + .chars() + .rev() + .collect::(); + fence_str + .find("```") + .map(|fence_idx| offset - fence_idx) + .unwrap_or_else(|| offset) + } else if md + .as_bytes() + .get(offset) + .map(|b| *b == b'\n') + .unwrap_or_default() + { + offset - 1 + } else { + offset + }; + + let code_end = if is_fenced { + previous_offset + } else { + code_block_end + }; + + code_blocks.push(RustCodeBlock { + is_fenced, + range: Range { + start: code_block_start, + end: code_block_end, + }, + code: Range { + start: code_start, + end: code_end, + }, + syntax: if !syntax.is_empty() { + Some(syntax.into_owned()) + } else { + None + }, + }); + } + _ => (), + } + + previous_offset = offset; + } + + code_blocks +} + #[derive(Clone, Default, Debug)] pub struct IdMap { map: FxHashMap, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1b6d7e87192d6..6e7141f94a776 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -3,6 +3,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/")] +#![feature(bind_by_move_pattern_guards)] #![feature(rustc_private)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs new file mode 100644 index 0000000000000..a013cc36c722d --- /dev/null +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -0,0 +1,109 @@ +use errors::Applicability; +use syntax::parse::lexer::{TokenAndSpan, StringReader as Lexer}; +use syntax::parse::{ParseSess, token}; +use syntax::source_map::FilePathMapping; +use syntax_pos::FileName; + +use clean; +use core::DocContext; +use fold::DocFolder; +use html::markdown::{self, RustCodeBlock}; +use passes::Pass; + +pub const CHECK_CODE_BLOCK_SYNTAX: Pass = + Pass::early("check-code-block-syntax", check_code_block_syntax, + "validates syntax inside Rust code blocks"); + +pub fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext) -> clean::Crate { + SyntaxChecker { cx }.fold_crate(krate) +} + +struct SyntaxChecker<'a, 'tcx: 'a, 'rcx: 'a> { + cx: &'a DocContext<'a, 'tcx, 'rcx>, +} + +impl<'a, 'tcx, 'rcx> SyntaxChecker<'a, 'tcx, 'rcx> { + fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) { + let sess = ParseSess::new(FilePathMapping::empty()); + let source_file = sess.source_map().new_source_file( + FileName::Custom(String::from("doctest")), + dox[code_block.code].to_owned(), + ); + + let errors = Lexer::new_or_buffered_errs(&sess, source_file, None).and_then(|mut lexer| { + while let Ok(TokenAndSpan { tok, .. }) = lexer.try_next_token() { + if tok == token::Eof { + break; + } + } + + let errors = lexer.buffer_fatal_errors(); + + if !errors.is_empty() { + Err(errors) + } else { + Ok(()) + } + }); + + if let Err(errors) = errors { + let mut diag = if let Some(sp) = + super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs) + { + let mut diag = self + .cx + .sess() + .struct_span_warn(sp, "could not parse code block as Rust code"); + + for mut err in errors { + diag.note(&format!("error from rustc: {}", err.message())); + err.cancel(); + } + + if code_block.syntax.is_none() && code_block.is_fenced { + let sp = sp.from_inner_byte_pos(0, 3); + diag.span_suggestion_with_applicability( + sp, + "mark blocks that do not contain Rust code as text", + String::from("```text"), + Applicability::MachineApplicable, + ); + } + + diag + } else { + // We couldn't calculate the span of the markdown block that had the error, so our + // diagnostics are going to be a bit lacking. + let mut diag = self.cx.sess().struct_span_warn( + super::span_of_attrs(&item.attrs), + "doc comment contains an invalid Rust code block", + ); + + for mut err in errors { + // Don't bother reporting the error, because we can't show where it happened. + err.cancel(); + } + + if code_block.syntax.is_none() && code_block.is_fenced { + diag.help("mark blocks that do not contain Rust code as text: ```text"); + } + + diag + }; + + diag.emit(); + } + } +} + +impl<'a, 'tcx, 'rcx> DocFolder for SyntaxChecker<'a, 'tcx, 'rcx> { + fn fold_item(&mut self, item: clean::Item) -> Option { + if let Some(dox) = &item.attrs.collapsed_doc_value() { + for code_block in markdown::rust_code_blocks(&dox) { + self.check_rust_syntax(&item, &dox, code_block); + } + } + + self.fold_item_recur(item) + } +} diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 56d6671266065..3d6096b07ce43 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -6,7 +6,7 @@ use syntax; use syntax::ast::{self, Ident, NodeId}; use syntax::feature_gate::UnstableFeatures; use syntax::symbol::Symbol; -use syntax_pos::{self, DUMMY_SP}; +use syntax_pos::DUMMY_SP; use std::ops::Range; @@ -16,6 +16,7 @@ use html::markdown::markdown_links; use clean::*; use passes::{look_for_tests, Pass}; +use super::span_of_attrs; pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass::early("collect-intra-doc-links", collect_intra_doc_links, @@ -440,15 +441,6 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { None } -pub fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { - if attrs.doc_strings.is_empty() { - return DUMMY_SP; - } - let start = attrs.doc_strings[0].span(); - let end = attrs.doc_strings.last().expect("No doc strings provided").span(); - start.to(end) -} - /// Reports a resolution failure diagnostic. /// /// If we cannot find the exact source span of the resolution failure, we use the span of the diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 23581d0051166..c9a3a2c003fe0 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -8,7 +8,7 @@ use rustc::util::nodemap::DefIdSet; use std::mem; use std::fmt; use syntax::ast::NodeId; -use syntax_pos::Span; +use syntax_pos::{DUMMY_SP, Span}; use std::ops::Range; use clean::{self, GetDefId, Item}; @@ -18,8 +18,6 @@ use fold::StripItem; use html::markdown::{find_testable_code, ErrorCodes, LangString}; -use self::collect_intra_doc_links::span_of_attrs; - mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -47,6 +45,9 @@ pub use self::private_items_doc_tests::CHECK_PRIVATE_ITEMS_DOC_TESTS; mod collect_trait_impls; pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; +mod check_code_block_syntax; +pub use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX; + /// Represents a single pass. #[derive(Copy, Clone)] pub enum Pass { @@ -137,6 +138,7 @@ pub const PASSES: &'static [Pass] = &[ STRIP_PRIV_IMPORTS, PROPAGATE_DOC_CFG, COLLECT_INTRA_DOC_LINKS, + CHECK_CODE_BLOCK_SYNTAX, COLLECT_TRAIT_IMPLS, ]; @@ -147,6 +149,7 @@ pub const DEFAULT_PASSES: &'static [&'static str] = &[ "strip-hidden", "strip-private", "collect-intra-doc-links", + "check-code-block-syntax", "collapse-docs", "unindent-comments", "propagate-doc-cfg", @@ -158,6 +161,7 @@ pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ "check-private-items-doc-tests", "strip-priv-imports", "collect-intra-doc-links", + "check-code-block-syntax", "collapse-docs", "unindent-comments", "propagate-doc-cfg", @@ -399,6 +403,16 @@ pub fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a>( } } +/// Return a span encompassing all the given attributes. +crate fn span_of_attrs(attrs: &clean::Attributes) -> Span { + if attrs.doc_strings.is_empty() { + return DUMMY_SP; + } + let start = attrs.doc_strings[0].span(); + let end = attrs.doc_strings.last().expect("No doc strings provided").span(); + start.to(end) +} + /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. /// /// This method will return `None` if we cannot construct a span from the source map or if the diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ecb34e43c590c..53650bd55aea3 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -238,19 +238,6 @@ impl<'a> StringReader<'a> { sr } - pub fn new_without_err(sess: &'a ParseSess, - source_file: Lrc, - override_span: Option, - prepend_error_text: &str) -> Result { - let mut sr = StringReader::new_raw(sess, source_file, override_span); - if sr.advance_token().is_err() { - eprintln!("{}", prepend_error_text); - sr.emit_fatal_errors(); - return Err(()); - } - Ok(sr) - } - pub fn new_or_buffered_errs(sess: &'a ParseSess, source_file: Lrc, override_span: Option) -> Result> { diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs index 537816be8d735..924e0386d3191 100644 --- a/src/test/rustdoc-ui/invalid-syntax.rs +++ b/src/test/rustdoc-ui/invalid-syntax.rs @@ -1,7 +1,66 @@ // compile-pass -// compile-flags: --error-format=human /// ``` /// \__________pkt->size___________/ \_result->size_/ \__pkt->size__/ /// ``` pub fn foo() {} + +/// ``` +/// | +/// LL | use foobar::Baz; +/// | ^^^^^^ did you mean `baz::foobar`? +/// ``` +pub fn bar() {} + +/// ``` +/// valid +/// ``` +/// +/// ``` +/// \_ +/// ``` +/// +/// ```text +/// "invalid +/// ``` +pub fn valid_and_invalid() {} + +/// This is a normal doc comment, but... +/// +/// There's a code block with bad syntax in it: +/// +/// ```rust +/// \_ +/// ``` +/// +/// Good thing we tested it! +pub fn baz() {} + +/// Indented block start +/// +/// code with bad syntax +/// \_ +/// +/// Indented block end +pub fn quux() {} + +/// Unclosed fence +/// +/// ``` +/// slkdjf +pub fn xyzzy() {} + +/// Indented code that contains a fence +/// +/// ``` +pub fn blah() {} + +/// ```edition2018 +/// \_ +/// ``` +pub fn blargh() {} + +#[doc = "```"] +/// \_ +#[doc = "```"] +pub fn crazy_attrs() {} diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr index b5661332e8d0e..10800380a05d3 100644 --- a/src/test/rustdoc-ui/invalid-syntax.stderr +++ b/src/test/rustdoc-ui/invalid-syntax.stderr @@ -1,10 +1,97 @@ -Output from rustc: -error: unknown start of token: / - --> :1:1 - | -1 | /__________pkt->size___________/ /_result->size_/ /__pkt->size__/ - | ^ - -warning: Invalid doc comment starting with: `/__________pkt->size___________/ /_result->size_/ /__pkt->size__/` -(Ignoring this codeblock) +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:3:5 + | +LL | /// ``` + | _____^ +LL | | /// /__________pkt->size___________/ /_result->size_/ /__pkt->size__/ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: / +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ^^^^^^^ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:8:5 + | +LL | /// ``` + | _____^ +LL | | /// | +LL | | /// LL | use foobar::Baz; +LL | | /// | ^^^^^^ did you mean `baz::foobar`? +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: ` +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ^^^^^^^ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:19:5 + | +LL | /// ``` + | _____^ +LL | | /// /_ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: / +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ^^^^^^^ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:32:5 + | +LL | /// ```rust + | _____^ +LL | | /// /_ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: / + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:41:9 + | +LL | /// code with bad syntax + | _________^ +LL | | /// /_ + | |__________^ + | + = note: error from rustc: unknown start of token: / + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:55:9 + | +LL | /// ``` + | ^^^ + | + = note: error from rustc: unknown start of token: ` + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:58:5 + | +LL | /// ```edition2018 + | _____^ +LL | | /// /_ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: / + +warning: doc comment contains an invalid Rust code block + --> $DIR/invalid-syntax.rs:63:1 + | +LL | / #[doc = "```"] +LL | | /// /_ +LL | | #[doc = "```"] + | |______________^ + | + = help: mark blocks that do not contain Rust code as text: ```text diff --git a/src/test/rustdoc/bad-codeblock-syntax.rs b/src/test/rustdoc/bad-codeblock-syntax.rs new file mode 100644 index 0000000000000..0ab2f68fcdebe --- /dev/null +++ b/src/test/rustdoc/bad-codeblock-syntax.rs @@ -0,0 +1,27 @@ +// @has bad_codeblock_syntax/fn.foo.html +// @has - '//*[@class="docblock"]/pre/code' '\_' +/// ``` +/// \_ +/// ``` +pub fn foo() {} + +// @has bad_codeblock_syntax/fn.bar.html +// @has - '//*[@class="docblock"]/pre/code' '`baz::foobar`' +/// ``` +/// `baz::foobar` +/// ``` +pub fn bar() {} + +// @has bad_codeblock_syntax/fn.quux.html +// @has - '//*[@class="docblock"]/pre/code' '\_' +/// ```rust +/// \_ +/// ``` +pub fn quux() {} + +// @has bad_codeblock_syntax/fn.ok.html +// @has - '//*[@class="docblock"]/pre/code[@class="language-text"]' '\_' +/// ```text +/// \_ +/// ``` +pub fn ok() {} From 09d073a4c59dee09f69f3cb144c3067a153c30e6 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Mon, 7 Jan 2019 07:09:17 -0800 Subject: [PATCH 0072/1064] stabilize extern_crate_self --- src/librustc_resolve/build_reduced_graph.rs | 6 +----- src/libsyntax/feature_gate.rs | 5 ++--- .../feature-gate-extern_crate_self.rs | 3 --- .../feature-gate-extern_crate_self.stderr | 11 ----------- .../extern-crate-self-fail.rs | 2 -- .../extern-crate-self-fail.stderr | 4 ++-- .../extern-crate-self-macro-alias.rs | 16 ++++++++++++++++ .../extern-crate-self-macro-item.rs | 12 ++++++++++++ .../extern-crate-self-macro-self.rs | 16 ++++++++++++++++ .../extern-crate-self-pass.rs | 2 -- 10 files changed, 49 insertions(+), 28 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-extern_crate_self.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr rename src/test/ui/imports/{ => extern-crate-self}/extern-crate-self-fail.rs (85%) rename src/test/ui/imports/{ => extern-crate-self}/extern-crate-self-fail.stderr (91%) create mode 100644 src/test/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs create mode 100644 src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs create mode 100644 src/test/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs rename src/test/ui/imports/{ => extern-crate-self}/extern-crate-self-pass.rs (79%) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a452bbf0c9d54..75bfdcc2f448a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -30,7 +30,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::base::Determinacy::Undetermined; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{is_builtin_attr, emit_feature_err, GateIssue}; +use syntax::feature_gate::is_builtin_attr; use syntax::parse::token::{self, Token}; use syntax::std_inject::injected_crate_name; use syntax::symbol::keywords; @@ -349,10 +349,6 @@ impl<'a> Resolver<'a> { .emit(); return; } else if orig_name == Some(keywords::SelfLower.name()) { - if !self.session.features_untracked().extern_crate_self { - emit_feature_err(&self.session.parse_sess, "extern_crate_self", item.span, - GateIssue::Language, "`extern crate self` is unstable"); - } self.graph_root } else { let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ed278e834cbc7..afbc010626276 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -453,9 +453,6 @@ declare_features! ( // Adds `reason` and `expect` lint attributes. (active, lint_reasons, "1.31.0", Some(54503), None), - // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`. - (active, extern_crate_self, "1.31.0", Some(56409), None), - // Allows paths to enum variants on type aliases. (active, type_alias_enum_variants, "1.31.0", Some(49683), None), @@ -685,6 +682,8 @@ declare_features! ( (accepted, uniform_paths, "1.32.0", Some(53130), None), // Allows `cfg(target_vendor = "...")`. (accepted, cfg_target_vendor, "1.33.0", Some(29718), None), + // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`. + (accepted, extern_crate_self, "1.34.0", Some(56409), None), ); // If you change this, please modify `src/doc/unstable-book` as well. You must diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_self.rs b/src/test/ui/feature-gates/feature-gate-extern_crate_self.rs deleted file mode 100644 index 2161932c2f6aa..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_crate_self.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate self as foo; //~ ERROR `extern crate self` is unstable - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr b/src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr deleted file mode 100644 index 530015b2cb712..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: `extern crate self` is unstable (see issue #56409) - --> $DIR/feature-gate-extern_crate_self.rs:1:1 - | -LL | extern crate self as foo; //~ ERROR `extern crate self` is unstable - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(extern_crate_self)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/imports/extern-crate-self-fail.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs similarity index 85% rename from src/test/ui/imports/extern-crate-self-fail.rs rename to src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs index eab7b7032aa07..defa0e294bd74 100644 --- a/src/test/ui/imports/extern-crate-self-fail.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs @@ -1,5 +1,3 @@ -#![feature(extern_crate_self)] - extern crate self; //~ ERROR `extern crate self;` requires renaming #[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self` diff --git a/src/test/ui/imports/extern-crate-self-fail.stderr b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr similarity index 91% rename from src/test/ui/imports/extern-crate-self-fail.stderr rename to src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr index 0ca0d89eaf08e..b47d10343f689 100644 --- a/src/test/ui/imports/extern-crate-self-fail.stderr +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr @@ -1,11 +1,11 @@ error: `extern crate self;` requires renaming - --> $DIR/extern-crate-self-fail.rs:3:1 + --> $DIR/extern-crate-self-fail.rs:1:1 | LL | extern crate self; //~ ERROR `extern crate self;` requires renaming | ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;` error: `macro_use` is not supported on `extern crate self` - --> $DIR/extern-crate-self-fail.rs:5:1 + --> $DIR/extern-crate-self-fail.rs:3:1 | LL | #[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self` | ^^^^^^^^^^^^ diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs new file mode 100644 index 0000000000000..79683522888cb --- /dev/null +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs @@ -0,0 +1,16 @@ +// run-pass + +// Test that a macro can correctly expand the alias +// in an `extern crate self as ALIAS` item. + +fn the_answer() -> usize { 42 } + +macro_rules! alias_self { + ($alias:ident) => { extern crate self as $alias; } +} + +alias_self!(the_alias); + +fn main() { + assert_eq!(the_alias::the_answer(), 42); +} diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs new file mode 100644 index 0000000000000..9c9397999ff67 --- /dev/null +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs @@ -0,0 +1,12 @@ +// compile-pass + +// Test that `extern crate self;` is accepted +// syntactically as an item for use in a macro. + +macro_rules! accept_item { ($x:item) => {} } + +accept_item! { + extern crate self; +} + +fn main() {} diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs new file mode 100644 index 0000000000000..009a92e877645 --- /dev/null +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs @@ -0,0 +1,16 @@ +// run-pass + +// Test that a macro can correctly expand `self` in +// an `extern crate self as ALIAS` item. + +fn the_answer() -> usize { 42 } + +macro_rules! extern_something { + ($alias:ident) => { extern crate $alias as the_alias; } +} + +extern_something!(self); + +fn main() { + assert_eq!(the_alias::the_answer(), 42); +} diff --git a/src/test/ui/imports/extern-crate-self-pass.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs similarity index 79% rename from src/test/ui/imports/extern-crate-self-pass.rs rename to src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs index bf255bb6b8194..6f6343a614886 100644 --- a/src/test/ui/imports/extern-crate-self-pass.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(extern_crate_self)] - extern crate self as foo; struct S; From e5e9867f604b9f656d529deb04a6b99338770c9e Mon Sep 17 00:00:00 2001 From: AB1908 Date: Tue, 15 Jan 2019 08:26:29 +0000 Subject: [PATCH 0073/1064] Pass a default value when unwrapping a span Fixes #57323 --- src/librustc_metadata/native_libs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index d35d64957b7b4..1f00086e32fe1 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -163,7 +163,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { !self.tcx.features().static_nobundle { feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, "static_nobundle", - span.unwrap(), + span.unwrap_or_else(|| syntax_pos::DUMMY_SP), GateIssue::Language, "kind=\"static-nobundle\" is feature gated"); } From 260fb31fd5d4d90d6694570c8a1964d7e1c5f81b Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Tue, 15 Jan 2019 00:09:21 +0900 Subject: [PATCH 0074/1064] Add missing unpretty option help message --- src/librustc/session/config.rs | 9 +++++++-- src/librustc_driver/pretty.rs | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 42adc6a87fdba..03dbd7b54e1e3 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1342,10 +1342,15 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, unpretty: Option = (None, parse_unpretty, [UNTRACKED], "Present the input source, unstable (and less-pretty) variants; valid types are any of the types for `--pretty`, as well as: + `expanded`, `expanded,identified`, + `expanded,hygiene` (with internal representations), `flowgraph=` (graphviz formatted flowgraph for node), + `flowgraph,unlabelled=` (unlabelled graphviz formatted flowgraph for node), `everybody_loops` (all function bodies replaced with `loop {}`), - `hir` (the HIR), `hir,identified`, or - `hir,typed` (HIR with types for each node)."), + `hir` (the HIR), `hir,identified`, + `hir,typed` (HIR with types for each node), + `hir-tree` (dump the raw HIR), + `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"), run_dsymutil: Option = (None, parse_opt_bool, [TRACKED], "run `dsymutil` and delete intermediate object files"), ui_testing: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index a9ec99358c1b2..dfd7a14a86435 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -123,7 +123,8 @@ pub fn parse_pretty(sess: &Session, sess.fatal(&format!("argument to `unpretty` must be one of `normal`, \ `expanded`, `flowgraph[,unlabelled]=`, \ `identified`, `expanded,identified`, `everybody_loops`, \ - `hir`, `hir,identified`, `hir,typed`, or `mir`; got {}", + `hir`, `hir,identified`, `hir,typed`, `hir-tree`, \ + `mir` or `mir-cfg`; got {}", name)); } else { sess.fatal(&format!("argument to `pretty` must be one of `normal`, `expanded`, \ From 8ef7413f23eca3921aa3ca1d0ebf72abd4a9eef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 22 Dec 2018 18:03:40 +0100 Subject: [PATCH 0075/1064] Optimize try_mark_green and eliminate the lock on dep node colors --- src/librustc/dep_graph/graph.rs | 165 ++++++++++++++++----------- src/librustc/dep_graph/prev.rs | 13 +-- src/librustc/ty/query/plumbing.rs | 49 ++------ src/librustc_data_structures/sync.rs | 6 +- 4 files changed, 117 insertions(+), 116 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 501ef01d74c6e..f8e426088dee5 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -3,7 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use smallvec::SmallVec; -use rustc_data_structures::sync::{Lrc, Lock}; +use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering}; use std::env; use std::hash::Hash; use std::collections::hash_map::Entry; @@ -58,7 +58,7 @@ struct DepGraphData { /// nodes and edges as well as all fingerprints of nodes that have them. previous: PreviousDepGraph, - colors: Lock, + colors: DepNodeColorMap, /// When we load, there may be `.o` files, cached mir, or other such /// things available to us. If we find that they are not dirty, we @@ -84,7 +84,7 @@ impl DepGraph { dep_node_debug: Default::default(), current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)), previous: prev_graph, - colors: Lock::new(DepNodeColorMap::new(prev_graph_node_count)), + colors: DepNodeColorMap::new(prev_graph_node_count), loaded_from_cache: Default::default(), })), } @@ -282,12 +282,11 @@ impl DepGraph { DepNodeColor::Red }; - let mut colors = data.colors.borrow_mut(); - debug_assert!(colors.get(prev_index).is_none(), + debug_assert!(data.colors.get(prev_index).is_none(), "DepGraph::with_task() - Duplicate DepNodeColor \ insertion for {:?}", key); - colors.insert(prev_index, color); + data.colors.insert(prev_index, color); } (result, dep_node_index) @@ -502,7 +501,7 @@ impl DepGraph { pub fn node_color(&self, dep_node: &DepNode) -> Option { if let Some(ref data) = self.data { if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) { - return data.colors.borrow().get(prev_index) + return data.colors.get(prev_index) } else { // This is a node that did not exist in the previous compilation // session, so we consider it to be red. @@ -513,56 +512,86 @@ impl DepGraph { None } - pub fn try_mark_green<'tcx>(&self, - tcx: TyCtxt<'_, 'tcx, 'tcx>, - dep_node: &DepNode) - -> Option { - debug!("try_mark_green({:?}) - BEGIN", dep_node); - let data = self.data.as_ref().unwrap(); + /// Try to read a node index for the node dep_node. + /// A node will have an index, when it's already been marked green, or when we can mark it + /// green. This function will mark the current task as a reader of the specified node, when + /// a node index can be found for that node. + pub fn try_mark_green_and_read( + &self, + tcx: TyCtxt<'_, '_, '_>, + dep_node: &DepNode + ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { + self.try_mark_green(tcx, dep_node).map(|(prev_index, dep_node_index)| { + debug_assert!(self.is_green(&dep_node)); + self.read_index(dep_node_index); + (prev_index, dep_node_index) + }) + } - #[cfg(not(parallel_queries))] - debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node)); - - if dep_node.kind.is_input() { - // We should only hit try_mark_green() for inputs that do not exist - // anymore in the current compilation session. Existing inputs are - // eagerly marked as either red/green before any queries are - // executed. - debug_assert!(dep_node.extract_def_id(tcx).is_none()); - debug!("try_mark_green({:?}) - END - DepNode is deleted input", dep_node); - return None; - } + pub fn try_mark_green( + &self, + tcx: TyCtxt<'_, '_, '_>, + dep_node: &DepNode + ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { + debug_assert!(!dep_node.kind.is_input()); - let (prev_deps, prev_dep_node_index) = match data.previous.edges_from(dep_node) { - Some(prev) => { - // This DepNode and the corresponding query invocation existed - // in the previous compilation session too, so we can try to - // mark it as green by recursively marking all of its - // dependencies green. - prev - } + // Return None if the dep graph is disabled + let data = self.data.as_ref()?; + + // Return None if the dep node didn't exist in the previous session + let prev_index = data.previous.node_to_index_opt(dep_node)?; + + match data.colors.get(prev_index) { + Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)), + Some(DepNodeColor::Red) => None, None => { - // This DepNode did not exist in the previous compilation session, - // so we cannot mark it as green. - debug!("try_mark_green({:?}) - END - DepNode does not exist in \ - current compilation session anymore", dep_node); - return None + self.try_mark_previous_green( + tcx.global_tcx(), + data, + prev_index, + &dep_node + ).map(|dep_node_index| { + (prev_index, dep_node_index) + }) } - }; + } + } - debug_assert!(data.colors.borrow().get(prev_dep_node_index).is_none()); + fn try_mark_previous_green<'tcx>( + &self, + tcx: TyCtxt<'_, 'tcx, 'tcx>, + data: &DepGraphData, + prev_dep_node_index: SerializedDepNodeIndex, + dep_node: &DepNode + ) -> Option { + debug!("try_mark_previous_green({:?}) - BEGIN", dep_node); + + #[cfg(not(parallel_queries))] + { + debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node)); + debug_assert!(data.colors.get(prev_dep_node_index).is_none()); + } + + debug_assert!(!dep_node.kind.is_input()); + debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node); + + // We never try to mark inputs as green + // FIXME: Make an debug_assert! + assert!(!dep_node.kind.is_input()); + + let prev_deps = data.previous.edge_targets_from(prev_dep_node_index); let mut current_deps = SmallVec::new(); for &dep_dep_node_index in prev_deps { - let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index); + let dep_dep_node_color = data.colors.get(dep_dep_node_index); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { // This dependency has been marked as green before, we are // still fine and can continue with checking the other // dependencies. - debug!("try_mark_green({:?}) --- found dependency {:?} to \ + debug!("try_mark_previous_green({:?}) --- found dependency {:?} to \ be immediately green", dep_node, data.previous.index_to_node(dep_dep_node_index)); @@ -573,7 +602,7 @@ impl DepGraph { // compared to the previous compilation session. We cannot // mark the DepNode as green and also don't need to bother // with checking any of the other dependencies. - debug!("try_mark_green({:?}) - END - dependency {:?} was \ + debug!("try_mark_previous_green({:?}) - END - dependency {:?} was \ immediately red", dep_node, data.previous.index_to_node(dep_dep_node_index)); @@ -585,12 +614,18 @@ impl DepGraph { // We don't know the state of this dependency. If it isn't // an input node, let's try to mark it green recursively. if !dep_dep_node.kind.is_input() { - debug!("try_mark_green({:?}) --- state of dependency {:?} \ + debug!("try_mark_previous_green({:?}) --- state of dependency {:?} \ is unknown, trying to mark it green", dep_node, dep_dep_node); - if let Some(node_index) = self.try_mark_green(tcx, dep_dep_node) { - debug!("try_mark_green({:?}) --- managed to MARK \ + let node_index = self.try_mark_previous_green( + tcx, + data, + dep_dep_node_index, + dep_dep_node + ); + if let Some(node_index) = node_index { + debug!("try_mark_previous_green({:?}) --- managed to MARK \ dependency {:?} as green", dep_node, dep_dep_node); current_deps.push(node_index); continue; @@ -620,20 +655,20 @@ impl DepGraph { } // We failed to mark it green, so we try to force the query. - debug!("try_mark_green({:?}) --- trying to force \ + debug!("try_mark_previous_green({:?}) --- trying to force \ dependency {:?}", dep_node, dep_dep_node); if ::ty::query::force_from_dep_node(tcx, dep_dep_node) { - let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index); + let dep_dep_node_color = data.colors.get(dep_dep_node_index); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { - debug!("try_mark_green({:?}) --- managed to \ + debug!("try_mark_previous_green({:?}) --- managed to \ FORCE dependency {:?} to green", dep_node, dep_dep_node); current_deps.push(node_index); } Some(DepNodeColor::Red) => { - debug!("try_mark_green({:?}) - END - \ + debug!("try_mark_previous_green({:?}) - END - \ dependency {:?} was red after forcing", dep_node, dep_dep_node); @@ -641,7 +676,7 @@ impl DepGraph { } None => { if !tcx.sess.has_errors() { - bug!("try_mark_green() - Forcing the DepNode \ + bug!("try_mark_previous_green() - Forcing the DepNode \ should have set its color") } else { // If the query we just forced has resulted @@ -653,7 +688,7 @@ impl DepGraph { } } else { // The DepNode could not be forced. - debug!("try_mark_green({:?}) - END - dependency {:?} \ + debug!("try_mark_previous_green({:?}) - END - dependency {:?} \ could not be forced", dep_node, dep_dep_node); return None } @@ -705,16 +740,15 @@ impl DepGraph { } // ... and finally storing a "Green" entry in the color map. - let mut colors = data.colors.borrow_mut(); // Multiple threads can all write the same color here #[cfg(not(parallel_queries))] - debug_assert!(colors.get(prev_dep_node_index).is_none(), - "DepGraph::try_mark_green() - Duplicate DepNodeColor \ + debug_assert!(data.colors.get(prev_dep_node_index).is_none(), + "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ insertion for {:?}", dep_node); - colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); + data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); - debug!("try_mark_green({:?}) - END - successfully marked as green", dep_node); + debug!("try_mark_previous_green({:?}) - END - successfully marked as green", dep_node); Some(dep_node_index) } @@ -735,9 +769,8 @@ impl DepGraph { pub fn exec_cache_promotions<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) { let green_nodes: Vec = { let data = self.data.as_ref().unwrap(); - let colors = data.colors.borrow(); - colors.values.indices().filter_map(|prev_index| { - match colors.get(prev_index) { + data.colors.values.indices().filter_map(|prev_index| { + match data.colors.get(prev_index) { Some(DepNodeColor::Green(_)) => { let dep_node = data.previous.index_to_node(prev_index); if dep_node.cache_on_disk(tcx) { @@ -1035,7 +1068,7 @@ pub struct TaskDeps { // A data structure that stores Option values as a contiguous // array, using one u32 per entry. struct DepNodeColorMap { - values: IndexVec, + values: IndexVec, } const COMPRESSED_NONE: u32 = 0; @@ -1045,12 +1078,12 @@ const COMPRESSED_FIRST_GREEN: u32 = 2; impl DepNodeColorMap { fn new(size: usize) -> DepNodeColorMap { DepNodeColorMap { - values: IndexVec::from_elem_n(COMPRESSED_NONE, size) + values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(), } } fn get(&self, index: SerializedDepNodeIndex) -> Option { - match self.values[index] { + match self.values[index].load(Ordering::Acquire) { COMPRESSED_NONE => None, COMPRESSED_RED => Some(DepNodeColor::Red), value => Some(DepNodeColor::Green(DepNodeIndex::from_u32( @@ -1059,10 +1092,10 @@ impl DepNodeColorMap { } } - fn insert(&mut self, index: SerializedDepNodeIndex, color: DepNodeColor) { - self.values[index] = match color { + fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) { + self.values[index].store(match color { DepNodeColor::Red => COMPRESSED_RED, DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN, - } + }, Ordering::Release) } } diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index 76d2954b4e35c..ea5350ac97fee 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -19,14 +19,11 @@ impl PreviousDepGraph { } #[inline] - pub fn edges_from(&self, - dep_node: &DepNode) - -> Option<(&[SerializedDepNodeIndex], SerializedDepNodeIndex)> { - self.index - .get(dep_node) - .map(|&node_index| { - (self.data.edge_targets_from(node_index), node_index) - }) + pub fn edge_targets_from( + &self, + dep_node_index: SerializedDepNodeIndex + ) -> &[SerializedDepNodeIndex] { + self.data.edge_targets_from(dep_node_index) } #[inline] diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 562cd75a75ff4..5d827e07c5997 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -2,7 +2,7 @@ //! that generate the actual methods on tcx which find and execute the //! provider, manage the caches, and so forth. -use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor}; +use dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; use errors::DiagnosticBuilder; use errors::Level; use errors::Diagnostic; @@ -335,40 +335,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { eprintln!("end of query stack"); } - /// Try to read a node index for the node dep_node. - /// A node will have an index, when it's already been marked green, or when we can mark it - /// green. This function will mark the current task as a reader of the specified node, when - /// a node index can be found for that node. - pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option { - match self.dep_graph.node_color(dep_node) { - Some(DepNodeColor::Green(dep_node_index)) => { - self.dep_graph.read_index(dep_node_index); - Some(dep_node_index) - } - Some(DepNodeColor::Red) => { - None - } - None => { - // try_mark_green (called below) will panic when full incremental - // compilation is disabled. If that's the case, we can't try to mark nodes - // as green anyway, so we can safely return None here. - if !self.dep_graph.is_fully_enabled() { - return None; - } - match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) { - Some(dep_node_index) => { - debug_assert!(self.dep_graph.is_green(&dep_node)); - self.dep_graph.read_index(dep_node_index); - Some(dep_node_index) - } - None => { - None - } - } - } - } - } - #[inline(never)] fn try_get_with>( self, @@ -435,10 +401,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } if !dep_node.kind.is_input() { - if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) { + if let Some((prev_dep_node_index, + dep_node_index)) = self.dep_graph.try_mark_green_and_read(self, + &dep_node) { return Ok(self.load_from_disk_and_cache_in_memory::( key, job, + prev_dep_node_index, dep_node_index, &dep_node )) @@ -454,6 +423,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, key: Q::Key, job: JobOwner<'a, 'gcx, Q>, + prev_dep_node_index: SerializedDepNodeIndex, dep_node_index: DepNodeIndex, dep_node: &DepNode ) -> Q::Value @@ -466,10 +436,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // First we try to load the result from the on-disk cache let result = if Q::cache_on_disk(key.clone()) && self.sess.opts.debugging_opts.incremental_queries { - let prev_dep_node_index = - self.dep_graph.prev_dep_node_index_of(dep_node); - let result = Q::try_load_from_disk(self.global_tcx(), - prev_dep_node_index); + let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index); // We always expect to find a cached result for things that // can be forced from DepNode. @@ -624,7 +591,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Ensuring an "input" or anonymous query makes no sense assert!(!dep_node.kind.is_anon()); assert!(!dep_node.kind.is_input()); - if self.try_mark_green_and_read(&dep_node).is_none() { + if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() { // A None return from `try_mark_green_and_read` means that this is either // a new dep node or that the dep node has already been marked red. // Either way, we can't call `dep_graph.read()` as we don't have the diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index f9f94f0be7b9a..0253eef4dfa3a 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -70,6 +70,7 @@ cfg_if! { pub struct Atomic(Cell); impl Atomic { + #[inline] pub fn new(v: T) -> Self { Atomic(Cell::new(v)) } @@ -80,10 +81,12 @@ cfg_if! { self.0.into_inner() } + #[inline] pub fn load(&self, _: Ordering) -> T { self.0.get() } + #[inline] pub fn store(&self, val: T, _: Ordering) { self.0.set(val) } @@ -118,6 +121,7 @@ cfg_if! { pub type AtomicUsize = Atomic; pub type AtomicBool = Atomic; + pub type AtomicU32 = Atomic; pub type AtomicU64 = Atomic; pub use self::serial_join as join; @@ -223,7 +227,7 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU64}; + pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; pub use std::sync::Arc as Lrc; pub use std::sync::Weak as Weak; From 13136787849c960db824b2ad15d227dc15fadd70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 15 Jan 2019 10:39:35 +0100 Subject: [PATCH 0076/1064] Address comments --- src/librustc/dep_graph/graph.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index f8e426088dee5..0a0dff05cb1ab 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -545,6 +545,10 @@ impl DepGraph { Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)), Some(DepNodeColor::Red) => None, None => { + // This DepNode and the corresponding query invocation existed + // in the previous compilation session too, so we can try to + // mark it as green by recursively marking all of its + // dependencies green. self.try_mark_previous_green( tcx.global_tcx(), data, @@ -557,6 +561,7 @@ impl DepGraph { } } + /// Try to mark a dep-node which existed in the previous compilation session as green fn try_mark_previous_green<'tcx>( &self, tcx: TyCtxt<'_, 'tcx, 'tcx>, @@ -572,12 +577,10 @@ impl DepGraph { debug_assert!(data.colors.get(prev_dep_node_index).is_none()); } + // We never try to mark inputs as green debug_assert!(!dep_node.kind.is_input()); - debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node); - // We never try to mark inputs as green - // FIXME: Make an debug_assert! - assert!(!dep_node.kind.is_input()); + debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node); let prev_deps = data.previous.edge_targets_from(prev_dep_node_index); From ff19a53ef07566aa30860023f6eac6e75ffaf900 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sun, 13 Jan 2019 13:06:26 +0100 Subject: [PATCH 0077/1064] Querify entry_fn --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/middle/dead.rs | 2 +- src/librustc/middle/entry.rs | 77 +++++++++++-------- src/librustc/session/config.rs | 8 +- src/librustc/session/mod.rs | 4 - src/librustc/ty/query/config.rs | 6 ++ src/librustc/ty/query/mod.rs | 4 +- src/librustc/ty/query/plumbing.rs | 1 + src/librustc_codegen_llvm/debuginfo/mod.rs | 7 +- .../back/symbol_export.rs | 2 +- src/librustc_codegen_ssa/base.rs | 8 +- src/librustc_codegen_utils/lib.rs | 9 +-- src/librustc_driver/driver.rs | 9 ++- src/librustc_mir/monomorphize/collector.rs | 23 ++---- src/librustc_mir/monomorphize/item.rs | 5 +- src/librustc_typeck/check/mod.rs | 28 +++---- src/librustc_typeck/lib.rs | 32 ++++---- 17 files changed, 116 insertions(+), 110 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 427fe51e6ff9c..9df41c981eb7b 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -583,6 +583,7 @@ define_dep_nodes!( <'tcx> [] CheckImplItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), + [] EntryFn(CrateNum), [] PluginRegistrarFn(CrateNum), [] ProcMacroDeclsStatic(CrateNum), [input] CrateDisambiguator(CrateNum), diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 0c769c91801b8..abbf0ae210c25 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -409,7 +409,7 @@ fn create_and_seed_worklist<'a, 'tcx>( } }).chain( // Seed entry point - tcx.sess.entry_fn.borrow().map(|(id, _, _)| id) + tcx.entry_fn(LOCAL_CRATE).map(|(def_id, _)| tcx.hir().as_local_node_id(def_id).unwrap()) ).collect::>(); // Seed implemented trait items diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 6b593a1a9f9b2..218ca3b7553c0 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -1,5 +1,5 @@ use hir::map as hir_map; -use hir::def_id::{CRATE_DEF_INDEX}; +use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; use session::{config, Session}; use session::config::EntryFnType; use syntax::ast::NodeId; @@ -8,6 +8,8 @@ use syntax::entry::EntryPointType; use syntax_pos::Span; use hir::{Item, ItemKind, ImplItem, TraitItem}; use hir::itemlikevisit::ItemLikeVisitor; +use ty::TyCtxt; +use ty::query::Providers; struct EntryContext<'a, 'tcx: 'a> { session: &'a Session, @@ -45,36 +47,34 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { } } -pub fn find_entry_point(session: &Session, - hir_map: &hir_map::Map<'_>, - crate_name: &str) { - let any_exe = session.crate_types.borrow().iter().any(|ty| { +fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> { + assert_eq!(cnum, LOCAL_CRATE); + + let any_exe = tcx.sess.crate_types.borrow().iter().any(|ty| { *ty == config::CrateType::Executable }); if !any_exe { // No need to find a main function - session.entry_fn.set(None); - return + return None; } // If the user wants no main function at all, then stop here. - if attr::contains_name(&hir_map.krate().attrs, "no_main") { - session.entry_fn.set(None); - return + if attr::contains_name(&tcx.hir().krate().attrs, "no_main") { + return None; } let mut ctxt = EntryContext { - session, - map: hir_map, + session: tcx.sess, + map: tcx.hir(), main_fn: None, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new(), }; - hir_map.krate().visit_all_item_likes(&mut ctxt); + tcx.hir().krate().visit_all_item_likes(&mut ctxt); - configure_main(&mut ctxt, crate_name); + configure_main(tcx, &ctxt) } // Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep @@ -135,43 +135,58 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { .span_label(item.span, "multiple `start` functions") .emit(); } - }, - EntryPointType::None => () + } + EntryPointType::None => (), } } -fn configure_main(this: &mut EntryContext<'_, '_>, crate_name: &str) { - if let Some((node_id, span)) = this.start_fn { - this.session.entry_fn.set(Some((node_id, span, EntryFnType::Start))); - } else if let Some((node_id, span)) = this.attr_main_fn { - this.session.entry_fn.set(Some((node_id, span, EntryFnType::Main))); - } else if let Some((node_id, span)) = this.main_fn { - this.session.entry_fn.set(Some((node_id, span, EntryFnType::Main))); +fn configure_main( + tcx: TyCtxt<'_, '_, '_>, + visitor: &EntryContext<'_, '_>, +) -> Option<(DefId, EntryFnType)> { + if let Some((node_id, _)) = visitor.start_fn { + Some((tcx.hir().local_def_id(node_id), EntryFnType::Start)) + } else if let Some((node_id, _)) = visitor.attr_main_fn { + Some((tcx.hir().local_def_id(node_id), EntryFnType::Main)) + } else if let Some((node_id, _)) = visitor.main_fn { + Some((tcx.hir().local_def_id(node_id), EntryFnType::Main)) } else { // No main function - this.session.entry_fn.set(None); - let mut err = struct_err!(this.session, E0601, - "`main` function not found in crate `{}`", crate_name); - if !this.non_main_fns.is_empty() { + let mut err = struct_err!(tcx.sess, E0601, + "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE)); + if !visitor.non_main_fns.is_empty() { // There were some functions named 'main' though. Try to give the user a hint. err.note("the main function must be defined at the crate level \ but you have one or more functions named 'main' that are not \ defined at the crate level. Either move the definition or \ attach the `#[main]` attribute to override this behavior."); - for &(_, span) in &this.non_main_fns { + for &(_, span) in &visitor.non_main_fns { err.span_note(span, "here is a function named 'main'"); } err.emit(); - this.session.abort_if_errors(); + tcx.sess.abort_if_errors(); } else { - if let Some(ref filename) = this.session.local_crate_source_file { + if let Some(ref filename) = tcx.sess.local_crate_source_file { err.note(&format!("consider adding a `main` function to `{}`", filename.display())); } - if this.session.teach(&err.get_code().unwrap()) { + if tcx.sess.teach(&err.get_code().unwrap()) { err.note("If you don't know the basics of Rust, you can go look to the Rust Book \ to get started: https://doc.rust-lang.org/book/"); } err.emit(); } + + None } } + +pub fn find_entry_point(tcx: TyCtxt<'_, '_, '_>) -> Option<(DefId, EntryFnType)> { + tcx.entry_fn(LOCAL_CRATE) +} + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + entry_fn, + ..*providers + }; +} diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 42adc6a87fdba..41e75aa32effc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -649,15 +649,15 @@ impl Options { } } -// The type of entry function, so -// users can have their own entry -// functions -#[derive(Copy, Clone, PartialEq)] +// The type of entry function, so users can have their own entry functions +#[derive(Copy, Clone, PartialEq, Hash, Debug)] pub enum EntryFnType { Main, Start, } +impl_stable_hash_via_hash!(EntryFnType); + #[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)] pub enum CrateType { Executable, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 7363b8b3a78fa..cf00bf330deea 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -67,8 +67,6 @@ pub struct Session { /// This is `None` if the host and target are the same. pub target_tlib_path: Option, pub parse_sess: ParseSess, - /// For a library crate, this is always none - pub entry_fn: Once>, pub sysroot: PathBuf, /// The name of the root source file of the crate, in the local file system. /// `None` means that there is no source file. @@ -1173,8 +1171,6 @@ pub fn build_session_( host_tlib_path, target_tlib_path, parse_sess: p_s, - // For a library crate, this is always none - entry_fn: Once::new(), sysroot, local_crate_source_file, working_dir, diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index ca5d1f6bd3203..38e90d6d823b2 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -629,6 +629,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::entry_fn<'tcx> { + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the entry function of a crate".into() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> { fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { "looking up the plugin registrar for a crate".into() diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 39d76ceed9507..ef5a98e6ecb3b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -22,7 +22,7 @@ use mir::mono::CodegenUnit; use mir; use mir::interpret::GlobalId; use session::{CompileResult, CrateDisambiguator}; -use session::config::OutputFilenames; +use session::config::{EntryFnType, OutputFilenames}; use traits::{self, Vtable}; use traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, @@ -476,6 +476,8 @@ define_queries! { <'tcx> [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc>, + // For a library crate, this is always none + [] fn entry_fn: EntryFn(CrateNum) -> Option<(DefId, EntryFnType)>, [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option, [] fn proc_macro_decls_static: ProcMacroDeclsStatic(CrateNum) -> Option, [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 562cd75a75ff4..bb47d9a9db970 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1362,6 +1362,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } + DepKind::EntryFn => { force!(entry_fn, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } DepKind::ProcMacroDeclsStatic => { force!(proc_macro_decls_static, krate!()); } DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 2eab626ae8e6e..b504aa515fd44 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -14,7 +14,7 @@ use llvm; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags, DILexicalBlock}; use rustc::hir::CodegenFnAttrFlags; -use rustc::hir::def_id::{DefId, CrateNum}; +use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::ty::subst::{Substs, UnpackedKind}; use abi::Abi; @@ -290,9 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let mut flags = DIFlags::FlagPrototyped; - let local_id = self.tcx().hir().as_local_node_id(def_id); - if let Some((id, _, _)) = *self.sess().entry_fn.borrow() { - if local_id == Some(id) { + if let Some((id, _)) = self.tcx.entry_fn(LOCAL_CRATE) { + if id == def_id { flags |= DIFlags::FlagMainSubprogram; } } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index bf69089a254a4..c372892c521be 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -194,7 +194,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) .collect(); - if tcx.sess.entry_fn.borrow().is_some() { + if tcx.entry_fn(LOCAL_CRATE).is_some() { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("main")); symbols.push((exported_symbol, SymbolExportLevel::C)); diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index b88ec075653ba..38caacba4d069 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -441,10 +441,8 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx ) { - let (main_def_id, span) = match *cx.sess().entry_fn.borrow() { - Some((id, span, _)) => { - (cx.tcx().hir().local_def_id(id), span) - } + let (main_def_id, span) = match cx.tcx().entry_fn(LOCAL_CRATE) { + Some((def_id, _)) => { (def_id, cx.tcx().def_span(def_id)) }, None => return, }; @@ -458,7 +456,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let main_llfn = cx.get_fn(instance); - let et = cx.sess().entry_fn.get().map(|e| e.2); + let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1); match et { Some(EntryFnType::Main) => create_entry_fn::(cx, span, main_llfn, main_def_id, true), Some(EntryFnType::Start) => create_entry_fn::(cx, span, main_llfn, main_def_id, false), diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index b59bca0ae0edb..5f61852178d0f 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -31,6 +31,7 @@ extern crate syntax_pos; #[macro_use] extern crate rustc_data_structures; use rustc::ty::TyCtxt; +use rustc::hir::def_id::LOCAL_CRATE; pub mod link; pub mod codegen_backend; @@ -42,11 +43,9 @@ pub mod symbol_names_test; /// that actually test that compilation succeeds without /// reporting an error. pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { - if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() { - let main_def_id = tcx.hir().local_def_id(id); - - if tcx.has_attr(main_def_id, "rustc_error") { - tcx.sess.span_fatal(span, "compilation successful"); + if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { + if tcx.has_attr(def_id, "rustc_error") { + tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful"); } } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 3b7de37ae4b3f..4244110072305 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1174,6 +1174,7 @@ pub fn default_provide(providers: &mut ty::query::Providers) { rustc_passes::provide(providers); rustc_traits::provide(providers); middle::region::provide(providers); + middle::entry::provide(providers); cstore::provide(providers); lint::provide(providers); } @@ -1210,10 +1211,6 @@ where rustc_incremental::load_query_result_cache(sess) }); - time(sess, "looking for entry point", || { - middle::entry::find_entry_point(sess, &hir_map, name) - }); - let mut local_providers = ty::query::Providers::default(); default_provide(&mut local_providers); codegen_backend.provide(&mut local_providers); @@ -1243,6 +1240,10 @@ where // tcx available. time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); + time(sess, "looking for entry point", || { + middle::entry::find_entry_point(tcx) + }); + time(sess, "looking for plugin registrar", || { plugin::build::find_plugin_registrar(tcx) }); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a6a8fe5ade56c..eb49547e9bf52 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -177,13 +177,13 @@ use rustc::hir::{self, CodegenFnAttrFlags}; use rustc::hir::itemlikevisit::ItemLikeVisitor; -use rustc::hir::def_id::DefId; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::Substs; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind}; use rustc::ty::adjustment::CustomCoerceUnsized; -use rustc::session::config; +use rustc::session::config::EntryFnType; use rustc::mir::{self, Location, Promoted}; use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::MonoItem; @@ -321,9 +321,7 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut roots = Vec::new(); { - let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _, _)| { - tcx.hir().local_def_id(node_id) - }); + let entry_fn = tcx.entry_fn(LOCAL_CRATE); debug!("collect_roots: entry_fn = {:?}", entry_fn); @@ -924,7 +922,7 @@ struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> { tcx: TyCtxt<'a, 'tcx, 'tcx>, mode: MonoItemCollectionMode, output: &'b mut Vec>, - entry_fn: Option, + entry_fn: Option<(DefId, EntryFnType)>, } impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { @@ -1023,7 +1021,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { true } MonoItemCollectionMode::Lazy => { - self.entry_fn == Some(def_id) || + self.entry_fn.map(|(id, _)| id) == Some(def_id) || self.tcx.is_reachable_non_generic(def_id) || self.tcx.codegen_fn_attrs(def_id).flags.contains( CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) @@ -1048,14 +1046,9 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { /// the return type of `main`. This is not needed when /// the user writes their own `start` manually. fn push_extra_entry_roots(&mut self) { - if self.tcx.sess.entry_fn.get().map(|e| e.2) != Some(config::EntryFnType::Main) { - return - } - - let main_def_id = if let Some(def_id) = self.entry_fn { - def_id - } else { - return + let main_def_id = match self.entry_fn { + Some((def_id, EntryFnType::Main)) => def_id, + _ => return, }; let start_def_id = match self.tcx.lang_items().require(StartFnLangItem) { diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 7014f539d5754..c831cbd98299c 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -1,6 +1,6 @@ use monomorphize::Instance; use rustc::hir; -use rustc::hir::def_id::DefId; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::session::config::OptLevel; use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts}; use rustc::ty::subst::Substs; @@ -75,8 +75,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { match *self.as_mono_item() { MonoItem::Fn(ref instance) => { - let entry_def_id = - tcx.sess.entry_fn.borrow().map(|(id, _, _)| tcx.hir().local_def_id(id)); + let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id); // If this function isn't inlined or otherwise has explicit // linkage, then we'll be creating a globally shared version. if self.explicit_linkage(tcx).is_some() || diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..cb7e83985874c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -132,7 +132,8 @@ use std::ops::{self, Deref}; use std::slice; use require_c_abi_if_variadic; -use session::{CompileIncomplete, config, Session}; +use session::{CompileIncomplete, Session}; +use session::config::EntryFnType; use TypeAndSubsts; use lint; use util::captures::Captures; @@ -1163,19 +1164,18 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // Check that the main return type implements the termination trait. if let Some(term_id) = fcx.tcx.lang_items().termination() { - if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() { - if id == fn_id { - if let config::EntryFnType::Main = entry_type { - let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]); - let trait_ref = ty::TraitRef::new(term_id, substs); - let return_ty_span = decl.output.span(); - let cause = traits::ObligationCause::new( - return_ty_span, fn_id, ObligationCauseCode::MainFunctionType); - - inherited.register_predicate( - traits::Obligation::new( - cause, param_env, trait_ref.to_predicate())); - } + if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) { + let main_id = fcx.tcx.hir().as_local_node_id(def_id).unwrap(); + if main_id == fn_id { + let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]); + let trait_ref = ty::TraitRef::new(term_id, substs); + let return_ty_span = decl.output.span(); + let cause = traits::ObligationCause::new( + return_ty_span, fn_id, ObligationCauseCode::MainFunctionType); + + inherited.register_predicate( + traits::Obligation::new( + cause, param_env, trait_ref.to_predicate())); } } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index c55a1258ce955..fb5b28c55da29 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -104,23 +104,22 @@ mod namespace; mod outlives; mod variance; -use hir::Node; use rustc_target::spec::abi::Abi; -use rustc::hir; +use rustc::hir::{self, Node}; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::infer::InferOk; use rustc::lint; use rustc::middle; use rustc::session; -use rustc::session::config::nightly_options; +use rustc::session::CompileIncomplete; +use rustc::session::config::{EntryFnType, nightly_options}; use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt}; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::query::Providers; use rustc::util; use rustc::util::profiling::ProfileCategory; -use session::{CompileIncomplete, config}; use syntax_pos::Span; -use syntax::ast; use util::common::time; use std::iter; @@ -185,10 +184,9 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) } -fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - main_id: ast::NodeId, - main_span: Span) { - let main_def_id = tcx.hir().local_def_id(main_id); +fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, main_def_id: DefId) { + let main_id = tcx.hir().as_local_node_id(main_def_id).unwrap(); + let main_span = tcx.def_span(main_def_id); let main_t = tcx.type_of(main_def_id); match main_t.sty { ty::FnDef(..) => { @@ -251,10 +249,9 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - start_id: ast::NodeId, - start_span: Span) { - let start_def_id = tcx.hir().local_def_id(start_id); +fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, start_def_id: DefId) { + let start_id = tcx.hir().as_local_node_id(start_def_id).unwrap(); + let start_span = tcx.def_span(start_def_id); let start_t = tcx.type_of(start_def_id); match start_t.sty { ty::FnDef(..) => { @@ -310,11 +307,10 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - if let Some((id, sp, entry_type)) = *tcx.sess.entry_fn.borrow() { - match entry_type { - config::EntryFnType::Main => check_main_fn_ty(tcx, id, sp), - config::EntryFnType::Start => check_start_fn_ty(tcx, id, sp), - } + match tcx.entry_fn(LOCAL_CRATE) { + Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id), + Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), + _ => {} } } From 096ca873330d61de91d81618ce3a1e9905581ff1 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 15 Jan 2019 17:11:07 +0100 Subject: [PATCH 0078/1064] Remove an unused function argument --- src/librustc/hir/intravisit.rs | 58 +-------------------- src/librustc_borrowck/borrowck/mod.rs | 9 ---- src/librustc_borrowck/borrowck/move_data.rs | 4 -- src/librustc_borrowck/dataflow.rs | 7 ++- 4 files changed, 4 insertions(+), 74 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index f633703be56d4..041291e80eee9 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -35,11 +35,9 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, Ident, Name, Attribute}; use syntax_pos::Span; use hir::*; use hir::def::Def; -use hir::map::{self, Map}; +use hir::map::Map; use super::itemlikevisit::DeepVisitor; -use std::cmp; - #[derive(Copy, Clone)] pub enum FnKind<'a> { /// `#[xxx] pub async/const/extern "Abi" fn foo()` @@ -1133,57 +1131,3 @@ pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) { // the right thing to do, should content be added in the future, // would be to walk it. } - -#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct IdRange { - pub min: NodeId, - pub max: NodeId, -} - -impl IdRange { - pub fn max() -> IdRange { - IdRange { - min: NodeId::MAX, - max: NodeId::from_u32(0), - } - } - - pub fn empty(&self) -> bool { - self.min >= self.max - } - - pub fn contains(&self, id: NodeId) -> bool { - id >= self.min && id < self.max - } - - pub fn add(&mut self, id: NodeId) { - self.min = cmp::min(self.min, id); - self.max = cmp::max(self.max, NodeId::from_u32(id.as_u32() + 1)); - } -} - - -pub struct IdRangeComputingVisitor<'a, 'hir: 'a> { - result: IdRange, - map: &'a map::Map<'hir>, -} - -impl<'a, 'hir> IdRangeComputingVisitor<'a, 'hir> { - pub fn new(map: &'a map::Map<'hir>) -> IdRangeComputingVisitor<'a, 'hir> { - IdRangeComputingVisitor { result: IdRange::max(), map: map } - } - - pub fn result(&self) -> IdRange { - self.result - } -} - -impl<'a, 'hir> Visitor<'hir> for IdRangeComputingVisitor<'a, 'hir> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { - NestedVisitorMap::OnlyBodies(&self.map) - } - - fn visit_id(&mut self, id: NodeId) { - self.result.add(id); - } -} diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 66303ab71b25f..72963cb7e7fb4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -39,7 +39,6 @@ use syntax_pos::{MultiSpan, Span}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc::hir; -use rustc::hir::intravisit::{self, Visitor}; use dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; @@ -157,12 +156,6 @@ fn build_borrowck_dataflow_data<'a, 'c, 'tcx, F>(this: &mut BorrowckCtxt<'a, 'tc where F: FnOnce(&mut BorrowckCtxt<'a, 'tcx>) -> &'c cfg::CFG { // Check the body of fn items. - let tcx = this.tcx; - let id_range = { - let mut visitor = intravisit::IdRangeComputingVisitor::new(&tcx.hir()); - visitor.visit_body(this.body); - visitor.result() - }; let (all_loans, move_data) = gather_loans::gather_loans_in_fn(this, body_id); @@ -184,7 +177,6 @@ fn build_borrowck_dataflow_data<'a, 'c, 'tcx, F>(this: &mut BorrowckCtxt<'a, 'tc Some(this.body), cfg, LoanDataFlowOperator, - id_range, all_loans.len()); for (loan_idx, loan) in all_loans.iter().enumerate() { loan_dfcx.add_gen(loan.gen_scope.item_local_id(), loan_idx); @@ -198,7 +190,6 @@ fn build_borrowck_dataflow_data<'a, 'c, 'tcx, F>(this: &mut BorrowckCtxt<'a, 'tc let flowed_moves = move_data::FlowedMoveData::new(move_data, this, cfg, - id_range, this.body); Some(AnalysisData { all_loans, diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index c5bee87e90fe4..56c9f928eb03a 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -15,7 +15,6 @@ use std::rc::Rc; use std::usize; use syntax_pos::Span; use rustc::hir; -use rustc::hir::intravisit::IdRange; #[derive(Default)] pub struct MoveData<'tcx> { @@ -559,7 +558,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { pub fn new(move_data: MoveData<'tcx>, bccx: &BorrowckCtxt<'a, 'tcx>, cfg: &cfg::CFG, - id_range: IdRange, body: &hir::Body) -> FlowedMoveData<'a, 'tcx> { let tcx = bccx.tcx; @@ -570,7 +568,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { Some(body), cfg, MoveDataFlowOperator, - id_range, move_data.moves.borrow().len()); let mut dfcx_assign = DataFlowContext::new(tcx, @@ -578,7 +575,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { Some(body), cfg, AssignDataFlowOperator, - id_range, move_data.var_assignments.borrow().len()); move_data.add_gen_kills(bccx, diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs index 56e25bd89c9ad..8cf620567405c 100644 --- a/src/librustc_borrowck/dataflow.rs +++ b/src/librustc_borrowck/dataflow.rs @@ -15,7 +15,7 @@ use rustc_data_structures::graph::implementation::OUTGOING; use rustc::util::nodemap::FxHashMap; use rustc::hir; -use rustc::hir::intravisit::{self, IdRange}; +use rustc::hir::intravisit; use rustc::hir::print as pprust; @@ -230,16 +230,15 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { body: Option<&hir::Body>, cfg: &cfg::CFG, oper: O, - id_range: IdRange, bits_per_id: usize) -> DataFlowContext<'a, 'tcx, O> { let usize_bits = mem::size_of::() * 8; let words_per_id = (bits_per_id + usize_bits - 1) / usize_bits; let num_nodes = cfg.graph.all_nodes().len(); - debug!("DataFlowContext::new(analysis_name: {}, id_range={:?}, \ + debug!("DataFlowContext::new(analysis_name: {}, \ bits_per_id={}, words_per_id={}) \ num_nodes: {}", - analysis_name, id_range, bits_per_id, words_per_id, + analysis_name, bits_per_id, words_per_id, num_nodes); let entry = if oper.initial_value() { usize::MAX } else {0}; From 93b55365b59767f87ac2a2e42876ad46210a0e55 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 15 Jan 2019 11:27:58 -0500 Subject: [PATCH 0079/1064] use structured macro and path resolve suggestions --- src/librustc_resolve/lib.rs | 24 ++++++++++--- src/test/ui/resolve/resolve-hint-macro.stderr | 2 +- ...uggest-path-instead-of-mod-dot-item.stderr | 36 ++++++++++++------- .../try-block/try-block-in-edition2015.stderr | 2 +- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a25009ccfb49c..439d149227203 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3321,7 +3321,12 @@ impl<'a> Resolver<'a> { if let Some(def) = def { match (def, source) { (Def::Macro(..), _) => { - err.span_label(span, format!("did you mean `{}!(...)`?", path_str)); + err.span_suggestion_with_applicability( + span, + "use `!` to invoke the macro", + format!("{}!", path_str), + Applicability::MaybeIncorrect, + ); return (err, candidates); } (Def::TyAlias(..), PathSource::Trait(_)) => { @@ -3333,13 +3338,22 @@ impl<'a> Resolver<'a> { } (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { ExprKind::Field(_, ident) => { - err.span_label(parent.span, format!("did you mean `{}::{}`?", - path_str, ident)); + err.span_suggestion_with_applicability( + parent.span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, ident), + Applicability::MaybeIncorrect, + ); return (err, candidates); } ExprKind::MethodCall(ref segment, ..) => { - err.span_label(parent.span, format!("did you mean `{}::{}(...)`?", - path_str, segment.ident)); + let span = parent.span.with_hi(segment.ident.span.hi()); + err.span_suggestion_with_applicability( + span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, segment.ident), + Applicability::MaybeIncorrect, + ); return (err, candidates); } _ => {} diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr index 4f6d0f695df44..ebe3c36f21eb1 100644 --- a/src/test/ui/resolve/resolve-hint-macro.stderr +++ b/src/test/ui/resolve/resolve-hint-macro.stderr @@ -2,7 +2,7 @@ error[E0423]: expected function, found macro `assert` --> $DIR/resolve-hint-macro.rs:2:5 | LL | assert(true); - | ^^^^^^ did you mean `assert!(...)`? + | ^^^^^^ help: use `!` to invoke the macro: `assert!` error: aborting due to previous error diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index 8a9426bfee862..b7b158ce7efa6 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -4,15 +4,15 @@ error[E0423]: expected value, found module `a` LL | a.I | ^-- | | - | did you mean `a::I`? + | help: use the path separator to refer to an item: `a::I` error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:22:5 | LL | a.g() - | ^---- + | ^-- | | - | did you mean `a::g(...)`? + | help: use the path separator to refer to an item: `a::g` error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5 @@ -20,16 +20,21 @@ error[E0423]: expected value, found module `a` LL | a.b.J | ^-- | | - | did you mean `a::b`? + | help: use the path separator to refer to an item: `a::b` error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:32:5 | LL | a::b.J - | ^^^--- - | | | - | | help: a constant with a similar name exists: `I` - | did you mean `a::b::J`? + | ^^^^ +help: a constant with a similar name exists + | +LL | a::I.J + | ^ +help: use the path separator to refer to an item + | +LL | a::b::J + | error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5 @@ -37,7 +42,7 @@ error[E0423]: expected value, found module `a` LL | a.b.f(); | ^-- | | - | did you mean `a::b`? + | help: use the path separator to refer to an item: `a::b` error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:40:12 @@ -51,10 +56,15 @@ error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5 | LL | a::b.f() - | ^^^----- - | | | - | | help: a constant with a similar name exists: `I` - | did you mean `a::b::f(...)`? + | ^^^^ +help: a constant with a similar name exists + | +LL | a::I.f() + | ^ +help: use the path separator to refer to an item + | +LL | a::b::f() + | ^^^^^^^ error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5 diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index 63650086bcaa9..a7b81060d3dc6 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -15,7 +15,7 @@ error[E0574]: expected struct, variant or union type, found macro `try` --> $DIR/try-block-in-edition2015.rs:4:33 | LL | let try_result: Option<_> = try { - | ^^^ did you mean `try!(...)`? + | ^^^ help: use `!` to invoke the macro: `try!` error: aborting due to 2 previous errors From b7cd24dd44eafa44797fdd4e418013d1ea0fd1db Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 15 Jan 2019 17:44:41 +0100 Subject: [PATCH 0080/1064] Make the query comment into a doc comment --- src/librustc/ty/query/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index ef5a98e6ecb3b..6bf99a98d4eff 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -476,7 +476,8 @@ define_queries! { <'tcx> [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc>, - // For a library crate, this is always none + /// Identifies the entry-point (e.g. the `main` function) for a given + /// crate, returning `None` if there is no entry point (such as for library crates). [] fn entry_fn: EntryFn(CrateNum) -> Option<(DefId, EntryFnType)>, [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option, [] fn proc_macro_decls_static: ProcMacroDeclsStatic(CrateNum) -> Option, From ed717f30ec3006e465ed4d68adf31cabdf0329fa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jan 2019 17:57:06 +0100 Subject: [PATCH 0081/1064] Fix sources sidebar not showing up --- src/librustdoc/html/render.rs | 2 +- src/librustdoc/html/static/source-script.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 31e06cb1a045f..1d50afe2821ac 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1042,7 +1042,7 @@ themePicker.onblur = handleThemeButtonsBlur; all_sources.sort(); let mut w = try_err!(File::create(&dst), &dst); try_err!(writeln!(&mut w, - "var N = null;var sourcesIndex = {{}};\n{}", + "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();", all_sources.join("\n")), &dst); } diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index 0affe1c6812f5..c5d6fa16f550e 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -137,5 +137,3 @@ function createSourceSidebar() { main.insertBefore(sidebar, main.firstChild); } - -createSourceSidebar(); From 6046be42ab911cf2eddd41cffaa0467098bb2317 Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 14 Jan 2019 15:50:33 -0600 Subject: [PATCH 0082/1064] fix nested matchers with ? --- src/libsyntax/ext/tt/macro_rules.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 24202ca8fbdc0..9a129e7e8fcd8 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -435,7 +435,8 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { match *seq_tt { TokenTree::MetaVarDecl(_, _, id) => id.name == "vis", TokenTree::Sequence(_, ref sub_seq) => - sub_seq.op == quoted::KleeneOp::ZeroOrMore, + sub_seq.op == quoted::KleeneOp::ZeroOrMore + || sub_seq.op == quoted::KleeneOp::ZeroOrOne, _ => false, } }) { @@ -543,7 +544,10 @@ impl FirstSets { } // Reverse scan: Sequence comes before `first`. - if subfirst.maybe_empty || seq_rep.op == quoted::KleeneOp::ZeroOrMore { + if subfirst.maybe_empty + || seq_rep.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.op == quoted::KleeneOp::ZeroOrOne + { // If sequence is potentially empty, then // union them (preserving first emptiness). first.add_all(&TokenSet { maybe_empty: true, ..subfirst }); @@ -591,8 +595,10 @@ impl FirstSets { assert!(first.maybe_empty); first.add_all(subfirst); - if subfirst.maybe_empty || - seq_rep.op == quoted::KleeneOp::ZeroOrMore { + if subfirst.maybe_empty + || seq_rep.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.op == quoted::KleeneOp::ZeroOrOne + { // continue scanning for more first // tokens, but also make sure we // restore empty-tracking state From dabe86db44c97698bc6a4ab2f8923a3f65b151f0 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 11:31:49 -0600 Subject: [PATCH 0083/1064] update/add tests --- src/test/ui/issues/issue-5067.rs | 37 ++++++++++--- src/test/ui/issues/issue-57597.rs | 80 +++++++++++++++++++++++++++ src/test/ui/issues/issue-57597.stderr | 74 +++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/issues/issue-57597.rs create mode 100644 src/test/ui/issues/issue-57597.stderr diff --git a/src/test/ui/issues/issue-5067.rs b/src/test/ui/issues/issue-5067.rs index 526a68311462e..616fd09907a2b 100644 --- a/src/test/ui/issues/issue-5067.rs +++ b/src/test/ui/issues/issue-5067.rs @@ -1,37 +1,59 @@ #![allow(unused_macros)] +// Tests that repetition matchers cannot match the empty token tree (since that would be +// ambiguous). + +// edition:2018 + macro_rules! foo { ( $()* ) => {}; //~^ ERROR repetition matches empty token tree ( $()+ ) => {}; //~^ ERROR repetition matches empty token tree - + ( $()? ) => {}; + //~^ ERROR repetition matches empty token tree ( $(),* ) => {}; // PASS ( $(),+ ) => {}; // PASS - + // `?` cannot have a separator... ( [$()*] ) => {}; //~^ ERROR repetition matches empty token tree ( [$()+] ) => {}; //~^ ERROR repetition matches empty token tree - + ( [$()?] ) => {}; + //~^ ERROR repetition matches empty token tree ( [$(),*] ) => {}; // PASS ( [$(),+] ) => {}; // PASS - + // `?` cannot have a separator... ( $($()* $(),* $(a)* $(a),* )* ) => {}; //~^ ERROR repetition matches empty token tree ( $($()* $(),* $(a)* $(a),* )+ ) => {}; //~^ ERROR repetition matches empty token tree - + ( $($()* $(),* $(a)* $(a),* )? ) => {}; + //~^ ERROR repetition matches empty token tree + ( $($()? $(),* $(a)? $(a),* )* ) => {}; + //~^ ERROR repetition matches empty token tree + ( $($()? $(),* $(a)? $(a),* )+ ) => {}; + //~^ ERROR repetition matches empty token tree + ( $($()? $(),* $(a)? $(a),* )? ) => {}; + //~^ ERROR repetition matches empty token tree ( $(a $(),* $(a)* $(a),* )* ) => {}; // PASS ( $($(a)+ $(),* $(a)* $(a),* )+ ) => {}; // PASS + ( $($(a)+ $(),* $(a)* $(a),* )? ) => {}; // PASS + + ( $(a $(),* $(a)? $(a),* )* ) => {}; // PASS + ( $($(a)+ $(),* $(a)? $(a),* )+ ) => {}; // PASS + ( $($(a)+ $(),* $(a)? $(a),* )? ) => {}; // PASS ( $(a $()+)* ) => {}; //~^ ERROR repetition matches empty token tree ( $(a $()*)+ ) => {}; //~^ ERROR repetition matches empty token tree + ( $(a $()+)? ) => {}; + //~^ ERROR repetition matches empty token tree + ( $(a $()?)+ ) => {}; + //~^ ERROR repetition matches empty token tree } - // --- Original Issue --- // macro_rules! make_vec { @@ -43,11 +65,10 @@ fn main() { let _ = make_vec![a 1, a 2, a 3]; } - // --- Minified Issue --- // macro_rules! m { - ( $()* ) => {} + ( $()* ) => {}; //~^ ERROR repetition matches empty token tree } diff --git a/src/test/ui/issues/issue-57597.rs b/src/test/ui/issues/issue-57597.rs new file mode 100644 index 0000000000000..ebeb3fe07adb4 --- /dev/null +++ b/src/test/ui/issues/issue-57597.rs @@ -0,0 +1,80 @@ +// Regression test for #57597. +// +// Make sure that nested matchers work correctly rather than causing an infinite loop or crash. + +// edition:2018 + +macro_rules! foo1 { + ($($($i:ident)?)+) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo2 { + ($($($i:ident)?)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo3 { + ($($($i:ident)?)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo4 { + ($($($($i:ident)?)?)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo5 { + ($($($($i:ident)*)?)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo6 { + ($($($($i:ident)?)*)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo7 { + ($($($($i:ident)?)?)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo8 { + ($($($($i:ident)*)*)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo9 { + ($($($($i:ident)?)*)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo10 { + ($($($($i:ident)?)*)+) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo11 { + ($($($($i:ident)+)?)*) => {}; + //~^ ERROR repetition matches empty token tree +} + +macro_rules! foo12 { + ($($($($i:ident)+)*)?) => {}; + //~^ ERROR repetition matches empty token tree +} + +fn main() { + foo1!(); + foo2!(); + foo3!(); + foo4!(); + foo5!(); + foo6!(); + foo7!(); + foo8!(); + foo9!(); + foo10!(); + foo11!(); + foo12!(); +} diff --git a/src/test/ui/issues/issue-57597.stderr b/src/test/ui/issues/issue-57597.stderr new file mode 100644 index 0000000000000..0a02ac8c499b6 --- /dev/null +++ b/src/test/ui/issues/issue-57597.stderr @@ -0,0 +1,74 @@ +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:8:7 + | +LL | ($($($i:ident)?)+) => {}; + | ^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:13:7 + | +LL | ($($($i:ident)?)*) => {}; + | ^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:18:7 + | +LL | ($($($i:ident)?)?) => {}; + | ^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:23:7 + | +LL | ($($($($i:ident)?)?)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:28:7 + | +LL | ($($($($i:ident)*)?)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:33:7 + | +LL | ($($($($i:ident)?)*)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:38:7 + | +LL | ($($($($i:ident)?)?)*) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:43:7 + | +LL | ($($($($i:ident)*)*)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:48:7 + | +LL | ($($($($i:ident)?)*)*) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:53:7 + | +LL | ($($($($i:ident)?)*)+) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:58:7 + | +LL | ($($($($i:ident)+)?)*) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-57597.rs:63:7 + | +LL | ($($($($i:ident)+)*)?) => {}; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + From 24ca5305263e4cee6d90e740962a94aed7842805 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Wed, 19 Dec 2018 16:43:29 -0500 Subject: [PATCH 0084/1064] Move spin_loop_hint to core::hint module --- src/libcore/hint.rs | 23 +++++++++++++++++++++++ src/libcore/sync/atomic.rs | 12 +++--------- src/libstd/lib.rs | 1 + 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index 9e57a4ebc9919..ad5a2071a7381 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -49,3 +49,26 @@ use intrinsics; pub unsafe fn unreachable_unchecked() -> ! { intrinsics::unreachable() } + +/// Save power or switch hyperthreads in a busy-wait spin-loop. +/// +/// This function is deliberately more primitive than +/// [`std::thread::yield_now`](../../std/thread/fn.yield_now.html) and +/// does not directly yield to the system's scheduler. +/// In some cases it might be useful to use a combination of both functions. +/// Careful benchmarking is advised. +/// +/// On some platforms this function may not do anything at all. +#[inline] +#[unstable(feature = "renamed_spin_loop", issue = "55002")] +pub fn spin_loop() { + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + unsafe { + asm!("pause" ::: "memory" : "volatile"); + } + + #[cfg(target_arch = "aarch64")] + unsafe { + asm!("yield" ::: "memory" : "volatile"); + } +} diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 99e6365d15ec0..8992e513e83a4 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -84,6 +84,8 @@ use intrinsics; use cell::UnsafeCell; use fmt; +use hint::spin_loop; + /// Save power or switch hyperthreads in a busy-wait spin-loop. /// /// This function is deliberately more primitive than @@ -96,15 +98,7 @@ use fmt; #[inline] #[stable(feature = "spin_loop_hint", since = "1.24.0")] pub fn spin_loop_hint() { - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - unsafe { - asm!("pause" ::: "memory" : "volatile"); - } - - #[cfg(target_arch = "aarch64")] - unsafe { - asm!("yield" ::: "memory" : "volatile"); - } + spin_loop() } /// A boolean type which can be safely shared between threads. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 41f1ac867ed15..83db3f347a761 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -286,6 +286,7 @@ #![feature(staged_api)] #![feature(stmt_expr_attributes)] #![feature(str_internals)] +#![feature(renamed_spin_loop)] #![feature(rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] From feda6040faa854f6bbe6ab9c7f11b59ec21ec1d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jan 2019 23:21:10 +0100 Subject: [PATCH 0085/1064] Fixes text becoming invisible when element targetted --- src/librustdoc/html/static/themes/dark.css | 8 +------- src/librustdoc/html/static/themes/light.css | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 1390be700634d..52a30967a2310 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -82,12 +82,6 @@ pre { border-bottom-color: #ddd; } -:target { background: #494a3d; } - -:target > .in-band { - background: #494a3d; -} - .content .method .where, .content .fn .where, .content .where.fmt-newline { @@ -252,7 +246,7 @@ a.test-arrow:hover{ color: #999; } -:target > code { +:target > code, :target > .in-band { background-color: #494a3d; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 2b04dd2388d45..d20fea666e61d 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -84,12 +84,6 @@ pre { border-bottom-color: #ddd; } -:target { background: #FDFFD3; } - -:target > .in-band { - background: #FDFFD3; -} - .content .method .where, .content .fn .where, .content .where.fmt-newline { @@ -247,7 +241,7 @@ a.test-arrow:hover{ color: #999; } -:target > code { +:target > code, :target > .in-band { background: #FDFFD3; } From aa1ce32b105ff506257019a22684a98b61ab166a Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 16:40:10 -0600 Subject: [PATCH 0086/1064] update test output --- src/test/ui/issues/issue-5067.stderr | 72 +++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/src/test/ui/issues/issue-5067.stderr b/src/test/ui/issues/issue-5067.stderr index 433b7c8c04907..7ffc6071407c5 100644 --- a/src/test/ui/issues/issue-5067.stderr +++ b/src/test/ui/issues/issue-5067.stderr @@ -1,62 +1,110 @@ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:4:8 + --> $DIR/issue-5067.rs:9:8 | LL | ( $()* ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:6:8 + --> $DIR/issue-5067.rs:11:8 | LL | ( $()+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:12:9 + --> $DIR/issue-5067.rs:13:8 + | +LL | ( $()? ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:18:9 | LL | ( [$()*] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:14:9 + --> $DIR/issue-5067.rs:20:9 | LL | ( [$()+] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:20:8 + --> $DIR/issue-5067.rs:22:9 + | +LL | ( [$()?] ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:27:8 | LL | ( $($()* $(),* $(a)* $(a),* )* ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:22:8 + --> $DIR/issue-5067.rs:29:8 | LL | ( $($()* $(),* $(a)* $(a),* )+ ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:28:12 + --> $DIR/issue-5067.rs:31:8 + | +LL | ( $($()* $(),* $(a)* $(a),* )? ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:33:8 + | +LL | ( $($()? $(),* $(a)? $(a),* )* ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:35:8 + | +LL | ( $($()? $(),* $(a)? $(a),* )+ ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:37:8 + | +LL | ( $($()? $(),* $(a)? $(a),* )? ) => {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:47:12 | LL | ( $(a $()+)* ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:30:12 + --> $DIR/issue-5067.rs:49:12 | LL | ( $(a $()*)+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:38:18 + --> $DIR/issue-5067.rs:51:12 + | +LL | ( $(a $()+)? ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:53:12 + | +LL | ( $(a $()?)+ ) => {}; + | ^^ + +error: repetition matches empty token tree + --> $DIR/issue-5067.rs:60:18 | LL | (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]); | ^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:50:8 + --> $DIR/issue-5067.rs:71:8 | -LL | ( $()* ) => {} +LL | ( $()* ) => {}; | ^^ -error: aborting due to 10 previous errors +error: aborting due to 18 previous errors From 9430423cab6909792fb1b3a850f1c3c8974a5111 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 15 Jan 2019 15:14:17 -0800 Subject: [PATCH 0087/1064] [rust-gdb] relax the GDB version regex The pretty-printer script is checking `gdb.VERSION` to see if it's at least 8.1 for some features. With `re.match`, it will only find the version at the beginning of that string, but in Fedora the string is something like "Fedora 8.2-5.fc29". Using `re.search` instead will find the first location that matches anywhere, so it will find my 8.2. --- src/etc/gdb_rust_pretty_printing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index 08ae289d60374..b9413563fd9ff 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -16,7 +16,7 @@ # This fix went in 8.1, so check for that. # See https://github.com/rust-lang/rust/issues/56730 gdb_81 = False -_match = re.match('([0-9]+)\\.([0-9]+)', gdb.VERSION) +_match = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION) if _match: if int(_match.group(1)) > 8 or (int(_match.group(1)) == 8 and int(_match.group(2)) >= 1): gdb_81 = True From d19294feeea5f09409974b94ddd3f441b8871bb3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jan 2019 09:27:43 +0900 Subject: [PATCH 0088/1064] Add new literal type Err --- src/librustc/ich/impls_syntax.rs | 1 + src/libsyntax/ext/quote.rs | 1 + src/libsyntax/parse/mod.rs | 1 + src/libsyntax/parse/token.rs | 2 ++ src/libsyntax/print/pprust.rs | 1 + 5 files changed, 6 insertions(+) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 70ec72d73bc6c..6ffb771ffcc4e 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -329,6 +329,7 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>( match *lit { token::Lit::Byte(val) | token::Lit::Char(val) | + token::Lit::Err(val) | token::Lit::Integer(val) | token::Lit::Float(val) | token::Lit::Str_(val) | diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index c3124144009ab..17c88a30bcd0b 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -646,6 +646,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), + token::Literal(token::Err(i), suf) => return mk_lit!("Err", suf, i), token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ea205530ca5cc..cbb503f56bc4a 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -466,6 +466,7 @@ crate fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Ha match lit { token::Byte(i) => (true, Some(LitKind::Byte(byte_lit(&i.as_str()).0))), token::Char(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), + token::Err(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), // There are some valid suffixes for integer and float literals, // so all the handling is done internally. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 25a4da38c8c51..69e934d64c6cd 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -60,6 +60,7 @@ impl DelimToken { pub enum Lit { Byte(ast::Name), Char(ast::Name), + Err(ast::Name), Integer(ast::Name), Float(ast::Name), Str_(ast::Name), @@ -73,6 +74,7 @@ impl Lit { match *self { Byte(_) => "byte literal", Char(_) => "char literal", + Err(_) => "error literal", Integer(_) => "integer literal", Float(_) => "float literal", Str_(_) | StrRaw(..) => "string literal", diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 2ad3d3a6d6487..123f9b49692d9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -224,6 +224,7 @@ pub fn token_to_string(tok: &Token) -> String { let mut out = match lit { token::Byte(b) => format!("b'{}'", b), token::Char(c) => format!("'{}'", c), + token::Err(c) => format!("'{}'", c), token::Float(c) | token::Integer(c) => c.to_string(), token::Str_(s) => format!("\"{}\"", s), From ec8db2a94446f2ef4da7ac89bbe5e171fe17e46f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jan 2019 09:28:06 +0900 Subject: [PATCH 0089/1064] Cancel process --- src/libsyntax/parse/lexer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0e1c3b4b61f3a..666653f9edf80 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1445,7 +1445,7 @@ impl<'a> StringReader<'a> { format!("\"{}\"", &self.src[start..end]), Applicability::MachineApplicable ).emit(); - return Ok(token::Literal(token::Str_(Symbol::intern("??")), None)) + FatalError.raise(); } if self.ch_is('\n') || self.is_eof() || self.ch_is('/') { // Only attempt to infer single line string literals. If we encounter From d33ee3fefa3fad88fee81b5abb316e94c387d72e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 16 Jan 2019 09:28:26 +0900 Subject: [PATCH 0090/1064] Fix tests --- src/test/ui/parser/lex-bad-char-literals-3.rs | 1 - src/test/ui/parser/lex-bad-char-literals-3.stderr | 12 +----------- src/test/ui/parser/lex-bad-char-literals-5.rs | 1 - src/test/ui/parser/lex-bad-char-literals-5.stderr | 12 +----------- 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/test/ui/parser/lex-bad-char-literals-3.rs b/src/test/ui/parser/lex-bad-char-literals-3.rs index f8749708f7721..d14ec1cc51560 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.rs +++ b/src/test/ui/parser/lex-bad-char-literals-3.rs @@ -1,7 +1,6 @@ // This test needs to the last one appearing in this file as it kills the parser static c: char = '●●' //~ ERROR: character literal may only contain one codepoint - //~| ERROR: mismatched types ; fn main() {} diff --git a/src/test/ui/parser/lex-bad-char-literals-3.stderr b/src/test/ui/parser/lex-bad-char-literals-3.stderr index 89f18e3e2aa4d..dde4a7db3aa79 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-3.stderr @@ -8,15 +8,5 @@ help: if you meant to write a `str` literal, use double quotes LL | "●●" //~ ERROR: character literal may only contain one codepoint | ^^^^ -error[E0308]: mismatched types - --> $DIR/lex-bad-char-literals-3.rs:3:5 - | -LL | '●●' //~ ERROR: character literal may only contain one codepoint - | ^^^^ expected char, found reference - | - = note: expected type `char` - found type `&'static str` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/lex-bad-char-literals-5.rs b/src/test/ui/parser/lex-bad-char-literals-5.rs index 247289ea4d54b..1236e76de420e 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.rs +++ b/src/test/ui/parser/lex-bad-char-literals-5.rs @@ -2,7 +2,6 @@ // This test needs to the last one appearing in this file as it kills the parser static c: char = '\x10\x10' //~ ERROR: character literal may only contain one codepoint - //~| ERROR: mismatched types ; fn main() {} diff --git a/src/test/ui/parser/lex-bad-char-literals-5.stderr b/src/test/ui/parser/lex-bad-char-literals-5.stderr index 523d71ff49d2b..4f734eaeff353 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-5.stderr @@ -8,15 +8,5 @@ help: if you meant to write a `str` literal, use double quotes LL | "/x10/x10" //~ ERROR: character literal may only contain one codepoint | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/lex-bad-char-literals-5.rs:4:5 - | -LL | '/x10/x10' //~ ERROR: character literal may only contain one codepoint - | ^^^^^^^^^^ expected char, found reference - | - = note: expected type `char` - found type `&'static str` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. From a6294b762859b3bb86b2a94c6857ae39beea9aeb Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 19:38:02 -0600 Subject: [PATCH 0091/1064] update/remove some old readmes --- .../infer/lexical_region_resolve/README.md | 4 + .../infer/region_constraints/README.md | 76 +---------------- .../obligation_forest/README.md | 81 ------------------ .../obligation_forest/mod.rs | 85 +++++++++++++++++-- 4 files changed, 85 insertions(+), 161 deletions(-) delete mode 100644 src/librustc_data_structures/obligation_forest/README.md diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md index 4483e522f3a1f..56320636a6743 100644 --- a/src/librustc/infer/lexical_region_resolve/README.md +++ b/src/librustc/infer/lexical_region_resolve/README.md @@ -2,8 +2,12 @@ > WARNING: This README is obsolete and will be removed soon! For > more info on how the current borrowck works, see the [rustc guide]. +> +> As of edition 2018, region inference is done using Non-lexical lifetimes, +> which is described in the guide and [this RFC]. [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html +[this RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md ## Terminology diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md index 775bbf955b830..ea7fffe9dc1c6 100644 --- a/src/librustc/infer/region_constraints/README.md +++ b/src/librustc/infer/region_constraints/README.md @@ -1,77 +1,3 @@ -# Region constraint collection - -> WARNING: This README is obsolete and will be removed soon! For -> more info on how the current borrowck works, see the [rustc guide]. +For info on how the current borrowck works, see the [rustc guide]. [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html - -## Terminology - -Note that we use the terms region and lifetime interchangeably. - -## Introduction - -As described in the rustc guide [chapter on type inference][ti], and unlike -normal type inference, which is similar in spirit to H-M and thus -works progressively, the region type inference works by accumulating -constraints over the course of a function. Finally, at the end of -processing a function, we process and solve the constraints all at -once. - -[ti]: https://rust-lang.github.io/rustc-guide/type-inference.html - -The constraints are always of one of three possible forms: - -- `ConstrainVarSubVar(Ri, Rj)` states that region variable Ri must be - a subregion of Rj -- `ConstrainRegSubVar(R, Ri)` states that the concrete region R (which - must not be a variable) must be a subregion of the variable Ri -- `ConstrainVarSubReg(Ri, R)` states the variable Ri should be less - than the concrete region R. This is kind of deprecated and ought to - be replaced with a verify (they essentially play the same role). - -In addition to constraints, we also gather up a set of "verifys" -(what, you don't think Verify is a noun? Get used to it my -friend!). These represent relations that must hold but which don't -influence inference proper. These take the form of: - -- `VerifyRegSubReg(Ri, Rj)` indicates that Ri <= Rj must hold, - where Rj is not an inference variable (and Ri may or may not contain - one). This doesn't influence inference because we will already have - inferred Ri to be as small as possible, so then we just test whether - that result was less than Rj or not. -- `VerifyGenericBound(R, Vb)` is a more complex expression which tests - that the region R must satisfy the bound `Vb`. The bounds themselves - may have structure like "must outlive one of the following regions" - or "must outlive ALL of the following regions. These bounds arise - from constraints like `T: 'a` -- if we know that `T: 'b` and `T: 'c` - (say, from where clauses), then we can conclude that `T: 'a` if `'b: - 'a` *or* `'c: 'a`. - -## Building up the constraints - -Variables and constraints are created using the following methods: - -- `new_region_var()` creates a new, unconstrained region variable; -- `make_subregion(Ri, Rj)` states that Ri is a subregion of Rj -- `lub_regions(Ri, Rj) -> Rk` returns a region Rk which is - the smallest region that is greater than both Ri and Rj -- `glb_regions(Ri, Rj) -> Rk` returns a region Rk which is - the greatest region that is smaller than both Ri and Rj - -The actual region resolution algorithm is not entirely -obvious, though it is also not overly complex. - -## Snapshotting - -It is also permitted to try (and rollback) changes to the graph. This -is done by invoking `start_snapshot()`, which returns a value. Then -later you can call `rollback_to()` which undoes the work. -Alternatively, you can call `commit()` which ends all snapshots. -Snapshots can be recursive---so you can start a snapshot when another -is in progress, but only the root snapshot can "commit". - -## Skolemization - -For a discussion on skolemization and higher-ranked subtyping, please -see the module `middle::infer::higher_ranked::doc`. diff --git a/src/librustc_data_structures/obligation_forest/README.md b/src/librustc_data_structures/obligation_forest/README.md deleted file mode 100644 index 982a2bacce164..0000000000000 --- a/src/librustc_data_structures/obligation_forest/README.md +++ /dev/null @@ -1,81 +0,0 @@ -The `ObligationForest` is a utility data structure used in trait -matching to track the set of outstanding obligations (those not yet -resolved to success or error). It also tracks the "backtrace" of each -pending obligation (why we are trying to figure this out in the first -place). - -### External view - -`ObligationForest` supports two main public operations (there are a -few others not discussed here): - -1. Add a new root obligations (`push_tree`). -2. Process the pending obligations (`process_obligations`). - -When a new obligation `N` is added, it becomes the root of an -obligation tree. This tree can also carry some per-tree state `T`, -which is given at the same time. This tree is a singleton to start, so -`N` is both the root and the only leaf. Each time the -`process_obligations` method is called, it will invoke its callback -with every pending obligation (so that will include `N`, the first -time). The callback also receives a (mutable) reference to the -per-tree state `T`. The callback should process the obligation `O` -that it is given and return one of three results: - -- `Ok(None)` -> ambiguous result. Obligation was neither a success - nor a failure. It is assumed that further attempts to process the - obligation will yield the same result unless something in the - surrounding environment changes. -- `Ok(Some(C))` - the obligation was *shallowly successful*. The - vector `C` is a list of subobligations. The meaning of this is that - `O` was successful on the assumption that all the obligations in `C` - are also successful. Therefore, `O` is only considered a "true" - success if `C` is empty. Otherwise, `O` is put into a suspended - state and the obligations in `C` become the new pending - obligations. They will be processed the next time you call - `process_obligations`. -- `Err(E)` -> obligation failed with error `E`. We will collect this - error and return it from `process_obligations`, along with the - "backtrace" of obligations (that is, the list of obligations up to - and including the root of the failed obligation). No further - obligations from that same tree will be processed, since the tree is - now considered to be in error. - -When the call to `process_obligations` completes, you get back an `Outcome`, -which includes three bits of information: - -- `completed`: a list of obligations where processing was fully - completed without error (meaning that all transitive subobligations - have also been completed). So, for example, if the callback from - `process_obligations` returns `Ok(Some(C))` for some obligation `O`, - then `O` will be considered completed right away if `C` is the - empty vector. Otherwise it will only be considered completed once - all the obligations in `C` have been found completed. -- `errors`: a list of errors that occurred and associated backtraces - at the time of error, which can be used to give context to the user. -- `stalled`: if true, then none of the existing obligations were - *shallowly successful* (that is, no callback returned `Ok(Some(_))`). - This implies that all obligations were either errors or returned an - ambiguous result, which means that any further calls to - `process_obligations` would simply yield back further ambiguous - results. This is used by the `FulfillmentContext` to decide when it - has reached a steady state. - -#### Snapshots - -The `ObligationForest` supports a limited form of snapshots; see -`start_snapshot`; `commit_snapshot`; and `rollback_snapshot`. In -particular, you can use a snapshot to roll back new root -obligations. However, it is an error to attempt to -`process_obligations` during a snapshot. - -### Implementation details - -For the most part, comments specific to the implementation are in the -code. This file only contains a very high-level overview. Basically, -the forest is stored in a vector. Each element of the vector is a node -in some tree. Each node in the vector has the index of an (optional) -parent and (for convenience) its root (which may be itself). It also -has a current state, described by `NodeState`. After each -processing step, we compress the vector to remove completed and error -nodes, which aren't needed anymore. diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 59497f0df18e9..9dd7d204f0373 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -1,9 +1,84 @@ //! The `ObligationForest` is a utility data structure used in trait -//! matching to track the set of outstanding obligations (those not -//! yet resolved to success or error). It also tracks the "backtrace" -//! of each pending obligation (why we are trying to figure this out -//! in the first place). See README.md for a general overview of how -//! to use this class. +//! matching to track the set of outstanding obligations (those not yet +//! resolved to success or error). It also tracks the "backtrace" of each +//! pending obligation (why we are trying to figure this out in the first +//! place). +//! +//! ### External view +//! +//! `ObligationForest` supports two main public operations (there are a +//! few others not discussed here): +//! +//! 1. Add a new root obligations (`push_tree`). +//! 2. Process the pending obligations (`process_obligations`). +//! +//! When a new obligation `N` is added, it becomes the root of an +//! obligation tree. This tree can also carry some per-tree state `T`, +//! which is given at the same time. This tree is a singleton to start, so +//! `N` is both the root and the only leaf. Each time the +//! `process_obligations` method is called, it will invoke its callback +//! with every pending obligation (so that will include `N`, the first +//! time). The callback also receives a (mutable) reference to the +//! per-tree state `T`. The callback should process the obligation `O` +//! that it is given and return one of three results: +//! +//! - `Ok(None)` -> ambiguous result. Obligation was neither a success +//! nor a failure. It is assumed that further attempts to process the +//! obligation will yield the same result unless something in the +//! surrounding environment changes. +//! - `Ok(Some(C))` - the obligation was *shallowly successful*. The +//! vector `C` is a list of subobligations. The meaning of this is that +//! `O` was successful on the assumption that all the obligations in `C` +//! are also successful. Therefore, `O` is only considered a "true" +//! success if `C` is empty. Otherwise, `O` is put into a suspended +//! state and the obligations in `C` become the new pending +//! obligations. They will be processed the next time you call +//! `process_obligations`. +//! - `Err(E)` -> obligation failed with error `E`. We will collect this +//! error and return it from `process_obligations`, along with the +//! "backtrace" of obligations (that is, the list of obligations up to +//! and including the root of the failed obligation). No further +//! obligations from that same tree will be processed, since the tree is +//! now considered to be in error. +//! +//! When the call to `process_obligations` completes, you get back an `Outcome`, +//! which includes three bits of information: +//! +//! - `completed`: a list of obligations where processing was fully +//! completed without error (meaning that all transitive subobligations +//! have also been completed). So, for example, if the callback from +//! `process_obligations` returns `Ok(Some(C))` for some obligation `O`, +//! then `O` will be considered completed right away if `C` is the +//! empty vector. Otherwise it will only be considered completed once +//! all the obligations in `C` have been found completed. +//! - `errors`: a list of errors that occurred and associated backtraces +//! at the time of error, which can be used to give context to the user. +//! - `stalled`: if true, then none of the existing obligations were +//! *shallowly successful* (that is, no callback returned `Ok(Some(_))`). +//! This implies that all obligations were either errors or returned an +//! ambiguous result, which means that any further calls to +//! `process_obligations` would simply yield back further ambiguous +//! results. This is used by the `FulfillmentContext` to decide when it +//! has reached a steady state. +//! +//! #### Snapshots +//! +//! The `ObligationForest` supports a limited form of snapshots; see +//! `start_snapshot`; `commit_snapshot`; and `rollback_snapshot`. In +//! particular, you can use a snapshot to roll back new root +//! obligations. However, it is an error to attempt to +//! `process_obligations` during a snapshot. +//! +//! ### Implementation details +//! +//! For the most part, comments specific to the implementation are in the +//! code. This file only contains a very high-level overview. Basically, +//! the forest is stored in a vector. Each element of the vector is a node +//! in some tree. Each node in the vector has the index of an (optional) +//! parent and (for convenience) its root (which may be itself). It also +//! has a current state, described by `NodeState`. After each +//! processing step, we compress the vector to remove completed and error +//! nodes, which aren't needed anymore. use fx::{FxHashMap, FxHashSet}; From 228969c696b380716ad7547e87c4b52f3df50c96 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 19:48:37 -0600 Subject: [PATCH 0092/1064] remove link to removed readme --- src/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/README.md b/src/README.md index 65228915866ea..14e773286bc6a 100644 --- a/src/README.md +++ b/src/README.md @@ -8,7 +8,6 @@ For more information on how various parts of the compiler work, see the [rustc g There is also useful content in the following READMEs, which are gradually being moved over to the guide: - https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query - https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph -- https://github.com/rust-lang/rust/blob/master/src/librustc/infer/region_constraints - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve From 48bee07768fab0f6c96fc51957ac6f18e10b7767 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 20:02:28 -0600 Subject: [PATCH 0093/1064] make the contribution doc reference the guide more; deduplication --- CONTRIBUTING.md | 250 ++++-------------------------------------------- 1 file changed, 21 insertions(+), 229 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 65cdfe67b5b08..9924055ca45ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,9 +19,16 @@ hop on [#rust-internals][pound-rust-internals]. As a reminder, all contributors are expected to follow our [Code of Conduct][coc]. +The [rustc-guide] is your friend! It describes how the compiler works and how +to contribute to it in more detail than this document. + +If this is your first time contributing, the [walkthrough] chapter of the guide +can give you a good example of how a typical contribution would go. + [pound-rust-internals]: https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals [internals]: https://internals.rust-lang.org [coc]: https://www.rust-lang.org/conduct.html +[walkthrough]: https://rust-lang.github.io/rustc-guide/walkthrough.html ## Feature Requests [feature-requests]: #feature-requests @@ -89,222 +96,14 @@ $ RUST_BACKTRACE=1 rustc ... ``` ## The Build System -[the-build-system]: #the-build-system - -Rust's build system allows you to bootstrap the compiler, run tests & -benchmarks, generate documentation, install a fresh build of Rust, and more. -It's your best friend when working on Rust, allowing you to compile & test -your contributions before submission. - -The build system lives in [the `src/bootstrap` directory][bootstrap] in the -project root. Our build system is itself written in Rust and is based on Cargo -to actually build all the compiler's crates. If you have questions on the build -system internals, try asking in [`#rust-internals`][pound-rust-internals]. - -[bootstrap]: https://github.com/rust-lang/rust/tree/master/src/bootstrap/ - -### Configuration -[configuration]: #configuration - -Before you can start building the compiler you need to configure the build for -your system. In most cases, that will just mean using the defaults provided -for Rust. - -To change configuration, you must copy the file `config.toml.example` -to `config.toml` in the directory from which you will be running the build, and -change the settings provided. - -There are large number of options provided in this config file that will alter the -configuration used in the build process. Some options to note: - -#### `[llvm]`: -- `assertions = true` = This enables LLVM assertions, which makes LLVM misuse cause an assertion failure instead of weird misbehavior. This also slows down the compiler's runtime by ~20%. -- `ccache = true` - Use ccache when building llvm - -#### `[build]`: -- `compiler-docs = true` - Build compiler documentation - -#### `[rust]`: -- `debuginfo = true` - Build a compiler with debuginfo. Makes building rustc slower, but then you can use a debugger to debug `rustc`. -- `debuginfo-lines = true` - An alternative to `debuginfo = true` that doesn't let you use a debugger, but doesn't make building rustc slower and still gives you line numbers in backtraces. -- `debuginfo-tools = true` - Build the extended tools with debuginfo. -- `debug-assertions = true` - Makes the log output of `debug!` work. -- `optimize = false` - Disable optimizations to speed up compilation of stage1 rust, but makes the stage1 compiler x100 slower. - -For more options, the `config.toml` file contains commented out defaults, with -descriptions of what each option will do. - -Note: Previously the `./configure` script was used to configure this -project. It can still be used, but it's recommended to use a `config.toml` -file. If you still have a `config.mk` file in your directory - from -`./configure` - you may need to delete it for `config.toml` to work. - -### Building -[building]: #building - -A default configuration requires around 3.5 GB of disk space, whereas building a debug configuration may require more than 30 GB. -Dependencies -- [build dependencies](README.md#building-from-source) -- `gdb` 6.2.0 minimum, 7.1 or later recommended for test builds +For info on how to configure and build the compiler, please see [this +chapter][rustcguidebuild] of the rustc-guide. This chapter contains info for +contributions to the compiler and the standard library. It also lists some +really useful commands to the build system (`./x.py`), which could save you a +lot of time. -The build system uses the `x.py` script to control the build process. This script -is used to build, test, and document various parts of the compiler. You can -execute it as: - -```sh -python x.py build -``` - -On some systems you can also use the shorter version: - -```sh -./x.py build -``` - -To learn more about the driver and top-level targets, you can execute: - -```sh -python x.py --help -``` - -The general format for the driver script is: - -```sh -python x.py [] -``` - -Some example commands are `build`, `test`, and `doc`. These will build, test, -and document the specified directory. The second argument, ``, is -optional and defaults to working over the entire compiler. If specified, -however, only that specific directory will be built. For example: - -```sh -# build the entire compiler -python x.py build - -# build all documentation -python x.py doc - -# run all test suites -python x.py test - -# build only the standard library -python x.py build src/libstd - -# test only one particular test suite -python x.py test src/test/rustdoc - -# build only the stage0 libcore library -python x.py build src/libcore --stage 0 -``` - -You can explore the build system through the various `--help` pages for each -subcommand. For example to learn more about a command you can run: - -``` -python x.py build --help -``` - -To learn about all possible rules you can execute, run: - -``` -python x.py build --help --verbose -``` - -Note: Previously `./configure` and `make` were used to build this project. -They are still available, but `x.py` is the recommended build system. - -### Useful commands -[useful-commands]: #useful-commands - -Some common invocations of `x.py` are: - -- `x.py build --help` - show the help message and explain the subcommand -- `x.py build src/libtest --stage 1` - build up to (and including) the first - stage. For most cases we don't need to build the stage2 compiler, so we can - save time by not building it. The stage1 compiler is a fully functioning - compiler and (probably) will be enough to determine if your change works as - expected. -- `x.py build src/rustc --stage 1` - This will build just rustc, without libstd. - This is the fastest way to recompile after you changed only rustc source code. - Note however that the resulting rustc binary won't have a stdlib to link - against by default. You can build libstd once with `x.py build src/libstd`, - but it is only guaranteed to work if recompiled, so if there are any issues - recompile it. -- `x.py test` - build the full compiler & run all tests (takes a while). This - is what gets run by the continuous integration system against your pull - request. You should run this before submitting to make sure your tests pass - & everything builds in the correct manner. -- `x.py test src/libstd --stage 1` - test the standard library without - recompiling stage 2. -- `x.py test src/test/run-pass --test-args TESTNAME` - Run a matching set of - tests. - - `TESTNAME` should be a substring of the tests to match against e.g. it could - be the fully qualified test name, or just a part of it. - `TESTNAME=collections::hash::map::test_map::test_capacity_not_less_than_len` - or `TESTNAME=test_capacity_not_less_than_len`. -- `x.py test src/test/run-pass --stage 1 --test-args ` - - Run a single rpass test with the stage1 compiler (this will be quicker than - running the command above as we only build the stage1 compiler, not the entire - thing). You can also leave off the directory argument to run all stage1 test - types. -- `x.py test src/libcore --stage 1` - Run stage1 tests in `libcore`. -- `x.py test src/tools/tidy` - Check that the source code is in compliance with - Rust's style guidelines. There is no official document describing Rust's full - guidelines as of yet, but basic rules like 4 spaces for indentation and no - more than 99 characters in a single line should be kept in mind when writing - code. - -### Using your local build -[using-local-build]: #using-local-build - -If you use Rustup to manage your rust install, it has a feature called ["custom -toolchains"][toolchain-link] that you can use to access your newly-built compiler -without having to install it to your system or user PATH. If you've run `python -x.py build`, then you can add your custom rustc to a new toolchain like this: - -[toolchain-link]: https://github.com/rust-lang-nursery/rustup.rs#working-with-custom-toolchains-and-local-builds - -``` -rustup toolchain link build//stage2 -``` - -Where `` is the build triple for the host (the triple of your -computer, by default), and `` is the name for your custom toolchain. (If you -added `--stage 1` to your build command, the compiler will be in the `stage1` -folder instead.) You'll only need to do this once - it will automatically point -to the latest build you've done. - -Once this is set up, you can use your custom toolchain just like any other. For -example, if you've named your toolchain `local`, running `cargo +local build` will -compile a project with your custom rustc, setting `rustup override set local` will -override the toolchain for your current directory, and `cargo +local doc` will use -your custom rustc and rustdoc to generate docs. (If you do this with a `--stage 1` -build, you'll need to build rustdoc specially, since it's not normally built in -stage 1. `python x.py build --stage 1 src/libstd src/tools/rustdoc` will build -rustdoc and libstd, which will allow rustdoc to be run with that toolchain.) - -### Out-of-tree builds -[out-of-tree-builds]: #out-of-tree-builds - -Rust's `x.py` script fully supports out-of-tree builds - it looks for -the Rust source code from the directory `x.py` was found in, but it -reads the `config.toml` configuration file from the directory it's -run in, and places all build artifacts within a subdirectory named `build`. - -This means that if you want to do an out-of-tree build, you can just do it: -``` -$ cd my/build/dir -$ cp ~/my-config.toml config.toml # Or fill in config.toml otherwise -$ path/to/rust/x.py build -... -$ # This will use the Rust source code in `path/to/rust`, but build -$ # artifacts will now be in ./build -``` - -It's absolutely fine to have multiple build directories with different -`config.toml` configurations using the same code. +[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html ## Pull Requests [pull-requests]: #pull-requests @@ -320,26 +119,13 @@ bring those changes into the source repository. Please make pull requests against the `master` branch. -Compiling all of `./x.py test` can take a while. When testing your pull request, -consider using one of the more specialized `./x.py` targets to cut down on the -amount of time you have to wait. You need to have built the compiler at least -once before running these will work, but that’s only one full build rather than -one each time. - - $ python x.py test --stage 1 - -is one such example, which builds just `rustc`, and then runs the tests. If -you’re adding something to the standard library, try - - $ python x.py test src/libstd --stage 1 - Please make sure your pull request is in compliance with Rust's style guidelines by running $ python x.py test src/tools/tidy Make this check before every pull request (and every new commit in a pull -request) ; you can add [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) +request); you can add [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) before every push to make sure you never forget to make this check. All pull requests are reviewed by another person. We have a bot, @@ -532,6 +318,12 @@ to check small fixes. For example, `rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. The CSS might be messed up, but you can verify that the HTML is right. +Additionally, contributions to the [rustc-guide] are always welcome. Contributions +can be made directly at [the +rust-lang/rustc-guide](https://github.com/rust-lang/rustc-guide) repo. The issue +tracker in that repo is also a great way to find things that need doing. There +are issues for beginners and advanced compiler devs alike! + ## Issue Triage [issue-triage]: #issue-triage @@ -627,7 +419,7 @@ For people new to Rust, and just starting to contribute, or even for more seasoned developers, some useful places to look for information are: -* The [rustc guide] contains information about how various parts of the compiler work +* The [rustc guide] contains information about how various parts of the compiler work and how to contribute to the compiler * [Rust Forge][rustforge] contains additional documentation, including write-ups of how to achieve common tasks * The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals From 32b28340b20ea8b45d3e663dc81bb9092ecdeeb1 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 15 Jan 2019 21:21:24 -0500 Subject: [PATCH 0094/1064] demonstrate symmetry --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 65792607a2824..a2f719cf406fe 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -170,7 +170,7 @@ use self::Ordering::*; /// let b2 = Book { isbn: 3, format: BookFormat::Ebook }; /// /// assert!(b1 == BookFormat::Paperback); -/// assert!(b1 != BookFormat::Ebook); +/// assert!(BookFormat::Ebook != b1); /// assert!(b1 == b2); /// ``` /// From bd8ee511a53547851a251c0e4b490cd381e970e8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 15 Jan 2019 18:46:09 -0800 Subject: [PATCH 0095/1064] Add some links in std::fs. A few items were referenced, but did not have links. --- src/libstd/fs.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 119b3f7f9f296..3538816c1124c 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1121,7 +1121,9 @@ impl Permissions { /// writing. /// /// This operation does **not** modify the filesystem. To modify the - /// filesystem use the `fs::set_permissions` function. + /// filesystem use the [`fs::set_permissions`] function. + /// + /// [`fs::set_permissions`]: fn.set_permissions.html /// /// # Examples /// @@ -1639,10 +1641,15 @@ pub fn hard_link, Q: AsRef>(src: P, dst: Q) -> io::Result<( /// /// The `dst` path will be a symbolic link pointing to the `src` path. /// On Windows, this will be a file symlink, not a directory symlink; -/// for this reason, the platform-specific `std::os::unix::fs::symlink` -/// and `std::os::windows::fs::{symlink_file, symlink_dir}` should be +/// for this reason, the platform-specific [`std::os::unix::fs::symlink`] +/// and [`std::os::windows::fs::symlink_file`] or [`symlink_dir`] should be /// used instead to make the intent explicit. /// +/// [`std::os::unix::fs::symlink`]: ../os/unix/fs/fn.symlink.html +/// [`std::os::windows::fs::symlink_file`]: ../os/windows/fs/fn.symlink_file.html +/// [`symlink_dir`]: ../os/windows/fs/fn.symlink_dir.html +/// +/// /// # Examples /// /// ```no_run @@ -1795,7 +1802,7 @@ pub fn create_dir>(path: P) -> io::Result<()> { /// * If any directory in the path specified by `path` /// does not already exist and it could not be created otherwise. The specific /// error conditions for when a directory is being created (after it is -/// determined to not exist) are outlined by `fs::create_dir`. +/// determined to not exist) are outlined by [`fs::create_dir`]. /// /// Notable exception is made for situations where any of the directories /// specified in the `path` could not be created as it was being created concurrently. @@ -1803,6 +1810,8 @@ pub fn create_dir>(path: P) -> io::Result<()> { /// concurrently from multiple threads or processes is guaranteed not to fail /// due to a race condition with itself. /// +/// [`fs::create_dir`]: fn.create_dir.html +/// /// # Examples /// /// ```no_run @@ -1868,7 +1877,10 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// # Errors /// -/// See `file::remove_file` and `fs::remove_dir`. +/// See [`fs::remove_file`] and [`fs::remove_dir`]. +/// +/// [`fs::remove_file`]: fn.remove_file.html +/// [`fs::remove_dir`]: fn.remove_dir.html /// /// # Examples /// From 1a51bb8174e97251a37fcd83ff8750b7773e762a Mon Sep 17 00:00:00 2001 From: tyler Date: Tue, 15 Jan 2019 20:09:06 -0800 Subject: [PATCH 0096/1064] OSX: fix #57534 registering thread dtors while running thread dtors --- src/libstd/sys/unix/fast_thread_local.rs | 61 +++++++++++++++++------- src/libstd/thread/local.rs | 8 +--- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs index d48d701dd50ea..742ffd12b883d 100644 --- a/src/libstd/sys/unix/fast_thread_local.rs +++ b/src/libstd/sys/unix/fast_thread_local.rs @@ -33,30 +33,57 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) { register_dtor_fallback(t, dtor); } -// macOS's analog of the above linux function is this _tlv_atexit function. -// The disassembly of thread_local globals in C++ (at least produced by -// clang) will have this show up in the output. +// This implementation is very similar to register_dtor_fallback in +// sys_common/thread_local.rs. The main difference is that we want to hook into +// macOS's analog of the above linux function, _tlv_atexit. OSX will run the +// registered dtors before any TLS slots get freed, and when the main thread +// exits. +// +// Unfortunately, calling _tlv_atexit while tls dtors are running is UB. The +// workaround below is to register, via _tlv_atexit, a custom DTOR list once per +// thread. thread_local dtors are pushed to the DTOR list without calling +// _tlv_atexit. #[cfg(target_os = "macos")] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) { + use cell::Cell; + use ptr; + + #[thread_local] + static REGISTERED: Cell = Cell::new(false); + if !REGISTERED.get() { + _tlv_atexit(run_dtors, ptr::null_mut()); + REGISTERED.set(true); + } + + type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>; + + #[thread_local] + static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut()); + if DTORS.get().is_null() { + let v: Box = box Vec::new(); + DTORS.set(Box::into_raw(v)); + } + extern { fn _tlv_atexit(dtor: unsafe extern fn(*mut u8), arg: *mut u8); } - _tlv_atexit(dtor, t); + + let list: &mut List = &mut *DTORS.get(); + list.push((t, dtor)); + + unsafe extern fn run_dtors(_: *mut u8) { + let mut ptr = DTORS.replace(ptr::null_mut()); + while !ptr.is_null() { + let list = Box::from_raw(ptr); + for (ptr, dtor) in list.into_iter() { + dtor(ptr); + } + ptr = DTORS.replace(ptr::null_mut()); + } + } } pub fn requires_move_before_drop() -> bool { - // The macOS implementation of TLS apparently had an odd aspect to it - // where the pointer we have may be overwritten while this destructor - // is running. Specifically if a TLS destructor re-accesses TLS it may - // trigger a re-initialization of all TLS variables, paving over at - // least some destroyed ones with initial values. - // - // This means that if we drop a TLS value in place on macOS that we could - // revert the value to its original state halfway through the - // destructor, which would be bad! - // - // Hence, we use `ptr::read` on macOS (to move to a "safe" location) - // instead of drop_in_place. - cfg!(target_os = "macos") + false } diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index efd231e017679..5d2eb5f8e7320 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -69,9 +69,6 @@ use mem; /// destroyed, but not all platforms have this guard. Those platforms that do /// not guard typically have a synthetic limit after which point no more /// destructors are run. -/// 3. On macOS, initializing TLS during destruction of other TLS slots can -/// sometimes cancel *all* destructors for the current thread, whether or not -/// the slots have already had their destructors run or not. /// /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with /// [`thread_local!`]: ../../std/macro.thread_local.html @@ -604,11 +601,8 @@ mod tests { } // Note that this test will deadlock if TLS destructors aren't run (this - // requires the destructor to be run to pass the test). macOS has a known bug - // where dtors-in-dtors may cancel other destructors, so we just ignore this - // test on macOS. + // requires the destructor to be run to pass the test). #[test] - #[cfg_attr(target_os = "macos", ignore)] fn dtors_in_dtors_in_dtors() { struct S1(Sender<()>); thread_local!(static K1: UnsafeCell> = UnsafeCell::new(None)); From ae4b14e837b613febc9a7ccfee4230fb22044a10 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Jan 2019 13:51:24 +1100 Subject: [PATCH 0097/1064] Use `Lit` rather than `P` in `hir::ExprKind`. It's simpler and makes some benchmark run up to 1% faster. It also makes `hir::ExprKind` more like `ast::ExprKind` (which underwent the equivalent change in #55777). --- src/librustc/hir/lowering.rs | 2 +- src/librustc/hir/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8badcbfc1b301..8cdc493e6fda7 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3775,7 +3775,7 @@ impl<'a> LoweringContext<'a> { let ohs = P(self.lower_expr(ohs)); hir::ExprKind::Unary(op, ohs) } - ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((*l).clone())), + ExprKind::Lit(ref l) => hir::ExprKind::Lit((*l).clone()), ExprKind::Cast(ref expr, ref ty) => { let expr = P(self.lower_expr(expr)); hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed())) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index fc4bd05476f6c..cf4bd27a0900a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1466,7 +1466,7 @@ pub enum ExprKind { /// A unary operation (For example: `!x`, `*x`) Unary(UnOp, P), /// A literal (For example: `1`, `"foo"`) - Lit(P), + Lit(Lit), /// A cast (`foo as f64`) Cast(P, P), Type(P, P), From 81cd1e64f38299276ce131db37994086ec94ad35 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 15 Jan 2019 20:48:52 -0800 Subject: [PATCH 0098/1064] Deprecate the unstable Vec::resize_default --- src/liballoc/vec.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index ba3b3dfbfc2e1..198d1ee4bb4fc 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1368,6 +1368,7 @@ impl Vec { /// # Examples /// /// ``` + /// # #![allow(deprecated)] /// #![feature(vec_resize_default)] /// /// let mut vec = vec![1, 2, 3]; @@ -1384,6 +1385,9 @@ impl Vec { /// [`Default`]: ../../std/default/trait.Default.html /// [`Clone`]: ../../std/clone/trait.Clone.html #[unstable(feature = "vec_resize_default", issue = "41758")] + #[rustc_deprecated(reason = "This is moving towards being removed in favor \ + of `.resize_with(Default::default)`. If you disagree, please comment \ + in the tracking issue.", since = "1.33.0")] pub fn resize_default(&mut self, new_len: usize) { let len = self.len(); From dc455286205bc0b3be6a6c6dcefff0498a6f4bcf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Jan 2019 16:20:32 +1100 Subject: [PATCH 0099/1064] Remove `hir::Label`. It's identical to `ast::Label`. --- src/librustc/hir/mod.rs | 13 +------------ src/librustc/ich/impls_hir.rs | 2 +- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index cf4bd27a0900a..aaef1c722be96 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -19,7 +19,7 @@ use syntax_pos::{Span, DUMMY_SP, symbol::InternedString}; use syntax::source_map::{self, Spanned}; use rustc_target::spec::abi::Abi; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; -use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy}; +use syntax::ast::{Attribute, Label, Lit, StrStyle, FloatTy, IntTy, UintTy}; use syntax::attr::InlineAttr; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; @@ -142,17 +142,6 @@ pub const DUMMY_HIR_ID: HirId = HirId { pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX; -#[derive(Clone, RustcEncodable, RustcDecodable, Copy)] -pub struct Label { - pub ident: Ident, -} - -impl fmt::Debug for Label { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "label({:?})", self.ident) - } -} - #[derive(Clone, RustcEncodable, RustcDecodable, Copy)] pub struct Lifetime { pub id: NodeId, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 8ff60e5f56225..f48059b328ff3 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -153,7 +153,7 @@ impl_stable_hash_for!(enum hir::LifetimeName { Error, }); -impl_stable_hash_for!(struct hir::Label { +impl_stable_hash_for!(struct ast::Label { ident }); From 193809ec3ad035f45724f31328142f38a4e9f66a Mon Sep 17 00:00:00 2001 From: AB1908 Date: Wed, 16 Jan 2019 05:32:03 +0000 Subject: [PATCH 0100/1064] Add regression test to close #53787 --- .../ui/issue-53787-inline-assembler-macro.rs | 24 +++++++++++++++++++ .../issue-53787-inline-assembler-macro.stderr | 9 +++++++ 2 files changed, 33 insertions(+) create mode 100644 src/test/ui/issue-53787-inline-assembler-macro.rs create mode 100644 src/test/ui/issue-53787-inline-assembler-macro.stderr diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issue-53787-inline-assembler-macro.rs new file mode 100644 index 0000000000000..4f1048f787dab --- /dev/null +++ b/src/test/ui/issue-53787-inline-assembler-macro.rs @@ -0,0 +1,24 @@ +// Regression test for Issue #53787: Fix ICE when creating a label in inline assembler with macros. + +#![feature(asm)] + +macro_rules! fake_jump { + ($id:expr) => { + unsafe { + + asm!( + " + jmp $0 + lea eax, [ebx] + xor eax, 0xDEADBEEF + retn + $0: + "::"0"($id)::"volatile", "intel"); + } + }; +} + +fn main() { + fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly + println!("Hello, world!"); +} diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issue-53787-inline-assembler-macro.stderr new file mode 100644 index 0000000000000..f63b2e1932754 --- /dev/null +++ b/src/test/ui/issue-53787-inline-assembler-macro.stderr @@ -0,0 +1,9 @@ +error[E0669]: invalid value for constraint in inline assembly + --> $DIR/issue-53787-inline-assembler-macro.rs:22:16 + | +LL | fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0669`. From 0772dbbb09bb28602756c964188563c64e78bc9c Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 16 Jan 2019 11:36:38 +0530 Subject: [PATCH 0101/1064] Fix release manifest generation --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8c1baa55bcdca..4ca285b9b1db1 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -95,6 +95,7 @@ static TARGETS: &'static [&'static str] = &[ "wasm32-unknown-unknown", "x86_64-apple-darwin", "x86_64-apple-ios", + "x86_64-fortanix-unknown-sgx", "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-gnu", From 3f0a75d80619e99e849c10fde406da4109db9e29 Mon Sep 17 00:00:00 2001 From: AB1908 Date: Wed, 16 Jan 2019 06:29:44 +0000 Subject: [PATCH 0102/1064] Remove trailing whitespace --- src/test/ui/issue-53787-inline-assembler-macro.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issue-53787-inline-assembler-macro.rs index 4f1048f787dab..937bce1b655dd 100644 --- a/src/test/ui/issue-53787-inline-assembler-macro.rs +++ b/src/test/ui/issue-53787-inline-assembler-macro.rs @@ -5,7 +5,6 @@ macro_rules! fake_jump { ($id:expr) => { unsafe { - asm!( " jmp $0 From 7bddcbae51b9417b9054ea042174416d8f538405 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 16 Jan 2019 14:37:22 +0100 Subject: [PATCH 0103/1064] With this change, I am able to build and test cross-platform `rustc` In particular, I can use the following in my `config.toml`: ``` [build] host = ["i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"] target = ["i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"] ``` Before this change, my attempt to run the test suite would fail because the error output differs depending on what your host and targets are. ---- To be concrete, here are the actual messages one can observe: ``` % ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=x86_64-unknown-linux-gnu error: the type `std::option::Option<[u32; 35184372088831]>` is too big for the current architecture error: aborting due to previous error % ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=i686-unknown-linux-gnu error: the type `std::option::Option<[u32; 536870911]>` is too big for the current architecture error: aborting due to previous error % ./build/i686-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=i686-unknown-linux-gnu error: the type `std::option::Option<[u32; 536870911]>` is too big for the current architecture error: aborting due to previous error % ./build/i686-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=x86_64-unknown-linux-gnu error: the type `[u32; 35184372088831]` is too big for the current architecture error: aborting due to previous error ``` To address these variations, I changed the test to be more aggressive in its normalization strategy. We cannot (and IMO should not) guarantee that `Option` will appear in the error output here. So I normalized both types `Option<[u32; N]>` and `[u32; N]` to just `TYPE` --- src/test/ui/huge-enum.rs | 6 ++---- src/test/ui/huge-enum.stderr | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/test/ui/huge-enum.rs b/src/test/ui/huge-enum.rs index 18ef45794af19..71c8fd55b23f3 100644 --- a/src/test/ui/huge-enum.rs +++ b/src/test/ui/huge-enum.rs @@ -1,7 +1,5 @@ -// error-pattern: Option -// normalize-stderr-test "<\[u32; \d+\]>" -> "<[u32; N]>" - -// FIXME: work properly with higher limits +// normalize-stderr-test "std::option::Option<\[u32; \d+\]>" -> "TYPE" +// normalize-stderr-test "\[u32; \d+\]" -> "TYPE" #[cfg(target_pointer_width = "32")] fn main() { diff --git a/src/test/ui/huge-enum.stderr b/src/test/ui/huge-enum.stderr index b7cf25504614a..67cae3d52ed2d 100644 --- a/src/test/ui/huge-enum.stderr +++ b/src/test/ui/huge-enum.stderr @@ -1,4 +1,4 @@ -error: the type `std::option::Option<[u32; N]>` is too big for the current architecture +error: the type `TYPE` is too big for the current architecture error: aborting due to previous error From 763392cb8ca09e0f332c1ab9b75376afbdafc18f Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Wed, 16 Jan 2019 23:05:50 +0900 Subject: [PATCH 0104/1064] Fix memory leak in P::filter_map --- src/libsyntax/ptr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index bb1744e2df169..3effe53cd29b0 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -101,6 +101,7 @@ impl P { // Recreate self from the raw pointer. Some(P { ptr: Box::from_raw(p) }) } else { + drop(Box::from_raw(p)); None } } From 9b68dcd32a1be5d219a6bcedc2c9fc63d6d463a4 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 16 Jan 2019 12:55:22 -0500 Subject: [PATCH 0105/1064] Don't explicitly increment the depth for new trait predicates --- src/librustc/traits/select.rs | 3 +- .../ui/did_you_mean/recursion_limit.stderr | 7 +++- src/test/ui/error-codes/E0275.stderr | 33 ++++++++++++++++++- src/test/ui/issues/issue-20413.stderr | 33 ++++++++++++++++++- 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 8b9863fa27879..718f7a6d8573b 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -697,8 +697,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match obligation.predicate { ty::Predicate::Trait(ref t) => { debug_assert!(!t.has_escaping_bound_vars()); - let mut obligation = obligation.with(t.clone()); - obligation.recursion_depth += 1; + let obligation = obligation.with(t.clone()); self.evaluate_trait_predicate_recursively(previous_stack, obligation) } diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index 292a80faa7420..0738c3f65b95f 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -1,10 +1,15 @@ -error[E0275]: overflow evaluating the requirement `E: std::marker::Send` +error[E0275]: overflow evaluating the requirement `J: std::marker::Send` --> $DIR/recursion_limit.rs:34:5 | LL | is_send::
(); //~ ERROR overflow evaluating the requirement | ^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate + = note: required because it appears within the type `I` + = note: required because it appears within the type `H` + = note: required because it appears within the type `G` + = note: required because it appears within the type `F` + = note: required because it appears within the type `E` = note: required because it appears within the type `D` = note: required because it appears within the type `C` = note: required because it appears within the type `B` diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index df3b362f82401..f2b0f392bc8bc 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -1,10 +1,41 @@ -error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: std::marker::Sized` +error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` --> $DIR/E0275.rs:5:1 | LL | impl Foo for T where Bar: Foo {} //~ ERROR E0275 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 043df0e392b45..1c353fec8aabf 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -6,7 +6,7 @@ LL | struct NoData; | = help: consider removing `T` or using a marker such as `std::marker::PhantomData` -error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: std::marker::Sized` +error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` --> $DIR/issue-20413.rs:8:1 | LL | / impl Foo for T where NoData: Foo { @@ -18,6 +18,37 @@ LL | | } | |_^ | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` = note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` From 01d0ae96188b99c367178a38906b7269e1ada244 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 10 Jan 2019 23:23:30 +0300 Subject: [PATCH 0106/1064] Prioritize variants as inherent associated items during name resolution --- src/librustc/lint/builtin.rs | 7 + src/librustc_lint/lib.rs | 5 + src/librustc_typeck/astconv.rs | 162 +++++++++++------- src/librustc_typeck/check/method/mod.rs | 61 +++---- src/librustc_typeck/check/mod.rs | 4 +- .../ui/type-alias-enum-variants-priority-2.rs | 13 ++ ...type-alias-enum-variants-priority-2.stderr | 12 ++ .../ui/type-alias-enum-variants-priority-3.rs | 10 ++ ...type-alias-enum-variants-priority-3.stderr | 8 + .../ui/type-alias-enum-variants-priority.rs | 20 +++ .../type-alias-enum-variants-priority.stderr | 26 +++ 11 files changed, 225 insertions(+), 103 deletions(-) create mode 100644 src/test/ui/type-alias-enum-variants-priority-2.rs create mode 100644 src/test/ui/type-alias-enum-variants-priority-2.stderr create mode 100644 src/test/ui/type-alias-enum-variants-priority-3.rs create mode 100644 src/test/ui/type-alias-enum-variants-priority-3.stderr create mode 100644 src/test/ui/type-alias-enum-variants-priority.rs create mode 100644 src/test/ui/type-alias-enum-variants-priority.stderr diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c8d137a42b2e8..a0bd4f01cd231 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -368,6 +368,12 @@ declare_lint! { report_in_external_macro: true } +declare_lint! { + pub AMBIGUOUS_ASSOCIATED_ITEMS, + Warn, + "ambiguous associated items" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -433,6 +439,7 @@ impl LintPass for HardwiredLints { parser::QUESTION_MARK_MACRO_SEP, parser::ILL_FORMED_ATTRIBUTE_INPUT, DEPRECATED_IN_FUTURE, + AMBIGUOUS_ASSOCIATED_ITEMS, ) } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2d764d11c66aa..71c859d8dbea7 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -341,6 +341,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #57571 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS), + reference: "issue #57644 ", + edition: None, + }, ]); // Register renamed and removed lints. diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8e5eaa18b9de0..534279e981d62 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -10,6 +10,7 @@ use hir::HirVec; use lint; use middle::resolve_lifetime as rl; use namespace::Namespace; +use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; @@ -1278,29 +1279,50 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } // Create a type from a path to an associated type. - // For a path `A::B::C::D`, `ty` and `ty_path_def` are the type and def for `A::B::C` + // For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C` // and item_segment is the path segment for `D`. We return a type and a def for // the whole path. - // Will fail except for `T::A` and `Self::A`; i.e., if `ty`/`ty_path_def` are not a type + // Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type // parameter or `Self`. - pub fn associated_path_def_to_ty(&self, - ref_id: ast::NodeId, - span: Span, - ty: Ty<'tcx>, - ty_path_def: Def, - item_segment: &hir::PathSegment) - -> (Ty<'tcx>, Def) - { + pub fn associated_path_to_ty( + &self, + ref_id: ast::NodeId, + span: Span, + qself_ty: Ty<'tcx>, + qself_def: Def, + assoc_segment: &hir::PathSegment, + permit_variants: bool, + ) -> (Ty<'tcx>, Def) { let tcx = self.tcx(); - let assoc_name = item_segment.ident; + let assoc_ident = assoc_segment.ident; - debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name); + debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident); - self.prohibit_generics(slice::from_ref(item_segment)); + self.prohibit_generics(slice::from_ref(assoc_segment)); + + // Check if we have an enum variant. + let mut variant_resolution = None; + if let ty::Adt(adt_def, _) = qself_ty.sty { + if adt_def.is_enum() { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(assoc_ident, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + let def = Def::Variant(variant_def.did); + if permit_variants { + check_type_alias_enum_variants_enabled(tcx, span); + tcx.check_stability(variant_def.did, Some(ref_id), span); + return (qself_ty, def); + } else { + variant_resolution = Some(def); + } + } + } + } // Find the type of the associated item, and the trait where the associated // item is declared. - let bound = match (&ty.sty, ty_path_def) { + let bound = match (&qself_ty.sty, qself_def) { (_, Def::SelfTy(Some(_), Some(impl_def_id))) => { // `Self` in an impl of a trait -- we have a concrete self type and a // trait reference. @@ -1313,77 +1335,61 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }; let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref)) - .filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_name)); + .filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident)); - match self.one_bound_for_assoc_type(candidates, "Self", assoc_name, span) { + match self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span) { Ok(bound) => bound, Err(ErrorReported) => return (tcx.types.err, Def::Err), } } (&ty::Param(_), Def::SelfTy(Some(param_did), None)) | (&ty::Param(_), Def::TyParam(param_did)) => { - match self.find_bound_for_assoc_item(param_did, assoc_name, span) { + match self.find_bound_for_assoc_item(param_did, assoc_ident, span) { Ok(bound) => bound, Err(ErrorReported) => return (tcx.types.err, Def::Err), } } - (&ty::Adt(adt_def, _substs), Def::Enum(_did)) => { - let ty_str = ty.to_string(); - // Incorrect enum variant. - let mut err = tcx.sess.struct_span_err( - span, - &format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str), - ); - // Check if it was a typo. - let input = adt_def.variants.iter().map(|variant| &variant.ident.name); - if let Some(suggested_name) = find_best_match_for_name( - input, - &assoc_name.as_str(), - None, - ) { - err.span_suggestion_with_applicability( + _ => { + if variant_resolution.is_some() { + // Variant in type position + let msg = format!("expected type, found variant `{}`", assoc_ident); + tcx.sess.span_err(span, &msg); + } else if qself_ty.is_enum() { + // Report as incorrect enum variant rather than ambiguous type. + let mut err = tcx.sess.struct_span_err( span, - "did you mean", - format!("{}::{}", ty_str, suggested_name.to_string()), - Applicability::MaybeIncorrect, + &format!("no variant `{}` on enum `{}`", &assoc_ident.as_str(), qself_ty), ); - } else { - err.span_label(span, "unknown variant"); - } - err.emit(); - return (tcx.types.err, Def::Err); - } - _ => { - // Check if we have an enum variant. - match ty.sty { - ty::Adt(adt_def, _) if adt_def.is_enum() => { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - - let def = Def::Variant(variant_def.did); - tcx.check_stability(def.def_id(), Some(ref_id), span); - return (ty, def); - } - }, - _ => (), - } - - // Don't print `TyErr` to the user. - if !ty.references_error() { + // Check if it was a typo. + let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT"); + if let Some(suggested_name) = find_best_match_for_name( + adt_def.variants.iter().map(|variant| &variant.ident.name), + &assoc_ident.as_str(), + None, + ) { + err.span_suggestion_with_applicability( + span, + "did you mean", + format!("{}::{}", qself_ty, suggested_name), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label(span, "unknown variant"); + } + err.emit(); + } else if !qself_ty.references_error() { + // Don't print `TyErr` to the user. self.report_ambiguous_associated_type(span, - &ty.to_string(), + &qself_ty.to_string(), "Trait", - &assoc_name.as_str()); + &assoc_ident.as_str()); } return (tcx.types.err, Def::Err); } }; let trait_did = bound.def_id(); - let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_name, trait_did, ref_id); + let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_ident, trait_did, ref_id); let item = tcx.associated_items(trait_did).find(|i| { Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident @@ -1394,11 +1400,35 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let def = Def::AssociatedTy(item.def_id); if !item.vis.is_accessible_from(def_scope, tcx) { - let msg = format!("{} `{}` is private", def.kind_name(), assoc_name); + let msg = format!("{} `{}` is private", def.kind_name(), assoc_ident); tcx.sess.span_err(span, &msg); } tcx.check_stability(item.def_id, Some(ref_id), span); + if let Some(variant_def) = variant_resolution { + let mut err = tcx.struct_span_lint_node( + AMBIGUOUS_ASSOCIATED_ITEMS, + ref_id, + span, + "ambiguous associated item", + ); + + let mut could_refer_to = |def: Def, also| { + let note_msg = format!("`{}` could{} refer to {} defined here", + assoc_ident, also, def.kind_name()); + err.span_note(tcx.def_span(def.def_id()), ¬e_msg); + }; + could_refer_to(variant_def, ""); + could_refer_to(def, " also"); + + err.span_suggestion_with_applicability( + span, + "use fully-qualified syntax", + format!("<{} as {}>::{}", qself_ty, "Trait", assoc_ident), + Applicability::HasPlaceholders, + ).emit(); + } + (ty, def) } @@ -1773,7 +1803,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { Def::Err }; - self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 + self.associated_path_to_ty(ast_ty.id, ast_ty.span, ty, def, segment, false).0 } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.id); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 02687df6a94fc..e71dc019471bd 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -408,45 +408,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; - let mode = probe::Mode::Path; - match self.probe_for_name(span, mode, method_name, IsSuggestion(false), - self_ty, expr_id, ProbeScope::TraitsInScope) { - Ok(pick) => { - debug!("resolve_ufcs: pick={:?}", pick); - if let Some(import_id) = pick.import_id { - let import_def_id = tcx.hir().local_def_id(import_id); - debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); - Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) - .unwrap().insert(import_def_id); + // Check if we have an enum variant. + if let ty::Adt(adt_def, _) = self_ty.sty { + if adt_def.is_enum() { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(method_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + check_type_alias_enum_variants_enabled(tcx, span); + + let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); + tcx.check_stability(def.def_id(), Some(expr_id), span); + return Ok(def); } - - let def = pick.item.def(); - debug!("resolve_ufcs: def={:?}", def); - tcx.check_stability(def.def_id(), Some(expr_id), span); - - Ok(def) } - Err(err) => { - // Check if we have an enum variant. - match self_ty.sty { - ty::Adt(adt_def, _) if adt_def.is_enum() => { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(method_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - - let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); - tcx.check_stability(def.def_id(), Some(expr_id), span); - return Ok(def); - } - }, - _ => (), - } + } - Err(err) - } + let pick = self.probe_for_name(span, probe::Mode::Path, method_name, IsSuggestion(false), + self_ty, expr_id, ProbeScope::TraitsInScope)?; + debug!("resolve_ufcs: pick={:?}", pick); + if let Some(import_id) = pick.import_id { + let import_def_id = tcx.hir().local_def_id(import_id); + debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); + Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) + .unwrap().insert(import_def_id); } + + let def = pick.item.def(); + debug!("resolve_ufcs: def={:?}", def); + tcx.check_stability(def.def_id(), Some(expr_id), span); + Ok(def) } /// Find item with name `item_name` defined in impl/trait `def_id` diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..22300f2ae11ed 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4724,8 +4724,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { Def::Err }; - let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span, - ty, def, segment); + let (ty, def) = AstConv::associated_path_to_ty(self, node_id, path_span, + ty, def, segment, true); // Write back the new resolution. let hir_id = self.tcx.hir().node_to_hir_id(node_id); diff --git a/src/test/ui/type-alias-enum-variants-priority-2.rs b/src/test/ui/type-alias-enum-variants-priority-2.rs new file mode 100644 index 0000000000000..295f8acf62f85 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-2.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_enum_variants)] + +enum E { + V(u8) +} + +impl E { + fn V() {} +} + +fn main() { + ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied +} diff --git a/src/test/ui/type-alias-enum-variants-priority-2.stderr b/src/test/ui/type-alias-enum-variants-priority-2.stderr new file mode 100644 index 0000000000000..c6ec96ebb7d3b --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-2.stderr @@ -0,0 +1,12 @@ +error[E0061]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/type-alias-enum-variants-priority-2.rs:12:5 + | +LL | V(u8) + | ----- defined here +... +LL | ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied + | ^^^^^^^^ expected 1 parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/type-alias-enum-variants-priority-3.rs b/src/test/ui/type-alias-enum-variants-priority-3.rs new file mode 100644 index 0000000000000..33f96553b57f0 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-3.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_enum_variants)] + +enum E { + V +} + +fn check() -> ::V {} +//~^ ERROR expected type, found variant `V` + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority-3.stderr b/src/test/ui/type-alias-enum-variants-priority-3.stderr new file mode 100644 index 0000000000000..b3451542a2570 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority-3.stderr @@ -0,0 +1,8 @@ +error: expected type, found variant `V` + --> $DIR/type-alias-enum-variants-priority-3.rs:7:15 + | +LL | fn check() -> ::V {} + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-enum-variants-priority.rs b/src/test/ui/type-alias-enum-variants-priority.rs new file mode 100644 index 0000000000000..db1da2b12e256 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_enum_variants)] +#![deny(ambiguous_associated_items)] + +enum E { + V +} + +trait Tr { + type V; + fn f() -> Self::V; +} + +impl Tr for E { + type V = u8; + fn f() -> Self::V { 0 } + //~^ ERROR ambiguous associated item + //~| WARN this was previously accepted +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority.stderr b/src/test/ui/type-alias-enum-variants-priority.stderr new file mode 100644 index 0000000000000..dcf7dc77ed5ea --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-priority.stderr @@ -0,0 +1,26 @@ +error: ambiguous associated item + --> $DIR/type-alias-enum-variants-priority.rs:15:15 + | +LL | fn f() -> Self::V { 0 } + | ^^^^^^^ help: use fully-qualified syntax: `::V` + | +note: lint level defined here + --> $DIR/type-alias-enum-variants-priority.rs:2:9 + | +LL | #![deny(ambiguous_associated_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57644 +note: `V` could refer to variant defined here + --> $DIR/type-alias-enum-variants-priority.rs:5:5 + | +LL | V + | ^ +note: `V` could also refer to associated type defined here + --> $DIR/type-alias-enum-variants-priority.rs:9:5 + | +LL | type V; + | ^^^^^^^ + +error: aborting due to previous error + From 9b8c3c4cff4302a50fc8c82a18f10fc97b0fb3b7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 16 Jan 2019 13:13:58 -0800 Subject: [PATCH 0107/1064] [rustbuild] Rebuild std after changes to codegen backends Use `clear_if_dirty` on std for backend changes, just as we do for changes to rustc itself, so new codegen is correctly applied to all later compiler stages. Fixes #48298. --- src/bootstrap/builder.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 9c58f5b179fd8..31adab64f609d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -660,6 +660,15 @@ impl<'a> Builder<'a> { } } + /// Get the paths to all of the compiler's codegen backends. + fn codegen_backends(&self, compiler: Compiler) -> impl Iterator { + fs::read_dir(self.sysroot_codegen_backends(compiler)) + .into_iter() + .flatten() + .filter_map(Result::ok) + .map(|entry| entry.path()) + } + pub fn rustdoc(&self, host: Interned) -> PathBuf { self.ensure(tool::Rustdoc { host }) } @@ -750,6 +759,9 @@ impl<'a> Builder<'a> { match mode { Mode::Std => { self.clear_if_dirty(&my_out, &self.rustc(compiler)); + for backend in self.codegen_backends(compiler) { + self.clear_if_dirty(&my_out, &backend); + } }, Mode::Test => { self.clear_if_dirty(&my_out, &libstd_stamp); From b2ce5a90995be655b1a1e8fd764e2b1c1f0dab14 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 17 Jan 2019 09:45:02 +1100 Subject: [PATCH 0108/1064] Make `hir::Stmt` a separate struct. Benefits: - It lets us move the `NodeId` field out of every `hir::StmtKind` variant `NodeId` to a more sensible spot. - It eliminates sadness in `Stmt::fmt`. - It makes `hir::Stmt` match `ast::Stmt`. --- src/librustc/cfg/construct.rs | 8 ++-- src/librustc/hir/check_attr.rs | 2 +- src/librustc/hir/intravisit.rs | 9 ++--- src/librustc/hir/lowering.rs | 50 ++++++++++++++----------- src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/mod.rs | 39 ++++++++----------- src/librustc/hir/print.rs | 10 ++--- src/librustc/ich/impls_hir.rs | 13 +++++-- src/librustc/middle/expr_use_visitor.rs | 6 +-- src/librustc/middle/liveness.rs | 4 +- src/librustc/middle/region.rs | 2 +- src/librustc_lint/unused.rs | 4 +- src/librustc_mir/hair/cx/block.rs | 10 ++--- src/librustc_passes/hir_stats.rs | 2 +- src/librustc_passes/rvalue_promotion.rs | 6 +-- src/librustc_typeck/check/mod.rs | 12 +++--- 16 files changed, 92 insertions(+), 87 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 978d20ea94789..1cbfcc1664323 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -99,15 +99,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex { - let hir_id = self.tcx.hir().node_to_hir_id(stmt.node.id()); + let hir_id = self.tcx.hir().node_to_hir_id(stmt.id); match stmt.node { - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { let exit = self.decl(&decl, pred); self.add_ast_node(hir_id.local_id, &[exit]) } - hir::StmtKind::Expr(ref expr, _) | - hir::StmtKind::Semi(ref expr, _) => { + hir::StmtKind::Expr(ref expr) | + hir::StmtKind::Semi(ref expr) => { let exit = self.expr(&expr, pred); self.add_ast_node(hir_id.local_id, &[exit]) } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index a214ec88c6654..1cffe5ace5a6e 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { fn check_stmt_attributes(&self, stmt: &hir::Stmt) { // When checking statements ignore expressions, they will be checked later - if let hir::StmtKind::Decl(_, _) = stmt.node { + if let hir::StmtKind::Decl(..) = stmt.node { for attr in stmt.node.attrs() { if attr.check_name("inline") { self.check_inline(attr, &stmt.span, Target::Statement); diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index f633703be56d4..3b9358d7c46a9 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -953,14 +953,13 @@ pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { } pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { + visitor.visit_id(statement.id); match statement.node { - StmtKind::Decl(ref declaration, id) => { - visitor.visit_id(id); + StmtKind::Decl(ref declaration) => { visitor.visit_decl(declaration) } - StmtKind::Expr(ref expression, id) | - StmtKind::Semi(ref expression, id) => { - visitor.visit_id(id); + StmtKind::Expr(ref expression) | + StmtKind::Semi(ref expression) => { visitor.visit_expr(expression) } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8badcbfc1b301..837960a0f1d95 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4331,10 +4331,11 @@ impl<'a> LoweringContext<'a> { ThinVec::new(), )) }; - let match_stmt = respan( - head_sp, - hir::StmtKind::Expr(match_expr, self.next_id().node_id) - ); + let match_stmt = hir::Stmt { + id: self.next_id().node_id, + node: hir::StmtKind::Expr(match_expr), + span: head_sp, + }; let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id)); @@ -4357,10 +4358,11 @@ impl<'a> LoweringContext<'a> { let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); let body_expr = P(self.expr_block(body_block, ThinVec::new())); - let body_stmt = respan( - body.span, - hir::StmtKind::Expr(body_expr, self.next_id().node_id) - ); + let body_stmt = hir::Stmt { + id: self.next_id().node_id, + node: hir::StmtKind::Expr(body_expr), + span: body.span, + }; let loop_block = P(self.block_all( e.span, @@ -4533,24 +4535,24 @@ impl<'a> LoweringContext<'a> { let (l, item_ids) = self.lower_local(l); let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids .into_iter() - .map(|item_id| Spanned { + .map(|item_id| hir::Stmt { + id: self.next_id().node_id, node: hir::StmtKind::Decl( P(Spanned { node: hir::DeclKind::Item(item_id), span: s.span, }), - self.next_id().node_id, ), span: s.span, }) .collect(); - ids.push(Spanned { + ids.push(hir::Stmt { + id: self.lower_node_id(s.id).node_id, node: hir::StmtKind::Decl( P(Spanned { node: hir::DeclKind::Local(l), span: s.span, }), - self.lower_node_id(s.id).node_id, ), span: s.span, }); @@ -4561,26 +4563,28 @@ impl<'a> LoweringContext<'a> { let mut id = Some(s.id); return self.lower_item_id(it) .into_iter() - .map(|item_id| Spanned { + .map(|item_id| hir::Stmt { + id: id.take() + .map(|id| self.lower_node_id(id).node_id) + .unwrap_or_else(|| self.next_id().node_id), node: hir::StmtKind::Decl( P(Spanned { node: hir::DeclKind::Item(item_id), span: s.span, }), - id.take() - .map(|id| self.lower_node_id(id).node_id) - .unwrap_or_else(|| self.next_id().node_id), ), span: s.span, }) .collect(); } - StmtKind::Expr(ref e) => Spanned { - node: hir::StmtKind::Expr(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id), + StmtKind::Expr(ref e) => hir::Stmt { + id: self.lower_node_id(s.id).node_id, + node: hir::StmtKind::Expr(P(self.lower_expr(e))), span: s.span, }, - StmtKind::Semi(ref e) => Spanned { - node: hir::StmtKind::Semi(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id), + StmtKind::Semi(ref e) => hir::Stmt { + id: self.lower_node_id(s.id).node_id, + node: hir::StmtKind::Semi(P(self.lower_expr(e))), span: s.span, }, StmtKind::Mac(..) => panic!("Shouldn't exist here"), @@ -4806,7 +4810,11 @@ impl<'a> LoweringContext<'a> { source, }); let decl = respan(sp, hir::DeclKind::Local(local)); - respan(sp, hir::StmtKind::Decl(P(decl), self.next_id().node_id)) + hir::Stmt { + id: self.next_id().node_id, + node: hir::StmtKind::Decl(P(decl)), + span: sp + } } fn stmt_let( diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index ae9bb37842990..7cc5d756ff311 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -426,7 +426,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_stmt(&mut self, stmt: &'hir Stmt) { - let id = stmt.node.id(); + let id = stmt.id; self.insert(stmt.span, id, Node::Stmt(stmt)); self.with_parent(id, |this| { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index fc4bd05476f6c..1e287ccc85c78 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -16,7 +16,7 @@ use util::nodemap::{NodeMap, FxHashSet}; use mir::mono::Linkage; use syntax_pos::{Span, DUMMY_SP, symbol::InternedString}; -use syntax::source_map::{self, Spanned}; +use syntax::source_map::Spanned; use rustc_target::spec::abi::Abi; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy}; @@ -1144,45 +1144,38 @@ impl UnOp { } /// A statement -pub type Stmt = Spanned; +#[derive(Clone, RustcEncodable, RustcDecodable)] +pub struct Stmt { + pub id: NodeId, + pub node: StmtKind, + pub span: Span, +} -impl fmt::Debug for StmtKind { +impl fmt::Debug for Stmt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Sadness. - let spanned = source_map::dummy_spanned(self.clone()); - write!(f, - "stmt({}: {})", - spanned.node.id(), - print::to_string(print::NO_ANN, |s| s.print_stmt(&spanned))) + write!(f, "stmt({}: {})", self.id, + print::to_string(print::NO_ANN, |s| s.print_stmt(self))) } } #[derive(Clone, RustcEncodable, RustcDecodable)] pub enum StmtKind { /// Could be an item or a local (let) binding: - Decl(P, NodeId), + Decl(P), /// Expr without trailing semi-colon (must have unit type): - Expr(P, NodeId), + Expr(P), /// Expr with trailing semi-colon (may have any type): - Semi(P, NodeId), + Semi(P), } impl StmtKind { pub fn attrs(&self) -> &[Attribute] { match *self { - StmtKind::Decl(ref d, _) => d.node.attrs(), - StmtKind::Expr(ref e, _) | - StmtKind::Semi(ref e, _) => &e.attrs, - } - } - - pub fn id(&self) -> NodeId { - match *self { - StmtKind::Decl(_, id) | - StmtKind::Expr(_, id) | - StmtKind::Semi(_, id) => id, + StmtKind::Decl(ref d) => d.node.attrs(), + StmtKind::Expr(ref e) | + StmtKind::Semi(ref e) => &e.attrs, } } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index d7acdefcc7d71..d92800c7b9537 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -992,14 +992,14 @@ impl<'a> State<'a> { pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> { self.maybe_print_comment(st.span.lo())?; match st.node { - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { self.print_decl(&decl)?; } - hir::StmtKind::Expr(ref expr, _) => { + hir::StmtKind::Expr(ref expr) => { self.space_if_not_bol()?; self.print_expr(&expr)?; } - hir::StmtKind::Semi(ref expr, _) => { + hir::StmtKind::Semi(ref expr) => { self.space_if_not_bol()?; self.print_expr(&expr)?; self.s.word(";")?; @@ -2401,13 +2401,13 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { /// seen the semicolon, and thus don't need another. fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool { match *stmt { - hir::StmtKind::Decl(ref d, _) => { + hir::StmtKind::Decl(ref d) => { match d.node { hir::DeclKind::Local(_) => true, hir::DeclKind::Item(_) => false, } } - hir::StmtKind::Expr(ref e, _) => { + hir::StmtKind::Expr(ref e) => { expr_requires_semi_to_be_stmt(&e) } hir::StmtKind::Semi(..) => { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 8ff60e5f56225..4da99f3c0f4b9 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -483,7 +483,12 @@ impl_stable_hash_for!(enum hir::UnOp { UnNeg }); -impl_stable_hash_for_spanned!(hir::StmtKind); +impl_stable_hash_for!(struct hir::Stmt { + id, + node, + span, +}); + impl_stable_hash_for!(struct hir::Local { pat, @@ -941,9 +946,9 @@ impl_stable_hash_for!(enum hir::ForeignItemKind { }); impl_stable_hash_for!(enum hir::StmtKind { - Decl(decl, id), - Expr(expr, id), - Semi(expr, id) + Decl(decl), + Expr(expr), + Semi(expr) }); impl_stable_hash_for!(struct hir::Arg { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c1aa25b6b75c2..0a65ce6fe8468 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -589,7 +589,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn walk_stmt(&mut self, stmt: &hir::Stmt) { match stmt.node { - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { match decl.node { hir::DeclKind::Local(ref local) => { self.walk_local(&local); @@ -602,8 +602,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } } - hir::StmtKind::Expr(ref expr, _) | - hir::StmtKind::Semi(ref expr, _) => { + hir::StmtKind::Expr(ref expr) | + hir::StmtKind::Semi(ref expr) => { self.consume_expr(&expr); } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a78cf1a471b4b..190d3d1eb5096 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -956,11 +956,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode) -> LiveNode { match stmt.node { - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { self.propagate_through_decl(&decl, succ) } - hir::StmtKind::Expr(ref expr, _) | hir::StmtKind::Semi(ref expr, _) => { + hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { self.propagate_through_expr(&expr, succ) } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index ce2a348950622..76fbe2119f310 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -835,7 +835,7 @@ fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: & } fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) { - let stmt_id = visitor.tcx.hir().node_to_hir_id(stmt.node.id()).local_id; + let stmt_id = visitor.tcx.hir().node_to_hir_id(stmt.id).local_id; debug!("resolve_stmt(stmt.id={:?})", stmt_id); // Every statement will clean up the temporaries created during diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 205f8941d1ee2..587b28b3edde2 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -41,7 +41,7 @@ impl LintPass for UnusedResults { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { let expr = match s.node { - hir::StmtKind::Semi(ref expr, _) => &**expr, + hir::StmtKind::Semi(ref expr) => &**expr, _ => return, }; @@ -205,7 +205,7 @@ impl LintPass for PathStatements { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements { fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { - if let hir::StmtKind::Semi(ref expr, _) = s.node { + if let hir::StmtKind::Semi(ref expr) = s.node { if let hir::ExprKind::Path(_) = expr.node { cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect"); } diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index ea8b2826732b4..6fd31ffba3997 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -46,12 +46,12 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> Vec> { let mut result = vec![]; for (index, stmt) in stmts.iter().enumerate() { - let hir_id = cx.tcx.hir().node_to_hir_id(stmt.node.id()); + let hir_id = cx.tcx.hir().node_to_hir_id(stmt.id); let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id); - let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.node.id())); + let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.id)); match stmt.node { - hir::StmtKind::Expr(ref expr, _) | - hir::StmtKind::Semi(ref expr, _) => { + hir::StmtKind::Expr(ref expr) | + hir::StmtKind::Semi(ref expr) => { result.push(StmtRef::Mirror(Box::new(Stmt { kind: StmtKind::Expr { scope: region::Scope { @@ -64,7 +64,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, span: stmt_span, }))) } - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { match decl.node { hir::DeclKind::Item(..) => { // ignore for purposes of the MIR diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 604b31e7167a9..f97f7dcf17f4e 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -144,7 +144,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { } fn visit_stmt(&mut self, s: &'v hir::Stmt) { - self.record("Stmt", Id::Node(s.node.id()), s); + self.record("Stmt", Id::Node(s.id), s); hir_visit::walk_stmt(self, s) } diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index f0b559f80a28c..4831232a9f919 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -220,7 +220,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_stmt(&mut self, stmt: &'tcx hir::Stmt) -> Promotability { match stmt.node { - hir::StmtKind::Decl(ref decl, _node_id) => { + hir::StmtKind::Decl(ref decl) => { match &decl.node { hir::DeclKind::Local(local) => { if self.remove_mut_rvalue_borrow(&local.pat) { @@ -238,8 +238,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { hir::DeclKind::Item(_) => Promotable } } - hir::StmtKind::Expr(ref box_expr, _node_id) | - hir::StmtKind::Semi(ref box_expr, _node_id) => { + hir::StmtKind::Expr(ref box_expr) | + hir::StmtKind::Semi(ref box_expr) => { let _ = self.check_expr(box_expr); NotPromotable } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..ba97c3d2549af 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4840,7 +4840,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) { // Don't do all the complex logic below for `DeclItem`. match stmt.node { - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { if let hir::DeclKind::Item(_) = decl.node { return } @@ -4848,7 +4848,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {} } - self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement"); + self.warn_if_unreachable(stmt.id, stmt.span, "statement"); // Hide the outer diverging and `has_errors` flags. let old_diverges = self.diverges.get(); @@ -4857,7 +4857,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.has_errors.set(false); match stmt.node { - hir::StmtKind::Decl(ref decl, _) => { + hir::StmtKind::Decl(ref decl) => { match decl.node { hir::DeclKind::Local(ref l) => { self.check_decl_local(&l); @@ -4866,11 +4866,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::DeclKind::Item(_) => () } } - hir::StmtKind::Expr(ref expr, _) => { + hir::StmtKind::Expr(ref expr) => { // Check with expected type of `()`. self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit()); } - hir::StmtKind::Semi(ref expr, _) => { + hir::StmtKind::Semi(ref expr) => { self.check_expr(&expr); } } @@ -5273,7 +5273,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None => return None, }; let last_expr = match last_stmt.node { - hir::StmtKind::Semi(ref e, _) => e, + hir::StmtKind::Semi(ref e) => e, _ => return None, }; let last_expr_ty = self.node_ty(last_expr.hir_id); From 0edc5c9779cbe5a3d244f3915ebb05813973e592 Mon Sep 17 00:00:00 2001 From: AB1908 Date: Wed, 16 Jan 2019 23:08:42 +0000 Subject: [PATCH 0109/1064] Fix error template --- src/test/ui/issue-53787-inline-assembler-macro.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issue-53787-inline-assembler-macro.stderr index f63b2e1932754..69f380bdc9c03 100644 --- a/src/test/ui/issue-53787-inline-assembler-macro.stderr +++ b/src/test/ui/issue-53787-inline-assembler-macro.stderr @@ -1,5 +1,5 @@ error[E0669]: invalid value for constraint in inline assembly - --> $DIR/issue-53787-inline-assembler-macro.rs:22:16 + --> $DIR/issue-53787-inline-assembler-macro.rs:21:16 | LL | fake_jump!("FirstFunc"); //~ ERROR invalid value for constraint in inline assembly | ^^^^^^^^^^^ From da06898a7539ff66e636a5bf9d3b176b865a2737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 16 Jan 2019 19:34:37 +0100 Subject: [PATCH 0110/1064] Avoid erase_regions_ty queries if there are no regions to erase It's overall faster to perform this extra check than to perform the query, even if the result is already in the query cache. --- src/librustc/ty/erase_regions.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs index bbf71c62ca69d..da7e021b2d54b 100644 --- a/src/librustc/ty/erase_regions.rs +++ b/src/librustc/ty/erase_regions.rs @@ -1,4 +1,4 @@ -use ty::{self, Ty, TyCtxt}; +use ty::{self, Ty, TyCtxt, TypeFlags}; use ty::fold::{TypeFolder, TypeFoldable}; pub(super) fn provide(providers: &mut ty::query::Providers<'_>) { @@ -21,6 +21,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn erase_regions(self, value: &T) -> T where T : TypeFoldable<'tcx> { + // If there's nothing to erase avoid performing the query at all + if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { + return value.clone(); + } + let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); debug!("erase_regions({:?}) = {:?}", value, value1); value1 From e4e888534eae603dfd0d9f9e75e8bb21d5e35f06 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 17 Jan 2019 00:39:15 +0100 Subject: [PATCH 0111/1064] Document Unpin in std::prelude documentation --- src/libstd/prelude/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index ec8318f3728eb..bf689bad559d3 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -44,8 +44,8 @@ //! The current version of the prelude (version 1) lives in //! [`std::prelude::v1`], and re-exports the following. //! -//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`]}. The marker -//! traits indicate fundamental properties of types. +//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`], [`Unpin`]}. The +//! marker traits indicate fundamental properties of types. //! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}. Various //! operations for both destructors and overloading `()`. //! * [`std::mem`]::[`drop`][`mem::drop`], a convenience function for explicitly @@ -108,6 +108,7 @@ //! [`Sync`]: ../marker/trait.Sync.html //! [`ToOwned`]: ../borrow/trait.ToOwned.html //! [`ToString`]: ../string/trait.ToString.html +//! [`Unpin`]: ../marker/trait.Unpin.html //! [`Vec`]: ../vec/struct.Vec.html //! [`Clone::clone`]: ../clone/trait.Clone.html#tymethod.clone //! [`mem::drop`]: ../mem/fn.drop.html From afbd004d696063adf1301ae461c41565f2f1921a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 17 Jan 2019 10:39:24 +1100 Subject: [PATCH 0112/1064] Remove `hir::StmtKind::Decl`. It's a level of indirection that hurts far more than it helps. The code is simpler without it. (This commit cuts more than 120 lines of code.) In particular, this commit removes some unnecessary `Span`s within `DeclKind` that were always identical to those in the enclosing `Stmt`, and some unnecessary allocations via `P`. --- src/librustc/cfg/construct.rs | 29 ++++----- src/librustc/hir/check_attr.rs | 4 +- src/librustc/hir/intravisit.rs | 15 +---- src/librustc/hir/lowering.rs | 34 +++-------- src/librustc/hir/mod.rs | 35 ++--------- src/librustc/hir/print.rs | 59 +++++++----------- src/librustc/ich/impls_hir.rs | 9 +-- src/librustc/lint/context.rs | 5 -- src/librustc/lint/mod.rs | 1 - src/librustc/middle/expr_use_visitor.rs | 16 ++--- src/librustc/middle/liveness.rs | 51 ++++++---------- src/librustc/middle/region.rs | 33 +++++----- src/librustc_mir/hair/cx/block.rs | 80 ++++++++++++------------- src/librustc_passes/hir_stats.rs | 5 -- src/librustc_passes/rvalue_promotion.rs | 26 ++++---- src/librustc_typeck/check/mod.rs | 20 ++----- 16 files changed, 150 insertions(+), 272 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 1cbfcc1664323..6122fe6370940 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -100,29 +100,20 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex { let hir_id = self.tcx.hir().node_to_hir_id(stmt.id); - match stmt.node { - hir::StmtKind::Decl(ref decl) => { - let exit = self.decl(&decl, pred); - self.add_ast_node(hir_id.local_id, &[exit]) + let exit = match stmt.node { + hir::StmtKind::Local(ref local) => { + let init_exit = self.opt_expr(&local.init, pred); + self.pat(&local.pat, init_exit) + } + hir::StmtKind::Item(_) => { + pred } - hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { - let exit = self.expr(&expr, pred); - self.add_ast_node(hir_id.local_id, &[exit]) + self.expr(&expr, pred) } - } - } - - fn decl(&mut self, decl: &hir::Decl, pred: CFGIndex) -> CFGIndex { - match decl.node { - hir::DeclKind::Local(ref local) => { - let init_exit = self.opt_expr(&local.init, pred); - self.pat(&local.pat, init_exit) - } - - hir::DeclKind::Item(_) => pred, - } + }; + self.add_ast_node(hir_id.local_id, &[exit]) } fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex { diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 1cffe5ace5a6e..9fa5f4aabe512 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -298,8 +298,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { fn check_stmt_attributes(&self, stmt: &hir::Stmt) { // When checking statements ignore expressions, they will be checked later - if let hir::StmtKind::Decl(..) = stmt.node { - for attr in stmt.node.attrs() { + if let hir::StmtKind::Local(ref l) = stmt.node { + for attr in l.attrs.iter() { if attr.check_name("inline") { self.check_inline(attr, &stmt.span, Target::Statement); } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 3b9358d7c46a9..a3eda804aa70c 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -260,9 +260,6 @@ pub trait Visitor<'v> : Sized { fn visit_pat(&mut self, p: &'v Pat) { walk_pat(self, p) } - fn visit_decl(&mut self, d: &'v Decl) { - walk_decl(self, d) - } fn visit_anon_const(&mut self, c: &'v AnonConst) { walk_anon_const(self, c) } @@ -955,9 +952,8 @@ pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { visitor.visit_id(statement.id); match statement.node { - StmtKind::Decl(ref declaration) => { - visitor.visit_decl(declaration) - } + StmtKind::Local(ref local) => visitor.visit_local(local), + StmtKind::Item(ref item) => visitor.visit_nested_item(**item), StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { visitor.visit_expr(expression) @@ -965,13 +961,6 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { } } -pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) { - match declaration.node { - DeclKind::Local(ref local) => visitor.visit_local(local), - DeclKind::Item(item) => visitor.visit_nested_item(item), - } -} - pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) { visitor.visit_id(constant.id); visitor.visit_nested_body(constant.body); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 837960a0f1d95..02e66300f24d9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1957,7 +1957,7 @@ impl<'a> LoweringContext<'a> { ) } - fn lower_local(&mut self, l: &Local) -> (P, SmallVec<[hir::ItemId; 1]>) { + fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[hir::ItemId; 1]>) { let LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id); let mut ids = SmallVec::<[hir::ItemId; 1]>::new(); if self.sess.features_untracked().impl_trait_in_bindings { @@ -1967,7 +1967,7 @@ impl<'a> LoweringContext<'a> { } } let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0); - (P(hir::Local { + (hir::Local { id: node_id, hir_id, ty: l.ty @@ -1984,7 +1984,7 @@ impl<'a> LoweringContext<'a> { span: l.span, attrs: l.attrs.clone(), source: hir::LocalSource::Normal, - }), ids) + }, ids) } fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability { @@ -4537,23 +4537,13 @@ impl<'a> LoweringContext<'a> { .into_iter() .map(|item_id| hir::Stmt { id: self.next_id().node_id, - node: hir::StmtKind::Decl( - P(Spanned { - node: hir::DeclKind::Item(item_id), - span: s.span, - }), - ), + node: hir::StmtKind::Item(P(item_id)), span: s.span, }) .collect(); ids.push(hir::Stmt { id: self.lower_node_id(s.id).node_id, - node: hir::StmtKind::Decl( - P(Spanned { - node: hir::DeclKind::Local(l), - span: s.span, - }), - ), + node: hir::StmtKind::Local(P(l)), span: s.span, }); return ids; @@ -4567,12 +4557,7 @@ impl<'a> LoweringContext<'a> { id: id.take() .map(|id| self.lower_node_id(id).node_id) .unwrap_or_else(|| self.next_id().node_id), - node: hir::StmtKind::Decl( - P(Spanned { - node: hir::DeclKind::Item(item_id), - span: s.span, - }), - ), + node: hir::StmtKind::Item(P(item_id)), span: s.span, }) .collect(); @@ -4799,7 +4784,7 @@ impl<'a> LoweringContext<'a> { ) -> hir::Stmt { let LoweredNodeId { node_id, hir_id } = self.next_id(); - let local = P(hir::Local { + let local = hir::Local { pat, ty: None, init: ex, @@ -4808,11 +4793,10 @@ impl<'a> LoweringContext<'a> { span: sp, attrs: ThinVec::new(), source, - }); - let decl = respan(sp, hir::DeclKind::Local(local)); + }; hir::Stmt { id: self.next_id().node_id, - node: hir::StmtKind::Decl(P(decl)), + node: hir::StmtKind::Local(P(local)), span: sp } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1e287ccc85c78..5660b879c9733 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1160,8 +1160,10 @@ impl fmt::Debug for Stmt { #[derive(Clone, RustcEncodable, RustcDecodable)] pub enum StmtKind { - /// Could be an item or a local (let) binding: - Decl(P), + /// A local (let) binding: + Local(P), + /// An item binding: + Item(P), /// Expr without trailing semi-colon (must have unit type): Expr(P), @@ -1173,7 +1175,8 @@ pub enum StmtKind { impl StmtKind { pub fn attrs(&self) -> &[Attribute] { match *self { - StmtKind::Decl(ref d) => d.node.attrs(), + StmtKind::Local(ref l) => &l.attrs, + StmtKind::Item(_) => &[], StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => &e.attrs, } @@ -1194,32 +1197,6 @@ pub struct Local { pub source: LocalSource, } -pub type Decl = Spanned; - -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub enum DeclKind { - /// A local (let) binding: - Local(P), - /// An item binding: - Item(ItemId), -} - -impl DeclKind { - pub fn attrs(&self) -> &[Attribute] { - match *self { - DeclKind::Local(ref l) => &l.attrs, - DeclKind::Item(_) => &[] - } - } - - pub fn is_local(&self) -> bool { - match *self { - DeclKind::Local(_) => true, - _ => false, - } - } -} - /// represents one arm of a 'match' #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Arm { diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index d92800c7b9537..e950f25c2ac9a 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -992,8 +992,23 @@ impl<'a> State<'a> { pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> { self.maybe_print_comment(st.span.lo())?; match st.node { - hir::StmtKind::Decl(ref decl) => { - self.print_decl(&decl)?; + hir::StmtKind::Local(ref loc) => { + self.space_if_not_bol()?; + self.ibox(indent_unit)?; + self.word_nbsp("let")?; + + self.ibox(indent_unit)?; + self.print_local_decl(&loc)?; + self.end()?; + if let Some(ref init) = loc.init { + self.nbsp()?; + self.word_space("=")?; + self.print_expr(&init)?; + } + self.end()? + } + hir::StmtKind::Item(ref item) => { + self.ann.nested(self, Nested::Item(**item))? } hir::StmtKind::Expr(ref expr) => { self.space_if_not_bol()?; @@ -1562,30 +1577,6 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> { - self.maybe_print_comment(decl.span.lo())?; - match decl.node { - hir::DeclKind::Local(ref loc) => { - self.space_if_not_bol()?; - self.ibox(indent_unit)?; - self.word_nbsp("let")?; - - self.ibox(indent_unit)?; - self.print_local_decl(&loc)?; - self.end()?; - if let Some(ref init) = loc.init { - self.nbsp()?; - self.word_space("=")?; - self.print_expr(&init)?; - } - self.end() - } - hir::DeclKind::Item(item) => { - self.ann.nested(self, Nested::Item(item)) - } - } - } - pub fn print_usize(&mut self, i: usize) -> io::Result<()> { self.s.word(i.to_string()) } @@ -2401,18 +2392,10 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { /// seen the semicolon, and thus don't need another. fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool { match *stmt { - hir::StmtKind::Decl(ref d) => { - match d.node { - hir::DeclKind::Local(_) => true, - hir::DeclKind::Item(_) => false, - } - } - hir::StmtKind::Expr(ref e) => { - expr_requires_semi_to_be_stmt(&e) - } - hir::StmtKind::Semi(..) => { - false - } + hir::StmtKind::Local(_) => true, + hir::StmtKind::Item(_) => false, + hir::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(&e), + hir::StmtKind::Semi(..) => false, } } diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 4da99f3c0f4b9..9aa8e4c229f47 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -501,12 +501,6 @@ impl_stable_hash_for!(struct hir::Local { source }); -impl_stable_hash_for_spanned!(hir::DeclKind); -impl_stable_hash_for!(enum hir::DeclKind { - Local(local), - Item(item_id) -}); - impl_stable_hash_for!(struct hir::Arm { attrs, pats, @@ -946,7 +940,8 @@ impl_stable_hash_for!(enum hir::ForeignItemKind { }); impl_stable_hash_for!(enum hir::StmtKind { - Decl(decl), + Local(local), + Item(item_id), Expr(expr), Semi(expr) }); diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index f5a7919ef09c8..837a3645d1c94 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -941,11 +941,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { hir_visit::walk_arm(self, a); } - fn visit_decl(&mut self, d: &'tcx hir::Decl) { - run_lints!(self, check_decl, d); - hir_visit::walk_decl(self, d); - } - fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam) { run_lints!(self, check_generic_param, p); hir_visit::walk_generic_param(self, p); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index a373faab3a204..3caa88dbc898e 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -191,7 +191,6 @@ macro_rules! late_lint_methods { fn check_stmt(a: &$hir hir::Stmt); fn check_arm(a: &$hir hir::Arm); fn check_pat(a: &$hir hir::Pat); - fn check_decl(a: &$hir hir::Decl); fn check_expr(a: &$hir hir::Expr); fn check_expr_post(a: &$hir hir::Expr); fn check_ty(a: &$hir hir::Ty); diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 0a65ce6fe8468..08210c3f075ce 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -589,17 +589,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn walk_stmt(&mut self, stmt: &hir::Stmt) { match stmt.node { - hir::StmtKind::Decl(ref decl) => { - match decl.node { - hir::DeclKind::Local(ref local) => { - self.walk_local(&local); - } + hir::StmtKind::Local(ref local) => { + self.walk_local(&local); + } - hir::DeclKind::Item(_) => { - // we don't visit nested items in this visitor, - // only the fn body we were given. - } - } + hir::StmtKind::Item(_) => { + // we don't visit nested items in this visitor, + // only the fn body we were given. } hir::StmtKind::Expr(ref expr) | diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 190d3d1eb5096..13464242f1ced 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -956,46 +956,31 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode) -> LiveNode { match stmt.node { - hir::StmtKind::Decl(ref decl) => { - self.propagate_through_decl(&decl, succ) - } + hir::StmtKind::Local(ref local) => { + // Note: we mark the variable as defined regardless of whether + // there is an initializer. Initially I had thought to only mark + // the live variable as defined if it was initialized, and then we + // could check for uninit variables just by scanning what is live + // at the start of the function. But that doesn't work so well for + // immutable variables defined in a loop: + // loop { let x; x = 5; } + // because the "assignment" loops back around and generates an error. + // + // So now we just check that variables defined w/o an + // initializer are not live at the point of their + // initialization, which is mildly more complex than checking + // once at the func header but otherwise equivalent. + let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ); + self.define_bindings_in_pat(&local.pat, succ) + } + hir::StmtKind::Item(..) => succ, hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { self.propagate_through_expr(&expr, succ) } } } - fn propagate_through_decl(&mut self, decl: &hir::Decl, succ: LiveNode) - -> LiveNode { - match decl.node { - hir::DeclKind::Local(ref local) => { - self.propagate_through_local(&local, succ) - } - hir::DeclKind::Item(_) => succ, - } - } - - fn propagate_through_local(&mut self, local: &hir::Local, succ: LiveNode) - -> LiveNode { - // Note: we mark the variable as defined regardless of whether - // there is an initializer. Initially I had thought to only mark - // the live variable as defined if it was initialized, and then we - // could check for uninit variables just by scanning what is live - // at the start of the function. But that doesn't work so well for - // immutable variables defined in a loop: - // loop { let x; x = 5; } - // because the "assignment" loops back around and generates an error. - // - // So now we just check that variables defined w/o an - // initializer are not live at the point of their - // initialization, which is mildly more complex than checking - // once at the func header but otherwise equivalent. - - let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ); - self.define_bindings_in_pat(&local.pat, succ) - } - fn propagate_through_exprs(&mut self, exprs: &[Expr], succ: LiveNode) -> LiveNode { exprs.iter().rev().fold(succ, |succ, expr| { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 76fbe2119f310..819dd8aa7d53e 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -784,20 +784,25 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk: // index information.) for (i, statement) in blk.stmts.iter().enumerate() { - if let hir::StmtKind::Decl(..) = statement.node { - // Each StmtKind::Decl introduces a subscope for bindings - // introduced by the declaration; this subscope covers - // a suffix of the block . Each subscope in a block - // has the previous subscope in the block as a parent, - // except for the first such subscope, which has the - // block itself as a parent. - visitor.enter_scope( - Scope { - id: blk.hir_id.local_id, - data: ScopeData::Remainder(FirstStatementIndex::new(i)) - } - ); - visitor.cx.var_parent = visitor.cx.parent; + match statement.node { + hir::StmtKind::Local(..) | + hir::StmtKind::Item(..) => { + // Each declaration introduces a subscope for bindings + // introduced by the declaration; this subscope covers a + // suffix of the block. Each subscope in a block has the + // previous subscope in the block as a parent, except for + // the first such subscope, which has the block itself as a + // parent. + visitor.enter_scope( + Scope { + id: blk.hir_id.local_id, + data: ScopeData::Remainder(FirstStatementIndex::new(i)) + } + ); + visitor.cx.var_parent = visitor.cx.parent; + } + hir::StmtKind::Expr(..) | + hir::StmtKind::Semi(..) => {} } visitor.visit_stmt(statement) } diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 6fd31ffba3997..c50d9ddcb152e 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -64,52 +64,48 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, span: stmt_span, }))) } - hir::StmtKind::Decl(ref decl) => { - match decl.node { - hir::DeclKind::Item(..) => { - // ignore for purposes of the MIR - } - hir::DeclKind::Local(ref local) => { - let remainder_scope = region::Scope { - id: block_id, - data: region::ScopeData::Remainder( - region::FirstStatementIndex::new(index)), - }; - - let mut pattern = cx.pattern_from_hir(&local.pat); + hir::StmtKind::Item(..) => { + // ignore for purposes of the MIR + } + hir::StmtKind::Local(ref local) => { + let remainder_scope = region::Scope { + id: block_id, + data: region::ScopeData::Remainder( + region::FirstStatementIndex::new(index)), + }; - if let Some(ty) = &local.ty { - if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) { - debug!("mirror_stmts: user_ty={:?}", user_ty); - pattern = Pattern { - ty: pattern.ty, - span: pattern.span, - kind: Box::new(PatternKind::AscribeUserType { - user_ty: PatternTypeProjection::from_user_type(user_ty), - user_ty_span: ty.span, - subpattern: pattern, - variance: ty::Variance::Covariant, - }) - }; - } - } + let mut pattern = cx.pattern_from_hir(&local.pat); - result.push(StmtRef::Mirror(Box::new(Stmt { - kind: StmtKind::Let { - remainder_scope: remainder_scope, - init_scope: region::Scope { - id: hir_id.local_id, - data: region::ScopeData::Node - }, - pattern, - initializer: local.init.to_ref(), - lint_level: cx.lint_level_of(local.id), - }, - opt_destruction_scope: opt_dxn_ext, - span: stmt_span, - }))); + if let Some(ty) = &local.ty { + if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) { + debug!("mirror_stmts: user_ty={:?}", user_ty); + pattern = Pattern { + ty: pattern.ty, + span: pattern.span, + kind: Box::new(PatternKind::AscribeUserType { + user_ty: PatternTypeProjection::from_user_type(user_ty), + user_ty_span: ty.span, + subpattern: pattern, + variance: ty::Variance::Covariant, + }) + }; } } + + result.push(StmtRef::Mirror(Box::new(Stmt { + kind: StmtKind::Let { + remainder_scope: remainder_scope, + init_scope: region::Scope { + id: hir_id.local_id, + data: region::ScopeData::Node + }, + pattern, + initializer: local.init.to_ref(), + lint_level: cx.lint_level_of(local.id), + }, + opt_destruction_scope: opt_dxn_ext, + span: stmt_span, + }))); } } } diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index f97f7dcf17f4e..74d6d75a7f528 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -158,11 +158,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_pat(self, p) } - fn visit_decl(&mut self, d: &'v hir::Decl) { - self.record("Decl", Id::None, d); - hir_visit::walk_decl(self, d) - } - fn visit_expr(&mut self, ex: &'v hir::Expr) { self.record("Expr", Id::Node(ex.id), ex); hir_visit::walk_expr(self, ex) diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 4831232a9f919..49914dc7078fd 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -220,24 +220,20 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_stmt(&mut self, stmt: &'tcx hir::Stmt) -> Promotability { match stmt.node { - hir::StmtKind::Decl(ref decl) => { - match &decl.node { - hir::DeclKind::Local(local) => { - if self.remove_mut_rvalue_borrow(&local.pat) { - if let Some(init) = &local.init { - self.mut_rvalue_borrows.insert(init.id); - } - } - - if let Some(ref expr) = local.init { - let _ = self.check_expr(&expr); - } - NotPromotable + hir::StmtKind::Local(ref local) => { + if self.remove_mut_rvalue_borrow(&local.pat) { + if let Some(init) = &local.init { + self.mut_rvalue_borrows.insert(init.id); } - // Item statements are allowed - hir::DeclKind::Item(_) => Promotable } + + if let Some(ref expr) = local.init { + let _ = self.check_expr(&expr); + } + NotPromotable } + // Item statements are allowed + hir::StmtKind::Item(..) => Promotable, hir::StmtKind::Expr(ref box_expr) | hir::StmtKind::Semi(ref box_expr) => { let _ = self.check_expr(box_expr); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ba97c3d2549af..daade27768ae3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4840,12 +4840,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) { // Don't do all the complex logic below for `DeclItem`. match stmt.node { - hir::StmtKind::Decl(ref decl) => { - if let hir::DeclKind::Item(_) = decl.node { - return - } - } - hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {} + hir::StmtKind::Item(..) => return, + hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {} } self.warn_if_unreachable(stmt.id, stmt.span, "statement"); @@ -4857,15 +4853,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.has_errors.set(false); match stmt.node { - hir::StmtKind::Decl(ref decl) => { - match decl.node { - hir::DeclKind::Local(ref l) => { - self.check_decl_local(&l); - } - // Ignore for now. - hir::DeclKind::Item(_) => () - } + hir::StmtKind::Local(ref l) => { + self.check_decl_local(&l); } + // Ignore for now. + hir::StmtKind::Item(_) => {} hir::StmtKind::Expr(ref expr) => { // Check with expected type of `()`. self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit()); From 22251a87be74865cc977f3fdcc995c1c467361c7 Mon Sep 17 00:00:00 2001 From: Alexander Ronald Altman Date: Wed, 16 Jan 2019 20:10:18 -0600 Subject: [PATCH 0113/1064] Enhance `Pin` impl applicability for `PartialEq` and `PartialOrd`. --- src/libcore/pin.rs | 50 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 762e07549a52a..022481f463514 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -99,6 +99,7 @@ use fmt; use marker::{Sized, Unpin}; +use cmp::{self, PartialEq, PartialOrd}; use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn}; /// A pinned pointer. @@ -112,16 +113,59 @@ use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn}; /// [`Unpin`]: ../../std/marker/trait.Unpin.html /// [`pin` module]: ../../std/pin/index.html // -// Note: the derives below are allowed because they all only use `&P`, so they -// cannot move the value behind `pointer`. +// Note: the derives below, and the explicit `PartialEq` and `PartialOrd` +// implementations, are allowed because they all only use `&P`, so they cannot move +// the value behind `pointer`. #[stable(feature = "pin", since = "1.33.0")] #[fundamental] #[repr(transparent)] -#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Copy, Clone, Hash, Eq, Ord)] pub struct Pin

{ pointer: P, } +#[stable(feature = "pin_partialeq_partialord_impl_applicability", since = "1.34.0")] +impl PartialEq> for Pin

+where + P: PartialEq, +{ + + fn eq(&self, other: &Pin) -> bool { + self.pointer == other.pointer + } + + fn ne(&self, other: &Pin) -> bool { + self.pointer != other.pointer + } +} + +#[stable(feature = "pin_partialeq_partialord_impl_applicability", since = "1.34.0")] +impl PartialOrd> for Pin

+where + P: PartialOrd, +{ + + fn partial_cmp(&self, other: &Pin) -> Option { + self.pointer.partial_cmp(&other.pointer) + } + + fn lt(&self, other: &Pin) -> bool { + self.pointer < other.pointer + } + + fn le(&self, other: &Pin) -> bool { + self.pointer <= other.pointer + } + + fn gt(&self, other: &Pin) -> bool { + self.pointer > other.pointer + } + + fn ge(&self, other: &Pin) -> bool { + self.pointer >= other.pointer + } +} + impl Pin

where P::Target: Unpin, From 1e3f475d643603b9570710b13e20de587a22a5ea Mon Sep 17 00:00:00 2001 From: AB1908 Date: Thu, 17 Jan 2019 03:40:36 +0000 Subject: [PATCH 0114/1064] Add test for linking non-existent static library --- src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs | 6 ++++++ .../ui/feature-gate/feature-gate-static-nobundle-2.stderr | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs create mode 100644 src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs new file mode 100644 index 0000000000000..92844f9306d28 --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs @@ -0,0 +1,6 @@ +//~ ERROR kind="static-nobundle" is feature gated +// Test the behavior of rustc when non-existent library is statically linked + +// compile-flags: -l static-nobundle=nonexistent + +fn main() {} diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr new file mode 100644 index 0000000000000..419c21901a02f --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr @@ -0,0 +1,7 @@ +error[E0658]: kind="static-nobundle" is feature gated (see issue #37403) + | + = help: add #![feature(static_nobundle)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From fefe1dacb6255304dab5c13fb669b1d9d40f9e03 Mon Sep 17 00:00:00 2001 From: Alexander Ronald Altman Date: Wed, 16 Jan 2019 23:03:29 -0600 Subject: [PATCH 0115/1064] Fix tidy errors. --- src/libcore/pin.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 022481f463514..7c09a36d89883 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -129,7 +129,6 @@ impl PartialEq> for Pin

where P: PartialEq, { - fn eq(&self, other: &Pin) -> bool { self.pointer == other.pointer } @@ -144,7 +143,6 @@ impl PartialOrd> for Pin

where P: PartialOrd, { - fn partial_cmp(&self, other: &Pin) -> Option { self.pointer.partial_cmp(&other.pointer) } From 6c8fdf971cb226a14491dba974ec50812a52e983 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 7 Jan 2019 10:04:30 +0100 Subject: [PATCH 0116/1064] Remove access level mention from DocContext Leftover from https://github.com/rust-lang/rust/commit/c754e8240cfbeeaca1672c349eccba3d050f866c. --- src/librustdoc/core.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 78dbf41bf21fd..6c3a973a41484 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -51,9 +51,6 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { /// The stack of module NodeIds up till this point pub crate_name: Option, pub cstore: Rc, - // Note that external items for which `doc(hidden)` applies to are shown as - // non-reachable while local items aren't. This is because we're reusing - // the access levels from crateanalysis. /// Later on moved into `html::render::CACHE_KEY` pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` From 6f1d06d21989e7b606a0c980a9fa99ffdafb91a2 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 7 Jan 2019 11:46:44 +0100 Subject: [PATCH 0117/1064] Querify glob map usage (last use of CrateAnalysis) --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/context.rs | 10 +++++++++ src/librustc/ty/mod.rs | 13 ++--------- src/librustc/ty/query/mod.rs | 2 ++ src/librustc/ty/query/plumbing.rs | 1 + src/librustc_driver/driver.rs | 26 +++++----------------- src/librustc_driver/lib.rs | 2 -- src/librustc_driver/pretty.rs | 16 +++---------- src/librustc_save_analysis/dump_visitor.rs | 9 +++----- src/librustc_save_analysis/lib.rs | 3 --- src/librustdoc/core.rs | 7 ++---- src/librustdoc/html/render.rs | 2 +- 12 files changed, 30 insertions(+), 62 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 427fe51e6ff9c..3cc780ec34273 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -630,6 +630,7 @@ define_dep_nodes!( <'tcx> [input] Freevars(DefId), [input] MaybeUnusedTraitImport(DefId), [input] MaybeUnusedExternCrates, + [input] NamesImportedByGlobUse(DefId), [eval_always] StabilityIndex, [eval_always] AllTraits, [input] AllCrateNums, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d69219efbd884..e37eab622df3f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -983,6 +983,9 @@ pub struct GlobalCtxt<'tcx> { maybe_unused_trait_imports: FxHashSet, maybe_unused_extern_crates: Vec<(DefId, Span)>, + /// A map of glob use to a set of names it actually imports. Currently only + /// used in save-analysis. + glob_map: FxHashMap>, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, @@ -1232,6 +1235,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .into_iter() .map(|(id, sp)| (hir.local_def_id(id), sp)) .collect(), + glob_map: resolutions.glob_map.into_iter().map(|(id, names)| { + (hir.local_def_id(id), names) + }).collect(), extern_prelude: resolutions.extern_prelude, hir_map: hir, def_path_hash_to_def_id, @@ -2972,6 +2978,10 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { assert_eq!(cnum, LOCAL_CRATE); Lrc::new(tcx.maybe_unused_extern_crates.clone()) }; + providers.names_imported_by_glob_use = |tcx, id| { + assert_eq!(id.krate, LOCAL_CRATE); + Lrc::new(tcx.glob_map.get(&id).cloned().unwrap_or_default()) + }; providers.stability_index = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 26b4735d926a5..f1b36e8def88b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -4,7 +4,7 @@ pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::fold::TypeFoldable; -use hir::{map as hir_map, FreevarMap, TraitMap}; +use hir::{map as hir_map, FreevarMap, GlobMap, TraitMap}; use hir::Node; use hir::def::{Def, CtorKind, ExportMap}; use hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -115,16 +115,6 @@ mod sty; // Data types -/// The complete set of all analyses described in this module. This is -/// produced by the driver and fed to codegen and later passes. -/// -/// N.B., these contents are being migrated into queries using the -/// *on-demand* infrastructure. -#[derive(Clone)] -pub struct CrateAnalysis { - pub glob_map: hir::GlobMap, -} - #[derive(Clone)] pub struct Resolutions { pub freevars: FreevarMap, @@ -132,6 +122,7 @@ pub struct Resolutions { pub maybe_unused_trait_imports: NodeSet, pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, pub export_map: ExportMap, + pub glob_map: GlobMap, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 39d76ceed9507..27b67487637c7 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -541,6 +541,8 @@ define_queries! { <'tcx> [] fn maybe_unused_trait_import: MaybeUnusedTraitImport(DefId) -> bool, [] fn maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum) -> Lrc>, + [] fn names_imported_by_glob_use: NamesImportedByGlobUse(DefId) + -> Lrc>, [] fn stability_index: stability_index_node(CrateNum) -> Lrc>, [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc>, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 562cd75a75ff4..681376eaa2acd 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1413,6 +1413,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::MaybeUnusedTraitImport => { force!(maybe_unused_trait_import, def_id!()); } + DepKind::NamesImportedByGlobUse => { force!(names_imported_by_glob_use, def_id!()); } DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); } DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); } DepKind::AllTraits => { force!(all_traits, LOCAL_CRATE); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1ecb8ef112c9e..aa7cb0c695c3c 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -168,7 +168,6 @@ pub fn compile_input( let ExpansionResult { expanded_crate, defs, - analysis, resolutions, mut hir_forest, } = { @@ -251,7 +250,6 @@ pub fn compile_input( output, &cstore, &hir_map, - &analysis, &resolutions, &expanded_crate, &hir_map.krate(), @@ -277,12 +275,11 @@ pub fn compile_input( sess, cstore, hir_map, - analysis, resolutions, &mut arenas, &crate_name, &outputs, - |tcx, analysis, rx, result| { + |tcx, rx, result| { { // Eventually, we will want to track plugins. tcx.dep_graph.with_ignore(|| { @@ -293,7 +290,6 @@ pub fn compile_input( output, opt_crate, tcx.hir().krate(), - &analysis, tcx, &crate_name, ); @@ -527,7 +523,6 @@ pub struct CompileState<'a, 'tcx: 'a> { pub hir_crate: Option<&'a hir::Crate>, pub hir_map: Option<&'a hir_map::Map<'tcx>>, pub resolutions: Option<&'a Resolutions>, - pub analysis: Option<&'a ty::CrateAnalysis>, pub tcx: Option>, } @@ -547,7 +542,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { hir_crate: None, hir_map: None, resolutions: None, - analysis: None, tcx: None, } } @@ -595,7 +589,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { out_file: &'a Option, cstore: &'tcx CStore, hir_map: &'a hir_map::Map<'tcx>, - analysis: &'a ty::CrateAnalysis, resolutions: &'a Resolutions, krate: &'a ast::Crate, hir_crate: &'a hir::Crate, @@ -606,7 +599,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { crate_name: Some(crate_name), cstore: Some(cstore), hir_map: Some(hir_map), - analysis: Some(analysis), resolutions: Some(resolutions), expanded_crate: Some(krate), hir_crate: Some(hir_crate), @@ -623,12 +615,10 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { out_file: &'a Option, krate: Option<&'a ast::Crate>, hir_crate: &'a hir::Crate, - analysis: &'a ty::CrateAnalysis, tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_name: &'a str, ) -> Self { CompileState { - analysis: Some(analysis), tcx: Some(tcx), expanded_crate: krate, hir_crate: Some(hir_crate), @@ -711,7 +701,6 @@ fn count_nodes(krate: &ast::Crate) -> usize { pub struct ExpansionResult { pub expanded_crate: ast::Crate, pub defs: hir_map::Definitions, - pub analysis: ty::CrateAnalysis, pub resolutions: Resolutions, pub hir_forest: hir_map::Forest, } @@ -772,16 +761,13 @@ where freevars: resolver.freevars, export_map: resolver.export_map, trait_map: resolver.trait_map, + glob_map: resolver.glob_map, maybe_unused_trait_imports: resolver.maybe_unused_trait_imports, maybe_unused_extern_crates: resolver.maybe_unused_extern_crates, extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| { (ident.name, entry.introduced_by_item) }).collect(), }, - - analysis: ty::CrateAnalysis { - glob_map: resolver.glob_map - }, }), Err(x) => Err(x), } @@ -1180,7 +1166,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>( sess: &'tcx Session, cstore: &'tcx CStore, hir_map: hir_map::Map<'tcx>, - analysis: ty::CrateAnalysis, resolutions: Resolutions, arenas: &'tcx mut AllArenas<'tcx>, name: &str, @@ -1190,7 +1175,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>( where F: for<'a> FnOnce( TyCtxt<'a, 'tcx, 'tcx>, - ty::CrateAnalysis, mpsc::Receiver>, CompileResult, ) -> R, @@ -1254,7 +1238,7 @@ where match typeck::check_crate(tcx) { Ok(x) => x, Err(x) => { - f(tcx, analysis, rx, Err(x)); + f(tcx, rx, Err(x)); return Err(x); } } @@ -1307,7 +1291,7 @@ where // lint warnings and so on -- kindck used to do this abort, but // kindck is gone now). -nmatsakis if sess.err_count() > 0 { - return Ok(f(tcx, analysis, rx, sess.compile_status())); + return Ok(f(tcx, rx, sess.compile_status())); } time(sess, "death checking", || middle::dead::check_crate(tcx)); @@ -1318,7 +1302,7 @@ where time(sess, "lint checking", || lint::check_crate(tcx)); - return Ok(f(tcx, analysis, rx, tcx.sess.compile_status())); + return Ok(f(tcx, rx, tcx.sess.compile_status())); }, ) } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 010ac28cdc944..c8a5bbe8315b3 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -879,7 +879,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { pretty::print_after_hir_lowering(state.session, state.cstore.unwrap(), state.hir_map.unwrap(), - state.analysis.unwrap(), state.resolutions.unwrap(), state.input, &state.expanded_crate.take().unwrap(), @@ -940,7 +939,6 @@ pub fn enable_save_analysis(control: &mut CompileController) { time(state.session, "save analysis", || { save::process_crate(state.tcx.unwrap(), state.expanded_crate.unwrap(), - state.analysis.unwrap(), state.crate_name.unwrap(), state.input, None, diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index a9ec99358c1b2..d1108304d11d9 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -190,7 +190,6 @@ impl PpSourceMode { sess: &'tcx Session, cstore: &'tcx CStore, hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, resolutions: &Resolutions, output_filenames: &OutputFilenames, id: &str, @@ -223,12 +222,11 @@ impl PpSourceMode { sess, cstore, hir_map.clone(), - analysis.clone(), resolutions.clone(), &mut arenas, id, output_filenames, - |tcx, _, _, _| { + |tcx, _, _| { let empty_tables = ty::TypeckTables::empty(None); let annotation = TypedAnnotation { tcx, @@ -959,7 +957,6 @@ pub fn print_after_parsing(sess: &Session, pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, cstore: &'tcx CStore, hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, resolutions: &Resolutions, input: &Input, krate: &ast::Crate, @@ -972,7 +969,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, print_with_analysis(sess, cstore, hir_map, - analysis, resolutions, crate_name, output_filenames, @@ -1010,7 +1006,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, s.call_with_pp_support_hir(sess, cstore, hir_map, - analysis, resolutions, output_filenames, crate_name, @@ -1033,7 +1028,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, s.call_with_pp_support_hir(sess, cstore, hir_map, - analysis, resolutions, output_filenames, crate_name, @@ -1048,7 +1042,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, s.call_with_pp_support_hir(sess, cstore, hir_map, - analysis, resolutions, output_filenames, crate_name, @@ -1081,7 +1074,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, s.call_with_pp_support_hir(sess, cstore, hir_map, - analysis, resolutions, output_filenames, crate_name, @@ -1103,13 +1095,12 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, } // In an ideal world, this would be a public function called by the driver after -// analsysis is performed. However, we want to call `phase_3_run_analysis_passes` +// analysis is performed. However, we want to call `phase_3_run_analysis_passes` // with a different callback than the standard driver, so that isn't easy. // Instead, we call that function ourselves. fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, cstore: &'a CStore, hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, resolutions: &Resolutions, crate_name: &str, output_filenames: &OutputFilenames, @@ -1134,12 +1125,11 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, sess, cstore, hir_map.clone(), - analysis.clone(), resolutions.clone(), &mut arenas, crate_name, output_filenames, - |tcx, _, _, _| { + |tcx, _, _| { match ppm { PpmMir | PpmMirCFG => { if let Some(nodeid) = nodeid { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 05156fb51f9da..995df3802aabd 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1238,12 +1238,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { }; // Make a comma-separated list of names of imported modules. - let glob_map = &self.save_ctxt.analysis.glob_map; - let names = if glob_map.contains_key(&id) { - glob_map.get(&id).unwrap().iter().map(|n| n.to_string()).collect() - } else { - Vec::new() - }; + let def_id = self.tcx.hir().local_def_id(id); + let names = self.tcx.names_imported_by_glob_use(def_id); + let names: Vec<_> = names.iter().map(|n| n.to_string()).collect(); // Otherwise it's a span with wrong macro expansion info, which // we don't want to track anyway, since it's probably macro-internal `use` diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 4d55004a055f0..73eb5de5c76f0 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -71,7 +71,6 @@ pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, tables: &'l ty::TypeckTables<'tcx>, access_levels: &'l AccessLevels, - analysis: &'l ty::CrateAnalysis, span_utils: SpanUtils<'tcx>, config: Config, impl_counter: Cell, @@ -1120,7 +1119,6 @@ impl<'b> SaveHandler for CallbackHandler<'b> { pub fn process_crate<'l, 'tcx, H: SaveHandler>( tcx: TyCtxt<'l, 'tcx, 'tcx>, krate: &ast::Crate, - analysis: &'l ty::CrateAnalysis, cratename: &str, input: &'l Input, config: Option, @@ -1139,7 +1137,6 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( let save_ctxt = SaveContext { tcx, tables: &ty::TypeckTables::empty(None), - analysis, access_levels: &access_levels, span_utils: SpanUtils::new(&tcx.sess), config: find_config(config), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6c3a973a41484..7069f04fe188c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -465,15 +465,13 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt freevars: resolver.freevars.clone(), export_map: resolver.export_map.clone(), trait_map: resolver.trait_map.clone(), + glob_map: resolver.glob_map.clone(), maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(), maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(), extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| { (ident.name, entry.introduced_by_item) }).collect(), }; - let analysis = ty::CrateAnalysis { - glob_map: resolver.glob_map.clone(), - }; let mut arenas = AllArenas::new(); let hir_map = hir_map::map_crate(&sess, &*cstore, &mut hir_forest, &defs); @@ -489,12 +487,11 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt &sess, &*cstore, hir_map, - analysis, resolutions, &mut arenas, &name, &output_filenames, - |tcx, _, _, result| { + |tcx, _, result| { if result.is_err() { sess.fatal("Compilation failed, aborting rustdoc"); } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3a64c56fc8eeb..dc1732dbb1d80 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -309,7 +309,7 @@ pub struct Cache { // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing - // the access levels from crateanalysis. + // the access levels from the privacy check pass. pub access_levels: AccessLevels, /// The version of the crate being documented, if given from the `--crate-version` flag. From f0d3df39cbe1a3afaaabddbc5764b4057c713dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 15 Jan 2019 21:53:37 +0100 Subject: [PATCH 0118/1064] Use a faster early exit during region expansion Turns out that the equality check for regions is rather expensive, and the current early exit check works in such a way, that the comparison is even done twice. As we only really care about the case of equal scopes, we can perform a faster, more specialized check and move it up one level, so we can eventually skip the additional full comparison as well. --- src/librustc/infer/lexical_region_resolve/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 39ce8cc621b49..24ead37403138 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -236,6 +236,14 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { match *b_data { VarValue::Value(cur_region) => { + // Identical scopes can show up quite often, if the fixed point + // iteration converges slowly, skip them + if let (ReScope(a_scope), ReScope(cur_scope)) = (a_region, cur_region) { + if a_scope == cur_scope { + return false; + } + } + let mut lub = self.lub_concrete_regions(a_region, cur_region); if lub == cur_region { return false; @@ -275,12 +283,6 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { let tcx = self.tcx(); - // Equal scopes can show up quite often, if the fixed point - // iteration converges slowly, skip them - if a == b { - return a; - } - match (a, b) { (&ty::ReClosureBound(..), _) | (_, &ty::ReClosureBound(..)) From 3884cc8df480eba9bb8d19fa46e9fe6c9f9d729b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 17 Jan 2019 15:32:05 +0100 Subject: [PATCH 0119/1064] Fix typo bug in DepGraph::try_mark_green(). --- src/librustc/dep_graph/graph.rs | 2 +- .../incremental/change_name_of_static_in_fn.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/test/incremental/change_name_of_static_in_fn.rs diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 501ef01d74c6e..7384af108edbb 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -600,7 +600,7 @@ impl DepGraph { DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => { - if dep_node.extract_def_id(tcx).is_none() { + if dep_dep_node.extract_def_id(tcx).is_none() { // If the node does not exist anymore, we // just fail to mark green. return None diff --git a/src/test/incremental/change_name_of_static_in_fn.rs b/src/test/incremental/change_name_of_static_in_fn.rs new file mode 100644 index 0000000000000..5b27b6808ead2 --- /dev/null +++ b/src/test/incremental/change_name_of_static_in_fn.rs @@ -0,0 +1,17 @@ + +// revisions:rpass1 rpass2 rpass3 + +// See issue #57692. + +#![allow(warnings)] + +fn main() { + #[cfg(rpass1)] + { + static map: u64 = 0; + } + #[cfg(not(rpass1))] + { + static MAP: u64 = 0; + } +} From 02843d9eb71ad50d490afc6276f4bfe59f182624 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Thu, 17 Jan 2019 10:18:56 -0500 Subject: [PATCH 0120/1064] properly deprecate suggestion methods --- src/librustc_errors/diagnostic_builder.rs | 90 +++++++++++++-------- src/librustc_resolve/build_reduced_graph.rs | 9 ++- src/librustc_resolve/lib.rs | 9 ++- src/librustc_typeck/check/_match.rs | 9 ++- src/libsyntax/parse/parser.rs | 9 ++- 5 files changed, 86 insertions(+), 40 deletions(-) diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 7449b2b758302..736cca6bd64af 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -33,7 +33,11 @@ pub struct DiagnosticBuilder<'a> { /// it easy to declare such methods on the builder. macro_rules! forward { // Forward pattern for &self -> &Self - (pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)*) -> &Self) => { + ( + $(#[$attrs:meta])* + pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)*) -> &Self + ) => { + $(#[$attrs])* pub fn $n(&self, $($name: $ty),*) -> &Self { #[allow(deprecated)] self.diagnostic.$n($($name),*); @@ -42,7 +46,11 @@ macro_rules! forward { }; // Forward pattern for &mut self -> &mut Self - (pub fn $n:ident(&mut self, $($name:ident: $ty:ty),* $(,)*) -> &mut Self) => { + ( + $(#[$attrs:meta])* + pub fn $n:ident(&mut self, $($name:ident: $ty:ty),* $(,)*) -> &mut Self + ) => { + $(#[$attrs])* pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { #[allow(deprecated)] self.diagnostic.$n($($name),*); @@ -52,10 +60,15 @@ macro_rules! forward { // Forward pattern for &mut self -> &mut Self, with S: Into // type parameter. No obvious way to make this more generic. - (pub fn $n:ident>( - &mut self, - $($name:ident: $ty:ty),* - $(,)*) -> &mut Self) => { + ( + $(#[$attrs:meta])* + pub fn $n:ident>( + &mut self, + $($name:ident: $ty:ty),* + $(,)* + ) -> &mut Self + ) => { + $(#[$attrs])* pub fn $n>(&mut self, $($name: $ty),*) -> &mut Self { #[allow(deprecated)] self.diagnostic.$n($($name),*); @@ -177,34 +190,43 @@ impl<'a> DiagnosticBuilder<'a> { msg: &str, ) -> &mut Self); - #[deprecated(note = "Use `span_suggestion_short_with_applicability`")] - forward!(pub fn span_suggestion_short( - &mut self, - sp: Span, - msg: &str, - suggestion: String, - ) -> &mut Self); - - #[deprecated(note = "Use `multipart_suggestion_with_applicability`")] - forward!(pub fn multipart_suggestion( - &mut self, - msg: &str, - suggestion: Vec<(Span, String)>, - ) -> &mut Self); - - #[deprecated(note = "Use `span_suggestion_with_applicability`")] - forward!(pub fn span_suggestion(&mut self, - sp: Span, - msg: &str, - suggestion: String, - ) -> &mut Self); - - #[deprecated(note = "Use `span_suggestions_with_applicability`")] - forward!(pub fn span_suggestions(&mut self, - sp: Span, - msg: &str, - suggestions: Vec, - ) -> &mut Self); + forward!( + #[deprecated(note = "Use `span_suggestion_short_with_applicability`")] + pub fn span_suggestion_short( + &mut self, + sp: Span, + msg: &str, + suggestion: String, + ) -> &mut Self + ); + + forward!( + #[deprecated(note = "Use `multipart_suggestion_with_applicability`")] + pub fn multipart_suggestion( + &mut self, + msg: &str, + suggestion: Vec<(Span, String)>, + ) -> &mut Self + ); + + forward!( + #[deprecated(note = "Use `span_suggestion_with_applicability`")] + pub fn span_suggestion( + &mut self, + sp: Span, + msg: &str, + suggestion: String, + ) -> &mut Self + ); + + forward!( + #[deprecated(note = "Use `span_suggestions_with_applicability`")] + pub fn span_suggestions(&mut self, + sp: Span, + msg: &str, + suggestions: Vec, + ) -> &mut Self + ); pub fn multipart_suggestion_with_applicability(&mut self, msg: &str, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a452bbf0c9d54..fea013826e949 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -21,6 +21,8 @@ use std::cell::Cell; use std::ptr; use rustc_data_structures::sync::Lrc; +use errors::Applicability; + use syntax::ast::{Name, Ident}; use syntax::attr; @@ -345,7 +347,12 @@ impl<'a> Resolver<'a> { let module = if orig_name.is_none() && ident.name == keywords::SelfLower.name() { self.session .struct_span_err(item.span, "`extern crate self;` requires renaming") - .span_suggestion(item.span, "try", "extern crate self as name;".into()) + .span_suggestion_with_applicability( + item.span, + "try", + "extern crate self as name;".into(), + Applicability::HasPlaceholders, + ) .emit(); return; } else if orig_name == Some(keywords::SelfLower.name()) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a25009ccfb49c..896cb3d5a0c69 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4823,8 +4823,13 @@ impl<'a> Resolver<'a> { } else if ident.span.rust_2018() { let msg = "relative paths are not supported in visibilities on 2018 edition"; self.session.struct_span_err(ident.span, msg) - .span_suggestion(path.span, "try", format!("crate::{}", path)) - .emit(); + .span_suggestion_with_applicability( + path.span, + "try", + format!("crate::{}", path), + Applicability::MaybeIncorrect, + ) + .emit(); return ty::Visibility::Public; } else { let ctxt = ident.span.ctxt(); diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 1767af4870d3b..47f258e1aea74 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -1,5 +1,6 @@ use check::{FnCtxt, Expectation, Diverges, Needs}; use check::coercion::CoerceMany; +use errors::Applicability; use rustc::hir::{self, PatKind}; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; @@ -989,7 +990,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); let suggested_name = find_best_match_for_name(input, &ident.as_str(), None); if let Some(suggested_name) = suggested_name { - err.span_suggestion(*span, "did you mean", suggested_name.to_string()); + err.span_suggestion_with_applicability( + *span, + "did you mean", + suggested_name.to_string(), + Applicability::MaybeIncorrect, + ); + // we don't want to throw `E0027` in case we have thrown `E0026` for them unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str()); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 823c786bded26..4f1bc2fc2412c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4063,12 +4063,13 @@ impl<'a> Parser<'a> { if let Some(mut err) = delayed_err { if let Some(etc_span) = etc_span { - err.multipart_suggestion( + err.multipart_suggestion_with_applicability( "move the `..` to the end of the field list", vec![ (etc_span, String::new()), (self.span, format!("{}.. }}", if ate_comma { "" } else { ", " })), ], + Applicability::MachineApplicable, ); } err.emit(); @@ -6913,7 +6914,11 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(fixed_name_sp, error_msg); err.span_label(fixed_name_sp, "dash-separated idents are not valid"); - err.multipart_suggestion(suggestion_msg, replacement); + err.multipart_suggestion_with_applicability( + suggestion_msg, + replacement, + Applicability::MachineApplicable, + ); err.emit(); } Ok(ident) From 75dcf9e35fb0a3f8e45ec9f4f7c0a4096fe60d2d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 11 Jan 2019 13:43:18 +0100 Subject: [PATCH 0121/1064] Add an end-to-end run-make test for cross-lang LTO. --- .../cross-lang-lto-clang/Makefile | 25 +++++++++++++++++++ .../cross-lang-lto-clang/clib.c | 9 +++++++ .../cross-lang-lto-clang/cmain.c | 12 +++++++++ .../cross-lang-lto-clang/main.rs | 11 ++++++++ .../cross-lang-lto-clang/rustlib.rs | 12 +++++++++ 5 files changed, 69 insertions(+) create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile new file mode 100644 index 0000000000000..1e5df8f881289 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile @@ -0,0 +1,25 @@ +# needs-matching-clang + +# This test makes sure that cross-language inlining actually works by checking +# the generated machine code. + +-include ../tools.mk + +all: cpp-executable rust-executable + +cpp-executable: + $(RUSTC) -Zcross-lang-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs + clang -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 + # Make sure we don't find a call instruction to the function we expect to + # always be inlined. + llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined" + # As a sanity check, make sure we do find a call instruction to a + # non-inlined function + llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined" + +rust-executable: + clang ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 + (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) + $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain + llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined" + llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c b/src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c new file mode 100644 index 0000000000000..90f33f24dc424 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c @@ -0,0 +1,9 @@ +#include + +uint32_t c_always_inlined() { + return 1234; +} + +__attribute__((noinline)) uint32_t c_never_inlined() { + return 12345; +} diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c b/src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c new file mode 100644 index 0000000000000..e62a40117ce83 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c @@ -0,0 +1,12 @@ +#include + +// A trivial function defined in Rust, returning a constant value. This should +// always be inlined. +uint32_t rust_always_inlined(); + + +uint32_t rust_never_inlined(); + +int main(int argc, char** argv) { + return rust_never_inlined() + rust_always_inlined(); +} diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs b/src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs new file mode 100644 index 0000000000000..8129dcb85d96a --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs @@ -0,0 +1,11 @@ +#[link(name = "xyz")] +extern "C" { + fn c_always_inlined() -> u32; + fn c_never_inlined() -> u32; +} + +fn main() { + unsafe { + println!("blub: {}", c_always_inlined() + c_never_inlined()); + } +} diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs b/src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs new file mode 100644 index 0000000000000..8a74d74a420bd --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs @@ -0,0 +1,12 @@ +#![crate_type="staticlib"] + +#[no_mangle] +pub extern "C" fn rust_always_inlined() -> u32 { + 42 +} + +#[no_mangle] +#[inline(never)] +pub extern "C" fn rust_never_inlined() -> u32 { + 421 +} From 50b25105924a23f1070e916ce3bff4be5a7c9c58 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 11 Jan 2019 13:29:59 +0100 Subject: [PATCH 0122/1064] compiletest: Support opt-in Clang-based run-make tests. Some cross-language run-make tests need a Clang compiler that matches the LLVM version of rustc. Since such a compiler usually isn't available these tests (marked with the "needs-matching-clang" directive) are ignored by default. For some CI jobs we do need these tests to run unconditionally though. In order to support this a --force-clang-based-tests flag is added to compiletest. If this flag is specified, compiletest will fail if it can't detect an appropriate version of Clang. --- src/tools/compiletest/src/common.rs | 7 +++ src/tools/compiletest/src/header.rs | 9 +++ src/tools/compiletest/src/main.rs | 86 ++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 98bc6e8ac0084..d034630a4dfa3 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -144,6 +144,10 @@ pub struct Config { /// (or, alternatively, to silently run them like regular run-pass tests). pub force_valgrind: bool, + /// Whether to fail if we don't have a clang version available that matches + /// rustc's LLVM version. + pub force_clang_based_tests: bool, + /// The directory containing the tests to run pub src_base: PathBuf, @@ -205,6 +209,9 @@ pub struct Config { /// Is LLVM a system LLVM pub system_llvm: bool, + /// The version of Clang available to run-make tests (if any). + pub clang_version: Option, + /// Path to the android tools pub android_cross_path: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 5eb1f5ec5ffda..0d664d4852bbf 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -111,6 +111,11 @@ impl EarlyProps { if ignore_llvm(config, ln) { props.ignore = Ignore::Ignore; } + + if !config.force_clang_based_tests && + config.parse_needs_matching_clang(ln) { + props.ignore = Ignore::Ignore; + } } if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) && @@ -705,6 +710,10 @@ impl Config { } } + fn parse_needs_matching_clang(&self, line: &str) -> bool { + self.parse_name_directive(line, "needs-matching-clang") + } + /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86` /// or `normalize-stderr-32bit`. fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective { diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 2e5feca54151c..bf6ea2a04035e 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -50,12 +50,32 @@ pub mod util; fn main() { env_logger::init(); - let config = parse_config(env::args().collect()); + let mut config = parse_config(env::args().collect()); if config.valgrind_path.is_none() && config.force_valgrind { panic!("Can't find Valgrind to run Valgrind tests"); } + // Some run-make tests need a version of Clang available that matches + // rustc's LLVM version. Since this isn't always the case, these tests are + // opt-in. + let clang_based_tests_possible = check_clang_based_tests_possible(&config); + match (clang_based_tests_possible, config.force_clang_based_tests) { + (Ok(_), true) | + (Err(_), false) => { + // Nothing to do + } + (Ok(_), false) => { + // If a valid clang version is available, run the tests even if + // they are not forced. + config.force_clang_based_tests = true; + } + (Err(msg), true) => { + // Tests are forced but we don't have a valid version of Clang. + panic!("{}", msg) + } + } + log_config(&config); run_tests(&config); } @@ -108,6 +128,11 @@ pub fn parse_config(args: Vec) -> Config { "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind", ) + .optflag( + "", + "force-clang-based-tests", + "fail if Clang-based run-make tests can't be run for some reason", + ) .optopt( "", "llvm-filecheck", @@ -189,6 +214,12 @@ pub fn parse_config(args: Vec) -> Config { "VERSION STRING", ) .optflag("", "system-llvm", "is LLVM the system LLVM") + .optopt( + "", + "clang-version", + "the version of Clang available to run-make tests", + "VERSION STRING", + ) .optopt( "", "android-cross-path", @@ -298,6 +329,7 @@ pub fn parse_config(args: Vec) -> Config { docck_python: matches.opt_str("docck-python").unwrap(), valgrind_path: matches.opt_str("valgrind-path"), force_valgrind: matches.opt_present("force-valgrind"), + force_clang_based_tests: matches.opt_present("force-clang-based-tests"), llvm_filecheck: matches.opt_str("llvm-filecheck").map(|s| PathBuf::from(&s)), src_base, build_base: opt_path(matches, "build-base"), @@ -323,6 +355,7 @@ pub fn parse_config(args: Vec) -> Config { lldb_native_rust, llvm_version: matches.opt_str("llvm-version"), system_llvm: matches.opt_present("system-llvm"), + clang_version: matches.opt_str("clang-version"), android_cross_path: android_cross_path, adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")), @@ -1031,3 +1064,54 @@ fn test_extract_gdb_version() { 7012050: "GNU gdb (GDB) 7.12.50.20161027-git", } } + + +fn check_clang_based_tests_possible(config: &Config) -> Result<(), String> { + + let llvm_version = if let Some(llvm_version) = config.llvm_version.as_ref() { + llvm_version + } else { + return Err(format!("Running `compiletest` with `--force-clang-based-tests` \ + requires `--llvm-version` to be specified.")); + }; + + let clang_major_version = if let Some(ref version_string) = config.clang_version { + major_version_from_clang_version_string(version_string)? + } else { + return Err(format!("Clang is required for running tests \ + (because of --force-clang-based-tests) \ + but it does not seem to be available.")); + }; + + let rustc_llvm_major_version = major_version_from_llvm_version_string(&llvm_version)?; + + return if clang_major_version != rustc_llvm_major_version { + Err(format!("`--force-clang-based-tests` needs the major version of Clang \ + and rustc's LLVM to be the same. Clang version is: {}, \ + Rustc LLVM is: {}", + config.clang_version.clone().unwrap(), + llvm_version)) + } else { + Ok(()) + }; + + fn major_version_from_clang_version_string(clang_version: &str) -> Result<&str, String> { + let re = regex::Regex::new(r"clang version (\d)\.\d").unwrap(); + if let Some(captures) = re.captures(clang_version) { + Ok(captures.get(1).unwrap().as_str()) + } else { + Err(format!("Failed to parse major version from Clang version \ + string '{}'.", clang_version)) + } + } + + fn major_version_from_llvm_version_string(llvm_version: &str) -> Result<&str, String> { + let re = regex::Regex::new(r"(\d)\.\d").unwrap(); + if let Some(captures) = re.captures(llvm_version) { + Ok(captures.get(1).unwrap().as_str()) + } else { + Err(format!("Failed to parse major version from LLVM version \ + string '{}'.", llvm_version)) + } + } +} From ea4fb95dc9e234d35a7a94f6cdc37cb5103c35ed Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 11 Jan 2019 13:37:08 +0100 Subject: [PATCH 0123/1064] Support clang-based run-make tests in rustbuild. --- src/bootstrap/test.rs | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2edc78ebaa94f..ff66c75dc8c65 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1106,13 +1106,13 @@ impl Step for Compiletest { }).to_string() }) }; - let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") { + let (lldb_exe, clang_exe) = + if builder.config.lldb_enabled && !target.contains("emscripten") { // Test against the lldb that was just built. - builder.llvm_out(target) - .join("bin") - .join("lldb") + (builder.llvm_out(target).join("bin").join("lldb"), + builder.llvm_out(target).join("bin").join("clang")) } else { - PathBuf::from("lldb") + (PathBuf::from("lldb"), PathBuf::from("clang")) }; let lldb_version = Command::new(&lldb_exe) .arg("--version") @@ -1127,6 +1127,31 @@ impl Step for Compiletest { } } + let clang_version = Command::new(&clang_exe) + .arg("--version") + .output() + .map(|output| { String::from_utf8_lossy(&output.stdout).to_string() }) + .ok(); + if let Some(ref vers) = clang_version { + cmd.arg("--clang-version").arg(vers); + } + + if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { + match &var.to_string_lossy()[..] { + "1" | "yes" | "on" => { + cmd.arg("--force-clang-based-tests"); + } + "0" | "no" | "off" => { + // Nothing to do. + } + other => { + // Let's make sure typos don't get unnoticed + panic!("Unrecognized option '{}' set in \ + RUSTBUILD_FORCE_CLANG_BASED_TESTS", other); + } + } + } + // Get paths from cmd args let paths = match &builder.config.cmd { Subcommand::Test { ref paths, .. } => &paths[..], From b38125c3bba8c6137bf47365c2009b647766059c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 15 Jan 2019 18:07:12 +0100 Subject: [PATCH 0124/1064] compiletest: Simplify handling of Clang-based tests. --- src/bootstrap/test.rs | 25 ++---- .../cross-lang-lto-clang/Makefile | 6 +- src/tools/compiletest/src/common.rs | 9 +- src/tools/compiletest/src/header.rs | 2 +- src/tools/compiletest/src/main.rs | 89 ++----------------- src/tools/compiletest/src/runtest.rs | 4 + 6 files changed, 26 insertions(+), 109 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ff66c75dc8c65..c9160aca9173e 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1106,13 +1106,11 @@ impl Step for Compiletest { }).to_string() }) }; - let (lldb_exe, clang_exe) = - if builder.config.lldb_enabled && !target.contains("emscripten") { + let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") { // Test against the lldb that was just built. - (builder.llvm_out(target).join("bin").join("lldb"), - builder.llvm_out(target).join("bin").join("clang")) + builder.llvm_out(target).join("bin").join("lldb") } else { - (PathBuf::from("lldb"), PathBuf::from("clang")) + PathBuf::from("lldb") }; let lldb_version = Command::new(&lldb_exe) .arg("--version") @@ -1127,19 +1125,14 @@ impl Step for Compiletest { } } - let clang_version = Command::new(&clang_exe) - .arg("--version") - .output() - .map(|output| { String::from_utf8_lossy(&output.stdout).to_string() }) - .ok(); - if let Some(ref vers) = clang_version { - cmd.arg("--clang-version").arg(vers); - } - if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { - match &var.to_string_lossy()[..] { + match &var.to_string_lossy().to_lowercase()[..] { "1" | "yes" | "on" => { - cmd.arg("--force-clang-based-tests"); + assert!(builder.config.lldb_enabled, + "RUSTBUILD_FORCE_CLANG_BASED_TESTS needs Clang/LLDB to \ + be built."); + let clang_exe = builder.llvm_out(target).join("bin").join("clang"); + cmd.arg("--run-clang-based-tests-with").arg(clang_exe); } "0" | "no" | "off" => { // Nothing to do. diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile index 1e5df8f881289..cf687070bc2ed 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile @@ -9,7 +9,7 @@ all: cpp-executable rust-executable cpp-executable: $(RUSTC) -Zcross-lang-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs - clang -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 + $(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 # Make sure we don't find a call instruction to the function we expect to # always be inlined. llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined" @@ -18,8 +18,8 @@ cpp-executable: llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined" rust-executable: - clang ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 + $(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) - $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain + $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined" llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index d034630a4dfa3..f6f8ef1dff485 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -144,9 +144,9 @@ pub struct Config { /// (or, alternatively, to silently run them like regular run-pass tests). pub force_valgrind: bool, - /// Whether to fail if we don't have a clang version available that matches - /// rustc's LLVM version. - pub force_clang_based_tests: bool, + /// The path to the Clang executable to run Clang-based tests with. If + /// `None` then these tests will be ignored. + pub run_clang_based_tests_with: Option, /// The directory containing the tests to run pub src_base: PathBuf, @@ -209,9 +209,6 @@ pub struct Config { /// Is LLVM a system LLVM pub system_llvm: bool, - /// The version of Clang available to run-make tests (if any). - pub clang_version: Option, - /// Path to the android tools pub android_cross_path: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 0d664d4852bbf..6a00bd3c42611 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -112,7 +112,7 @@ impl EarlyProps { props.ignore = Ignore::Ignore; } - if !config.force_clang_based_tests && + if config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln) { props.ignore = Ignore::Ignore; } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index bf6ea2a04035e..682cce663a1ff 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -50,32 +50,12 @@ pub mod util; fn main() { env_logger::init(); - let mut config = parse_config(env::args().collect()); + let config = parse_config(env::args().collect()); if config.valgrind_path.is_none() && config.force_valgrind { panic!("Can't find Valgrind to run Valgrind tests"); } - // Some run-make tests need a version of Clang available that matches - // rustc's LLVM version. Since this isn't always the case, these tests are - // opt-in. - let clang_based_tests_possible = check_clang_based_tests_possible(&config); - match (clang_based_tests_possible, config.force_clang_based_tests) { - (Ok(_), true) | - (Err(_), false) => { - // Nothing to do - } - (Ok(_), false) => { - // If a valid clang version is available, run the tests even if - // they are not forced. - config.force_clang_based_tests = true; - } - (Err(msg), true) => { - // Tests are forced but we don't have a valid version of Clang. - panic!("{}", msg) - } - } - log_config(&config); run_tests(&config); } @@ -128,10 +108,11 @@ pub fn parse_config(args: Vec) -> Config { "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind", ) - .optflag( + .optopt( "", - "force-clang-based-tests", - "fail if Clang-based run-make tests can't be run for some reason", + "run-clang-based-tests-with", + "path to Clang executable", + "PATH", ) .optopt( "", @@ -214,12 +195,6 @@ pub fn parse_config(args: Vec) -> Config { "VERSION STRING", ) .optflag("", "system-llvm", "is LLVM the system LLVM") - .optopt( - "", - "clang-version", - "the version of Clang available to run-make tests", - "VERSION STRING", - ) .optopt( "", "android-cross-path", @@ -329,7 +304,7 @@ pub fn parse_config(args: Vec) -> Config { docck_python: matches.opt_str("docck-python").unwrap(), valgrind_path: matches.opt_str("valgrind-path"), force_valgrind: matches.opt_present("force-valgrind"), - force_clang_based_tests: matches.opt_present("force-clang-based-tests"), + run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"), llvm_filecheck: matches.opt_str("llvm-filecheck").map(|s| PathBuf::from(&s)), src_base, build_base: opt_path(matches, "build-base"), @@ -355,7 +330,6 @@ pub fn parse_config(args: Vec) -> Config { lldb_native_rust, llvm_version: matches.opt_str("llvm-version"), system_llvm: matches.opt_present("system-llvm"), - clang_version: matches.opt_str("clang-version"), android_cross_path: android_cross_path, adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")), @@ -1064,54 +1038,3 @@ fn test_extract_gdb_version() { 7012050: "GNU gdb (GDB) 7.12.50.20161027-git", } } - - -fn check_clang_based_tests_possible(config: &Config) -> Result<(), String> { - - let llvm_version = if let Some(llvm_version) = config.llvm_version.as_ref() { - llvm_version - } else { - return Err(format!("Running `compiletest` with `--force-clang-based-tests` \ - requires `--llvm-version` to be specified.")); - }; - - let clang_major_version = if let Some(ref version_string) = config.clang_version { - major_version_from_clang_version_string(version_string)? - } else { - return Err(format!("Clang is required for running tests \ - (because of --force-clang-based-tests) \ - but it does not seem to be available.")); - }; - - let rustc_llvm_major_version = major_version_from_llvm_version_string(&llvm_version)?; - - return if clang_major_version != rustc_llvm_major_version { - Err(format!("`--force-clang-based-tests` needs the major version of Clang \ - and rustc's LLVM to be the same. Clang version is: {}, \ - Rustc LLVM is: {}", - config.clang_version.clone().unwrap(), - llvm_version)) - } else { - Ok(()) - }; - - fn major_version_from_clang_version_string(clang_version: &str) -> Result<&str, String> { - let re = regex::Regex::new(r"clang version (\d)\.\d").unwrap(); - if let Some(captures) = re.captures(clang_version) { - Ok(captures.get(1).unwrap().as_str()) - } else { - Err(format!("Failed to parse major version from Clang version \ - string '{}'.", clang_version)) - } - } - - fn major_version_from_llvm_version_string(llvm_version: &str) -> Result<&str, String> { - let re = regex::Regex::new(r"(\d)\.\d").unwrap(); - if let Some(captures) = re.captures(llvm_version) { - Ok(captures.get(1).unwrap().as_str()) - } else { - Err(format!("Failed to parse major version from LLVM version \ - string '{}'.", llvm_version)) - } - } -} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 400c205d44b20..f0050f2adb957 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2587,6 +2587,10 @@ impl<'test> TestCx<'test> { cmd.env("RUSTC_LINKER", linker); } + if let Some(ref clang) = self.config.run_clang_based_tests_with { + cmd.env("CLANG", clang); + } + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); From 9be4c76910e0df7decb33c5d400260f1d8c217a1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 9 Jan 2019 19:37:38 +0100 Subject: [PATCH 0125/1064] Add signed num::NonZeroI* types Multiple people have asked for them, in https://github.com/rust-lang/rust/issues/49137. Given that the unsigned ones already exist, they are very easy to add and not an additional maintenance burden. --- src/libcore/num/mod.rs | 36 +++++++++++-------- src/libcore/tests/nonzero.rs | 10 +++++- .../ui/try-block/try-block-bad-type.stderr | 4 +-- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 6827364c0f805..41caa1788fbb8 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -10,9 +10,9 @@ use ops; use str::FromStr; macro_rules! impl_nonzero_fmt { - ( ( $( $Trait: ident ),+ ) for $Ty: ident ) => { + ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { $( - #[stable(feature = "nonzero", since = "1.28.0")] + #[$stability] impl fmt::$Trait for $Ty { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -31,7 +31,7 @@ macro_rules! doc_comment { } macro_rules! nonzero_integers { - ( $( $Ty: ident($Int: ty); )+ ) => { + ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => { $( doc_comment! { concat!("An integer that is known not to equal zero. @@ -41,10 +41,10 @@ For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!( ```rust use std::mem::size_of; -assert_eq!(size_of::>(), size_of::<", stringify!($Int), +assert_eq!(size_of::>(), size_of::<", stringify!($Int), ">()); ```"), - #[stable(feature = "nonzero", since = "1.28.0")] + #[$stability] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] @@ -57,14 +57,14 @@ assert_eq!(size_of::>(), size_of::<", st /// # Safety /// /// The value must not be zero. - #[stable(feature = "nonzero", since = "1.28.0")] + #[$stability] #[inline] pub const unsafe fn new_unchecked(n: $Int) -> Self { $Ty(n) } /// Create a non-zero if the given value is not zero. - #[stable(feature = "nonzero", since = "1.28.0")] + #[$stability] #[inline] pub fn new(n: $Int) -> Option { if n != 0 { @@ -75,7 +75,7 @@ assert_eq!(size_of::>(), size_of::<", st } /// Returns the value as a primitive type. - #[stable(feature = "nonzero", since = "1.28.0")] + #[$stability] #[inline] pub const fn get(self) -> $Int { self.0 @@ -91,19 +91,25 @@ assert_eq!(size_of::>(), size_of::<", st } impl_nonzero_fmt! { - (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty + #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty } )+ } } nonzero_integers! { - NonZeroU8(u8); - NonZeroU16(u16); - NonZeroU32(u32); - NonZeroU64(u64); - NonZeroU128(u128); - NonZeroUsize(usize); + #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8); + #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16); + #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32); + #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64); + #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128); + #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize); + #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8); + #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16); + #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32); + #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64); + #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128); + #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize); } /// Provides intentionally-wrapped arithmetic on `T`. diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index c813bf20cb61a..4532568ee0c16 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -1,4 +1,4 @@ -use core::num::NonZeroU32; +use core::num::{NonZeroU32, NonZeroI32}; use core::option::Option; use core::option::Option::{Some, None}; use std::mem::size_of; @@ -13,6 +13,7 @@ fn test_create_nonzero_instance() { #[test] fn test_size_nonzero_in_option() { assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::(), size_of::>()); } #[test] @@ -118,3 +119,10 @@ fn test_from_nonzero() { let num: u32 = nz.into(); assert_eq!(num, 1u32); } + +#[test] +fn test_from_signed_nonzero() { + let nz = NonZeroI32::new(1).unwrap(); + let num: i32 = nz.into(); + assert_eq!(num, 1i32); +} diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr index 202885e383ece..c2f9e9b52bee6 100644 --- a/src/test/ui/try-block/try-block-bad-type.stderr +++ b/src/test/ui/try-block/try-block-bad-type.stderr @@ -5,11 +5,11 @@ LL | Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` | ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32` | = help: the following implementations were found: - > + > > > - > > + and 2 others = note: required by `std::convert::From::from` error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == &str` From 7b557119883685e541d555135fb81c0dc10e2752 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 17 Jan 2019 18:57:46 +0100 Subject: [PATCH 0126/1064] Make MutexGuard's Debug implementation more useful. Fixes #57702. --- src/libstd/sync/mutex.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 856bb26042490..e4cc29792072f 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -450,9 +450,13 @@ impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> { #[stable(feature = "std_debug", since = "1.16.0")] impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("MutexGuard") - .field("lock", &self.__lock) - .finish() + struct MutexFmt<'a, T: ?Sized>(&'a MutexGuard<'a, T>); + impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexFmt<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Mutex").field("data", &&*self.0).finish() + } + } + f.debug_struct("MutexGuard").field("lock", &MutexFmt(self)).finish() } } From c2863dd1b43f4f1fe63a209922f7e72db53f9663 Mon Sep 17 00:00:00 2001 From: lenoil98 Date: Thu, 17 Jan 2019 13:20:00 -0500 Subject: [PATCH 0127/1064] Update bootstrap.py Add PowerPC64 support on FreeBSD --- src/bootstrap/bootstrap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index f3dbae6909a4d..e8c1594bda343 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -230,6 +230,9 @@ def default_build_triple(): err = "unknown OS type: {}".format(ostype) sys.exit(err) + if cputype == 'powerpc' and ostype == 'unknown-freebsd': + cputype = subprocess.check_output( + ['uname', '-p']).strip().decode(default_encoding) cputype_mapper = { 'BePC': 'i686', 'aarch64': 'aarch64', From 2e9deed9f130d2342bec2a55358305cb7137605e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 17 Jan 2019 20:03:59 +0100 Subject: [PATCH 0128/1064] Simplify Debug implementation of MutexGuard. Just transparently print the guarded data, instead of wrapping it in `MutexGuard { lock: Mutex { data: ... } }`. --- src/libstd/sync/mutex.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index e4cc29792072f..59829db23cbc2 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -450,13 +450,7 @@ impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> { #[stable(feature = "std_debug", since = "1.16.0")] impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - struct MutexFmt<'a, T: ?Sized>(&'a MutexGuard<'a, T>); - impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexFmt<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Mutex").field("data", &&*self.0).finish() - } - } - f.debug_struct("MutexGuard").field("lock", &MutexFmt(self)).finish() + fmt::Debug::fmt(&**self, f) } } From 351946f97438b3ce31f6777a62de150673b6239d Mon Sep 17 00:00:00 2001 From: Nicolas Bigaouette Date: Thu, 17 Jan 2019 14:16:26 -0500 Subject: [PATCH 0129/1064] Install missing 'rust-gdbui'' See https://github.com/rust-lang/rust/pull/53774#issuecomment-419704939 --- src/bootstrap/dist.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index df34dfe4544ae..2cab55ef2e0fa 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -602,6 +602,8 @@ impl Step for DebuggerScripts { // gdb debugger scripts builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); + builder.install(&builder.src.join("src/etc/rust-gdbui"), &sysroot.join("bin"), + 0o755); cp_debugger_script("gdb_load_rust_pretty_printers.py"); cp_debugger_script("gdb_rust_pretty_printing.py"); From bf9c0fb650e94fc522e1583d557c43320d2f41c0 Mon Sep 17 00:00:00 2001 From: Nicolas Bigaouette Date: Thu, 17 Jan 2019 15:05:55 -0500 Subject: [PATCH 0130/1064] Fix typo: 'rust-gdbgui' instead of 'rust-gdbui' --- src/bootstrap/dist.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 2cab55ef2e0fa..71662e8b94149 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -602,7 +602,7 @@ impl Step for DebuggerScripts { // gdb debugger scripts builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); - builder.install(&builder.src.join("src/etc/rust-gdbui"), &sysroot.join("bin"), + builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755); cp_debugger_script("gdb_load_rust_pretty_printers.py"); From 32662c2953bfc05e0cbef30ee51647f679bb1f4f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:20:27 +0900 Subject: [PATCH 0131/1064] Change from error to invalid --- src/libsyntax/parse/token.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 69e934d64c6cd..99041fd7cd634 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -74,7 +74,7 @@ impl Lit { match *self { Byte(_) => "byte literal", Char(_) => "char literal", - Err(_) => "error literal", + Err(_) => "invalid literal", Integer(_) => "integer literal", Float(_) => "float literal", Str_(_) | StrRaw(..) => "string literal", From bde3795d465c1a1768afa49cc5e79cea93cb99f3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:22:00 +0900 Subject: [PATCH 0132/1064] Continue cheking --- src/libsyntax/parse/lexer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 666653f9edf80..2bf7ff4bd7a28 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1445,7 +1445,7 @@ impl<'a> StringReader<'a> { format!("\"{}\"", &self.src[start..end]), Applicability::MachineApplicable ).emit(); - FatalError.raise(); + return Ok(token::Literal(token::Char(Symbol::intern("??")), None)) } if self.ch_is('\n') || self.is_eof() || self.ch_is('/') { // Only attempt to infer single line string literals. If we encounter From 7e2e61c618b53ccaa5d64b57b4c1872bc73746aa Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:23:25 +0900 Subject: [PATCH 0133/1064] Change from mk_lit! to cx.expr --- src/libsyntax/ext/quote.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 17c88a30bcd0b..01cb1341b9f36 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -646,7 +646,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), - token::Literal(token::Err(i), suf) => return mk_lit!("Err", suf, i), + token::Literal(token::Err(_i), _suf) => return cx.expr(sp, ast::ExprKind::Err), token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), From 8bbb63c60055b896b5daa619f76a3a81c585344e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:23:56 +0900 Subject: [PATCH 0134/1064] Add token::Err --- src/librustdoc/html/highlight.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 87e979b93e9ef..558ba1c2e2ef2 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -296,7 +296,7 @@ impl<'a> Classifier<'a> { token::Literal(lit, _suf) => { match lit { // Text literals. - token::Byte(..) | token::Char(..) | + token::Byte(..) | token::Char(..) | token::Err(..) | token::ByteStr(..) | token::ByteStrRaw(..) | token::Str_(..) | token::StrRaw(..) => Class::String, From b721c1a885537de960733a54f86ba7a6f24a4857 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 18 Jan 2019 05:24:17 +0900 Subject: [PATCH 0135/1064] Fix tests --- src/test/ui/parser/lex-bad-char-literals-3.rs | 5 ++++- .../ui/parser/lex-bad-char-literals-3.stderr | 22 ++++++++++++++++++- src/test/ui/parser/lex-bad-char-literals-5.rs | 5 ++++- .../ui/parser/lex-bad-char-literals-5.stderr | 22 ++++++++++++++++++- src/test/ui/str/str-as-char.fixed | 4 ++-- src/test/ui/str/str-as-char.rs | 4 ++-- src/test/ui/str/str-as-char.stderr | 16 +++++++++++--- 7 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/test/ui/parser/lex-bad-char-literals-3.rs b/src/test/ui/parser/lex-bad-char-literals-3.rs index d14ec1cc51560..10a8cd4a53eab 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.rs +++ b/src/test/ui/parser/lex-bad-char-literals-3.rs @@ -3,4 +3,7 @@ static c: char = '●●' //~ ERROR: character literal may only contain one codepoint ; -fn main() {} +fn main() { + let ch: &str = '●●'; //~ ERROR: character literal may only contain one codepoint + //~^ ERROR: mismatched types +} diff --git a/src/test/ui/parser/lex-bad-char-literals-3.stderr b/src/test/ui/parser/lex-bad-char-literals-3.stderr index dde4a7db3aa79..9b4e69870cae8 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-3.stderr @@ -8,5 +8,25 @@ help: if you meant to write a `str` literal, use double quotes LL | "●●" //~ ERROR: character literal may only contain one codepoint | ^^^^ -error: aborting due to previous error +error: character literal may only contain one codepoint + --> $DIR/lex-bad-char-literals-3.rs:7:20 + | +LL | let ch: &str = '●●'; //~ ERROR: character literal may only contain one codepoint + | ^^^^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let ch: &str = "●●"; //~ ERROR: character literal may only contain one codepoint + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/lex-bad-char-literals-3.rs:7:20 + | +LL | let ch: &str = '●●'; //~ ERROR: character literal may only contain one codepoint + | ^^^^ expected &str, found char + | + = note: expected type `&str` + found type `char` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/lex-bad-char-literals-5.rs b/src/test/ui/parser/lex-bad-char-literals-5.rs index 1236e76de420e..964099c3fa98d 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.rs +++ b/src/test/ui/parser/lex-bad-char-literals-5.rs @@ -4,4 +4,7 @@ static c: char = '\x10\x10' //~ ERROR: character literal may only contain one codepoint ; -fn main() {} +fn main() { + let ch: &str = '\x10\x10'; //~ ERROR: character literal may only contain one codepoint + //~^ ERROR: mismatched types +} diff --git a/src/test/ui/parser/lex-bad-char-literals-5.stderr b/src/test/ui/parser/lex-bad-char-literals-5.stderr index 4f734eaeff353..177d8c599a894 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-5.stderr @@ -8,5 +8,25 @@ help: if you meant to write a `str` literal, use double quotes LL | "/x10/x10" //~ ERROR: character literal may only contain one codepoint | ^^^^^^^^^^ -error: aborting due to previous error +error: character literal may only contain one codepoint + --> $DIR/lex-bad-char-literals-5.rs:8:20 + | +LL | let ch: &str = '/x10/x10'; //~ ERROR: character literal may only contain one codepoint + | ^^^^^^^^^^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let ch: &str = "/x10/x10"; //~ ERROR: character literal may only contain one codepoint + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/lex-bad-char-literals-5.rs:8:20 + | +LL | let ch: &str = '/x10/x10'; //~ ERROR: character literal may only contain one codepoint + | ^^^^^^^^^^ expected &str, found char + | + = note: expected type `&str` + found type `char` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/str/str-as-char.fixed b/src/test/ui/str/str-as-char.fixed index 9d4297b55c816..accead5c850cc 100644 --- a/src/test/ui/str/str-as-char.fixed +++ b/src/test/ui/str/str-as-char.fixed @@ -1,6 +1,6 @@ // run-rustfix fn main() { - println!("●●"); - //~^ ERROR character literal may only contain one codepoint + println!("{}", "●●"); //~ ERROR character literal may only contain one codepoint + //~^ ERROR format argument must be a string literal } diff --git a/src/test/ui/str/str-as-char.rs b/src/test/ui/str/str-as-char.rs index 710fa74a32a1c..fb179ec7245d2 100644 --- a/src/test/ui/str/str-as-char.rs +++ b/src/test/ui/str/str-as-char.rs @@ -1,6 +1,6 @@ // run-rustfix fn main() { - println!('●●'); - //~^ ERROR character literal may only contain one codepoint + println!('●●'); //~ ERROR character literal may only contain one codepoint + //~^ ERROR format argument must be a string literal } diff --git a/src/test/ui/str/str-as-char.stderr b/src/test/ui/str/str-as-char.stderr index 540a1b55376ff..4ca430a4cde9b 100644 --- a/src/test/ui/str/str-as-char.stderr +++ b/src/test/ui/str/str-as-char.stderr @@ -1,12 +1,22 @@ error: character literal may only contain one codepoint --> $DIR/str-as-char.rs:4:14 | -LL | println!('●●'); +LL | println!('●●'); //~ ERROR character literal may only contain one codepoint | ^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | println!("●●"); +LL | println!("●●"); //~ ERROR character literal may only contain one codepoint | ^^^^ -error: aborting due to previous error +error: format argument must be a string literal + --> $DIR/str-as-char.rs:4:14 + | +LL | println!('●●'); //~ ERROR character literal may only contain one codepoint + | ^^^^ +help: you might be missing a string literal to format with + | +LL | println!("{}", '●●'); //~ ERROR character literal may only contain one codepoint + | ^^^^^ + +error: aborting due to 2 previous errors From 25189874fb14b53c6647c337f34d77a7dd51a5a0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 17 Jan 2019 21:28:23 +0100 Subject: [PATCH 0136/1064] Fix non-clickable urls --- src/librustdoc/html/static/rustdoc.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8a8b7adcf7d4a..36765496ff4e9 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -391,10 +391,6 @@ h4 > code, h3 > code, .invisible > code { display: block; } -.in-band, code { - z-index: -5; -} - .invisible { width: 100%; display: inline-block; From d34b3e9bf2becb8fe8184559e2a376d1e7ab1fa3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 16 Jan 2019 01:47:49 +0300 Subject: [PATCH 0137/1064] privacy: Account for associated existential types --- src/librustc_privacy/lib.rs | 43 +++++++++++-------- .../ui/privacy/private-in-public-assoc-ty.rs | 9 +++- .../privacy/private-in-public-assoc-ty.stderr | 20 ++++++--- .../privacy/private-in-public-existential.rs | 10 +++++ 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4890369e13f20..c0d7248fab7f3 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -13,7 +13,7 @@ extern crate rustc_typeck; extern crate syntax_pos; extern crate rustc_data_structures; -use rustc::hir::{self, Node, PatKind}; +use rustc::hir::{self, Node, PatKind, AssociatedItemKind}; use rustc::hir::def::Def; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; @@ -548,7 +548,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { let mut reach = self.reach(trait_item_ref.id.node_id, item_level); reach.generics().predicates(); - if trait_item_ref.kind == hir::AssociatedItemKind::Type && + if trait_item_ref.kind == AssociatedItemKind::Type && !trait_item_ref.defaultness.has_value() { // No type to visit. } else { @@ -1333,11 +1333,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { if self.item_is_public(&impl_item_ref.id.node_id, &impl_item_ref.vis) { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { - hir::AssociatedItemKind::Const => { + AssociatedItemKind::Const => { found_pub_static = true; intravisit::walk_impl_item(self, impl_item); } - hir::AssociatedItemKind::Method { has_self: false } => { + AssociatedItemKind::Method { has_self: false } => { found_pub_static = true; intravisit::walk_impl_item(self, impl_item); } @@ -1558,6 +1558,24 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { in_assoc_ty: false, } } + + fn check_trait_or_impl_item(&self, node_id: ast::NodeId, assoc_item_kind: AssociatedItemKind, + defaultness: hir::Defaultness, vis: ty::Visibility) { + let mut check = self.check(node_id, vis); + + let (check_ty, is_assoc_ty) = match assoc_item_kind { + AssociatedItemKind::Const | AssociatedItemKind::Method { .. } => (true, false), + AssociatedItemKind::Type => (defaultness.has_value(), true), + // `ty()` for existential types is the underlying type, + // it's not a part of interface, so we skip it. + AssociatedItemKind::Existential => (false, true), + }; + check.in_assoc_ty = is_assoc_ty; + check.generics().predicates(); + if check_ty { + check.ty(); + } + } } impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1592,16 +1610,8 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> self.check(item.id, item_visibility).generics().predicates(); for trait_item_ref in trait_item_refs { - let mut check = self.check(trait_item_ref.id.node_id, item_visibility); - check.in_assoc_ty = trait_item_ref.kind == hir::AssociatedItemKind::Type; - check.generics().predicates(); - - if trait_item_ref.kind == hir::AssociatedItemKind::Type && - !trait_item_ref.defaultness.has_value() { - // No type to visit. - } else { - check.ty(); - } + self.check_trait_or_impl_item(trait_item_ref.id.node_id, trait_item_ref.kind, + trait_item_ref.defaultness, item_visibility); } } hir::ItemKind::TraitAlias(..) => { @@ -1647,9 +1657,8 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> } else { impl_vis }; - let mut check = self.check(impl_item.id, impl_item_vis); - check.in_assoc_ty = impl_item_ref.kind == hir::AssociatedItemKind::Type; - check.generics().predicates().ty(); + self.check_trait_or_impl_item(impl_item_ref.id.node_id, impl_item_ref.kind, + impl_item_ref.defaultness, impl_item_vis); } } } diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.rs b/src/test/ui/privacy/private-in-public-assoc-ty.rs index c6e86ed64ae73..81d23959fd4ad 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.rs +++ b/src/test/ui/privacy/private-in-public-assoc-ty.rs @@ -1,7 +1,7 @@ // Private types and traits are not allowed in interfaces of associated types. // This test also ensures that the checks are performed even inside private modules. -#![feature(associated_type_defaults)] +#![feature(associated_type_defaults, existential_type)] mod m { struct Priv; @@ -23,10 +23,17 @@ mod m { type Alias4 = Priv; //~^ ERROR private type `m::Priv` in public interface + + type Exist; + fn infer_exist() -> Self::Exist; } impl PubTr for u8 { type Alias1 = Priv; //~^ ERROR private type `m::Priv` in public interface + + existential type Exist: PrivTr; + //~^ ERROR private trait `m::PrivTr` in public interface + fn infer_exist() -> Self::Exist { Priv } } } diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr index 6740277c9a7c1..0e5dab1a08c37 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr +++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr @@ -6,7 +6,7 @@ LL | | //~^ WARN private trait `m::PrivTr` in public interface LL | | //~| WARN this was previously accepted LL | | //~| WARN private type `m::Priv` in public interface ... | -LL | | //~^ ERROR private type `m::Priv` in public interface +LL | | fn infer_exist() -> Self::Exist; LL | | } | |_____^ | @@ -22,7 +22,7 @@ LL | | //~^ WARN private trait `m::PrivTr` in public interface LL | | //~| WARN this was previously accepted LL | | //~| WARN private type `m::Priv` in public interface ... | -LL | | //~^ ERROR private type `m::Priv` in public interface +LL | | fn infer_exist() -> Self::Exist; LL | | } | |_____^ | @@ -39,7 +39,7 @@ LL | type Alias4 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:28:9 + --> $DIR/private-in-public-assoc-ty.rs:31:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -47,6 +47,16 @@ LL | struct Priv; LL | type Alias1 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type -error: aborting due to 2 previous errors +error[E0445]: private trait `m::PrivTr` in public interface + --> $DIR/private-in-public-assoc-ty.rs:34:9 + | +LL | trait PrivTr {} + | - `m::PrivTr` declared as private +... +LL | existential type Exist: PrivTr; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0446`. +Some errors occurred: E0445, E0446. +For more information about an error, try `rustc --explain E0445`. diff --git a/src/test/ui/privacy/private-in-public-existential.rs b/src/test/ui/privacy/private-in-public-existential.rs index 95658f45df6f5..61c6130e47019 100644 --- a/src/test/ui/privacy/private-in-public-existential.rs +++ b/src/test/ui/privacy/private-in-public-existential.rs @@ -12,4 +12,14 @@ fn check() -> Pub { Priv } +pub trait Trait { + type Pub: Default; + fn method() -> Self::Pub; +} + +impl Trait for u8 { + existential type Pub: Default; + fn method() -> Self::Pub { Priv } +} + fn main() {} From 1318e53ea8a8ed6da271d6130dab71131542ab98 Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Sat, 8 Dec 2018 14:17:50 -0500 Subject: [PATCH 0138/1064] Persist doc test executables to given path. --- src/librustdoc/config.rs | 4 ++++ src/librustdoc/lib.rs | 5 +++++ src/librustdoc/markdown.rs | 2 +- src/librustdoc/test.rs | 42 +++++++++++++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index d99136802514d..279d3b921345a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -68,6 +68,8 @@ pub struct Options { pub should_test: bool, /// List of arguments to pass to the test harness, if running tests. pub test_args: Vec, + /// Whether to persist the doctest executables. + pub persist_doctests: Option, // Options that affect the documentation process @@ -431,6 +433,7 @@ impl Options { let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some(); let static_root_path = matches.opt_str("static-root-path"); let generate_search_filter = !matches.opt_present("disable-per-crate-search"); + let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -456,6 +459,7 @@ impl Options { manual_passes, display_warnings, crate_version, + persist_doctests, render_options: RenderOptions { output, external_html, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1b6d7e87192d6..7fe0999bdca50 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -340,6 +340,11 @@ fn opts() -> Vec { o.optflag("", "disable-per-crate-search", "disables generating the crate selector on the search box") + unstable("persist-doctests", |o| { + o.optopt("", + "persist-doctests", + "Persists the rustdoc test executables", + "PATH") }), ] } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index da56194c27c2c..65a96e9001b26 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -142,7 +142,7 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> isize { options.libs, options.codegen_options, options.externs, true, opts, options.maybe_sysroot, None, Some(options.input), - options.linker, options.edition); + options.linker, options.edition, options.persist_doctests); collector.set_position(DUMMY_SP); let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); let res = find_testable_code(&input_str, &mut collector, codes); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index af47c7d5e8bfa..03b66759d40e1 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -120,7 +120,8 @@ pub fn run(mut options: Options) -> isize { Some(source_map), None, options.linker, - options.edition + options.edition, + options.persist_doctests, ); { @@ -184,7 +185,8 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, cg: CodegenOptions, externs: Externs, should_panic: bool, no_run: bool, as_test_harness: bool, compile_fail: bool, mut error_codes: Vec, opts: &TestOptions, - maybe_sysroot: Option, linker: Option, edition: Edition) { + maybe_sysroot: Option, linker: Option, edition: Edition, + persist_doctests: Option) { // The test harness wants its own `main` and top-level functions, so // never wrap the test in `fn main() { ... }`. let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts); @@ -249,6 +251,20 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, let old = io::set_panic(Some(box Sink(data.clone()))); let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout())); + enum DirState { + Temp(tempfile::TempDir), + Perm(PathBuf), + } + + impl DirState { + fn path(&self) -> &std::path::Path { + match self { + DirState::Temp(t) => t.path(), + DirState::Perm(p) => p.as_path(), + } + } + } + let (libdir, outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| { let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping())); let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()), @@ -267,7 +283,17 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let outdir = Mutex::new( - TempFileBuilder::new().prefix("rustdoctest").tempdir().expect("rustdoc needs a tempdir") + if let Some(mut path) = persist_doctests { + path.push(format!("{}_{}", filename.to_string().rsplit('/').next().unwrap().replace(".", "_"), line)); + std::fs::create_dir_all(&path).expect("Couldn't create directory for doctest executables"); + + DirState::Perm(path) + } else { + DirState::Temp(TempFileBuilder::new() + .prefix("rustdoctest") + .tempdir() + .expect("rustdoc needs a tempdir")) + } ); let libdir = sess.target_filesearch(PathKind::All).get_lib_path(); let mut control = driver::CompileController::basic(); @@ -629,13 +655,15 @@ pub struct Collector { filename: Option, linker: Option, edition: Edition, + persist_doctests: Option, } impl Collector { pub fn new(cratename: String, cfgs: Vec, libs: Vec, cg: CodegenOptions, externs: Externs, use_headers: bool, opts: TestOptions, maybe_sysroot: Option, source_map: Option>, - filename: Option, linker: Option, edition: Edition) -> Collector { + filename: Option, linker: Option, edition: Edition, + persist_doctests: Option) -> Collector { Collector { tests: Vec::new(), names: Vec::new(), @@ -652,6 +680,7 @@ impl Collector { filename, linker, edition, + persist_doctests, } } @@ -695,6 +724,8 @@ impl Tester for Collector { let maybe_sysroot = self.maybe_sysroot.clone(); let linker = self.linker.clone(); let edition = config.edition.unwrap_or(self.edition); + let persist_doctests = self.persist_doctests.clone(); + debug!("Creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { desc: testing::TestDesc { @@ -727,7 +758,8 @@ impl Tester for Collector { &opts, maybe_sysroot, linker, - edition) + edition, + persist_doctests) })) } { Ok(()) => (), From a3f7f97205dc158875228f607effc4f5e35438f8 Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Sat, 8 Dec 2018 14:22:08 -0500 Subject: [PATCH 0139/1064] Fix tidy error. --- src/librustdoc/test.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 03b66759d40e1..725d686153156 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -284,8 +284,16 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, let outdir = Mutex::new( if let Some(mut path) = persist_doctests { - path.push(format!("{}_{}", filename.to_string().rsplit('/').next().unwrap().replace(".", "_"), line)); - std::fs::create_dir_all(&path).expect("Couldn't create directory for doctest executables"); + path.push(format!("{}_{}", + filename + .to_string() + .rsplit('/') + .next() + .unwrap() + .replace(".", "_"), line) + ); + std::fs::create_dir_all(&path) + .expect("Couldn't create directory for doctest executables"); DirState::Perm(path) } else { From 22e97da30ab0d7cf41ec5adb63285ec887e601c3 Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Sat, 8 Dec 2018 15:50:03 -0500 Subject: [PATCH 0140/1064] Bless test. --- src/test/rustdoc-ui/failed-doctest-output.stdout | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index d584845e1f2ed..ad3458c8173b2 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -12,7 +12,8 @@ error[E0425]: cannot find value `no` in this scope 3 | no | ^^ not found in this scope -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:319:13 + +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:326:13 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ---- @@ -21,7 +22,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 11)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -', src/librustdoc/test.rs:354:17 +', src/librustdoc/test.rs:395:17 failures: From 80ee94c1f8640e866840dbcafe76ccdcbfe20fd8 Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Sun, 16 Dec 2018 17:31:36 -0500 Subject: [PATCH 0141/1064] Minor changes to wording and formatting. --- src/dlmalloc | 1 + src/libcompiler_builtins | 1 + src/liblibc | 1 + src/librustdoc/config.rs | 3 ++- src/librustdoc/lib.rs | 2 +- src/librustdoc/test.rs | 3 ++- src/test/rustdoc-ui/failed-doctest-output.stdout | 5 ++--- 7 files changed, 10 insertions(+), 6 deletions(-) create mode 160000 src/dlmalloc create mode 160000 src/libcompiler_builtins create mode 160000 src/liblibc diff --git a/src/dlmalloc b/src/dlmalloc new file mode 160000 index 0000000000000..c99638dc2ecfc --- /dev/null +++ b/src/dlmalloc @@ -0,0 +1 @@ +Subproject commit c99638dc2ecfc750cc1656f6edb2bd062c1e0981 diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins new file mode 160000 index 0000000000000..fe74674f6e4be --- /dev/null +++ b/src/libcompiler_builtins @@ -0,0 +1 @@ +Subproject commit fe74674f6e4be76d47b66f67d529ebf4186f4eb1 diff --git a/src/liblibc b/src/liblibc new file mode 160000 index 0000000000000..c75ca6465a139 --- /dev/null +++ b/src/liblibc @@ -0,0 +1 @@ +Subproject commit c75ca6465a139704e00295be355b1f067af2f535 diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 279d3b921345a..1c14dbf1cef8b 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -68,7 +68,7 @@ pub struct Options { pub should_test: bool, /// List of arguments to pass to the test harness, if running tests. pub test_args: Vec, - /// Whether to persist the doctest executables. + /// Otional path to persist the doctest executables to. pub persist_doctests: Option, // Options that affect the documentation process @@ -123,6 +123,7 @@ impl fmt::Debug for Options { .field("lint_cap", &self.lint_cap) .field("should_test", &self.should_test) .field("test_args", &self.test_args) + .field("persist_doctests", &self.persist_doctests) .field("default_passes", &self.default_passes) .field("manual_passes", &self.manual_passes) .field("display_warnings", &self.display_warnings) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7fe0999bdca50..08bbc95ad6524 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -343,7 +343,7 @@ fn opts() -> Vec { unstable("persist-doctests", |o| { o.optopt("", "persist-doctests", - "Persists the rustdoc test executables", + "Directory to persist doctest executables into", "PATH") }), ] diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 725d686153156..0b9fbc81da626 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -290,7 +290,8 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, .rsplit('/') .next() .unwrap() - .replace(".", "_"), line) + .replace(".", "_"), + line) ); std::fs::create_dir_all(&path) .expect("Couldn't create directory for doctest executables"); diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index ad3458c8173b2..c54e7be46bb8d 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -12,8 +12,7 @@ error[E0425]: cannot find value `no` in this scope 3 | no | ^^ not found in this scope - -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:326:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:361:13 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ---- @@ -22,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 11)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -', src/librustdoc/test.rs:395:17 +', src/librustdoc/test.rs:396:17 failures: From 09cad1b8a56adce59df92a588e43552dc2f832f0 Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Mon, 31 Dec 2018 18:05:57 -0500 Subject: [PATCH 0142/1064] Add book section and fix typo. --- src/dlmalloc | 1 - src/doc/rustdoc/src/unstable-features.md | 4 ++++ src/libcompiler_builtins | 1 - src/liblibc | 1 - src/librustdoc/config.rs | 3 ++- src/librustdoc/lib.rs | 1 + 6 files changed, 7 insertions(+), 4 deletions(-) delete mode 160000 src/dlmalloc delete mode 160000 src/libcompiler_builtins delete mode 160000 src/liblibc diff --git a/src/dlmalloc b/src/dlmalloc deleted file mode 160000 index c99638dc2ecfc..0000000000000 --- a/src/dlmalloc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c99638dc2ecfc750cc1656f6edb2bd062c1e0981 diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 905b06465340a..92ea366686cc8 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -417,3 +417,7 @@ JavaScript, and font files in a single location, rather than duplicating it once (grouping of crate docs generated into the same output directory, like with `cargo doc`). Per-crate files like the search index will still load from the documentation root, but anything that gets renamed with `--resource-suffix` will load from the given path. + +### `--persist-doctests`: persist doctest executables after running + +This feature allows the persistence of the doctest executables to the specified path. \ No newline at end of file diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins deleted file mode 160000 index fe74674f6e4be..0000000000000 --- a/src/libcompiler_builtins +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fe74674f6e4be76d47b66f67d529ebf4186f4eb1 diff --git a/src/liblibc b/src/liblibc deleted file mode 160000 index c75ca6465a139..0000000000000 --- a/src/liblibc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c75ca6465a139704e00295be355b1f067af2f535 diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 1c14dbf1cef8b..635d071b8e061 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -68,7 +68,8 @@ pub struct Options { pub should_test: bool, /// List of arguments to pass to the test harness, if running tests. pub test_args: Vec, - /// Otional path to persist the doctest executables to. + /// Optional path to persist the doctest executables to, defaults to a + /// temporary directory if not set. pub persist_doctests: Option, // Options that affect the documentation process diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 08bbc95ad6524..4bbc01d32de3a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -340,6 +340,7 @@ fn opts() -> Vec { o.optflag("", "disable-per-crate-search", "disables generating the crate selector on the search box") + }), unstable("persist-doctests", |o| { o.optopt("", "persist-doctests", From f5413cd1e232837775bd8dfc803af4429e8c89c4 Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Mon, 31 Dec 2018 20:03:33 -0500 Subject: [PATCH 0143/1064] Bless test. Bless test, remove submodule, and fix book entry. bless test again? maybe it'll work this time... --- src/doc/rustdoc/src/unstable-features.md | 10 +++++++++- src/test/rustdoc-ui/failed-doctest-output.stdout | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 92ea366686cc8..d3eb8cb3d3b8a 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -420,4 +420,12 @@ renamed with `--resource-suffix` will load from the given path. ### `--persist-doctests`: persist doctest executables after running -This feature allows the persistence of the doctest executables to the specified path. \ No newline at end of file +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs --test -Z unstable-options --persist-doctests target/rustdoctest +``` + +This flag allows you to keep doctest executables around after they're compiled or run. +Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but +with this option, you can keep those binaries around for farther testing. \ No newline at end of file diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index c54e7be46bb8d..8af05e9ca97b1 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -12,7 +12,7 @@ error[E0425]: cannot find value `no` in this scope 3 | no | ^^ not found in this scope -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:361:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:354:13 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ---- @@ -21,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 11)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -', src/librustdoc/test.rs:396:17 +', src/librustdoc/test.rs:389:17 failures: From 55768330a9046d240c5e542419d808626106a0aa Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Jan 2019 09:51:24 +1100 Subject: [PATCH 0144/1064] Remove unneeded `origin` arg from `iterate_until_fixed_point`'s closure. --- src/librustc/infer/lexical_region_resolve/mod.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 39ce8cc621b49..f45ed395c414f 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -186,8 +186,8 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - self.iterate_until_fixed_point("Expansion", |constraint, origin| { - debug!("expansion: constraint={:?} origin={:?}", constraint, origin); + self.iterate_until_fixed_point("Expansion", |constraint| { + debug!("expansion: constraint={:?}", constraint); match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); @@ -722,18 +722,17 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } fn iterate_until_fixed_point(&self, tag: &str, mut body: F) - where - F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool), + where F: FnMut(&Constraint<'tcx>) -> (bool, bool), { - let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect(); + let mut constraints: SmallVec<[_; 16]> = self.data.constraints.keys().collect(); let mut iteration = 0; let mut changed = true; while changed { changed = false; iteration += 1; debug!("---- {} Iteration {}{}", "#", tag, iteration); - constraints.retain(|(constraint, origin)| { - let (edge_changed, retain) = body(constraint, origin); + constraints.retain(|constraint| { + let (edge_changed, retain) = body(constraint); if edge_changed { debug!("Updated due to constraint {:?}", constraint); changed = true; From 92fd6f9d30d0b6b4ecbcf01534809fb66393f139 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Jan 2019 10:00:51 +1100 Subject: [PATCH 0145/1064] Inline `expand_node`. This requires restructuring things a little so that there is only one callsite, ensuring that inlinining doesn't cause unnecessary code bloat. This reduces instruction counts for the `unicode_normalization` benchmark by up to 4%. --- .../infer/lexical_region_resolve/mod.rs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f45ed395c414f..545192a1f2113 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -188,32 +188,37 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { self.iterate_until_fixed_point("Expansion", |constraint| { debug!("expansion: constraint={:?}", constraint); - match *constraint { + let (a_region, b_vid, b_data, retain) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (self.expand_node(a_region, b_vid, b_data), false) + (a_region, b_vid, b_data, false) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue => (false, false), + VarValue::ErrorValue => return (false, false), VarValue::Value(a_region) => { - let b_node = var_values.value_mut(b_vid); - let changed = self.expand_node(a_region, b_vid, b_node); - let retain = match *b_node { + let b_data = var_values.value_mut(b_vid); + let retain = match *b_data { VarValue::Value(ReStatic) | VarValue::ErrorValue => false, _ => true }; - (changed, retain) + (a_region, b_vid, b_data, retain) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { // These constraints are checked after expansion // is done, in `collect_errors`. - (false, false) + return (false, false) } - } + }; + + let changed = self.expand_node(a_region, b_vid, b_data); + (changed, retain) }) } + // This function is very hot in some workloads. There's a single callsite + // so always inlining is ok even though it's large. + #[inline(always)] fn expand_node( &self, a_region: Region<'tcx>, From e3ba6ed3f571119e2f9165805e77c20b5e7a14b4 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Thu, 17 Jan 2019 13:53:21 +0000 Subject: [PATCH 0146/1064] Fix suggestions given mulitple bad lifetimes When given multiple lifetimes prior to type parameters in generic parameters, do not ICE and print the correct suggestion. --- src/librustc_errors/lib.rs | 9 ++-- src/libsyntax/parse/parser.rs | 21 +++------ src/test/ui/lifetime-before-type-params.rs | 9 ++++ .../ui/lifetime-before-type-params.stderr | 47 +++++++++++++++++++ .../suggestions/suggest-move-lifetimes.stderr | 4 +- 5 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/lifetime-before-type-params.rs create mode 100644 src/test/ui/lifetime-before-type-params.stderr diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index a074441f8a179..3e25f98ccd27c 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -135,10 +135,11 @@ impl CodeSuggestion { if let Some(line) = line_opt { if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) { let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi)); - buf.push_str(match hi_opt { - Some(hi) => &line[lo..hi], - None => &line[lo..], - }); + match hi_opt { + Some(hi) if hi > lo => buf.push_str(&line[lo..hi]), + Some(_) => (), + None => buf.push_str(&line[lo..]), + } } if let None = hi_opt { buf.push('\n'); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 823c786bded26..5b430d13516b4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5234,22 +5234,13 @@ impl<'a> Parser<'a> { kind: ast::GenericParamKind::Lifetime, }); if let Some(sp) = seen_ty_param { - let param_span = self.prev_span; - let ate_comma = self.eat(&token::Comma); - let remove_sp = if ate_comma { - param_span.until(self.span) - } else { - last_comma_span.unwrap_or(param_span).to(param_span) - }; - bad_lifetime_pos.push(param_span); - - if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) { + let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); + bad_lifetime_pos.push(self.prev_span); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { suggestions.push((remove_sp, String::new())); - suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet))); - } - if ate_comma { - last_comma_span = Some(self.prev_span); - continue + suggestions.push(( + sp.shrink_to_lo(), + format!("{}, ", snippet))); } } } else if self.check_ident() { diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs new file mode 100644 index 0000000000000..9b905d4883a16 --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.rs @@ -0,0 +1,9 @@ +#![allow(unused)] +fn first() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters +fn second<'a, T, 'b>() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters +fn third() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters +fn fourth<'a, T, 'b, U, 'c, V>() {} +//~^ ERROR lifetime parameters must be declared prior to type parameters diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr new file mode 100644 index 0000000000000..7ac8dffdfbe0c --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.stderr @@ -0,0 +1,47 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:2:13 + | +LL | fn first() {} + | ^^ ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn first<'a, 'b, T>() {} + | ^^^ ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:4:18 + | +LL | fn second<'a, T, 'b>() {} + | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn second<'a, 'b, T>() {} + | ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:6:16 + | +LL | fn third() {} + | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn third<'a, T, U>() {} + | ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/lifetime-before-type-params.rs:8:18 + | +LL | fn fourth<'a, T, 'b, U, 'c, V>() {} + | ^^ ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn fourth<'a, 'b, 'c, T, U, V>() {} + | ^^^ ^^^ -- -- + +error[E0601]: `main` function not found in crate `lifetime_before_type_params` + | + = note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index 72a2cbe6bf6de..b36e927b5c0c6 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -16,7 +16,7 @@ LL | struct B { //~ ERROR lifetime parameters must be declared help: move the lifetime parameter prior to the first type parameter | LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared - | ^^^ -- + | ^^^ -- error: lifetime parameters must be declared prior to type parameters --> $DIR/suggest-move-lifetimes.rs:10:16 @@ -36,7 +36,7 @@ LL | struct D { //~ ERROR lifetime parameters must be decla help: move the lifetime parameter prior to the first type parameter | LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared - | ^^^ ^^^ ^^^ --- + | ^^^ ^^^ ^^^ -- -- error: aborting due to 4 previous errors From 7c31d54619a1c774fc5ad067f336ed92b6421584 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 17 Jan 2019 17:36:34 -0800 Subject: [PATCH 0147/1064] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 2b4a5f1f0bb6e..ffe65875fd050 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 2b4a5f1f0bb6e13759e88ea9512527b0beba154f +Subproject commit ffe65875fd05018599ad07e7389e99050c7915be From 2f8a77445f8b8bb3322060ea386b50afe52d00e8 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 3 Dec 2018 14:40:04 -0600 Subject: [PATCH 0148/1064] better lifetime error message --- .../borrow_check/nll/region_infer/error_reporting/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 77c8a896b04ed..2a858bdd601ae 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -505,7 +505,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) { let mut diag = infcx.tcx.sess.struct_span_err( span, - "unsatisfied lifetime constraints", // FIXME + "lifetime may not live long enough" ); let counter = &mut 1; From 274d293cab4ec3d994d9f84192464168e971ea56 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 11 Dec 2018 15:49:40 -0600 Subject: [PATCH 0149/1064] Update tests --- .../escape-argument-callee.stderr | 2 +- .../propagate-approximated-fail-no-postdom.stderr | 2 +- .../propagate-approximated-ref.rs | 3 +-- .../propagate-approximated-ref.stderr | 11 +++++------ .../propagate-approximated-val.rs | 3 +-- .../propagate-approximated-val.stderr | 11 +++++------ ...agate-fail-to-approximate-longer-no-bounds.stderr | 2 +- ...te-fail-to-approximate-longer-wrong-bounds.stderr | 2 +- .../region-lbr-named-does-not-outlive-static.stderr | 2 +- .../region-lbr1-does-not-outlive-ebr2.rs | 4 ++-- .../region-lbr1-does-not-outlive-ebr2.stderr | 2 +- .../return-wrong-bound-region.stderr | 2 +- src/test/ui/nll/issue-48238.stderr | 2 +- src/test/ui/nll/issue-50716.stderr | 2 +- src/test/ui/nll/issue-52113.rs | 9 ++++----- src/test/ui/nll/issue-52113.stderr | 6 +++--- src/test/ui/nll/issue-52742.rs | 6 +++--- src/test/ui/nll/issue-52742.stderr | 2 +- src/test/ui/nll/issue-55394.rs | 2 +- src/test/ui/nll/issue-55394.stderr | 4 ++-- src/test/ui/nll/mir_check_cast_closure.rs | 2 +- src/test/ui/nll/mir_check_cast_closure.stderr | 2 +- src/test/ui/nll/mir_check_cast_reify.rs | 2 +- src/test/ui/nll/mir_check_cast_reify.stderr | 2 +- src/test/ui/nll/mir_check_cast_unsafe_fn.rs | 2 +- src/test/ui/nll/mir_check_cast_unsafe_fn.stderr | 2 +- src/test/ui/nll/mir_check_cast_unsize.rs | 2 +- src/test/ui/nll/mir_check_cast_unsize.stderr | 2 +- .../ty-outlives/projection-one-region-closure.stderr | 4 ++-- .../projection-one-region-trait-bound-closure.stderr | 4 ++-- .../projection-two-region-trait-bound-closure.rs | 2 +- .../projection-two-region-trait-bound-closure.stderr | 4 ++-- src/test/ui/nll/type-alias-free-regions.stderr | 4 ++-- src/test/ui/nll/user-annotations/closure-substs.rs | 8 ++++---- .../ui/nll/user-annotations/closure-substs.stderr | 12 ++++++------ .../constant-in-expr-inherent-1.stderr | 2 +- .../constant-in-expr-normalize.stderr | 2 +- .../constant-in-expr-trait-item-1.stderr | 2 +- .../constant-in-expr-trait-item-2.stderr | 2 +- .../constant-in-expr-trait-item-3.stderr | 2 +- src/test/ui/nll/user-annotations/issue-54124.rs | 4 ++-- src/test/ui/nll/user-annotations/issue-54124.stderr | 8 ++++---- src/test/ui/nll/user-annotations/patterns.stderr | 8 ++++---- src/test/ui/nll/user-annotations/wf-self-type.rs | 2 +- src/test/ui/nll/user-annotations/wf-self-type.stderr | 4 ++-- src/test/ui/nll/where_clauses_in_functions.rs | 2 +- src/test/ui/nll/where_clauses_in_functions.stderr | 2 +- src/test/ui/nll/where_clauses_in_structs.rs | 2 +- src/test/ui/nll/where_clauses_in_structs.stderr | 2 +- src/test/ui/regions/regions-static-bound.nll.stderr | 2 +- src/test/ui/regions/regions-static-bound.rs | 2 +- 51 files changed, 88 insertions(+), 93 deletions(-) diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 66f8791bfcb65..8e407070342cf 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -9,7 +9,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) i32)) ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/escape-argument-callee.rs:26:45 | LL | let mut closure = expect_sig(|p, y| *p = y); diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 5594271a21d60..55e4573e60bbb 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -16,7 +16,7 @@ LL | | }, = note: late-bound region is '_#5r = note: late-bound region is '_#6r -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 | LL | |_outlives1, _outlives2, _outlives3, x, y| { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs index 7296bbad5189f..1c409a14b7280 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs @@ -41,10 +41,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3 #[rustc_regions] fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - // Only works if 'x: 'y: demand_y(x, y, x.get()) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index a827b85318792..5863b9bc84094 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -3,10 +3,9 @@ note: External requirements | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { | _______________________________________________^ -LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) -LL | | //~^ ERROR unsatisfied lifetime constraints +LL | | //~^ ERROR lifetime may not live long enough LL | | }); | |_____^ | @@ -24,17 +23,17 @@ note: No external requirements | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { -LL | | LL | | // Only works if 'x: 'y: -... | +LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR lifetime may not live long enough LL | | }); LL | | } | |_^ | = note: defining type: DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]) with substs [] -error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-ref.rs:46:9 +error: lifetime may not live long enough + --> $DIR/propagate-approximated-ref.rs:45:9 | LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs index eb6159c14e1e2..233a5dcab08ab 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs @@ -34,10 +34,9 @@ fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y: #[rustc_regions] fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { - // Only works if 'x: 'y: demand_y(outlives1, outlives2, x.get()) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index 1f9d1d7fb5038..b6d9d8529cf5c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -3,10 +3,9 @@ note: External requirements | LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { | _____________________________________________^ -LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(outlives1, outlives2, x.get()) -LL | | //~^ ERROR unsatisfied lifetime constraints +LL | | //~^ ERROR lifetime may not live long enough LL | | }); | |_____^ | @@ -24,17 +23,17 @@ note: No external requirements | LL | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { -LL | | LL | | // Only works if 'x: 'y: -... | +LL | | demand_y(outlives1, outlives2, x.get()) +LL | | //~^ ERROR lifetime may not live long enough LL | | }); LL | | } | |_^ | = note: defining type: DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]) with substs [] -error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-val.rs:39:9 +error: lifetime may not live long enough + --> $DIR/propagate-approximated-val.rs:38:9 | LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 1a8988f365d0c..93eb93bdc0638 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -16,7 +16,7 @@ LL | | }); = note: late-bound region is '_#2r = note: late-bound region is '_#3r -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index d0492bdc573c3..c7809de88b922 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -16,7 +16,7 @@ LL | | }); = note: late-bound region is '_#3r = note: late-bound region is '_#4r -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr index 0bc05922235cf..d0a24a267fd4f 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/region-lbr-named-does-not-outlive-static.rs:9:5 | LL | fn foo<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs index 1be27aebb3f0d..4d864c6e58868 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs +++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs @@ -7,7 +7,7 @@ fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { &*x - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr index 2332332f5b8c0..6dc98a944086f 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/region-lbr1-does-not-outlive-ebr2.rs:9:5 | LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 26243f9b821d3..4a035d0c9cd83 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -9,7 +9,7 @@ LL | expect_sig(|a, b| b); // ought to return `a` for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32 ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/return-wrong-bound-region.rs:11:23 | LL | expect_sig(|a, b| b); // ought to return `a` diff --git a/src/test/ui/nll/issue-48238.stderr b/src/test/ui/nll/issue-48238.stderr index 913effa1c93c0..7cb5eb736c0e3 100644 --- a/src/test/ui/nll/issue-48238.stderr +++ b/src/test/ui/nll/issue-48238.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-48238.rs:11:13 | LL | move || use_val(&orig); //~ ERROR diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index fa893df3e15ad..229bb1777cc5e 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-50716.rs:16:14 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) diff --git a/src/test/ui/nll/issue-52113.rs b/src/test/ui/nll/issue-52113.rs index 8428e55eeb65b..795f4f426ffff 100644 --- a/src/test/ui/nll/issue-52113.rs +++ b/src/test/ui/nll/issue-52113.rs @@ -3,8 +3,8 @@ #![allow(warnings)] #![feature(nll)] -trait Bazinga { } -impl Bazinga for F { } +trait Bazinga {} +impl Bazinga for F {} fn produce1<'a>(data: &'a u32) -> impl Bazinga + 'a { let x = move || { @@ -21,7 +21,6 @@ fn produce2<'a>(data: &'a mut Vec<&'a u32>, value: &'a u32) -> impl Bazinga + 'a x } - fn produce3<'a, 'b: 'a>(data: &'a mut Vec<&'a u32>, value: &'b u32) -> impl Bazinga + 'a { let x = move || { let value: &'a u32 = value; @@ -35,7 +34,7 @@ fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl B let value: &'a u32 = value; data.push(value); }; - x //~ ERROR unsatisfied lifetime constraints + x //~ ERROR lifetime may not live long enough } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/issue-52113.stderr b/src/test/ui/nll/issue-52113.stderr index 873612d7657d6..ceae16185bbb1 100644 --- a/src/test/ui/nll/issue-52113.stderr +++ b/src/test/ui/nll/issue-52113.stderr @@ -1,12 +1,12 @@ -error: unsatisfied lifetime constraints - --> $DIR/issue-52113.rs:38:5 +error: lifetime may not live long enough + --> $DIR/issue-52113.rs:37:5 | LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here ... -LL | x //~ ERROR unsatisfied lifetime constraints +LL | x //~ ERROR lifetime may not live long enough | ^ returning this value requires that `'a` must outlive `'b` error: aborting due to previous error diff --git a/src/test/ui/nll/issue-52742.rs b/src/test/ui/nll/issue-52742.rs index d8251cb20640a..150e67fe09481 100644 --- a/src/test/ui/nll/issue-52742.rs +++ b/src/test/ui/nll/issue-52742.rs @@ -7,14 +7,14 @@ struct Foo<'a, 'b> { } struct Bar<'b> { - z: &'b u32 + z: &'b u32, } impl Foo<'_, '_> { fn take_bar(&mut self, b: Bar<'_>) { self.y = b.z - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr index f733702cd8b4b..6b25296c4bda1 100644 --- a/src/test/ui/nll/issue-52742.stderr +++ b/src/test/ui/nll/issue-52742.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-52742.rs:15:9 | LL | fn take_bar(&mut self, b: Bar<'_>) { diff --git a/src/test/ui/nll/issue-55394.rs b/src/test/ui/nll/issue-55394.rs index 4a83c33239c19..deb1034525edb 100644 --- a/src/test/ui/nll/issue-55394.rs +++ b/src/test/ui/nll/issue-55394.rs @@ -8,7 +8,7 @@ struct Foo<'s> { impl Foo<'_> { fn new(bar: &mut Bar) -> Self { - Foo { bar } //~ ERROR unsatisfied lifetime constraints + Foo { bar } //~ERROR lifetime may not live long enough } } diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr index a4c5160c7b326..bcdd78248eb4b 100644 --- a/src/test/ui/nll/issue-55394.stderr +++ b/src/test/ui/nll/issue-55394.stderr @@ -1,11 +1,11 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-55394.rs:11:9 | LL | fn new(bar: &mut Bar) -> Self { | - ---- return type is Foo<'2> | | | let's call the lifetime of this reference `'1` -LL | Foo { bar } //~ ERROR unsatisfied lifetime constraints +LL | Foo { bar } //~ERROR lifetime may not live long enough | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` error: aborting due to previous error diff --git a/src/test/ui/nll/mir_check_cast_closure.rs b/src/test/ui/nll/mir_check_cast_closure.rs index 5298e840defd5..0619ff37d972b 100644 --- a/src/test/ui/nll/mir_check_cast_closure.rs +++ b/src/test/ui/nll/mir_check_cast_closure.rs @@ -5,7 +5,7 @@ fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { let g: fn(_, _) -> _ = |_x, y| y; g - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_closure.stderr b/src/test/ui/nll/mir_check_cast_closure.stderr index b88353371dfbc..e14cb074c81f8 100644 --- a/src/test/ui/nll/mir_check_cast_closure.stderr +++ b/src/test/ui/nll/mir_check_cast_closure.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_closure.rs:7:5 | LL | fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { diff --git a/src/test/ui/nll/mir_check_cast_reify.rs b/src/test/ui/nll/mir_check_cast_reify.rs index b0ad8e34b17b5..be12e313b42e6 100644 --- a/src/test/ui/nll/mir_check_cast_reify.rs +++ b/src/test/ui/nll/mir_check_cast_reify.rs @@ -35,7 +35,7 @@ fn bar<'a>(x: &'a u32) -> &'static u32 { // as part of checking the `ReifyFnPointer`. let f: fn(_) -> _ = foo; f(x) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_reify.stderr b/src/test/ui/nll/mir_check_cast_reify.stderr index 2585486f12702..4e8eec330a579 100644 --- a/src/test/ui/nll/mir_check_cast_reify.stderr +++ b/src/test/ui/nll/mir_check_cast_reify.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_reify.rs:37:5 | LL | fn bar<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.rs b/src/test/ui/nll/mir_check_cast_unsafe_fn.rs index 29fbf462b30a9..9df9c05748924 100644 --- a/src/test/ui/nll/mir_check_cast_unsafe_fn.rs +++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.rs @@ -7,7 +7,7 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { // in `g`. These are related via the `UnsafeFnPointer` cast. let g: unsafe fn(_) -> _ = f; unsafe { g(input) } - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr index e7b945a51caaf..52959850a3332 100644 --- a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr +++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_unsafe_fn.rs:9:14 | LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/mir_check_cast_unsize.rs b/src/test/ui/nll/mir_check_cast_unsize.rs index e98d5e14fca62..d15c4e4f46722 100644 --- a/src/test/ui/nll/mir_check_cast_unsize.rs +++ b/src/test/ui/nll/mir_check_cast_unsize.rs @@ -6,7 +6,7 @@ use std::fmt::Debug; fn bar<'a>(x: &'a u32) -> &'static dyn Debug { x - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/mir_check_cast_unsize.stderr b/src/test/ui/nll/mir_check_cast_unsize.stderr index 189bb2dff5275..364d6c17ea7f6 100644 --- a/src/test/ui/nll/mir_check_cast_unsize.stderr +++ b/src/test/ui/nll/mir_check_cast_unsize.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/mir_check_cast_unsize.rs:8:5 | LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug { diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index f2bfdaecdaf27..e8283d1ab5da2 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -40,7 +40,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`... -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:45:39 | LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -94,7 +94,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:56:39 | LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index fc59100d1873a..78a8c803dd972 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -31,7 +31,7 @@ LL | | } T ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-trait-bound-closure.rs:37:39 | LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -76,7 +76,7 @@ LL | | } T ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-one-region-trait-bound-closure.rs:47:39 | LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs index 25877e6665c40..20edfb33931af 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs @@ -85,7 +85,7 @@ where T: Anything<'b, 'b>, { with_signature(cell, t, |cell, t| require(cell, t)); - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } #[rustc_regions] diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index c2b54b610fffa..d8725dc4284f3 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -217,7 +217,7 @@ LL | | where LL | | T: Anything<'b, 'b>, LL | | { LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | //~^ ERROR unsatisfied lifetime constraints +LL | | //~^ ERROR lifetime may not live long enough LL | | } | |_^ | @@ -226,7 +226,7 @@ LL | | } T ] -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 | LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr index 6b3bb60d51d3b..bcd141bb406b1 100644 --- a/src/test/ui/nll/type-alias-free-regions.stderr +++ b/src/test/ui/nll/type-alias-free-regions.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/type-alias-free-regions.rs:19:9 | LL | impl<'a> FromBox<'a> for C<'a> { @@ -8,7 +8,7 @@ LL | fn from_box(b: Box) -> Self { LL | C { f: b } //~ ERROR | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/type-alias-free-regions.rs:29:9 | LL | impl<'a> FromTuple<'a> for C<'a> { diff --git a/src/test/ui/nll/user-annotations/closure-substs.rs b/src/test/ui/nll/user-annotations/closure-substs.rs index 9dc84aa0ba7b5..cafdd9257fdc0 100644 --- a/src/test/ui/nll/user-annotations/closure-substs.rs +++ b/src/test/ui/nll/user-annotations/closure-substs.rs @@ -5,21 +5,21 @@ fn foo<'a>() { // Here `x` is free in the closure sig: |x: &'a i32| -> &'static i32 { - return x; //~ ERROR unsatisfied lifetime constraints + return x; //~ ERROR lifetime may not live long enough }; } fn foo1() { // Here `x` is bound in the closure sig: |x: &i32| -> &'static i32 { - return x; //~ ERROR unsatisfied lifetime constraints + return x; //~ ERROR lifetime may not live long enough }; } fn bar<'a>() { // Here `x` is free in the closure sig: |x: &'a i32, b: fn(&'static i32)| { - b(x); //~ ERROR unsatisfied lifetime constraints + b(x); //~ ERROR lifetime may not live long enough }; } @@ -30,4 +30,4 @@ fn bar1() { }; } -fn main() { } +fn main() {} diff --git a/src/test/ui/nll/user-annotations/closure-substs.stderr b/src/test/ui/nll/user-annotations/closure-substs.stderr index ffc6e5a275705..a46ab61418efb 100644 --- a/src/test/ui/nll/user-annotations/closure-substs.stderr +++ b/src/test/ui/nll/user-annotations/closure-substs.stderr @@ -1,27 +1,27 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/closure-substs.rs:8:16 | LL | fn foo<'a>() { | -- lifetime `'a` defined here ... -LL | return x; //~ ERROR unsatisfied lifetime constraints +LL | return x; //~ ERROR lifetime may not live long enough | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/closure-substs.rs:15:16 | LL | |x: &i32| -> &'static i32 { | - let's call the lifetime of this reference `'1` -LL | return x; //~ ERROR unsatisfied lifetime constraints +LL | return x; //~ ERROR lifetime may not live long enough | ^ returning this value requires that `'1` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/closure-substs.rs:22:9 | LL | fn bar<'a>() { | -- lifetime `'a` defined here ... -LL | b(x); //~ ERROR unsatisfied lifetime constraints +LL | b(x); //~ ERROR lifetime may not live long enough | ^^^^ argument requires that `'a` must outlive `'static` error[E0521]: borrowed data escapes outside of closure diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index 94fbe01772412..541a7113ec740 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-inherent-1.rs:10:5 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr index 7aeb276eeb929..5b97c12b626b3 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-normalize.rs:20:5 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr index fee9abc1ed83a..10e48b5bc348b 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-trait-item-1.rs:12:5 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr index 047aad9831923..5bfa32ec64492 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-trait-item-2.rs:12:5 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr index b373cebacb063..a1e60db05d08f 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/constant-in-expr-trait-item-3.rs:12:5 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/issue-54124.rs b/src/test/ui/nll/user-annotations/issue-54124.rs index 042ad028575bb..e1de67aa93869 100644 --- a/src/test/ui/nll/user-annotations/issue-54124.rs +++ b/src/test/ui/nll/user-annotations/issue-54124.rs @@ -1,8 +1,8 @@ #![feature(nll)] fn test<'a>() { - let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints - //~^ ERROR unsatisfied lifetime constraints + let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/nll/user-annotations/issue-54124.stderr b/src/test/ui/nll/user-annotations/issue-54124.stderr index 5b5afaee8df71..b1c2411e46c01 100644 --- a/src/test/ui/nll/user-annotations/issue-54124.stderr +++ b/src/test/ui/nll/user-annotations/issue-54124.stderr @@ -1,19 +1,19 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-54124.rs:4:22 | LL | fn test<'a>() { | -- lifetime `'a` defined here -LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints +LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough | ^ - let's call the lifetime of this reference `'1` | | | requires that `'1` must outlive `'a` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-54124.rs:4:22 | LL | fn test<'a>() { | -- lifetime `'a` defined here -LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints +LL | let _:fn(&()) = |_:&'a ()| {}; //~ ERROR lifetime may not live long enough | ^ requires that `'a` must outlive `'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/user-annotations/patterns.stderr b/src/test/ui/nll/user-annotations/patterns.stderr index b0c554e6ca1d4..476578e074dac 100644 --- a/src/test/ui/nll/user-annotations/patterns.stderr +++ b/src/test/ui/nll/user-annotations/patterns.stderr @@ -148,7 +148,7 @@ LL | value1: &x, //~ ERROR LL | } | - `x` dropped here while still borrowed -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:113:5 | LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { @@ -157,7 +157,7 @@ LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { LL | y //~ ERROR | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:125:5 | LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { @@ -166,7 +166,7 @@ LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { LL | y //~ ERROR | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:130:5 | LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 { @@ -175,7 +175,7 @@ LL | let Single { value: y }: Single<&'a u32> = Single { value: &22 }; LL | y //~ ERROR | ^ returning this value requires that `'a` must outlive `'static` -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/patterns.rs:134:18 | LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/wf-self-type.rs b/src/test/ui/nll/user-annotations/wf-self-type.rs index da9ef8c89a169..d8caf4693b504 100644 --- a/src/test/ui/nll/user-annotations/wf-self-type.rs +++ b/src/test/ui/nll/user-annotations/wf-self-type.rs @@ -9,7 +9,7 @@ impl<'a, 'b> Foo<'a, 'b> { } pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { - Foo::xmute(u) //~ ERROR unsatisfied lifetime constraints + Foo::xmute(u) //~ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/user-annotations/wf-self-type.stderr b/src/test/ui/nll/user-annotations/wf-self-type.stderr index 401fe2a058a60..00500c8d6541f 100644 --- a/src/test/ui/nll/user-annotations/wf-self-type.stderr +++ b/src/test/ui/nll/user-annotations/wf-self-type.stderr @@ -1,11 +1,11 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/wf-self-type.rs:12:5 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here -LL | Foo::xmute(u) //~ ERROR unsatisfied lifetime constraints +LL | Foo::xmute(u) //~ ERROR lifetime may not live long enough | ^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` error: aborting due to previous error diff --git a/src/test/ui/nll/where_clauses_in_functions.rs b/src/test/ui/nll/where_clauses_in_functions.rs index 256ec6000faa7..0d35c09b8ef07 100644 --- a/src/test/ui/nll/where_clauses_in_functions.rs +++ b/src/test/ui/nll/where_clauses_in_functions.rs @@ -11,7 +11,7 @@ where fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { foo(x, y) - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/where_clauses_in_functions.stderr b/src/test/ui/nll/where_clauses_in_functions.stderr index 4419a19010c9e..f3b65ec31ac7d 100644 --- a/src/test/ui/nll/where_clauses_in_functions.stderr +++ b/src/test/ui/nll/where_clauses_in_functions.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/where_clauses_in_functions.rs:13:5 | LL | fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { diff --git a/src/test/ui/nll/where_clauses_in_structs.rs b/src/test/ui/nll/where_clauses_in_structs.rs index 1b02f26a67837..8bc6b2e4a4fbb 100644 --- a/src/test/ui/nll/where_clauses_in_structs.rs +++ b/src/test/ui/nll/where_clauses_in_structs.rs @@ -11,7 +11,7 @@ struct Foo<'a: 'b, 'b> { fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { Foo { x, y }; - //~^ ERROR unsatisfied lifetime constraints + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/where_clauses_in_structs.stderr b/src/test/ui/nll/where_clauses_in_structs.stderr index 8704b0dc85c21..e0feb40273f6b 100644 --- a/src/test/ui/nll/where_clauses_in_structs.stderr +++ b/src/test/ui/nll/where_clauses_in_structs.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/where_clauses_in_structs.rs:13:11 | LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr index f667afdef7fa7..d6cec03e0ff2e 100644 --- a/src/test/ui/regions/regions-static-bound.nll.stderr +++ b/src/test/ui/regions/regions-static-bound.nll.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/regions-static-bound.rs:9:5 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { diff --git a/src/test/ui/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound.rs index 3ee518702e064..c1a15e50a4d06 100644 --- a/src/test/ui/regions/regions-static-bound.rs +++ b/src/test/ui/regions/regions-static-bound.rs @@ -7,7 +7,7 @@ fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () where 'a: 'b, 'b: 'static { t } fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { t //[ll]~ ERROR E0312 - //[nll]~^ ERROR unsatisfied lifetime constraints + //[nll]~^ ERROR lifetime may not live long enough } fn error(u: &(), v: &()) { From db2d243e9e5cbecdf21f813e8d8bf8e08a2cf3fd Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 17 Jan 2019 22:04:27 -0600 Subject: [PATCH 0150/1064] fix compat-mode ui test --- src/test/ui/nll/issue-55401.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/nll/issue-55401.stderr b/src/test/ui/nll/issue-55401.stderr index 9e50db7b6045d..952b5441f86ff 100644 --- a/src/test/ui/nll/issue-55401.stderr +++ b/src/test/ui/nll/issue-55401.stderr @@ -1,4 +1,4 @@ -error: unsatisfied lifetime constraints +error: lifetime may not live long enough --> $DIR/issue-55401.rs:5:5 | LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 { From ec3c5b0199045b3ae3959631998451543bd99518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:19:30 -0800 Subject: [PATCH 0151/1064] Use structured suggestion to surround struct literal with parenthesis --- src/librustc_resolve/lib.rs | 42 ++++++++++++++++++++++++---- src/test/ui/error-codes/E0423.stderr | 12 ++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 39be3cb744080..430edcafae26a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3369,6 +3369,29 @@ impl<'a> Resolver<'a> { Ok(ref snippet) if snippet == "{" => true, _ => false, }; + // In case this could be a struct literal that needs to be surrounded + // by parenthesis, find the appropriate span. + let mut i = 0; + let mut closing_brace = None; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet == "}" { + let sp = span.to(sp); + if let Ok(snippet) = sm.span_to_snippet(sp) { + closing_brace = Some((sp, snippet)); + } + break; + } + } + _ => break, + } + i += 1; + if i > 100 { // The bigger the span the more likely we're + break; // incorrect. Bound it to 100 chars long. + } + } match source { PathSource::Expr(Some(parent)) => { match parent.node { @@ -3395,11 +3418,20 @@ impl<'a> Resolver<'a> { } }, PathSource::Expr(None) if followed_by_brace == true => { - err.span_label( - span, - format!("did you mean `({} {{ /* fields */ }})`?", - path_str), - ); + if let Some((sp, snippet)) = closing_brace { + err.span_suggestion_with_applicability( + sp, + "surround the struct literal with parenthesis", + format!("({})", snippet), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label( + span, + format!("did you mean `({} {{ /* fields */ }})`?", + path_str), + ); + } return (err, candidates); }, _ => { diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index df9ed631a1c2e..3f3c78c68d097 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -29,19 +29,25 @@ error[E0423]: expected value, found struct `S` --> $DIR/E0423.rs:12:32 | LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } - | ^ did you mean `(S { /* fields */ })`? + | ^--------------- + | | + | help: surround the struct literal with parenthesis: `(S { x: 1, y: 2 })` error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:15:8 | LL | if T {} == T {} { println!("Ok"); } - | ^ did you mean `(T { /* fields */ })`? + | ^--- + | | + | help: surround the struct literal with parenthesis: `(T {})` error[E0423]: expected value, found struct `std::ops::Range` --> $DIR/E0423.rs:21:14 | LL | for _ in std::ops::Range { start: 0, end: 10 } {} - | ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`? + | ^^^^^^^^^^^^^^^---------------------- + | | + | help: surround the struct literal with parenthesis: `(std::ops::Range { start: 0, end: 10 })` error: aborting due to 7 previous errors From 90507295db1665b7567f66fc12ceb0b15e32d44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 20:26:00 -0800 Subject: [PATCH 0152/1064] Do not give incorrect label for return type mismatch --- src/librustc_typeck/check/coercion.rs | 28 ++++++++-- ...o-type-err-cause-on-impl-trait-return-2.rs | 17 ++++++ ...pe-err-cause-on-impl-trait-return-2.stderr | 12 +++++ ...-to-type-err-cause-on-impl-trait-return.rs | 36 +++++++++++++ ...type-err-cause-on-impl-trait-return.stderr | 52 +++++++++++++++++++ 5 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index a82a0d3ce5232..d1c54f824fe9d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1224,9 +1224,31 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause.span, blk_id, ); - if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { - if !sp.overlaps(cause.span) { - db.span_label(*sp, reason_label); + // TODO: replace with navigating up the chain until hitting an fn or + // bailing if no "pass-through" Node is found, in order to provide a + // suggestion when encountering something like: + // ``` + // fn foo(a: bool) -> impl Debug { + // if a { + // bar()?; + // } + // { + // let x = unsafe { bar() }; + // x + // } + // } + // ``` + // + // Verify that this is a tail expression of a function, otherwise the + // label pointing out the cause for the type coercion will be wrong + // as prior return coercions would not be relevant (#57664). + let parent_id = fcx.tcx.hir().get_parent_node(blk_id); + let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); + if fcx.get_node_fn_decl(parent).is_some() { + if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { + if !sp.overlaps(cause.span) { + db.span_label(*sp, reason_label); + } } } } diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs new file mode 100644 index 0000000000000..50f1fe873cb5f --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs @@ -0,0 +1,17 @@ +fn unrelated() -> Result<(), std::string::ParseError> { // #57664 + let x = 0; + + match x { + 1 => { + let property_value_as_string = "a".parse()?; + } + 2 => { + let value: &bool = unsafe { &42 }; + //~^ ERROR mismatched types + } + }; + + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr new file mode 100644 index 0000000000000..edaa60e5b8d8b --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return-2.rs:9:41 + | +LL | let value: &bool = unsafe { &42 }; + | ^^^ expected bool, found integer + | + = note: expected type `&bool` + found type `&{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs new file mode 100644 index 0000000000000..a27df240d0792 --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs @@ -0,0 +1,36 @@ +fn foo() -> impl std::fmt::Display { + if false { + return 0i32; + } + 1u32 + //~^ ERROR mismatched types +} + +fn bar() -> impl std::fmt::Display { + if false { + return 0i32; + } else { + return 1u32; + //~^ ERROR mismatched types + } +} + +fn baz() -> impl std::fmt::Display { + if false { + //~^ ERROR mismatched types + return 0i32; + } else { + 1u32 + } +} + +fn qux() -> impl std::fmt::Display { + if false { + //~^ ERROR if and else have incompatible types + 0i32 + } else { + 1u32 + } +} + +fn main() {} diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr new file mode 100644 index 0000000000000..54f7b108c3dd4 --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -0,0 +1,52 @@ +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 + | +LL | return 0i32; + | ---- expected because of this statement +LL | } +LL | 1u32 + | ^^^^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 + | +LL | return 1u32; + | ^^^^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5 + | +LL | / if false { +LL | | //~^ ERROR mismatched types +LL | | return 0i32; +LL | | } else { +LL | | 1u32 +LL | | } + | |_____^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error[E0308]: if and else have incompatible types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:5 + | +LL | / if false { +LL | | //~^ ERROR if and else have incompatible types +LL | | 0i32 +LL | | } else { +LL | | 1u32 +LL | | } + | |_____^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 19255dc2e670085a7bf6864feccb323077309325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 20:45:50 -0800 Subject: [PATCH 0153/1064] Point more places where expectation comes from --- src/librustc_typeck/check/coercion.rs | 4 +--- src/test/ui/diverging-tuple-parts-39485.stderr | 5 ++++- src/test/ui/issues/issue-10176.stderr | 5 ++++- .../ui/point-to-type-err-cause-on-impl-trait-return.stderr | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d1c54f824fe9d..28114b527933d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1246,9 +1246,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); if fcx.get_node_fn_decl(parent).is_some() { if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { - if !sp.overlaps(cause.span) { - db.span_label(*sp, reason_label); - } + db.span_label(*sp, reason_label); } } } diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index c399650d3258b..f8da9282f5fb7 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -15,7 +15,10 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^-^ + | | | + | | expected because of this statement + | expected isize, found tuple | = note: expected type `isize` found type `(!, !)` diff --git a/src/test/ui/issues/issue-10176.stderr b/src/test/ui/issues/issue-10176.stderr index 45482447ebe2c..592c84bd17d0e 100644 --- a/src/test/ui/issues/issue-10176.stderr +++ b/src/test/ui/issues/issue-10176.stderr @@ -4,7 +4,10 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) - | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^-^ + | | | + | | expected because of this statement + | expected isize, found tuple | = note: expected type `isize` found type `(!, !)` diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 54f7b108c3dd4..b94a9f4df4875 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -25,6 +25,7 @@ error[E0308]: mismatched types LL | / if false { LL | | //~^ ERROR mismatched types LL | | return 0i32; + | | ---- expected because of this statement LL | | } else { LL | | 1u32 LL | | } From c4318502bca669f399b7428d3e9a180b1de041bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:06:09 -0800 Subject: [PATCH 0154/1064] Avoid pointing at multiple places on return type error --- src/librustc_typeck/check/coercion.rs | 4 +-- src/librustc_typeck/check/mod.rs | 28 +++++++++++++------ .../ui/diverging-tuple-parts-39485.stderr | 5 +--- src/test/ui/issues/issue-10176.stderr | 5 +--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 28114b527933d..f040781e56f7c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1216,7 +1216,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> "supposed to be part of a block tail expression, but the \ expression is empty"); }); - fcx.suggest_mismatched_types_on_tail( + let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail( &mut db, expr, expected, @@ -1244,7 +1244,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> // as prior return coercions would not be relevant (#57664). let parent_id = fcx.tcx.hir().get_parent_node(blk_id); let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); - if fcx.get_node_fn_decl(parent).is_some() { + if fcx.get_node_fn_decl(parent).is_some() && !pointing_at_return_type { if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { db.span_label(*sp, reason_label); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..ce876a799644a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5089,12 +5089,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { found: Ty<'tcx>, cause_span: Span, blk_id: ast::NodeId, - ) { + ) -> bool { self.suggest_missing_semicolon(err, expression, expected, cause_span); + let mut pointing_at_return_type = false; if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { - self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); + pointing_at_return_type = self.suggest_missing_return_type( + err, &fn_decl, expected, found, can_suggest); } self.suggest_ref_or_into(err, expression, expected, found); + pointing_at_return_type } pub fn suggest_ref_or_into( @@ -5193,12 +5196,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// This routine checks if the return type is left as default, the method is not part of an /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return /// type. - fn suggest_missing_return_type(&self, - err: &mut DiagnosticBuilder<'tcx>, - fn_decl: &hir::FnDecl, - expected: Ty<'tcx>, - found: Ty<'tcx>, - can_suggest: bool) { + fn suggest_missing_return_type( + &self, + err: &mut DiagnosticBuilder<'tcx>, + fn_decl: &hir::FnDecl, + expected: Ty<'tcx>, + found: Ty<'tcx>, + can_suggest: bool, + ) -> bool { // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()` or an impl). match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) { @@ -5208,16 +5213,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "try adding a return type", format!("-> {} ", self.resolve_type_vars_with_obligations(found)), Applicability::MachineApplicable); + true } (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => { err.span_label(span, "possibly return type missing here?"); + true } (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => { // `fn main()` must return `()`, do not suggest changing return type err.span_label(span, "expected `()` because of default return type"); + true } // expectation was caused by something else, not the default return - (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => {} + (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false, (&hir::FunctionRetTy::Return(ref ty), _, _, _) => { // Only point to return type if the expected type is the return type, as if they // are not, the expectation must have been caused by something else. @@ -5229,7 +5237,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if ty.sty == expected.sty { err.span_label(sp, format!("expected `{}` because of return type", expected)); + return true; } + false } } } diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index f8da9282f5fb7..c399650d3258b 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -15,10 +15,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^-^ - | | | - | | expected because of this statement - | expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple | = note: expected type `isize` found type `(!, !)` diff --git a/src/test/ui/issues/issue-10176.stderr b/src/test/ui/issues/issue-10176.stderr index 592c84bd17d0e..45482447ebe2c 100644 --- a/src/test/ui/issues/issue-10176.stderr +++ b/src/test/ui/issues/issue-10176.stderr @@ -4,10 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) - | ^^^^^^^^^^^^^^^^^^-^ - | | | - | | expected because of this statement - | expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple | = note: expected type `isize` found type `(!, !)` From 9b8243ac2450c49f95cfbee517109ce13d00f95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:18:51 -0800 Subject: [PATCH 0155/1064] Point at more cases involving return types --- src/librustc_typeck/check/mod.rs | 8 ++++++-- .../point-to-type-err-cause-on-impl-trait-return.stderr | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ce876a799644a..7b9b97ff065a6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4347,11 +4347,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { struct_span_err!(self.tcx.sess, expr.span, E0572, "return statement outside of function body").emit(); } else if let Some(ref e) = *expr_opt { - *self.ret_coercion_span.borrow_mut() = Some(e.span); + if self.ret_coercion_span.borrow().is_none() { + *self.ret_coercion_span.borrow_mut() = Some(e.span); + } self.check_return_expr(e); } else { let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut(); - *self.ret_coercion_span.borrow_mut() = Some(expr.span); + if self.ret_coercion_span.borrow().is_none() { + *self.ret_coercion_span.borrow_mut() = Some(expr.span); + } let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression); if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) { coercion.coerce_forced_unit( diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index b94a9f4df4875..be3d2c0db4ca1 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -13,6 +13,9 @@ LL | 1u32 error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 | +LL | return 0i32; + | ---- expected because of this statement +LL | } else { LL | return 1u32; | ^^^^ expected i32, found u32 | From fbb072837dbbaf30a1e81674b457e5ea816dbca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 22:32:59 -0800 Subject: [PATCH 0156/1064] Fix tidy error --- src/librustc_typeck/check/coercion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index f040781e56f7c..7f053d6af9611 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1224,7 +1224,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause.span, blk_id, ); - // TODO: replace with navigating up the chain until hitting an fn or + // FIXME: replace with navigating up the chain until hitting an fn or // bailing if no "pass-through" Node is found, in order to provide a // suggestion when encountering something like: // ``` From 8dea0d0172d5a50b75dbde8ece24201f0d5b2125 Mon Sep 17 00:00:00 2001 From: Kevin Leimkuhler Date: Thu, 11 Oct 2018 09:53:15 -0700 Subject: [PATCH 0157/1064] Add initial impl of is_sorted to Iterator --- src/libcore/iter/iterator.rs | 84 +++++++++++++++++++ src/libcore/lib.rs | 1 + src/libcore/tests/iter.rs | 13 +++ src/libcore/tests/lib.rs | 1 + .../feature-gates/feature-gate-is_sorted.rs | 16 ++++ .../feature-gate-is_sorted.stderr | 19 +++++ 6 files changed, 134 insertions(+) create mode 100644 src/test/ui/feature-gates/feature-gate-is_sorted.rs create mode 100644 src/test/ui/feature-gates/feature-gate-is_sorted.stderr diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 0ad29afbadeac..6c3f8d919120b 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -2605,6 +2605,90 @@ pub trait Iterator { } } } + + /// Checks if the elements of this iterator are sorted. + /// + /// That is, for each element `a` and its following element `b`, `a <= b` + /// must hold. If the iterator yields exactly zero or one element, `true` + /// is returned. + /// + /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above + /// definition implies that this function returns `false` if any two + /// consecutive items are not comparable. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_sorted)] + /// + /// assert!([1, 2, 2, 9].iter().is_sorted()); + /// assert!(![1, 3, 2, 4].iter().is_sorted()); + /// assert!([0].iter().is_sorted()); + /// assert!(std::iter::empty::().is_sorted()); + /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted()); + /// ``` + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + fn is_sorted(self) -> bool + where + Self: Sized, + Self::Item: PartialOrd, + { + self.is_sorted_by(|a, b| a.partial_cmp(b)) + } + + /// Checks if the elements of this iterator are sorted using the given + /// comparator function. + /// + /// Instead of using `PartialOrd::partial_cmp`, this function uses the given + /// `compare` function to determine the ordering of two elements. Apart from + /// that, it's equivalent to `is_sorted`; see its documentation for more + /// information. + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + fn is_sorted_by(mut self, mut compare: F) -> bool + where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option + { + let mut last = match self.next() { + Some(e) => e, + None => return true, + }; + + while let Some(curr) = self.next() { + if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) { + return false; + } + last = curr; + } + + true + } + + /// Checks if the elements of this iterator are sorted using the given + /// key extraction function. + /// + /// Instead of comparing the iterator's elements directly, this function + /// compares the keys of the elements, as determined by `f`. Apart from + /// that, it's equivalent to `is_sorted`; see its documentation for more + /// information. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_sorted)] + /// + /// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); + /// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); + /// ``` + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + fn is_sorted_by_key(self, mut f: F) -> bool + where + Self: Sized, + F: FnMut(&Self::Item) -> K, + K: PartialOrd + { + self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b))) + } } /// Select an element from an iterator based on the given "projection" diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 33c0da8a54049..df32cfa337313 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -79,6 +79,7 @@ #![feature(extern_types)] #![feature(fundamental)] #![feature(intrinsics)] +#![feature(is_sorted)] #![feature(iter_once_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 3944bc749d029..0fa99745d9065 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -2235,3 +2235,16 @@ fn test_monad_laws_associativity() { assert_eq!((0..10).flat_map(f).flat_map(g).sum::(), (0..10).flat_map(|x| f(x).flat_map(g)).sum::()); } + +#[test] +fn test_is_sorted() { + assert!([1, 2, 2, 9].iter().is_sorted()); + assert!(![1, 3, 2].iter().is_sorted()); + assert!([0].iter().is_sorted()); + assert!(std::iter::empty::().is_sorted()); + assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted()); + assert!([-2, -1, 0, 3].iter().is_sorted()); + assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); + assert!(!["c", "bb", "aaa"].iter().is_sorted()); + assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index a9b8decfd0262..3e8549f8ae366 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -10,6 +10,7 @@ #![feature(flt2dec)] #![feature(fmt_internals)] #![feature(hashmap_internals)] +#![feature(is_sorted)] #![feature(iter_copied)] #![feature(iter_nth_back)] #![feature(iter_once_with)] diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs new file mode 100644 index 0000000000000..6b0f943b6c796 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + assert!([1, 2, 2, 9].iter().is_sorted()); + //^ ERROR: use of unstable library feature 'is_sorted' + assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); + //^ ERROR: use of unstable library feature 'is_sorted' +} \ No newline at end of file diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr new file mode 100644 index 0000000000000..e4c7891760cea --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr @@ -0,0 +1,19 @@ +error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) + --> $DIR/feature-gate-is_sorted.rs:12:33 + | +LL | assert!([1, 2, 2, 9].iter().is_sorted()); + | ^^^^^^^^^ + | + = help: add #![feature(is_sorted)] to the crate attributes to enable + +error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) + --> $DIR/feature-gate-is_sorted.rs:14:39 + | +LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); + | ^^^^^^^^^^^^^^^^ + | + = help: add #![feature(is_sorted)] to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From 02477f6f99c22509825a85bd090e42f935b33983 Mon Sep 17 00:00:00 2001 From: Kevin Leimkuhler Date: Thu, 11 Oct 2018 15:59:54 -0700 Subject: [PATCH 0158/1064] Add is_sorted impl for [T] --- src/libcore/iter/iterator.rs | 36 ++++----- src/libcore/slice/mod.rs | 79 ++++++++++++++++++- src/libcore/tests/slice.rs | 15 ++++ .../feature-gates/feature-gate-is_sorted.rs | 2 +- 4 files changed, 110 insertions(+), 22 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 6c3f8d919120b..879cc8357cd24 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -2608,19 +2608,18 @@ pub trait Iterator { /// Checks if the elements of this iterator are sorted. /// - /// That is, for each element `a` and its following element `b`, `a <= b` - /// must hold. If the iterator yields exactly zero or one element, `true` - /// is returned. + /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the + /// iterator yields exactly zero or one element, `true` is returned. /// - /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above - /// definition implies that this function returns `false` if any two - /// consecutive items are not comparable. + /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition + /// implies that this function returns `false` if any two consecutive items are not + /// comparable. /// /// # Examples /// /// ``` /// #![feature(is_sorted)] - /// + /// /// assert!([1, 2, 2, 9].iter().is_sorted()); /// assert!(![1, 3, 2, 4].iter().is_sorted()); /// assert!([0].iter().is_sorted()); @@ -2636,13 +2635,11 @@ pub trait Iterator { self.is_sorted_by(|a, b| a.partial_cmp(b)) } - /// Checks if the elements of this iterator are sorted using the given - /// comparator function. + /// Checks if the elements of this iterator are sorted using the given comparator function. /// - /// Instead of using `PartialOrd::partial_cmp`, this function uses the given - /// `compare` function to determine the ordering of two elements. Apart from - /// that, it's equivalent to `is_sorted`; see its documentation for more - /// information. + /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare` + /// function to determine the ordering of two elements. Apart from that, it's equivalent to + /// `is_sorted`; see its documentation for more information. #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] fn is_sorted_by(mut self, mut compare: F) -> bool where @@ -2664,19 +2661,18 @@ pub trait Iterator { true } - /// Checks if the elements of this iterator are sorted using the given - /// key extraction function. + /// Checks if the elements of this iterator are sorted using the given key extraction + /// function. /// - /// Instead of comparing the iterator's elements directly, this function - /// compares the keys of the elements, as determined by `f`. Apart from - /// that, it's equivalent to `is_sorted`; see its documentation for more - /// information. + /// Instead of comparing the iterator's elements directly, this function compares the keys of + /// the elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see + /// its documentation for more information. /// /// # Examples /// /// ``` /// #![feature(is_sorted)] - /// + /// /// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); /// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); /// ``` diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 7fdc2acb8cc92..d4cac3e4f4b8f 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1783,7 +1783,7 @@ impl [T] { /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; /// a[1..5].rotate_left(1); /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']); - /// ``` + /// ``` #[stable(feature = "slice_rotate", since = "1.26.0")] pub fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); @@ -2250,6 +2250,83 @@ impl [T] { from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len)) } } + + /// Checks if the elements of this slice are sorted. + /// + /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the + /// slice yields exactly zero or one element, `true` is returned. + /// + /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition + /// implies that this function returns `false` if any two consecutive items are not + /// comparable. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_sorted)] + /// let empty: [i32; 0] = []; + /// + /// assert!([1, 2, 2, 9].is_sorted()); + /// assert!(![1, 3, 2, 4].is_sorted()); + /// assert!([0].is_sorted()); + /// assert!(empty.is_sorted()); + /// assert!(![0.0, 1.0, std::f32::NAN].is_sorted()); + /// ``` + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + pub fn is_sorted(&self) -> bool + where + T: PartialOrd, + { + self.is_sorted_by(|a, b| a.partial_cmp(b)) + } + + /// Checks if the elements of this slice are sorted using the given comparator function. + /// + /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare` + /// function to determine the ordering of two elements. Apart from that, it's equivalent to + /// `is_sorted`; see its documentation for more information. + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + pub fn is_sorted_by(&self, mut compare: F) -> bool + where + F: FnMut(&T, &T) -> Option + { + let mut last = match self.first() { + Some(e) => e, + None => return true, + }; + + for curr in &self[1..] { + if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) { + return false; + } + last = &curr; + } + + true + } + + /// Checks if the elements of this slice are sorted using the given key extraction function. + /// + /// Instead of comparing the slice's elements directly, this function compares the keys of the + /// elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see its + /// documentation for more information. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_sorted)] + /// + /// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); + /// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); + /// ``` + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + pub fn is_sorted_by_key(&self, mut f: F) -> bool + where + F: FnMut(&T) -> K, + K: PartialOrd + { + self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b))) + } } #[lang = "slice_u8"] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 2c96efbda7673..e210e83122c47 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1317,3 +1317,18 @@ fn test_copy_within_panics_src_inverted() { // 2 is greater than 1, so this range is invalid. bytes.copy_within(2..1, 0); } + +#[test] +fn test_is_sorted() { + let empty: [i32; 0] = []; + + assert!([1, 2, 2, 9].is_sorted()); + assert!(![1, 3, 2].is_sorted()); + assert!([0].is_sorted()); + assert!(empty.is_sorted()); + assert!(![0.0, 1.0, std::f32::NAN].is_sorted()); + assert!([-2, -1, 0, 3].is_sorted()); + assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); + assert!(!["c", "bb", "aaa"].is_sorted()); + assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); +} diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs index 6b0f943b6c796..82fee379a4fa7 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -13,4 +13,4 @@ fn main() { //^ ERROR: use of unstable library feature 'is_sorted' assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); //^ ERROR: use of unstable library feature 'is_sorted' -} \ No newline at end of file +} From ce47dde59f45d55fa27dce9a614d1a972f9d8a4f Mon Sep 17 00:00:00 2001 From: Kevin Leimkuhler Date: Fri, 12 Oct 2018 14:47:01 -0700 Subject: [PATCH 0159/1064] Add is_sorted unstable documentation --- .../src/library-features/is-sorted.md | 11 ++++++++++ src/libcore/iter/iterator.rs | 2 ++ src/libcore/slice/mod.rs | 2 ++ .../feature-gates/feature-gate-is_sorted.rs | 7 ++++++ .../feature-gate-is_sorted.stderr | 22 ++++++++++++++++--- 5 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/doc/unstable-book/src/library-features/is-sorted.md diff --git a/src/doc/unstable-book/src/library-features/is-sorted.md b/src/doc/unstable-book/src/library-features/is-sorted.md new file mode 100644 index 0000000000000..e3b7dc3b28eb2 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/is-sorted.md @@ -0,0 +1,11 @@ +# `is_sorted` + +The tracking issue for this feature is: [#53485] + +[#53485]: https://github.com/rust-lang/rust/issues/53485 + +------------------------ + +Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`; +add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to +`Iterator`. diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 879cc8357cd24..67591381fdc92 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -2626,6 +2626,7 @@ pub trait Iterator { /// assert!(std::iter::empty::().is_sorted()); /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted()); /// ``` + #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] fn is_sorted(self) -> bool where @@ -2676,6 +2677,7 @@ pub trait Iterator { /// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); /// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); /// ``` + #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] fn is_sorted_by_key(self, mut f: F) -> bool where diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index d4cac3e4f4b8f..ab160a6c0c406 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2272,6 +2272,7 @@ impl [T] { /// assert!(empty.is_sorted()); /// assert!(![0.0, 1.0, std::f32::NAN].is_sorted()); /// ``` + #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] pub fn is_sorted(&self) -> bool where @@ -2319,6 +2320,7 @@ impl [T] { /// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); /// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); /// ``` + #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] pub fn is_sorted_by_key(&self, mut f: F) -> bool where diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs index 82fee379a4fa7..f44e74838ed23 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -9,8 +9,15 @@ // except according to those terms. fn main() { + // Assert `Iterator` methods are feature gated assert!([1, 2, 2, 9].iter().is_sorted()); //^ ERROR: use of unstable library feature 'is_sorted' assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); //^ ERROR: use of unstable library feature 'is_sorted' + + // Assert `[T]` methods are feature gated + assert!([1, 2, 2, 9].is_sorted()); + //^ ERROR: use of unstable library feature 'is_sorted' + assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); + //^ ERROR: use of unstable library feature 'is_sorted' } diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr index e4c7891760cea..873cee533705d 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:12:33 + --> $DIR/feature-gate-is_sorted.rs:13:33 | LL | assert!([1, 2, 2, 9].iter().is_sorted()); | ^^^^^^^^^ @@ -7,13 +7,29 @@ LL | assert!([1, 2, 2, 9].iter().is_sorted()); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:14:39 + --> $DIR/feature-gate-is_sorted.rs:15:39 | LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^ | = help: add #![feature(is_sorted)] to the crate attributes to enable -error: aborting due to 2 previous errors +error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) + --> $DIR/feature-gate-is_sorted.rs:19:26 + | +LL | assert!([1, 2, 2, 9].is_sorted()); + | ^^^^^^^^^ + | + = help: add #![feature(is_sorted)] to the crate attributes to enable + +error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) + --> $DIR/feature-gate-is_sorted.rs:21:32 + | +LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); + | ^^^^^^^^^^^^^^^^ + | + = help: add #![feature(is_sorted)] to the crate attributes to enable + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. From ccc027eff7604bf75f1ad490f415a338e44c1038 Mon Sep 17 00:00:00 2001 From: Kevin Leimkuhler Date: Sat, 13 Oct 2018 17:26:57 -0700 Subject: [PATCH 0160/1064] Improve documentation and slice impl --- src/libcore/iter/iterator.rs | 8 ++++++-- src/libcore/slice/mod.rs | 21 ++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 67591381fdc92..4035ad6b77ca5 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -2640,7 +2640,9 @@ pub trait Iterator { /// /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare` /// function to determine the ordering of two elements. Apart from that, it's equivalent to - /// `is_sorted`; see its documentation for more information. + /// [`is_sorted`]; see its documentation for more information. + /// + /// [`is_sorted`]: trait.Iterator.html#method.is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] fn is_sorted_by(mut self, mut compare: F) -> bool where @@ -2666,9 +2668,11 @@ pub trait Iterator { /// function. /// /// Instead of comparing the iterator's elements directly, this function compares the keys of - /// the elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see + /// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see /// its documentation for more information. /// + /// [`is_sorted`]: trait.Iterator.html#method.is_sorted + /// /// # Examples /// /// ``` diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ab160a6c0c406..9c82aca9ab230 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2285,22 +2285,23 @@ impl [T] { /// /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare` /// function to determine the ordering of two elements. Apart from that, it's equivalent to - /// `is_sorted`; see its documentation for more information. + /// [`is_sorted`]; see its documentation for more information. + /// + /// [`is_sorted`]: #method.is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] pub fn is_sorted_by(&self, mut compare: F) -> bool where F: FnMut(&T, &T) -> Option { - let mut last = match self.first() { - Some(e) => e, - None => return true, - }; + let len = self.len(); + if len <= 1 { + return true; + } - for curr in &self[1..] { - if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) { + for i in 1..len { + if compare(&self[i - 1], &self[i]).map(|o| o == Ordering::Greater).unwrap_or(true) { return false; } - last = &curr; } true @@ -2309,9 +2310,11 @@ impl [T] { /// Checks if the elements of this slice are sorted using the given key extraction function. /// /// Instead of comparing the slice's elements directly, this function compares the keys of the - /// elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see its + /// elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see its /// documentation for more information. /// + /// [`is_sorted`]: #method.is_sorted + /// /// # Examples /// /// ``` From 67729b4040a17508640af17c21876650b34ff6de Mon Sep 17 00:00:00 2001 From: Kevin Leimkuhler Date: Sun, 14 Oct 2018 20:45:28 -0700 Subject: [PATCH 0161/1064] Compare pairs with `slice::windows` --- src/libcore/iter/iterator.rs | 5 ++++- src/libcore/slice/mod.rs | 12 +++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 4035ad6b77ca5..ac21586c0b8a9 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -2655,7 +2655,10 @@ pub trait Iterator { }; while let Some(curr) = self.next() { - if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) { + if compare(&last, &curr) + .map(|o| o == Ordering::Greater) + .unwrap_or(true) + { return false; } last = curr; diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 9c82aca9ab230..11ce8115d3095 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2293,13 +2293,11 @@ impl [T] { where F: FnMut(&T, &T) -> Option { - let len = self.len(); - if len <= 1 { - return true; - } - - for i in 1..len { - if compare(&self[i - 1], &self[i]).map(|o| o == Ordering::Greater).unwrap_or(true) { + for pair in self.windows(2) { + if compare(&pair[0], &pair[1]) + .map(|o| o == Ordering::Greater) + .unwrap_or(true) + { return false; } } From 54f11240b701f7d4031c3d1545232ebad4436c15 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Mon, 17 Dec 2018 15:54:19 +0100 Subject: [PATCH 0162/1064] Override `Iterator::is_sorted_by` in `slice::Iter` impl Additionally, the root implementation was changed a bit: it now uses `all` instead of coding that logic manually. To avoid duplicate code, the inherent `[T]::is_sorted_by` method now calls `self.iter().is_sorted_by(...)`. This should always be inlined and not result in overhead. --- src/libcore/slice/mod.rs | 35 ++++++++++++------- .../feature-gates/feature-gate-is_sorted.rs | 10 ------ .../feature-gate-is_sorted.stderr | 8 ++--- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 11ce8115d3095..df4d97ee6a44d 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2293,16 +2293,7 @@ impl [T] { where F: FnMut(&T, &T) -> Option { - for pair in self.windows(2) { - if compare(&pair[0], &pair[1]) - .map(|o| o == Ordering::Greater) - .unwrap_or(true) - { - return false; - } - } - - true + self.iter().is_sorted_by(|a, b| compare(*a, *b)) } /// Checks if the elements of this slice are sorted using the given key extraction function. @@ -2853,7 +2844,13 @@ macro_rules! len { // The shared definition of the `Iter` and `IterMut` iterators macro_rules! iterator { - (struct $name:ident -> $ptr:ty, $elem:ty, $raw_mut:tt, $( $mut_:tt )*) => { + ( + struct $name:ident -> $ptr:ty, + $elem:ty, + $raw_mut:tt, + {$( $mut_:tt )*}, + {$($extra:tt)*} + ) => { impl<'a, T> $name<'a, T> { // Helper function for creating a slice from the iterator. #[inline(always)] @@ -3030,6 +3027,8 @@ macro_rules! iterator { i }) } + + $($extra)* } #[stable(feature = "rust1", since = "1.0.0")] @@ -3167,7 +3166,17 @@ impl<'a, T> Iter<'a, T> { } } -iterator!{struct Iter -> *const T, &'a T, const, /* no mut */} +iterator!{struct Iter -> *const T, &'a T, const, {/* no mut */}, { + fn is_sorted_by(self, mut compare: F) -> bool + where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option, + { + self.as_slice().windows(2).all(|w| { + compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false) + }) + } +}} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Iter<'_, T> { @@ -3268,7 +3277,7 @@ impl<'a, T> IterMut<'a, T> { } } -iterator!{struct IterMut -> *mut T, &'a mut T, mut, mut} +iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}} /// An internal abstraction over the splitting iterators, so that /// splitn, splitn_mut etc can be implemented once. diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs index f44e74838ed23..432ead65b1721 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - fn main() { // Assert `Iterator` methods are feature gated assert!([1, 2, 2, 9].iter().is_sorted()); diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr index 873cee533705d..8230c1e3a38dc 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:13:33 + --> $DIR/feature-gate-is_sorted.rs:3:33 | LL | assert!([1, 2, 2, 9].iter().is_sorted()); | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | assert!([1, 2, 2, 9].iter().is_sorted()); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:15:39 + --> $DIR/feature-gate-is_sorted.rs:5:39 | LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:19:26 + --> $DIR/feature-gate-is_sorted.rs:9:26 | LL | assert!([1, 2, 2, 9].is_sorted()); | ^^^^^^^^^ @@ -23,7 +23,7 @@ LL | assert!([1, 2, 2, 9].is_sorted()); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:21:32 + --> $DIR/feature-gate-is_sorted.rs:11:32 | LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^ From b4766f80775a2635c026626070201356f33d2700 Mon Sep 17 00:00:00 2001 From: Kevin Leimkuhler Date: Thu, 17 Jan 2019 22:33:25 -0800 Subject: [PATCH 0163/1064] Correct error location indicated by comments --- src/test/ui/feature-gates/feature-gate-is_sorted.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs index 432ead65b1721..078ecc577610b 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -1,13 +1,13 @@ fn main() { // Assert `Iterator` methods are feature gated assert!([1, 2, 2, 9].iter().is_sorted()); - //^ ERROR: use of unstable library feature 'is_sorted' + //~^ ERROR: use of unstable library feature 'is_sorted': new API assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); - //^ ERROR: use of unstable library feature 'is_sorted' + //~^ ERROR: use of unstable library feature 'is_sorted': new API // Assert `[T]` methods are feature gated assert!([1, 2, 2, 9].is_sorted()); - //^ ERROR: use of unstable library feature 'is_sorted' + //~^ ERROR: use of unstable library feature 'is_sorted': new API assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); - //^ ERROR: use of unstable library feature 'is_sorted' + //~^ ERROR: use of unstable library feature 'is_sorted': new API } From 954769e2ed16a90bfda2b69395fc099b93581352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 22:51:01 -0800 Subject: [PATCH 0164/1064] Fix test after rebase --- .../ui/point-to-type-err-cause-on-impl-trait-return.rs | 2 +- .../point-to-type-err-cause-on-impl-trait-return.stderr | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs index a27df240d0792..95b40368143ef 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs @@ -26,10 +26,10 @@ fn baz() -> impl std::fmt::Display { fn qux() -> impl std::fmt::Display { if false { - //~^ ERROR if and else have incompatible types 0i32 } else { 1u32 + //~^ ERROR if and else have incompatible types } } diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index be3d2c0db4ca1..62da0787b02a9 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -38,15 +38,17 @@ LL | | } found type `u32` error[E0308]: if and else have incompatible types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 | LL | / if false { -LL | | //~^ ERROR if and else have incompatible types LL | | 0i32 + | | ---- expected because of this LL | | } else { LL | | 1u32 + | | ^^^^ expected i32, found u32 +LL | | //~^ ERROR if and else have incompatible types LL | | } - | |_____^ expected i32, found u32 + | |_____- if and else have incompatible types | = note: expected type `i32` found type `u32` From 2e06d9c91b9f0bccde4a0e445ce2014c3fe85506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 18 Jan 2019 00:12:09 -0800 Subject: [PATCH 0165/1064] Point at return type when appropriate --- src/librustc_typeck/check/coercion.rs | 16 ++++++++++++++-- .../fully-qualified-type-name2.stderr | 2 ++ .../fully-qualified-type-name4.stderr | 2 ++ src/test/ui/liveness/liveness-forgot-ret.stderr | 2 +- src/test/ui/proc-macro/span-preservation.stderr | 3 +++ src/test/ui/return/return-from-diverging.stderr | 2 ++ src/test/ui/tail-typeck.stderr | 4 +++- src/test/ui/wrong-ret-type.stderr | 4 +++- 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 7f053d6af9611..dd63b4f20fa55 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1250,14 +1250,26 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> } } } - _ => { + ObligationCauseCode::ReturnType(_id) => { db = fcx.report_mismatched_types(cause, expected, found, err); - if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { + let _id = fcx.tcx.hir().get_parent_node(_id); + let mut pointing_at_return_type = false; + if let Some((fn_decl, can_suggest)) = fcx.get_fn_decl(_id) { + pointing_at_return_type = fcx.suggest_missing_return_type( + &mut db, &fn_decl, expected, found, can_suggest); + } + if let (Some(sp), false) = ( + fcx.ret_coercion_span.borrow().as_ref(), + pointing_at_return_type, + ) { if !sp.overlaps(cause.span) { db.span_label(*sp, reason_label); } } } + _ => { + db = fcx.report_mismatched_types(cause, expected, found, err); + } } if let Some(augment_error) = augment_error { diff --git a/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr b/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr index 9a33d29766fb9..47bb5e475b473 100644 --- a/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr +++ b/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/fully-qualified-type-name2.rs:12:12 | +LL | fn bar(x: x::Foo) -> y::Foo { + | ------ expected `y::Foo` because of return type LL | return x; | ^ expected enum `y::Foo`, found enum `x::Foo` | diff --git a/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr b/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr index f03aaa67edbb8..b341879ab919a 100644 --- a/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr +++ b/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/fully-qualified-type-name4.rs:6:12 | +LL | fn bar(x: usize) -> Option { + | ------------- expected `std::option::Option` because of return type LL | return x; | ^ expected enum `std::option::Option`, found usize | diff --git a/src/test/ui/liveness/liveness-forgot-ret.stderr b/src/test/ui/liveness/liveness-forgot-ret.stderr index bbcbbdbe8dd5b..a970b80fdbbd9 100644 --- a/src/test/ui/liveness/liveness-forgot-ret.stderr +++ b/src/test/ui/liveness/liveness-forgot-ret.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/liveness-forgot-ret.rs:3:19 | LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } - | - ^^^^^ expected isize, found () - expected because of this statement + | - ^^^^^ expected isize, found () | | | this function's body doesn't return | diff --git a/src/test/ui/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr index 1f9103a6d2ee8..db524907b656f 100644 --- a/src/test/ui/proc-macro/span-preservation.stderr +++ b/src/test/ui/proc-macro/span-preservation.stderr @@ -15,6 +15,9 @@ LL | let x: usize = "hello";;;;; //~ ERROR mismatched types error[E0308]: mismatched types --> $DIR/span-preservation.rs:19:29 | +LL | fn b(x: Option) -> usize { + | ----- expected `usize` because of return type +LL | match x { LL | Some(x) => { return x }, //~ ERROR mismatched types | ^ expected usize, found isize diff --git a/src/test/ui/return/return-from-diverging.stderr b/src/test/ui/return/return-from-diverging.stderr index c84dd1953a07b..2862ae641df15 100644 --- a/src/test/ui/return/return-from-diverging.stderr +++ b/src/test/ui/return/return-from-diverging.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/return-from-diverging.rs:4:12 | +LL | fn fail() -> ! { + | - expected `!` because of return type LL | return "wow"; //~ ERROR mismatched types | ^^^^^ expected !, found reference | diff --git a/src/test/ui/tail-typeck.stderr b/src/test/ui/tail-typeck.stderr index eadf3d6d3350e..1170f5c17c18a 100644 --- a/src/test/ui/tail-typeck.stderr +++ b/src/test/ui/tail-typeck.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/tail-typeck.rs:3:26 | LL | fn f() -> isize { return g(); } - | ^^^ expected isize, found usize + | ----- ^^^ expected isize, found usize + | | + | expected `isize` because of return type error: aborting due to previous error diff --git a/src/test/ui/wrong-ret-type.stderr b/src/test/ui/wrong-ret-type.stderr index 221806f731f60..cf59f42683d72 100644 --- a/src/test/ui/wrong-ret-type.stderr +++ b/src/test/ui/wrong-ret-type.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/wrong-ret-type.rs:2:49 | LL | fn mk_int() -> usize { let i: isize = 3; return i; } - | ^ expected usize, found isize + | ----- ^ expected usize, found isize + | | + | expected `usize` because of return type error: aborting due to previous error From 1dc4e417fa2a73d5ffa24428df6b7d4dbbf41f4a Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 18 Jan 2019 11:40:53 +0100 Subject: [PATCH 0166/1064] Manually inline a function that was only used once --- src/librustc/ty/mod.rs | 10 ---------- src/librustc_mir/interpret/eval_context.rs | 10 +++++----- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 26b4735d926a5..2fdcb2681db0b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2946,16 +2946,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - /// Given the DefId of an item, returns its MIR, borrowed immutably. - /// Returns None if there is no MIR for the DefId - pub fn maybe_optimized_mir(self, did: DefId) -> Option<&'gcx Mir<'gcx>> { - if self.is_mir_available(did) { - Some(self.optimized_mir(did)) - } else { - None - } - } - /// Get the attributes of a definition. pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> { if let Some(id) = self.hir().as_local_node_id(did) { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 19362b6cfdb1c..90f7ba761ea1d 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -265,11 +265,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } trace!("load mir {:?}", instance); match instance { - ty::InstanceDef::Item(def_id) => { - self.tcx.maybe_optimized_mir(def_id).ok_or_else(|| - EvalErrorKind::NoMirFor(self.tcx.item_path_str(def_id)).into() - ) - } + ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { + Ok(self.tcx.optimized_mir(did)) + } else { + err!(NoMirFor(self.tcx.item_path_str(def_id))) + }, _ => Ok(self.tcx.instance_mir(instance)), } } From 13dc584db39e5f36755b7b051a908277f5e5505f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 18 Jan 2019 12:35:14 +0100 Subject: [PATCH 0167/1064] Merge visitors in AST validation --- src/librustc_passes/ast_validation.rs | 255 +++++++++++--------------- 1 file changed, 111 insertions(+), 144 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 3d0e46d998622..20f63b142997c 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -20,9 +20,79 @@ use errors::Applicability; struct AstValidator<'a> { session: &'a Session, + + // Used to ban nested `impl Trait`, e.g., `impl Into`. + // Nested `impl Trait` _is_ allowed in associated type position, + // e.g `impl Iterator` + outer_impl_trait: Option, + + // Used to ban `impl Trait` in path projections like `::Item` + // or `Foo::Bar` + is_impl_trait_banned: bool, } impl<'a> AstValidator<'a> { + fn with_banned_impl_trait(&mut self, f: F) + where F: FnOnce(&mut Self) + { + let old_is_impl_trait_banned = self.is_impl_trait_banned; + self.is_impl_trait_banned = true; + f(self); + self.is_impl_trait_banned = old_is_impl_trait_banned; + } + + fn with_impl_trait(&mut self, outer_impl_trait: Option, f: F) + where F: FnOnce(&mut Self) + { + let old_outer_impl_trait = self.outer_impl_trait; + self.outer_impl_trait = outer_impl_trait; + f(self); + self.outer_impl_trait = old_outer_impl_trait; + } + + // Mirrors visit::walk_ty, but tracks relevant state + fn walk_ty(&mut self, t: &'a Ty) { + match t.node { + TyKind::ImplTrait(..) => { + self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) + } + TyKind::Path(ref qself, ref path) => { + // We allow these: + // - `Option` + // - `option::Option` + // - `option::Option::Foo + // + // But not these: + // - `::Foo` + // - `option::Option::Foo`. + // + // To implement this, we disallow `impl Trait` from `qself` + // (for cases like `::Foo>`) + // but we allow `impl Trait` in `GenericArgs` + // iff there are no more PathSegments. + if let Some(ref qself) = *qself { + // `impl Trait` in `qself` is always illegal + self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty)); + } + + // Note that there should be a call to visit_path here, + // so if any logic is added to process `Path`s a call to it should be + // added both in visit_path and here. This code mirrors visit::walk_path. + for (i, segment) in path.segments.iter().enumerate() { + // Allow `impl Trait` iff we're on the final path segment + if i == path.segments.len() - 1 { + self.visit_path_segment(path.span, segment); + } else { + self.with_banned_impl_trait(|this| { + this.visit_path_segment(path.span, segment) + }); + } + } + } + _ => visit::walk_ty(self, t), + } + } + fn err_handler(&self) -> &errors::Handler { &self.session.diagnostic() } @@ -267,6 +337,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.no_questions_in_bounds(bounds, "trait object types", false); } TyKind::ImplTrait(_, ref bounds) => { + if self.is_impl_trait_banned { + struct_span_err!(self.session, ty.span, E0667, + "`impl Trait` is not allowed in path parameters").emit(); + } + + if let Some(outer_impl_trait) = self.outer_impl_trait { + struct_span_err!(self.session, ty.span, E0666, + "nested `impl Trait` is not allowed") + .span_label(outer_impl_trait, "outer `impl Trait`") + .span_label(ty.span, "nested `impl Trait` here") + .emit(); + + } if !bounds.iter() .any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) { self.err_handler().span_err(ty.span, "at least one trait must be specified"); @@ -275,7 +358,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { _ => {} } - visit::walk_ty(self, ty) + self.walk_ty(ty) } fn visit_label(&mut self, label: &'a Label) { @@ -414,6 +497,28 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_foreign_item(self, fi) } + // Mirrors visit::walk_generic_args, but tracks relevant state + fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) { + match *generic_args { + GenericArgs::AngleBracketed(ref data) => { + walk_list!(self, visit_generic_arg, &data.args); + // Type bindings such as `Item=impl Debug` in `Iterator` + // are allowed to contain nested `impl Trait`. + self.with_impl_trait(None, |this| { + walk_list!(this, visit_assoc_type_binding, &data.bindings); + }); + } + GenericArgs::Parenthesized(ref data) => { + walk_list!(self, visit_ty, &data.inputs); + if let Some(ref type_) = data.output { + // `-> Foo` syntax is essentially an associated type binding, + // so it is also allowed to contain nested `impl Trait`. + self.with_impl_trait(None, |this| visit::walk_ty(this, type_)); + } + } + } + } + fn visit_generics(&mut self, generics: &'a Generics) { let mut seen_non_lifetime_param = false; let mut seen_default = None; @@ -490,148 +595,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -// Bans nested `impl Trait`, e.g., `impl Into`. -// Nested `impl Trait` _is_ allowed in associated type position, -// e.g `impl Iterator` -struct NestedImplTraitVisitor<'a> { - session: &'a Session, - outer_impl_trait: Option, -} - -impl<'a> NestedImplTraitVisitor<'a> { - fn with_impl_trait(&mut self, outer_impl_trait: Option, f: F) - where F: FnOnce(&mut NestedImplTraitVisitor<'a>) - { - let old_outer_impl_trait = self.outer_impl_trait; - self.outer_impl_trait = outer_impl_trait; - f(self); - self.outer_impl_trait = old_outer_impl_trait; - } -} - - -impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> { - fn visit_ty(&mut self, t: &'a Ty) { - if let TyKind::ImplTrait(..) = t.node { - if let Some(outer_impl_trait) = self.outer_impl_trait { - struct_span_err!(self.session, t.span, E0666, - "nested `impl Trait` is not allowed") - .span_label(outer_impl_trait, "outer `impl Trait`") - .span_label(t.span, "nested `impl Trait` here") - .emit(); - - } - self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)); - } else { - visit::walk_ty(self, t); - } - } - fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) { - match *generic_args { - GenericArgs::AngleBracketed(ref data) => { - for arg in &data.args { - self.visit_generic_arg(arg) - } - for type_binding in &data.bindings { - // Type bindings such as `Item=impl Debug` in `Iterator` - // are allowed to contain nested `impl Trait`. - self.with_impl_trait(None, |this| visit::walk_ty(this, &type_binding.ty)); - } - } - GenericArgs::Parenthesized(ref data) => { - for type_ in &data.inputs { - self.visit_ty(type_); - } - if let Some(ref type_) = data.output { - // `-> Foo` syntax is essentially an associated type binding, - // so it is also allowed to contain nested `impl Trait`. - self.with_impl_trait(None, |this| visit::walk_ty(this, type_)); - } - } - } - } - - fn visit_mac(&mut self, _mac: &Spanned) { - // covered in AstValidator - } -} - -// Bans `impl Trait` in path projections like `::Item` or `Foo::Bar`. -struct ImplTraitProjectionVisitor<'a> { - session: &'a Session, - is_banned: bool, -} - -impl<'a> ImplTraitProjectionVisitor<'a> { - fn with_ban(&mut self, f: F) - where F: FnOnce(&mut ImplTraitProjectionVisitor<'a>) - { - let old_is_banned = self.is_banned; - self.is_banned = true; - f(self); - self.is_banned = old_is_banned; - } -} - -impl<'a> Visitor<'a> for ImplTraitProjectionVisitor<'a> { - fn visit_ty(&mut self, t: &'a Ty) { - match t.node { - TyKind::ImplTrait(..) => { - if self.is_banned { - struct_span_err!(self.session, t.span, E0667, - "`impl Trait` is not allowed in path parameters").emit(); - } - } - TyKind::Path(ref qself, ref path) => { - // We allow these: - // - `Option` - // - `option::Option` - // - `option::Option::Foo - // - // But not these: - // - `::Foo` - // - `option::Option::Foo`. - // - // To implement this, we disallow `impl Trait` from `qself` - // (for cases like `::Foo>`) - // but we allow `impl Trait` in `GenericArgs` - // iff there are no more PathSegments. - if let Some(ref qself) = *qself { - // `impl Trait` in `qself` is always illegal - self.with_ban(|this| this.visit_ty(&qself.ty)); - } - - for (i, segment) in path.segments.iter().enumerate() { - // Allow `impl Trait` iff we're on the final path segment - if i == path.segments.len() - 1 { - visit::walk_path_segment(self, path.span, segment); - } else { - self.with_ban(|this| - visit::walk_path_segment(this, path.span, segment)); - } - } - } - _ => visit::walk_ty(self, t), - } - } - - fn visit_mac(&mut self, _mac: &Spanned) { - // covered in AstValidator - } -} - pub fn check_crate(session: &Session, krate: &Crate) { - visit::walk_crate( - &mut NestedImplTraitVisitor { - session, - outer_impl_trait: None, - }, krate); - - visit::walk_crate( - &mut ImplTraitProjectionVisitor { - session, - is_banned: false, - }, krate); - - visit::walk_crate(&mut AstValidator { session }, krate) + visit::walk_crate(&mut AstValidator { + session, + outer_impl_trait: None, + is_impl_trait_banned: false, + }, krate) } From efda6816bd29beea2702c7c3f76a252a405e60ae Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 18 Jan 2019 13:31:05 +0100 Subject: [PATCH 0168/1064] Allow evaluating trivial drop glue in constants --- src/librustc_mir/const_eval.rs | 29 ++++++++++++++++------------- src/test/ui/consts/drop_none.rs | 13 +++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/consts/drop_none.rs diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index f5f4048167938..f6ecf7c9436a2 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -391,19 +391,22 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx> ret: Option, ) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> { debug!("eval_fn_call: {:?}", instance); - // Execution might have wandered off into other crates, so we cannot to a stability- - // sensitive check here. But we can at least rule out functions that are not const - // at all. - if !ecx.tcx.is_const_fn_raw(instance.def_id()) { - // Some functions we support even if they are non-const -- but avoid testing - // that for const fn! We certainly do *not* want to actually call the fn - // though, so be sure we return here. - return if ecx.hook_fn(instance, args, dest)? { - ecx.goto_block(ret)?; // fully evaluated and done - Ok(None) - } else { - err!(MachineError(format!("calling non-const function `{}`", instance))) - }; + // Only check non-glue functions + if let ty::InstanceDef::Item(def_id) = instance.def { + // Execution might have wandered off into other crates, so we cannot to a stability- + // sensitive check here. But we can at least rule out functions that are not const + // at all. + if !ecx.tcx.is_const_fn_raw(def_id) { + // Some functions we support even if they are non-const -- but avoid testing + // that for const fn! We certainly do *not* want to actually call the fn + // though, so be sure we return here. + return if ecx.hook_fn(instance, args, dest)? { + ecx.goto_block(ret)?; // fully evaluated and done + Ok(None) + } else { + err!(MachineError(format!("calling non-const function `{}`", instance))) + }; + } } // This is a const fn. Call it. Ok(Some(match ecx.load_mir(instance.def) { diff --git a/src/test/ui/consts/drop_none.rs b/src/test/ui/consts/drop_none.rs new file mode 100644 index 0000000000000..86a197ffb993e --- /dev/null +++ b/src/test/ui/consts/drop_none.rs @@ -0,0 +1,13 @@ +// compile-pass +#![allow(dead_code)] +struct A; +impl Drop for A { + fn drop(&mut self) {} +} + +const FOO: Option = None; + +const BAR: () = (FOO, ()).1; + + +fn main() {} From 79ef9718bb8e7b1fe45770a1ca43fb79bebbbbf0 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Fri, 18 Jan 2019 16:46:51 +0100 Subject: [PATCH 0169/1064] Remove delay_span_bug from qualify_min_const_fn This is causing issues with a new Clippy lint that will be able to detect possible const functions. As per https://github.com/rust-lang/rust-clippy/pull/3648#discussion_r247927450 --- src/librustc_mir/transform/qualify_min_const_fn.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 059b88a4d702a..85bf1e70ebf42 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -21,6 +21,7 @@ pub fn is_min_const_fn( | Predicate::RegionOutlives(_) | Predicate::TypeOutlives(_) | Predicate::WellFormed(_) + | Predicate::Projection(_) | Predicate::ConstEvaluatable(..) => continue, | Predicate::ObjectSafe(_) => { bug!("object safe predicate on function: {:#?}", predicate) @@ -29,13 +30,6 @@ pub fn is_min_const_fn( bug!("closure kind predicate on function: {:#?}", predicate) } Predicate::Subtype(_) => bug!("subtype predicate on function: {:#?}", predicate), - Predicate::Projection(_) => { - let span = tcx.def_span(current); - // we'll hit a `Predicate::Trait` later which will report an error - tcx.sess - .delay_span_bug(span, "projection without trait bound"); - continue; - } Predicate::Trait(pred) => { if Some(pred.def_id()) == tcx.lang_items().sized_trait() { continue; From 87f5a98a5d8f29d1a631cd06a39863a1e494b4d7 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Fri, 18 Jan 2019 19:08:31 +0100 Subject: [PATCH 0170/1064] Use `to_ne_bytes` for converting IPv4Address to octets It is easier and it should be also faster, because `to_ne_bytes` just calls `mem::transmute`. --- src/libstd/net/ip.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index f98113e0896f7..29f635919cb90 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -393,8 +393,7 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn octets(&self) -> [u8; 4] { - let bits = u32::from_be(self.inner.s_addr); - [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8] + self.inner.s_addr.to_ne_bytes() } /// Returns [`true`] for the special 'unspecified' address (0.0.0.0). From dcd56d11da6e1d7cb8874d27d1fbb4f6a94a71de Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 18 Jan 2019 14:10:45 -0600 Subject: [PATCH 0171/1064] remove more old readmes --- src/librustc/infer/higher_ranked/README.md | 407 +-------------------- src/librustc/ty/query/README.md | 303 +-------------- 2 files changed, 8 insertions(+), 702 deletions(-) diff --git a/src/librustc/infer/higher_ranked/README.md b/src/librustc/infer/higher_ranked/README.md index b1ac8bae4fb98..e7afaa5beb0a7 100644 --- a/src/librustc/infer/higher_ranked/README.md +++ b/src/librustc/infer/higher_ranked/README.md @@ -1,403 +1,8 @@ -# Skolemization and functions +To learn more about how Higher-ranked trait bounds work in the _old_ trait +solver, see [this chapter][oldhrtb] of the rustc-guide. -One of the trickiest and most subtle aspects of regions is dealing -with higher-ranked things which include bound region variables, such -as function types. I strongly suggest that if you want to understand -the situation, you read this paper (which is, admittedly, very long, -but you don't have to read the whole thing): +To learn more about how they work in the _new_ trait solver, see [this +chapter][newhrtb]. -http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/ - -Although my explanation will never compete with SPJ's (for one thing, -his is approximately 100 pages), I will attempt to explain the basic -problem and also how we solve it. Note that the paper only discusses -subtyping, not the computation of LUB/GLB. - -The problem we are addressing is that there is a kind of subtyping -between functions with bound region parameters. Consider, for -example, whether the following relation holds: - - for<'a> fn(&'a isize) <: for<'b> fn(&'b isize)? (Yes, a => b) - -The answer is that of course it does. These two types are basically -the same, except that in one we used the name `a` and one we used -the name `b`. - -In the examples that follow, it becomes very important to know whether -a lifetime is bound in a function type (that is, is a lifetime -parameter) or appears free (is defined in some outer scope). -Therefore, from now on I will always write the bindings explicitly, -using the Rust syntax `for<'a> fn(&'a isize)` to indicate that `a` is a -lifetime parameter. - -Now let's consider two more function types. Here, we assume that the -`'b` lifetime is defined somewhere outside and hence is not a lifetime -parameter bound by the function type (it "appears free"): - - for<'a> fn(&'a isize) <: fn(&'b isize)? (Yes, a => b) - -This subtyping relation does in fact hold. To see why, you have to -consider what subtyping means. One way to look at `T1 <: T2` is to -say that it means that it is always ok to treat an instance of `T1` as -if it had the type `T2`. So, with our functions, it is always ok to -treat a function that can take pointers with any lifetime as if it -were a function that can only take a pointer with the specific -lifetime `'b`. After all, `'b` is a lifetime, after all, and -the function can take values of any lifetime. - -You can also look at subtyping as the *is a* relationship. This amounts -to the same thing: a function that accepts pointers with any lifetime -*is a* function that accepts pointers with some specific lifetime. - -So, what if we reverse the order of the two function types, like this: - - fn(&'b isize) <: for<'a> fn(&'a isize)? (No) - -Does the subtyping relationship still hold? The answer of course is -no. In this case, the function accepts *only the lifetime `'b`*, -so it is not reasonable to treat it as if it were a function that -accepted any lifetime. - -What about these two examples: - - for<'a,'b> fn(&'a isize, &'b isize) <: for<'a> fn(&'a isize, &'a isize)? (Yes) - for<'a> fn(&'a isize, &'a isize) <: for<'a,'b> fn(&'a isize, &'b isize)? (No) - -Here, it is true that functions which take two pointers with any two -lifetimes can be treated as if they only accepted two pointers with -the same lifetime, but not the reverse. - -## The algorithm - -Here is the algorithm we use to perform the subtyping check: - -1. Replace all bound regions in the subtype with new variables -2. Replace all bound regions in the supertype with placeholder - equivalents. A "placeholder" region is just a new fresh region - name. -3. Check that the parameter and return types match as normal -4. Ensure that no placeholder regions 'leak' into region variables - visible from "the outside" - -Let's walk through some examples and see how this algorithm plays out. - -#### First example - -We'll start with the first example, which was: - - 1. for<'a> fn(&'a T) <: for<'b> fn(&'b T)? Yes: a -> b - -After steps 1 and 2 of the algorithm we will have replaced the types -like so: - - 1. fn(&'A T) <: fn(&'x T)? - -Here the upper case `&A` indicates a *region variable*, that is, a -region whose value is being inferred by the system. I also replaced -`&b` with `&x`---I'll use letters late in the alphabet (`x`, `y`, `z`) -to indicate placeholder region names. We can assume they don't appear -elsewhere. Note that neither the sub- nor the supertype bind any -region names anymore (as indicated by the absence of `<` and `>`). - -The next step is to check that the parameter types match. Because -parameters are contravariant, this means that we check whether: - - &'x T <: &'A T - -Region pointers are contravariant so this implies that - - &A <= &x - -must hold, where `<=` is the subregion relationship. Processing -*this* constrain simply adds a constraint into our graph that `&A <= -&x` and is considered successful (it can, for example, be satisfied by -choosing the value `&x` for `&A`). - -So far we have encountered no error, so the subtype check succeeds. - -#### The third example - -Now let's look first at the third example, which was: - - 3. fn(&'a T) <: for<'b> fn(&'b T)? No! - -After steps 1 and 2 of the algorithm we will have replaced the types -like so: - - 3. fn(&'a T) <: fn(&'x T)? - -This looks pretty much the same as before, except that on the LHS -`'a` was not bound, and hence was left as-is and not replaced with -a variable. The next step is again to check that the parameter types -match. This will ultimately require (as before) that `'a` <= `&x` -must hold: but this does not hold. `self` and `x` are both distinct -free regions. So the subtype check fails. - -#### Checking for placeholder leaks - -You may be wondering about that mysterious last step in the algorithm. -So far it has not been relevant. The purpose of that last step is to -catch something like *this*: - - for<'a> fn() -> fn(&'a T) <: fn() -> for<'b> fn(&'b T)? No. - -Here the function types are the same but for where the binding occurs. -The subtype returns a function that expects a value in precisely one -region. The supertype returns a function that expects a value in any -region. If we allow an instance of the subtype to be used where the -supertype is expected, then, someone could call the fn and think that -the return value has type `fn(&'b T)` when it really has type -`fn(&'a T)` (this is case #3, above). Bad. - -So let's step through what happens when we perform this subtype check. -We first replace the bound regions in the subtype (the supertype has -no bound regions). This gives us: - - fn() -> fn(&'A T) <: fn() -> for<'b> fn(&'b T)? - -Now we compare the return types, which are covariant, and hence we have: - - fn(&'A T) <: for<'b> fn(&'b T)? - -Here we replace the bound region in the supertype with a placeholder to yield: - - fn(&'A T) <: fn(&'x T)? - -And then proceed to compare the argument types: - - &'x T <: &'A T - 'A <= 'x - -Finally, this is where it gets interesting! This is where an error -*should* be reported. But in fact this will not happen. The reason why -is that `A` is a variable: we will infer that its value is the fresh -region `x` and think that everything is happy. In fact, this behavior -is *necessary*, it was key to the first example we walked through. - -The difference between this example and the first one is that the variable -`A` already existed at the point where the placeholders were added. In -the first example, you had two functions: - - for<'a> fn(&'a T) <: for<'b> fn(&'b T) - -and hence `&A` and `&x` were created "together". In general, the -intention of the placeholder names is that they are supposed to be -fresh names that could never be equal to anything from the outside. -But when inference comes into play, we might not be respecting this -rule. - -So the way we solve this is to add a fourth step that examines the -constraints that refer to placeholder names. Basically, consider a -non-directed version of the constraint graph. Let `Tainted(x)` be the -set of all things reachable from a placeholder variable `x`. -`Tainted(x)` should not contain any regions that existed before the -step at which the placeholders were created. So this case here -would fail because `&x` was created alone, but is relatable to `&A`. - -## Computing the LUB and GLB - -The paper I pointed you at is written for Haskell. It does not -therefore considering subtyping and in particular does not consider -LUB or GLB computation. We have to consider this. Here is the -algorithm I implemented. - -First though, let's discuss what we are trying to compute in more -detail. The LUB is basically the "common supertype" and the GLB is -"common subtype"; one catch is that the LUB should be the -*most-specific* common supertype and the GLB should be *most general* -common subtype (as opposed to any common supertype or any common -subtype). - -Anyway, to help clarify, here is a table containing some function -pairs and their LUB/GLB (for conciseness, in this table, I'm just -including the lifetimes here, not the rest of the types, and I'm -writing `fn<>` instead of `for<> fn`): - -``` -Type 1 Type 2 LUB GLB -fn<'a>('a) fn('X) fn('X) fn<'a>('a) -fn('a) fn('X) -- fn<'a>('a) -fn<'a,'b>('a, 'b) fn<'x>('x, 'x) fn<'a>('a, 'a) fn<'a,'b>('a, 'b) -fn<'a,'b>('a, 'b, 'a) fn<'x,'y>('x, 'y, 'y) fn<'a>('a, 'a, 'a) fn<'a,'b,'c>('a,'b,'c) -``` - -### Conventions - -I use lower-case letters (e.g., `&a`) for bound regions and upper-case -letters for free regions (`&A`). Region variables written with a -dollar-sign (e.g., `$a`). I will try to remember to enumerate the -bound-regions on the fn type as well (e.g., `for<'a> fn(&a)`). - -### High-level summary - -Both the LUB and the GLB algorithms work in a similar fashion. They -begin by replacing all bound regions (on both sides) with fresh region -inference variables. Therefore, both functions are converted to types -that contain only free regions. We can then compute the LUB/GLB in a -straightforward way, as described in `combine.rs`. This results in an -interim type T. The algorithms then examine the regions that appear -in T and try to, in some cases, replace them with bound regions to -yield the final result. - -To decide whether to replace a region `R` that appears in `T` with -a bound region, the algorithms make use of two bits of -information. First is a set `V` that contains all region -variables created as part of the LUB/GLB computation (roughly; see -`region_vars_confined_to_snapshot()` for full details). `V` will -contain the region variables created to replace the bound regions -in the input types, but it also contains 'intermediate' variables -created to represent the LUB/GLB of individual regions. -Basically, when asked to compute the LUB/GLB of a region variable -with another region, the inferencer cannot oblige immediately -since the values of that variables are not known. Therefore, it -creates a new variable that is related to the two regions. For -example, the LUB of two variables `$x` and `$y` is a fresh -variable `$z` that is constrained such that `$x <= $z` and `$y <= -$z`. So `V` will contain these intermediate variables as well. - -The other important factor in deciding how to replace a region in T is -the function `Tainted($r)` which, for a region variable, identifies -all regions that the region variable is related to in some way -(`Tainted()` made an appearance in the subtype computation as well). - -### LUB - -The LUB algorithm proceeds in three steps: - -1. Replace all bound regions (on both sides) with fresh region - inference variables. -2. Compute the LUB "as normal", meaning compute the GLB of each - pair of argument types and the LUB of the return types and - so forth. Combine those to a new function type `F`. -3. Replace each region `R` that appears in `F` as follows: - - Let `V` be the set of variables created during the LUB - computational steps 1 and 2, as described in the previous section. - - If `R` is not in `V`, replace `R` with itself. - - If `Tainted(R)` contains a region that is not in `V`, - replace `R` with itself. - - Otherwise, select the earliest variable in `Tainted(R)` that originates - from the left-hand side and replace `R` with the bound region that - this variable was a replacement for. - -So, let's work through the simplest example: `fn(&A)` and `for<'a> fn(&a)`. -In this case, `&a` will be replaced with `$a` and the interim LUB type -`fn($b)` will be computed, where `$b=GLB(&A,$a)`. Therefore, `V = -{$a, $b}` and `Tainted($b) = { $b, $a, &A }`. When we go to replace -`$b`, we find that since `&A \in Tainted($b)` is not a member of `V`, -we leave `$b` as is. When region inference happens, `$b` will be -resolved to `&A`, as we wanted. - -Let's look at a more complex one: `fn(&a, &b)` and `fn(&x, &x)`. In -this case, we'll end up with a (pre-replacement) LUB type of `fn(&g, -&h)` and a graph that looks like: - -``` - $a $b *--$x - \ \ / / - \ $h-* / - $g-----------* -``` - -Here `$g` and `$h` are fresh variables that are created to represent -the LUB/GLB of things requiring inference. This means that `V` and -`Tainted` will look like: - -``` -V = {$a, $b, $g, $h, $x} -Tainted($g) = Tainted($h) = { $a, $b, $h, $g, $x } -``` - -Therefore we replace both `$g` and `$h` with `$a`, and end up -with the type `fn(&a, &a)`. - -### GLB - -The procedure for computing the GLB is similar. The difference lies -in computing the replacements for the various variables. For each -region `R` that appears in the type `F`, we again compute `Tainted(R)` -and examine the results: - -1. If `R` is not in `V`, it is not replaced. -2. Else, if `Tainted(R)` contains only variables in `V`, and it - contains exactly one variable from the LHS and one variable from - the RHS, then `R` can be mapped to the bound version of the - variable from the LHS. -3. Else, if `Tainted(R)` contains no variable from the LHS and no - variable from the RHS, then `R` can be mapped to itself. -4. Else, `R` is mapped to a fresh bound variable. - -These rules are pretty complex. Let's look at some examples to see -how they play out. - -Out first example was `fn(&a)` and `fn(&X)`. In this case, `&a` will -be replaced with `$a` and we will ultimately compute a -(pre-replacement) GLB type of `fn($g)` where `$g=LUB($a,&X)`. -Therefore, `V={$a,$g}` and `Tainted($g)={$g,$a,&X}. To find the -replacement for `$g` we consult the rules above: -- Rule (1) does not apply because `$g \in V` -- Rule (2) does not apply because `&X \in Tainted($g)` -- Rule (3) does not apply because `$a \in Tainted($g)` -- Hence, by rule (4), we replace `$g` with a fresh bound variable `&z`. -So our final result is `fn(&z)`, which is correct. - -The next example is `fn(&A)` and `fn(&Z)`. In this case, we will again -have a (pre-replacement) GLB of `fn(&g)`, where `$g = LUB(&A,&Z)`. -Therefore, `V={$g}` and `Tainted($g) = {$g, &A, &Z}`. In this case, -by rule (3), `$g` is mapped to itself, and hence the result is -`fn($g)`. This result is correct (in this case, at least), but it is -indicative of a case that *can* lead us into concluding that there is -no GLB when in fact a GLB does exist. See the section "Questionable -Results" below for more details. - -The next example is `fn(&a, &b)` and `fn(&c, &c)`. In this case, as -before, we'll end up with `F=fn($g, $h)` where `Tainted($g) = -Tainted($h) = {$g, $h, $a, $b, $c}`. Only rule (4) applies and hence -we'll select fresh bound variables `y` and `z` and wind up with -`fn(&y, &z)`. - -For the last example, let's consider what may seem trivial, but is -not: `fn(&a, &a)` and `fn(&b, &b)`. In this case, we'll get `F=fn($g, -$h)` where `Tainted($g) = {$g, $a, $x}` and `Tainted($h) = {$h, $a, -$x}`. Both of these sets contain exactly one bound variable from each -side, so we'll map them both to `&a`, resulting in `fn(&a, &a)`, which -is the desired result. - -### Shortcomings and correctness - -You may be wondering whether this algorithm is correct. The answer is -"sort of". There are definitely cases where they fail to compute a -result even though a correct result exists. I believe, though, that -if they succeed, then the result is valid, and I will attempt to -convince you. The basic argument is that the "pre-replacement" step -computes a set of constraints. The replacements, then, attempt to -satisfy those constraints, using bound identifiers where needed. - -For now I will briefly go over the cases for LUB/GLB and identify -their intent: - -- LUB: - - The region variables that are substituted in place of bound regions - are intended to collect constraints on those bound regions. - - If Tainted(R) contains only values in V, then this region is unconstrained - and can therefore be generalized, otherwise it cannot. -- GLB: - - The region variables that are substituted in place of bound regions - are intended to collect constraints on those bound regions. - - If Tainted(R) contains exactly one variable from each side, and - only variables in V, that indicates that those two bound regions - must be equated. - - Otherwise, if Tainted(R) references any variables from left or right - side, then it is trying to combine a bound region with a free one or - multiple bound regions, so we need to select fresh bound regions. - -Sorry this is more of a shorthand to myself. I will try to write up something -more convincing in the future. - -#### Where are the algorithms wrong? - -- The pre-replacement computation can fail even though using a - bound-region would have succeeded. -- We will compute GLB(fn(fn($a)), fn(fn($b))) as fn($c) where $c is the - GLB of $a and $b. But if inference finds that $a and $b must be mapped - to regions without a GLB, then this is effectively a failure to compute - the GLB. However, the result `fn<$c>(fn($c))` is a valid GLB. +[oldhrtb]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html +[newhrtb]: https://rust-lang.github.io/rustc-guide/borrow_check/region_inference.html#placeholders-and-universes diff --git a/src/librustc/ty/query/README.md b/src/librustc/ty/query/README.md index 0fcaef5de54c2..4b5e08cecd99c 100644 --- a/src/librustc/ty/query/README.md +++ b/src/librustc/ty/query/README.md @@ -1,302 +1,3 @@ -# The Rust Compiler Query System - -The Compiler Query System is the key to our new demand-driven -organization. The idea is pretty simple. You have various queries -that compute things about the input -- for example, there is a query -called `type_of(def_id)` that, given the def-id of some item, will -compute the type of that item and return it to you. - -Query execution is **memoized** -- so the first time you invoke a -query, it will go do the computation, but the next time, the result is -returned from a hashtable. Moreover, query execution fits nicely into -**incremental computation**; the idea is roughly that, when you do a -query, the result **may** be returned to you by loading stored data -from disk (but that's a separate topic we won't discuss further here). - -The overall vision is that, eventually, the entire compiler -control-flow will be query driven. There will effectively be one -top-level query ("compile") that will run compilation on a crate; this -will in turn demand information about that crate, starting from the -*end*. For example: - -- This "compile" query might demand to get a list of codegen-units - (i.e., modules that need to be compiled by LLVM). -- But computing the list of codegen-units would invoke some subquery - that returns the list of all modules defined in the Rust source. -- That query in turn would invoke something asking for the HIR. -- This keeps going further and further back until we wind up doing the - actual parsing. - -However, that vision is not fully realized. Still, big chunks of the -compiler (for example, generating MIR) work exactly like this. - -### Invoking queries - -To invoke a query is simple. The tcx ("type context") offers a method -for each defined query. So, for example, to invoke the `type_of` -query, you would just do this: - -```rust -let ty = tcx.type_of(some_def_id); -``` - -### Cycles between queries - -Currently, cycles during query execution should always result in a -compilation error. Typically, they arise because of illegal programs -that contain cyclic references they shouldn't (though sometimes they -arise because of compiler bugs, in which case we need to factor our -queries in a more fine-grained fashion to avoid them). - -However, it is nonetheless often useful to *recover* from a cycle -(after reporting an error, say) and try to soldier on, so as to give a -better user experience. In order to recover from a cycle, you don't -get to use the nice method-call-style syntax. Instead, you invoke -using the `try_get` method, which looks roughly like this: - -```rust -use ty::query::queries; -... -match queries::type_of::try_get(tcx, DUMMY_SP, self.did) { - Ok(result) => { - // no cycle occurred! You can use `result` - } - Err(err) => { - // A cycle occurred! The error value `err` is a `DiagnosticBuilder`, - // meaning essentially an "in-progress", not-yet-reported error message. - // See below for more details on what to do here. - } -} -``` - -So, if you get back an `Err` from `try_get`, then a cycle *did* occur. This means that -you must ensure that a compiler error message is reported. You can do that in two ways: - -The simplest is to invoke `err.emit()`. This will emit the cycle error to the user. - -However, often cycles happen because of an illegal program, and you -know at that point that an error either already has been reported or -will be reported due to this cycle by some other bit of code. In that -case, you can invoke `err.cancel()` to not emit any error. It is -traditional to then invoke: - -``` -tcx.sess.delay_span_bug(some_span, "some message") -``` - -`delay_span_bug()` is a helper that says: we expect a compilation -error to have happened or to happen in the future; so, if compilation -ultimately succeeds, make an ICE with the message `"some -message"`. This is basically just a precaution in case you are wrong. - -### How the compiler executes a query - -So you may be wondering what happens when you invoke a query -method. The answer is that, for each query, the compiler maintains a -cache -- if your query has already been executed, then, the answer is -simple: we clone the return value out of the cache and return it -(therefore, you should try to ensure that the return types of queries -are cheaply cloneable; insert a `Rc` if necessary). - -#### Providers - -If, however, the query is *not* in the cache, then the compiler will -try to find a suitable **provider**. A provider is a function that has -been defined and linked into the compiler somewhere that contains the -code to compute the result of the query. - -**Providers are defined per-crate.** The compiler maintains, -internally, a table of providers for every crate, at least -conceptually. Right now, there are really two sets: the providers for -queries about the **local crate** (that is, the one being compiled) -and providers for queries about **external crates** (that is, -dependencies of the local crate). Note that what determines the crate -that a query is targeting is not the *kind* of query, but the *key*. -For example, when you invoke `tcx.type_of(def_id)`, that could be a -local query or an external query, depending on what crate the `def_id` -is referring to (see the `self::keys::Key` trait for more information -on how that works). - -Providers always have the same signature: - -```rust -fn provider<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx, 'tcx>, - key: QUERY_KEY) - -> QUERY_RESULT -{ - ... -} -``` - -Providers take two arguments: the `tcx` and the query key. Note also -that they take the *global* tcx (i.e., they use the `'tcx` lifetime -twice), rather than taking a tcx with some active inference context. -They return the result of the query. - -#### How providers are setup - -When the tcx is created, it is given the providers by its creator using -the `Providers` struct. This struct is generate by the macros here, but it -is basically a big list of function pointers: - -```rust -struct Providers { - type_of: for<'cx, 'tcx> fn(TyCtxt<'cx, 'tcx, 'tcx>, DefId) -> Ty<'tcx>, - ... -} -``` - -At present, we have one copy of the struct for local crates, and one -for external crates, though the plan is that we may eventually have -one per crate. - -These `Provider` structs are ultimately created and populated by -`librustc_driver`, but it does this by distributing the work -throughout the other `rustc_*` crates. This is done by invoking -various `provide` functions. These functions tend to look something -like this: - -```rust -pub fn provide(providers: &mut Providers) { - *providers = Providers { - type_of, - ..*providers - }; -} -``` - -That is, they take an `&mut Providers` and mutate it in place. Usually -we use the formulation above just because it looks nice, but you could -as well do `providers.type_of = type_of`, which would be equivalent. -(Here, `type_of` would be a top-level function, defined as we saw -before.) So, if we want to add a provider for some other query, -let's call it `fubar`, into the crate above, we might modify the `provide()` -function like so: - -```rust -pub fn provide(providers: &mut Providers) { - *providers = Providers { - type_of, - fubar, - ..*providers - }; -} - -fn fubar<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>, key: DefId) -> Fubar<'tcx> { .. } -``` - -NB. Most of the `rustc_*` crates only provide **local -providers**. Almost all **extern providers** wind up going through the -`rustc_metadata` crate, which loads the information from the crate -metadata. But in some cases there are crates that provide queries for -*both* local and external crates, in which case they define both a -`provide` and a `provide_extern` function that `rustc_driver` can -invoke. - -### Adding a new kind of query - -So suppose you want to add a new kind of query, how do you do so? -Well, defining a query takes place in two steps: - -1. first, you have to specify the query name and arguments; and then, -2. you have to supply query providers where needed. - -To specify the query name and arguments, you simply add an entry -to the big macro invocation in `mod.rs`. This will probably have changed -by the time you read this README, but at present it looks something -like: - -``` -define_queries! { <'tcx> - /// Records the type of every item. - [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>, - - ... -} -``` - -Each line of the macro defines one query. The name is broken up like this: - -``` -[] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>, -^^ ^^^^^^^ ^^^^^^^^^^ ^^^^^ ^^^^^^^^ -| | | | | -| | | | result type of query -| | | query key type -| | dep-node constructor -| name of query -query flags -``` - -Let's go over them one by one: - -- **Query flags:** these are largely unused right now, but the intention - is that we'll be able to customize various aspects of how the query is - processed. -- **Name of query:** the name of the query method - (`tcx.type_of(..)`). Also used as the name of a struct - (`ty::query::queries::type_of`) that will be generated to represent - this query. -- **Dep-node constructor:** indicates the constructor function that - connects this query to incremental compilation. Typically, this is a - `DepNode` variant, which can be added by modifying the - `define_dep_nodes!` macro invocation in - `librustc/dep_graph/dep_node.rs`. - - However, sometimes we use a custom function, in which case the - name will be in snake case and the function will be defined at the - bottom of the file. This is typically used when the query key is - not a def-id, or just not the type that the dep-node expects. -- **Query key type:** the type of the argument to this query. - This type must implement the `ty::query::keys::Key` trait, which - defines (for example) how to map it to a crate, and so forth. -- **Result type of query:** the type produced by this query. This type - should (a) not use `RefCell` or other interior mutability and (b) be - cheaply cloneable. Interning or using `Rc` or `Arc` is recommended for - non-trivial data types. - - The one exception to those rules is the `ty::steal::Steal` type, - which is used to cheaply modify MIR in place. See the definition - of `Steal` for more details. New uses of `Steal` should **not** be - added without alerting `@rust-lang/compiler`. - -So, to add a query: - -- Add an entry to `define_queries!` using the format above. -- Possibly add a corresponding entry to the dep-node macro. -- Link the provider by modifying the appropriate `provide` method; - or add a new one if needed and ensure that `rustc_driver` is invoking it. - -#### Query structs and descriptions - -For each kind, the `define_queries` macro will generate a "query struct" -named after the query. This struct is a kind of a place-holder -describing the query. Each such struct implements the -`self::config::QueryConfig` trait, which has associated types for the -key/value of that particular query. Basically the code generated looks something -like this: - -```rust -// Dummy struct representing a particular kind of query: -pub struct type_of<'tcx> { phantom: PhantomData<&'tcx ()> } - -impl<'tcx> QueryConfig for type_of<'tcx> { - type Key = DefId; - type Value = Ty<'tcx>; -} -``` - -There is an additional trait that you may wish to implement called -`self::config::QueryDescription`. This trait is used during cycle -errors to give a "human readable" name for the query, so that we can -summarize what was happening when the cycle occurred. Implementing -this trait is optional if the query key is `DefId`, but if you *don't* -implement it, you get a pretty generic error ("processing `foo`..."). -You can put new impls into the `config` module. They look something like this: - -```rust -impl<'tcx> QueryDescription for queries::type_of<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, key: DefId) -> String { - format!("computing the type of `{}`", tcx.item_path_str(key)) - } -} -``` +For more information about how the query system works, see the [rustc guide]. +[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html From 0c4602aaef787d94ec01d990744bc9e6941ed2eb Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Fri, 18 Jan 2019 15:28:23 -0600 Subject: [PATCH 0172/1064] Update README.md Point contributors to the rustc-guide... --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cb1f06257ed15..514e420ca457c 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,13 @@ Read ["Installation"] from [The Book]. ["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html [The Book]: https://doc.rust-lang.org/book/index.html -## Building from Source +## Installing from Source [building-from-source]: #building-from-source +_Note: If you wish to contribute to the compiler, you should read +[this chapter](https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html) +of the rustc-guide instead._ + ### Building on *nix 1. Make sure you have installed the dependencies: From a5d4aeddc8e2ecf1279f2138788777a29fedc3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 19 Jan 2019 04:29:26 +0100 Subject: [PATCH 0173/1064] Address some comments --- src/librustc_passes/ast_validation.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 20f63b142997c..d1a3d7c1f81e0 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -6,6 +6,7 @@ // This pass is supposed to perform only simple checks not requiring name resolution // or type checking or some other kind of complex analysis. +use std::mem; use rustc::lint; use rustc::session::Session; use syntax::ast::*; @@ -32,22 +33,16 @@ struct AstValidator<'a> { } impl<'a> AstValidator<'a> { - fn with_banned_impl_trait(&mut self, f: F) - where F: FnOnce(&mut Self) - { - let old_is_impl_trait_banned = self.is_impl_trait_banned; - self.is_impl_trait_banned = true; + fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) { + let old = mem::replace(&mut self.is_impl_trait_banned, true); f(self); - self.is_impl_trait_banned = old_is_impl_trait_banned; + self.is_impl_trait_banned = old; } - fn with_impl_trait(&mut self, outer_impl_trait: Option, f: F) - where F: FnOnce(&mut Self) - { - let old_outer_impl_trait = self.outer_impl_trait; - self.outer_impl_trait = outer_impl_trait; + fn with_impl_trait(&mut self, outer_impl_trait: Option, f: impl FnOnce(&mut Self)) { + let old = mem::replace(&mut self.outer_impl_trait, outer_impl_trait); f(self); - self.outer_impl_trait = old_outer_impl_trait; + self.outer_impl_trait = old; } // Mirrors visit::walk_ty, but tracks relevant state From beb0c74950ec51582b58e3f13e5b2a47b14f524d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 18 Jan 2019 07:40:55 +0100 Subject: [PATCH 0174/1064] Combine all builtin early lints and use a separate walk for plugin lints. Add a -Z no-interleave-lints option to allow benchmarking lints --- src/librustc/lint/builtin.rs | 4 + src/librustc/lint/context.rs | 323 ++++++++++++++++--------- src/librustc/lint/mod.rs | 191 +++++++++++---- src/librustc/session/config.rs | 2 + src/librustc_driver/driver.rs | 10 +- src/librustc_lint/builtin.rs | 96 ++++++++ src/librustc_lint/lib.rs | 93 +++---- src/librustc_lint/nonstandard_style.rs | 12 + src/librustc_lint/types.rs | 12 + src/librustc_lint/unused.rs | 24 ++ 10 files changed, 551 insertions(+), 216 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c8d137a42b2e8..0d2dc8382024f 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -374,6 +374,10 @@ declare_lint! { pub struct HardwiredLints; impl LintPass for HardwiredLints { + fn name(&self) -> &'static str { + "HardwiredLints" + } + fn get_lints(&self) -> LintArray { lint_array!( ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index f5a7919ef09c8..e426858349368 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -18,8 +18,8 @@ use self::TargetLint::*; use std::slice; use rustc_data_structures::sync::ReadGuard; -use lint::{EarlyLintPassObject, LateLintPassObject}; -use lint::{Level, Lint, LintId, LintPass, LintBuffer}; +use lint::{EarlyLintPass, EarlyLintPassObject, LateLintPassObject}; +use lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use lint::builtin::BuiltinLintDiagnostics; use lint::levels::{LintLevelSets, LintLevelsBuilder}; use middle::privacy::AccessLevels; @@ -28,6 +28,7 @@ use session::{config, early_error, Session}; use ty::{self, TyCtxt, Ty}; use ty::layout::{LayoutError, LayoutOf, TyLayout}; use util::nodemap::FxHashMap; +use util::common::time; use std::default::Default as StdDefault; use syntax::ast; @@ -74,7 +75,6 @@ pub struct LintSession<'a, PassObject> { passes: Option>, } - /// Lints that are buffered up early on in the `Session` before the /// `LintLevels` is calculated #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] @@ -175,18 +175,25 @@ impl LintStore { pub fn register_early_pass(&mut self, sess: Option<&Session>, from_plugin: bool, + register_only: bool, pass: EarlyLintPassObject) { self.push_pass(sess, from_plugin, &pass); - self.early_passes.as_mut().unwrap().push(pass); + if !register_only { + self.early_passes.as_mut().unwrap().push(pass); + } } pub fn register_pre_expansion_pass( &mut self, sess: Option<&Session>, + from_plugin: bool, + register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(sess, false, &pass); - self.pre_expansion_passes.as_mut().unwrap().push(pass); + self.push_pass(sess, from_plugin, &pass); + if !register_only { + self.pre_expansion_passes.as_mut().unwrap().push(pass); + } } pub fn register_late_pass(&mut self, @@ -535,6 +542,11 @@ pub struct EarlyContext<'a> { buffered: LintBuffer, } +pub struct EarlyContextAndPass<'a, T: EarlyLintPass> { + context: EarlyContext<'a>, + pass: T, +} + /// Convenience macro for calling a `LintPass` method on every pass in the context. macro_rules! run_lints { ($cx:expr, $f:ident, $($args:expr),*) => ({ // Move the vector of passes out of `$cx` so that we can @@ -560,8 +572,6 @@ pub trait LintContext<'tcx>: Sized { fn lints(&self) -> &LintStore; fn lint_sess(&self) -> &LintSession<'tcx, Self::PassObject>; fn lint_sess_mut(&mut self) -> &mut LintSession<'tcx, Self::PassObject>; - fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]); - fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]); fn lookup_and_emit>(&self, lint: &'static Lint, @@ -624,15 +634,6 @@ pub trait LintContext<'tcx>: Sized { fn lint(&self, lint: &'static Lint, msg: &str) { self.lookup_and_emit(lint, None as Option, msg); } - - /// Merge the lints specified by any lint attributes into the - /// current lint context, call the provided function, then reset the - /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, - id: ast::NodeId, - attrs: &'tcx [ast::Attribute], - f: F) - where F: FnOnce(&mut Self); } @@ -640,7 +641,6 @@ impl<'a> EarlyContext<'a> { fn new( sess: &'a Session, krate: &'a ast::Crate, - passes: Option>, buffered: LintBuffer, ) -> EarlyContext<'a> { EarlyContext { @@ -648,21 +648,56 @@ impl<'a> EarlyContext<'a> { krate, lint_sess: LintSession { lints: sess.lint_store.borrow(), - passes, + passes: None, }, builder: LintLevelSets::builder(sess), buffered, } } +} +macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({ + $cx.pass.$f(&$cx.context, $($args),*); +}) } + +impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { fn check_id(&mut self, id: ast::NodeId) { - for early_lint in self.buffered.take(id) { - self.lookup_and_emit_with_diagnostics(early_lint.lint_id.lint, - Some(early_lint.span.clone()), - &early_lint.msg, - early_lint.diagnostic); + for early_lint in self.context.buffered.take(id) { + self.context.lookup_and_emit_with_diagnostics( + early_lint.lint_id.lint, + Some(early_lint.span.clone()), + &early_lint.msg, + early_lint.diagnostic + ); } } + + /// Merge the lints specified by any lint attributes into the + /// current lint context, call the provided function, then reset the + /// lints in effect to their previous state. + fn with_lint_attrs(&mut self, + id: ast::NodeId, + attrs: &'a [ast::Attribute], + f: F) + where F: FnOnce(&mut Self) + { + let push = self.context.builder.push(attrs); + self.check_id(id); + self.enter_attrs(attrs); + f(self); + self.exit_attrs(attrs); + self.context.builder.pop(push); + } + + fn enter_attrs(&mut self, attrs: &'a [ast::Attribute]) { + debug!("early context: enter_attrs({:?})", attrs); + run_early_pass!(self, enter_lint_attrs, attrs); + } + + fn exit_attrs(&mut self, attrs: &'a [ast::Attribute]) { + debug!("early context: exit_attrs({:?})", attrs); + run_early_pass!(self, exit_lint_attrs, attrs); + } } impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> { @@ -685,16 +720,6 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> { &mut self.lint_sess } - fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]) { - debug!("late context: enter_attrs({:?})", attrs); - run_lints!(self, enter_lint_attrs, attrs); - } - - fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]) { - debug!("late context: exit_attrs({:?})", attrs); - run_lints!(self, exit_lint_attrs, attrs); - } - fn lookup>(&self, lint: &'static Lint, span: Option, @@ -706,20 +731,6 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> { None => self.tcx.struct_lint_node(lint, id, msg), } } - - fn with_lint_attrs(&mut self, - id: ast::NodeId, - attrs: &'tcx [ast::Attribute], - f: F) - where F: FnOnce(&mut Self) - { - let prev = self.last_ast_node_with_lint_attrs; - self.last_ast_node_with_lint_attrs = id; - self.enter_attrs(attrs); - f(self); - self.exit_attrs(attrs); - self.last_ast_node_with_lint_attrs = prev; - } } impl<'a> LintContext<'a> for EarlyContext<'a> { @@ -742,16 +753,6 @@ impl<'a> LintContext<'a> for EarlyContext<'a> { &mut self.lint_sess } - fn enter_attrs(&mut self, attrs: &'a [ast::Attribute]) { - debug!("early context: enter_attrs({:?})", attrs); - run_lints!(self, enter_lint_attrs, attrs); - } - - fn exit_attrs(&mut self, attrs: &'a [ast::Attribute]) { - debug!("early context: exit_attrs({:?})", attrs); - run_lints!(self, exit_lint_attrs, attrs); - } - fn lookup>(&self, lint: &'static Lint, span: Option, @@ -759,23 +760,36 @@ impl<'a> LintContext<'a> for EarlyContext<'a> { -> DiagnosticBuilder<'_> { self.builder.struct_lint(lint, span.map(|s| s.into()), msg) } +} +impl<'a, 'tcx> LateContext<'a, 'tcx> { + /// Merge the lints specified by any lint attributes into the + /// current lint context, call the provided function, then reset the + /// lints in effect to their previous state. fn with_lint_attrs(&mut self, id: ast::NodeId, - attrs: &'a [ast::Attribute], + attrs: &'tcx [ast::Attribute], f: F) where F: FnOnce(&mut Self) { - let push = self.builder.push(attrs); - self.check_id(id); + let prev = self.last_ast_node_with_lint_attrs; + self.last_ast_node_with_lint_attrs = id; self.enter_attrs(attrs); f(self); self.exit_attrs(attrs); - self.builder.pop(push); + self.last_ast_node_with_lint_attrs = prev; + } + + fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]) { + debug!("late context: enter_attrs({:?})", attrs); + run_lints!(self, enter_lint_attrs, attrs); + } + + fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]) { + debug!("late context: exit_attrs({:?})", attrs); + run_lints!(self, exit_lint_attrs, attrs); } -} -impl<'a, 'tcx> LateContext<'a, 'tcx> { fn with_param_env(&mut self, id: ast::NodeId, f: F) where F: FnOnce(&mut Self), { @@ -1008,26 +1022,26 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { } } -impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { +impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> { fn visit_item(&mut self, it: &'a ast::Item) { self.with_lint_attrs(it.id, &it.attrs, |cx| { - run_lints!(cx, check_item, it); + run_early_pass!(cx, check_item, it); ast_visit::walk_item(cx, it); - run_lints!(cx, check_item_post, it); + run_early_pass!(cx, check_item_post, it); }) } fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) { self.with_lint_attrs(it.id, &it.attrs, |cx| { - run_lints!(cx, check_foreign_item, it); + run_early_pass!(cx, check_foreign_item, it); ast_visit::walk_foreign_item(cx, it); - run_lints!(cx, check_foreign_item_post, it); + run_early_pass!(cx, check_foreign_item_post, it); }) } fn visit_pat(&mut self, p: &'a ast::Pat) { let mut visit_subpats = true; - run_lints!(self, check_pat, p, &mut visit_subpats); + run_early_pass!(self, check_pat, p, &mut visit_subpats); self.check_id(p.id); if visit_subpats { ast_visit::walk_pat(self, p); @@ -1036,23 +1050,23 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { self.with_lint_attrs(e.id, &e.attrs, |cx| { - run_lints!(cx, check_expr, e); + run_early_pass!(cx, check_expr, e); ast_visit::walk_expr(cx, e); }) } fn visit_stmt(&mut self, s: &'a ast::Stmt) { - run_lints!(self, check_stmt, s); + run_early_pass!(self, check_stmt, s); self.check_id(s.id); ast_visit::walk_stmt(self, s); } fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, decl: &'a ast::FnDecl, span: Span, id: ast::NodeId) { - run_lints!(self, check_fn, fk, decl, span, id); + run_early_pass!(self, check_fn, fk, decl, span, id); self.check_id(id); ast_visit::walk_fn(self, fk, decl, span); - run_lints!(self, check_fn_post, fk, decl, span, id); + run_early_pass!(self, check_fn_post, fk, decl, span, id); } fn visit_variant_data(&mut self, @@ -1061,120 +1075,120 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { g: &'a ast::Generics, item_id: ast::NodeId, _: Span) { - run_lints!(self, check_struct_def, s, ident, g, item_id); + run_early_pass!(self, check_struct_def, s, ident, g, item_id); self.check_id(s.id()); ast_visit::walk_struct_def(self, s); - run_lints!(self, check_struct_def_post, s, ident, g, item_id); + run_early_pass!(self, check_struct_def_post, s, ident, g, item_id); } fn visit_struct_field(&mut self, s: &'a ast::StructField) { self.with_lint_attrs(s.id, &s.attrs, |cx| { - run_lints!(cx, check_struct_field, s); + run_early_pass!(cx, check_struct_field, s); ast_visit::walk_struct_field(cx, s); }) } fn visit_variant(&mut self, v: &'a ast::Variant, g: &'a ast::Generics, item_id: ast::NodeId) { self.with_lint_attrs(item_id, &v.node.attrs, |cx| { - run_lints!(cx, check_variant, v, g); + run_early_pass!(cx, check_variant, v, g); ast_visit::walk_variant(cx, v, g, item_id); - run_lints!(cx, check_variant_post, v, g); + run_early_pass!(cx, check_variant_post, v, g); }) } fn visit_ty(&mut self, t: &'a ast::Ty) { - run_lints!(self, check_ty, t); + run_early_pass!(self, check_ty, t); self.check_id(t.id); ast_visit::walk_ty(self, t); } fn visit_ident(&mut self, ident: ast::Ident) { - run_lints!(self, check_ident, ident); + run_early_pass!(self, check_ident, ident); } fn visit_mod(&mut self, m: &'a ast::Mod, s: Span, _a: &[ast::Attribute], n: ast::NodeId) { - run_lints!(self, check_mod, m, s, n); + run_early_pass!(self, check_mod, m, s, n); self.check_id(n); ast_visit::walk_mod(self, m); - run_lints!(self, check_mod_post, m, s, n); + run_early_pass!(self, check_mod_post, m, s, n); } fn visit_local(&mut self, l: &'a ast::Local) { self.with_lint_attrs(l.id, &l.attrs, |cx| { - run_lints!(cx, check_local, l); + run_early_pass!(cx, check_local, l); ast_visit::walk_local(cx, l); }) } fn visit_block(&mut self, b: &'a ast::Block) { - run_lints!(self, check_block, b); + run_early_pass!(self, check_block, b); self.check_id(b.id); ast_visit::walk_block(self, b); - run_lints!(self, check_block_post, b); + run_early_pass!(self, check_block_post, b); } fn visit_arm(&mut self, a: &'a ast::Arm) { - run_lints!(self, check_arm, a); + run_early_pass!(self, check_arm, a); ast_visit::walk_arm(self, a); } fn visit_expr_post(&mut self, e: &'a ast::Expr) { - run_lints!(self, check_expr_post, e); + run_early_pass!(self, check_expr_post, e); } fn visit_generic_param(&mut self, param: &'a ast::GenericParam) { - run_lints!(self, check_generic_param, param); + run_early_pass!(self, check_generic_param, param); ast_visit::walk_generic_param(self, param); } fn visit_generics(&mut self, g: &'a ast::Generics) { - run_lints!(self, check_generics, g); + run_early_pass!(self, check_generics, g); ast_visit::walk_generics(self, g); } fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) { - run_lints!(self, check_where_predicate, p); + run_early_pass!(self, check_where_predicate, p); ast_visit::walk_where_predicate(self, p); } fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef, m: &'a ast::TraitBoundModifier) { - run_lints!(self, check_poly_trait_ref, t, m); + run_early_pass!(self, check_poly_trait_ref, t, m); ast_visit::walk_poly_trait_ref(self, t, m); } fn visit_trait_item(&mut self, trait_item: &'a ast::TraitItem) { self.with_lint_attrs(trait_item.id, &trait_item.attrs, |cx| { - run_lints!(cx, check_trait_item, trait_item); + run_early_pass!(cx, check_trait_item, trait_item); ast_visit::walk_trait_item(cx, trait_item); - run_lints!(cx, check_trait_item_post, trait_item); + run_early_pass!(cx, check_trait_item_post, trait_item); }); } fn visit_impl_item(&mut self, impl_item: &'a ast::ImplItem) { self.with_lint_attrs(impl_item.id, &impl_item.attrs, |cx| { - run_lints!(cx, check_impl_item, impl_item); + run_early_pass!(cx, check_impl_item, impl_item); ast_visit::walk_impl_item(cx, impl_item); - run_lints!(cx, check_impl_item_post, impl_item); + run_early_pass!(cx, check_impl_item_post, impl_item); }); } fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) { - run_lints!(self, check_lifetime, lt); + run_early_pass!(self, check_lifetime, lt); self.check_id(lt.id); } fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) { - run_lints!(self, check_path, p, id); + run_early_pass!(self, check_path, p, id); self.check_id(id); ast_visit::walk_path(self, p); } fn visit_attribute(&mut self, attr: &'a ast::Attribute) { - run_lints!(self, check_attribute, attr); + run_early_pass!(self, check_attribute, attr); } fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) { - run_lints!(self, check_mac_def, mac, id); + run_early_pass!(self, check_mac_def, mac, id); self.check_id(id); } @@ -1186,7 +1200,7 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { // want to get #53686 fixed quickly. -nmatsakis ast_visit::walk_path(self, &mac.node.path); - run_lints!(self, check_mac, mac); + run_early_pass!(self, check_mac, mac); } } @@ -1231,43 +1245,112 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.sess.lint_store.borrow_mut().late_passes = passes; } -pub fn check_ast_crate( +struct EarlyLintPassObjects<'a> { + lints: &'a mut [EarlyLintPassObject], +} + +impl LintPass for EarlyLintPassObjects<'_> { + fn name(&self) -> &'static str { + panic!() + } + + fn get_lints(&self) -> LintArray { + panic!() + } +} + +macro_rules! expand_early_lint_pass_impl_methods { + ([$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { + for obj in self.lints.iter_mut() { + obj.$name(context, $($param),*); + } + })* + ) +} + +macro_rules! early_lint_pass_impl { + ([], [$($methods:tt)*]) => ( + impl EarlyLintPass for EarlyLintPassObjects<'_> { + expand_early_lint_pass_impl_methods!([$($methods)*]); + } + ) +} + +early_lint_methods!(early_lint_pass_impl, []); + + +fn early_lint_crate( + sess: &Session, + krate: &ast::Crate, + pass: T, + buffered: LintBuffer, +) -> LintBuffer { + let mut cx = EarlyContextAndPass { + context: EarlyContext::new(sess, krate, buffered), + pass, + }; + + // Visit the whole crate. + cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| { + // since the root module isn't visited as an item (because it isn't an + // item), warn for it here. + run_early_pass!(cx, check_crate, krate); + + ast_visit::walk_crate(cx, krate); + + run_early_pass!(cx, check_crate_post, krate); + }); + cx.context.buffered +} + +pub fn check_ast_crate( sess: &Session, krate: &ast::Crate, pre_expansion: bool, + builtin_lints: T, ) { - let (passes, buffered) = if pre_expansion { + let (mut passes, mut buffered) = if pre_expansion { ( - sess.lint_store.borrow_mut().pre_expansion_passes.take(), + sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow_mut().early_passes.take(), + sess.lint_store.borrow_mut().early_passes.take().unwrap(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; - let (passes, buffered) = { - let mut cx = EarlyContext::new(sess, krate, passes, buffered); - // Visit the whole crate. - cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| { - // since the root module isn't visited as an item (because it isn't an - // item), warn for it here. - run_lints!(cx, check_crate, krate); + if !sess.opts.debugging_opts.no_interleave_lints { + buffered = early_lint_crate(sess, krate, builtin_lints, buffered); - ast_visit::walk_crate(cx, krate); - - run_lints!(cx, check_crate_post, krate); - }); - (cx.lint_sess.passes, cx.buffered) - }; + if !passes.is_empty() { + buffered = early_lint_crate( + sess, + krate, + EarlyLintPassObjects { lints: &mut passes[..] }, + buffered, + ); + } + } else { + for pass in &mut passes { + buffered = time(sess, &format!("running lint: {}", pass.name()), || { + early_lint_crate( + sess, + krate, + EarlyLintPassObjects { lints: slice::from_mut(pass) }, + buffered, + ) + }); + } + } // Put the lint store levels and passes back in the session. if pre_expansion { - sess.lint_store.borrow_mut().pre_expansion_passes = passes; + sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes); } else { - sess.lint_store.borrow_mut().early_passes = passes; + sess.lint_store.borrow_mut().early_passes = Some(passes); } // All of the buffered lints should have been emitted at this point. diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 730ce919bd295..0f20081270f46 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -36,7 +36,6 @@ use syntax::source_map::{MultiSpan, ExpnFormat}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; use syntax::symbol::Symbol; -use syntax::visit as ast_visit; use syntax_pos::Span; use ty::TyCtxt; use ty::query::Providers; @@ -162,6 +161,8 @@ macro_rules! lint_array { pub type LintArray = Vec<&'static Lint>; pub trait LintPass { + fn name(&self) -> &'static str; + /// Get descriptions of the lints this `LintPass` object can emit. /// /// N.B., there is no enforcement that the object only emits lints it registered. @@ -308,6 +309,10 @@ macro_rules! declare_combined_late_lint_pass { } impl LintPass for $name { + fn name(&self) -> &'static str { + panic!() + } + fn get_lints(&self) -> LintArray { let mut lints = Vec::new(); $(lints.extend_from_slice(&self.$passes.get_lints());)* @@ -317,57 +322,139 @@ macro_rules! declare_combined_late_lint_pass { ) } -pub trait EarlyLintPass: LintPass { - fn check_ident(&mut self, _: &EarlyContext<'_>, _: ast::Ident) { } - fn check_crate(&mut self, _: &EarlyContext<'_>, _: &ast::Crate) { } - fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &ast::Crate) { } - fn check_mod(&mut self, _: &EarlyContext<'_>, _: &ast::Mod, _: Span, _: ast::NodeId) { } - fn check_mod_post(&mut self, _: &EarlyContext<'_>, _: &ast::Mod, _: Span, _: ast::NodeId) { } - fn check_foreign_item(&mut self, _: &EarlyContext<'_>, _: &ast::ForeignItem) { } - fn check_foreign_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::ForeignItem) { } - fn check_item(&mut self, _: &EarlyContext<'_>, _: &ast::Item) { } - fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::Item) { } - fn check_local(&mut self, _: &EarlyContext<'_>, _: &ast::Local) { } - fn check_block(&mut self, _: &EarlyContext<'_>, _: &ast::Block) { } - fn check_block_post(&mut self, _: &EarlyContext<'_>, _: &ast::Block) { } - fn check_stmt(&mut self, _: &EarlyContext<'_>, _: &ast::Stmt) { } - fn check_arm(&mut self, _: &EarlyContext<'_>, _: &ast::Arm) { } - fn check_pat(&mut self, _: &EarlyContext<'_>, _: &ast::Pat, _: &mut bool) { } - fn check_expr(&mut self, _: &EarlyContext<'_>, _: &ast::Expr) { } - fn check_expr_post(&mut self, _: &EarlyContext<'_>, _: &ast::Expr) { } - fn check_ty(&mut self, _: &EarlyContext<'_>, _: &ast::Ty) { } - fn check_generic_param(&mut self, _: &EarlyContext<'_>, _: &ast::GenericParam) { } - fn check_generics(&mut self, _: &EarlyContext<'_>, _: &ast::Generics) { } - fn check_where_predicate(&mut self, _: &EarlyContext<'_>, _: &ast::WherePredicate) { } - fn check_poly_trait_ref(&mut self, _: &EarlyContext<'_>, _: &ast::PolyTraitRef, - _: &ast::TraitBoundModifier) { } - fn check_fn(&mut self, _: &EarlyContext<'_>, - _: ast_visit::FnKind<'_>, _: &ast::FnDecl, _: Span, _: ast::NodeId) { } - fn check_fn_post(&mut self, _: &EarlyContext<'_>, - _: ast_visit::FnKind<'_>, _: &ast::FnDecl, _: Span, _: ast::NodeId) { } - fn check_trait_item(&mut self, _: &EarlyContext<'_>, _: &ast::TraitItem) { } - fn check_trait_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::TraitItem) { } - fn check_impl_item(&mut self, _: &EarlyContext<'_>, _: &ast::ImplItem) { } - fn check_impl_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::ImplItem) { } - fn check_struct_def(&mut self, _: &EarlyContext<'_>, - _: &ast::VariantData, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } - fn check_struct_def_post(&mut self, _: &EarlyContext<'_>, - _: &ast::VariantData, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } - fn check_struct_field(&mut self, _: &EarlyContext<'_>, _: &ast::StructField) { } - fn check_variant(&mut self, _: &EarlyContext<'_>, _: &ast::Variant, _: &ast::Generics) { } - fn check_variant_post(&mut self, _: &EarlyContext<'_>, _: &ast::Variant, _: &ast::Generics) { } - fn check_lifetime(&mut self, _: &EarlyContext<'_>, _: &ast::Lifetime) { } - fn check_path(&mut self, _: &EarlyContext<'_>, _: &ast::Path, _: ast::NodeId) { } - fn check_attribute(&mut self, _: &EarlyContext<'_>, _: &ast::Attribute) { } - fn check_mac_def(&mut self, _: &EarlyContext<'_>, _: &ast::MacroDef, _id: ast::NodeId) { } - fn check_mac(&mut self, _: &EarlyContext<'_>, _: &ast::Mac) { } - - /// Called when entering a syntax node that can have lint attributes such - /// as `#[allow(...)]`. Called with *all* the attributes of that node. - fn enter_lint_attrs(&mut self, _: &EarlyContext<'_>, _: &[ast::Attribute]) { } - - /// Counterpart to `enter_lint_attrs`. - fn exit_lint_attrs(&mut self, _: &EarlyContext<'_>, _: &[ast::Attribute]) { } +#[macro_export] +macro_rules! early_lint_methods { + ($macro:path, $args:tt) => ( + $macro!($args, [ + fn check_ident(a: ast::Ident); + fn check_crate(a: &ast::Crate); + fn check_crate_post(a: &ast::Crate); + fn check_mod(a: &ast::Mod, b: Span, c: ast::NodeId); + fn check_mod_post(a: &ast::Mod, b: Span, c: ast::NodeId); + fn check_foreign_item(a: &ast::ForeignItem); + fn check_foreign_item_post(a: &ast::ForeignItem); + fn check_item(a: &ast::Item); + fn check_item_post(a: &ast::Item); + fn check_local(a: &ast::Local); + fn check_block(a: &ast::Block); + fn check_block_post(a: &ast::Block); + fn check_stmt(a: &ast::Stmt); + fn check_arm(a: &ast::Arm); + fn check_pat(a: &ast::Pat, b: &mut bool); // FIXME: &mut bool looks just broken + fn check_expr(a: &ast::Expr); + fn check_expr_post(a: &ast::Expr); + fn check_ty(a: &ast::Ty); + fn check_generic_param(a: &ast::GenericParam); + fn check_generics(a: &ast::Generics); + fn check_where_predicate(a: &ast::WherePredicate); + fn check_poly_trait_ref(a: &ast::PolyTraitRef, + b: &ast::TraitBoundModifier); + fn check_fn(a: syntax::visit::FnKind<'_>, b: &ast::FnDecl, c: Span, d_: ast::NodeId); + fn check_fn_post( + a: syntax::visit::FnKind<'_>, + b: &ast::FnDecl, + c: Span, + d: ast::NodeId + ); + fn check_trait_item(a: &ast::TraitItem); + fn check_trait_item_post(a: &ast::TraitItem); + fn check_impl_item(a: &ast::ImplItem); + fn check_impl_item_post(a: &ast::ImplItem); + fn check_struct_def( + a: &ast::VariantData, + b: ast::Ident, + c: &ast::Generics, + d: ast::NodeId + ); + fn check_struct_def_post( + a: &ast::VariantData, + b: ast::Ident, + c: &ast::Generics, + d: ast::NodeId + ); + fn check_struct_field(a: &ast::StructField); + fn check_variant(a: &ast::Variant, b: &ast::Generics); + fn check_variant_post(a: &ast::Variant, b: &ast::Generics); + fn check_lifetime(a: &ast::Lifetime); + fn check_path(a: &ast::Path, b: ast::NodeId); + fn check_attribute(a: &ast::Attribute); + fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId); + fn check_mac(a: &ast::Mac); + + /// Called when entering a syntax node that can have lint attributes such + /// as `#[allow(...)]`. Called with *all* the attributes of that node. + fn enter_lint_attrs(a: &[ast::Attribute]); + + /// Counterpart to `enter_lint_attrs`. + fn exit_lint_attrs(a: &[ast::Attribute]); + ]); + ) +} + +macro_rules! expand_early_lint_pass_methods { + ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})* + ) +} + +macro_rules! declare_early_lint_pass { + ([], [$($methods:tt)*]) => ( + pub trait EarlyLintPass: LintPass { + expand_early_lint_pass_methods!(&EarlyContext<'_>, [$($methods)*]); + } + ) +} + +early_lint_methods!(declare_early_lint_pass, []); + +#[macro_export] +macro_rules! expand_combined_early_lint_pass_method { + ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ + $($self.$passes.$name $params;)* + }) +} + +#[macro_export] +macro_rules! expand_combined_early_lint_pass_methods { + ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { + expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*)); + })* + ) +} + +#[macro_export] +macro_rules! declare_combined_early_lint_pass { + ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => ( + #[allow(non_snake_case)] + $v struct $name { + $($passes: $passes,)* + } + + impl $name { + $v fn new() -> Self { + Self { + $($passes: $constructor,)* + } + } + } + + impl EarlyLintPass for $name { + expand_combined_early_lint_pass_methods!([$($passes),*], $methods); + } + + impl LintPass for $name { + fn name(&self) -> &'static str { + panic!() + } + + fn get_lints(&self) -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&self.$passes.get_lints());)* + lints + } + } + ) } /// A lint pass boxed up as a trait object. diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 42adc6a87fdba..ffd6525e6e70d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1364,6 +1364,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"), no_leak_check: bool = (false, parse_bool, [UNTRACKED], "disables the 'leak check' for subtyping; unsound, but useful for tests"), + no_interleave_lints: bool = (false, parse_bool, [UNTRACKED], + "don't interleave execution of lints; allows benchmarking individual lints"), crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], "inject the given attribute in the crate"), self_profile: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1ecb8ef112c9e..495df73e5e9c9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -898,7 +898,7 @@ where sess.track_errors(|| { let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(Some(sess), true, pass); + ls.register_early_pass(Some(sess), true, false, pass); } for pass in late_lint_passes { ls.register_late_pass(Some(sess), true, pass); @@ -919,7 +919,11 @@ where } time(sess, "pre ast expansion lint checks", || { - lint::check_ast_crate(sess, &krate, true) + lint::check_ast_crate( + sess, + &krate, + true, + rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); }); let mut resolver = Resolver::new( @@ -1131,7 +1135,7 @@ where }); time(sess, "early lint checks", || { - lint::check_ast_crate(sess, &krate, false) + lint::check_ast_crate(sess, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new()) }); // Discard hygiene data, which isn't required after lowering to HIR. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f895542e43ada..7b48ab459748d 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -60,6 +60,10 @@ declare_lint! { pub struct WhileTrue; impl LintPass for WhileTrue { + fn name(&self) -> &'static str { + "WhileTrue" + } + fn get_lints(&self) -> LintArray { lint_array!(WHILE_TRUE) } @@ -109,6 +113,10 @@ impl BoxPointers { } impl LintPass for BoxPointers { + fn name(&self) -> &'static str { + "BoxPointers" + } + fn get_lints(&self) -> LintArray { lint_array!(BOX_POINTERS) } @@ -158,6 +166,10 @@ declare_lint! { pub struct NonShorthandFieldPatterns; impl LintPass for NonShorthandFieldPatterns { + fn name(&self) -> &'static str { + "NonShorthandFieldPatterns" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_SHORTHAND_FIELD_PATTERNS) } @@ -211,6 +223,10 @@ declare_lint! { pub struct UnsafeCode; impl LintPass for UnsafeCode { + fn name(&self) -> &'static str { + "UnsafeCode" + } + fn get_lints(&self) -> LintArray { lint_array!(UNSAFE_CODE) } @@ -373,6 +389,10 @@ impl MissingDoc { } impl LintPass for MissingDoc { + fn name(&self) -> &'static str { + "MissingDoc" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_DOCS) } @@ -519,6 +539,10 @@ declare_lint! { pub struct MissingCopyImplementations; impl LintPass for MissingCopyImplementations { + fn name(&self) -> &'static str { + "MissingCopyImplementations" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_COPY_IMPLEMENTATIONS) } @@ -586,6 +610,10 @@ impl MissingDebugImplementations { } impl LintPass for MissingDebugImplementations { + fn name(&self) -> &'static str { + "MissingDebugImplementations" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_DEBUG_IMPLEMENTATIONS) } @@ -643,6 +671,10 @@ declare_lint! { pub struct AnonymousParameters; impl LintPass for AnonymousParameters { + fn name(&self) -> &'static str { + "AnonymousParameters" + } + fn get_lints(&self) -> LintArray { lint_array!(ANONYMOUS_PARAMETERS) } @@ -707,6 +739,10 @@ impl DeprecatedAttr { } impl LintPass for DeprecatedAttr { + fn name(&self) -> &'static str { + "DeprecatedAttr" + } + fn get_lints(&self) -> LintArray { lint_array!() } @@ -747,6 +783,10 @@ declare_lint! { pub struct UnusedDocComment; impl LintPass for UnusedDocComment { + fn name(&self) -> &'static str { + "UnusedDocComment" + } + fn get_lints(&self) -> LintArray { lint_array![UNUSED_DOC_COMMENTS] } @@ -787,6 +827,10 @@ declare_lint! { pub struct PluginAsLibrary; impl LintPass for PluginAsLibrary { + fn name(&self) -> &'static str { + "PluginAsLibrary" + } + fn get_lints(&self) -> LintArray { lint_array![PLUGIN_AS_LIBRARY] } @@ -839,6 +883,10 @@ declare_lint! { pub struct InvalidNoMangleItems; impl LintPass for InvalidNoMangleItems { + fn name(&self) -> &'static str { + "InvalidNoMangleItems" + } + fn get_lints(&self) -> LintArray { lint_array!(NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS) @@ -910,6 +958,10 @@ declare_lint! { } impl LintPass for MutableTransmutes { + fn name(&self) -> &'static str { + "MutableTransmutes" + } + fn get_lints(&self) -> LintArray { lint_array!(MUTABLE_TRANSMUTES) } @@ -970,6 +1022,10 @@ declare_lint! { } impl LintPass for UnstableFeatures { + fn name(&self) -> &'static str { + "UnstableFeatures" + } + fn get_lints(&self) -> LintArray { lint_array!(UNSTABLE_FEATURES) } @@ -997,6 +1053,10 @@ declare_lint! { } impl LintPass for UnionsWithDropFields { + fn name(&self) -> &'static str { + "UnionsWithDropFields" + } + fn get_lints(&self) -> LintArray { lint_array!(UNIONS_WITH_DROP_FIELDS) } @@ -1029,6 +1089,10 @@ declare_lint! { } impl LintPass for UnreachablePub { + fn name(&self) -> &'static str { + "UnreachablePub" + } + fn get_lints(&self) -> LintArray { lint_array!(UNREACHABLE_PUB) } @@ -1099,6 +1163,10 @@ declare_lint! { } impl LintPass for TypeAliasBounds { + fn name(&self) -> &'static str { + "TypeAliasBounds" + } + fn get_lints(&self) -> LintArray { lint_array!(TYPE_ALIAS_BOUNDS) } @@ -1203,6 +1271,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { pub struct UnusedBrokenConst; impl LintPass for UnusedBrokenConst { + fn name(&self) -> &'static str { + "UnusedBrokenConst" + } + fn get_lints(&self) -> LintArray { lint_array!() } @@ -1249,6 +1321,10 @@ declare_lint! { } impl LintPass for TrivialConstraints { + fn name(&self) -> &'static str { + "TrivialConstraints" + } + fn get_lints(&self) -> LintArray { lint_array!(TRIVIAL_BOUNDS) } @@ -1303,6 +1379,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { pub struct SoftLints; impl LintPass for SoftLints { + fn name(&self) -> &'static str { + "SoftLints" + } + fn get_lints(&self) -> LintArray { lint_array!( WHILE_TRUE, @@ -1337,6 +1417,10 @@ declare_lint! { pub struct EllipsisInclusiveRangePatterns; impl LintPass for EllipsisInclusiveRangePatterns { + fn name(&self) -> &'static str { + "EllipsisInclusiveRangePatterns" + } + fn get_lints(&self) -> LintArray { lint_array!(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS) } @@ -1411,6 +1495,10 @@ impl UnnameableTestItems { } impl LintPass for UnnameableTestItems { + fn name(&self) -> &'static str { + "UnnameableTestItems" + } + fn get_lints(&self) -> LintArray { lint_array!(UNNAMEABLE_TEST_ITEMS) } @@ -1454,6 +1542,10 @@ declare_lint! { pub struct KeywordIdents; impl LintPass for KeywordIdents { + fn name(&self) -> &'static str { + "KeywordIdents" + } + fn get_lints(&self) -> LintArray { lint_array!(KEYWORD_IDENTS) } @@ -1559,6 +1651,10 @@ impl EarlyLintPass for KeywordIdents { pub struct ExplicitOutlivesRequirements; impl LintPass for ExplicitOutlivesRequirements { + fn name(&self) -> &'static str { + "ExplicitOutlivesRequirements" + } + fn get_lints(&self) -> LintArray { lint_array![EXPLICIT_OUTLIVES_REQUIREMENTS] } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2d764d11c66aa..fedc0410f2402 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -39,7 +39,7 @@ mod types; mod unused; use rustc::lint; -use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray}; +use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; use rustc::lint::builtin::{ BARE_TRAIT_OBJECTS, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, @@ -71,57 +71,68 @@ use unused::*; /// Useful for other parts of the compiler. pub use builtin::SoftLints; +macro_rules! pre_expansion_lint_passes { + ($macro:path, $args:tt) => ( + $macro!($args, [ + KeywordIdents: KeywordIdents, + ]); + ) +} + +macro_rules! early_lint_passes { + ($macro:path, $args:tt) => ( + $macro!($args, [ + UnusedParens: UnusedParens, + UnusedImportBraces: UnusedImportBraces, + UnsafeCode: UnsafeCode, + AnonymousParameters: AnonymousParameters, + UnusedDocComment: UnusedDocComment, + EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns, + NonCamelCaseTypes: NonCamelCaseTypes, + DeprecatedAttr: DeprecatedAttr::new(), + ]); + ) +} + +macro_rules! declare_combined_early_pass { + ([$name:ident], $passes:tt) => ( + early_lint_methods!(declare_combined_early_lint_pass, [pub $name, $passes]); + ) +} + +pre_expansion_lint_passes!(declare_combined_early_pass, [BuiltinCombinedPreExpansionLintPass]); +early_lint_passes!(declare_combined_early_pass, [BuiltinCombinedEarlyLintPass]); + /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { - macro_rules! add_early_builtin { - ($sess:ident, $($name:ident),*,) => ( - {$( - store.register_early_pass($sess, false, box $name); - )*} - ) - } - - macro_rules! add_pre_expansion_builtin { - ($sess:ident, $($name:ident),*,) => ( - {$( - store.register_pre_expansion_pass($sess, box $name); - )*} - ) - } - - macro_rules! add_early_builtin_with_new { - ($sess:ident, $($name:ident),*,) => ( - {$( - store.register_early_pass($sess, false, box $name::new()); - )*} - ) - } - macro_rules! add_lint_group { ($sess:ident, $name:expr, $($lint:ident),*) => ( store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]); ) } - add_pre_expansion_builtin!(sess, - KeywordIdents, - ); - - add_early_builtin!(sess, - UnusedParens, - UnusedImportBraces, - UnsafeCode, - AnonymousParameters, - UnusedDocComment, - EllipsisInclusiveRangePatterns, - NonCamelCaseTypes, - ); + macro_rules! register_passes { + ([$method:ident], [$($passes:ident: $constructor:expr,)*]) => ( + $( + store.$method(sess, false, false, box $constructor); + )* + ) + } - add_early_builtin_with_new!(sess, - DeprecatedAttr, - ); + if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) { + pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass]); + early_lint_passes!(register_passes, [register_early_pass]); + } else { + store.register_pre_expansion_pass( + sess, + false, + true, + box BuiltinCombinedPreExpansionLintPass::new() + ); + store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new()); + } late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [ HardwiredLints: HardwiredLints, diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index a4a3fa552e988..256d28a39794e 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -105,6 +105,10 @@ impl NonCamelCaseTypes { } impl LintPass for NonCamelCaseTypes { + fn name(&self) -> &'static str { + "NonCamelCaseTypes" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_CAMEL_CASE_TYPES) } @@ -235,6 +239,10 @@ impl NonSnakeCase { } impl LintPass for NonSnakeCase { + fn name(&self) -> &'static str { + "NonSnakeCase" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_SNAKE_CASE) } @@ -381,6 +389,10 @@ impl NonUpperCaseGlobals { } impl LintPass for NonUpperCaseGlobals { + fn name(&self) -> &'static str { + "NonUpperCaseGlobals" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_UPPER_CASE_GLOBALS) } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 642681a73a8a0..aa6f396145473 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -53,6 +53,10 @@ impl TypeLimits { } impl LintPass for TypeLimits { + fn name(&self) -> &'static str { + "TypeLimits" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_COMPARISONS, OVERFLOWING_LITERALS) @@ -783,6 +787,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { pub struct ImproperCTypes; impl LintPass for ImproperCTypes { + fn name(&self) -> &'static str { + "ImproperCTypes" + } + fn get_lints(&self) -> LintArray { lint_array!(IMPROPER_CTYPES) } @@ -809,6 +817,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { pub struct VariantSizeDifferences; impl LintPass for VariantSizeDifferences { + fn name(&self) -> &'static str { + "VariantSizeDifferences" + } + fn get_lints(&self) -> LintArray { lint_array!(VARIANT_SIZE_DIFFERENCES) } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index bc29020e79f2a..a05ad95a49de7 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -33,6 +33,10 @@ declare_lint! { pub struct UnusedResults; impl LintPass for UnusedResults { + fn name(&self) -> &'static str { + "UnusedResults" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS) } @@ -198,6 +202,10 @@ declare_lint! { pub struct PathStatements; impl LintPass for PathStatements { + fn name(&self) -> &'static str { + "PathStatements" + } + fn get_lints(&self) -> LintArray { lint_array!(PATH_STATEMENTS) } @@ -223,6 +231,10 @@ declare_lint! { pub struct UnusedAttributes; impl LintPass for UnusedAttributes { + fn name(&self) -> &'static str { + "UnusedAttributes" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_ATTRIBUTES) } @@ -365,6 +377,10 @@ impl UnusedParens { } impl LintPass for UnusedParens { + fn name(&self) -> &'static str { + "UnusedParens" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_PARENS) } @@ -483,6 +499,10 @@ impl UnusedImportBraces { } impl LintPass for UnusedImportBraces { + fn name(&self) -> &'static str { + "UnusedImportBraces" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_IMPORT_BRACES) } @@ -506,6 +526,10 @@ declare_lint! { pub struct UnusedAllocation; impl LintPass for UnusedAllocation { + fn name(&self) -> &'static str { + "UnusedAllocation" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_ALLOCATION) } From 9b5535a6f38340d3be8fcae1822a04ba3febf82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 19 Jan 2019 06:26:34 +0100 Subject: [PATCH 0175/1064] Fix lints in tests --- .../compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs | 4 ++++ src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs | 4 ++++ src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_for_crate.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_tool_test.rs | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs index bca1d7a72b4ab..16630e2b31285 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -19,6 +19,10 @@ declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT, PLEASE_LINT) } diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs index 3e0e4e60e0db8..efa3de9a686b8 100644 --- a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs @@ -32,6 +32,10 @@ declare_lint!(MISSING_WHITELISTED_ATTR, Deny, struct MissingWhitelistedAttrPass; impl LintPass for MissingWhitelistedAttrPass { + fn name(&self) -> &'static str { + "MissingWhitelistedAttrPass" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_WHITELISTED_ATTR) } diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs index b6c517f2764bd..f34e10218d455 100644 --- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs @@ -17,6 +17,10 @@ macro_rules! fake_lint_pass { struct $struct; impl LintPass for $struct { + fn name(&self) -> &'static str { + stringify!($struct) + } + fn get_lints(&self) -> LintArray { $lints } diff --git a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs b/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs index 23bda04f9b328..82aa28b26b648 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs @@ -17,6 +17,10 @@ declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(CRATE_NOT_OKAY) } diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs index bca1d7a72b4ab..16630e2b31285 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -19,6 +19,10 @@ declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT, PLEASE_LINT) } diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs index 9b0127ea5c006..4e45189b42427 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs @@ -19,6 +19,10 @@ declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT) } diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs index 5c9569ddc6575..1a9bd9e66dbac 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs @@ -18,6 +18,10 @@ declare_tool_lint!(pub clippy::TEST_GROUP, Warn, "Warn about other stuff"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT, TEST_GROUP) } From c7d25a2a4082e6d2601ea4c06ea01b632d196172 Mon Sep 17 00:00:00 2001 From: Alexis Hunt Date: Mon, 14 Jan 2019 08:10:45 -0500 Subject: [PATCH 0176/1064] Make `str` indexing generic on `SliceIndex`. --- src/libcore/ops/index.rs | 15 - src/libcore/slice/mod.rs | 16 +- src/libcore/str/mod.rs | 296 +++++++----------- src/test/ui/index-help.stderr | 2 +- src/test/ui/indexing-requires-a-uint.rs | 2 +- src/test/ui/indexing-requires-a-uint.stderr | 4 +- src/test/ui/integral-indexing.rs | 16 +- src/test/ui/integral-indexing.stderr | 32 +- .../ui/on-unimplemented/slice-index.stderr | 4 +- src/test/ui/str/str-idx.rs | 5 +- src/test/ui/str/str-idx.stderr | 38 ++- src/test/ui/str/str-mut-idx.rs | 8 +- src/test/ui/str/str-mut-idx.stderr | 36 ++- 13 files changed, 239 insertions(+), 235 deletions(-) diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index 6cfa36741d0ca..d4ed86142768d 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -51,21 +51,6 @@ /// ``` #[lang = "index"] #[rustc_on_unimplemented( - on( - _Self="&str", - note="you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book " - ), - on( - _Self="str", - note="you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book " - ), - on( - _Self="std::string::String", - note="you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book " - ), message="the type `{Self}` cannot be indexed by `{Idx}`", label="`{Self}` cannot be indexed by `{Idx}`", )] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 7fdc2acb8cc92..2245d48f889e0 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2312,7 +2312,6 @@ impl [u8] { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] impl ops::Index for [T] where I: SliceIndex<[T]> { @@ -2325,7 +2324,6 @@ impl ops::Index for [T] } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] impl ops::IndexMut for [T] where I: SliceIndex<[T]> { @@ -2376,7 +2374,19 @@ mod private_slice_index { /// A helper trait used for indexing operations. #[stable(feature = "slice_get_slice", since = "1.28.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] +#[rustc_on_unimplemented( + on( + T = "str", + label = "string indices are ranges of `usize`", + ), + on( + all(any(T = "str", T = "&str", T = "std::string::String"), _Self="{integer}"), + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book " + ), + message = "the type `{T}` cannot be indexed by `{Self}`", + label = "slice indices are of type `usize` or ranges of `usize`", +)] pub trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index bdde187d931cc..1ee8b7735c17d 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1621,190 +1621,26 @@ mod traits { } } - /// Implements substring slicing with syntax `&self[begin .. end]`. - /// - /// Returns a slice of the given string from the byte range - /// [`begin`..`end`). - /// - /// This operation is `O(1)`. - /// - /// # Panics - /// - /// Panics if `begin` or `end` does not point to the starting - /// byte offset of a character (as defined by `is_char_boundary`). - /// Requires that `begin <= end` and `end <= len` where `len` is the - /// length of the string. - /// - /// # Examples - /// - /// ``` - /// let s = "Löwe 老虎 Léopard"; - /// assert_eq!(&s[0 .. 1], "L"); - /// - /// assert_eq!(&s[1 .. 9], "öwe 老"); - /// - /// // these will panic: - /// // byte 2 lies within `ö`: - /// // &s[2 ..3]; - /// - /// // byte 8 lies within `老` - /// // &s[1 .. 8]; - /// - /// // byte 100 is outside the string - /// // &s[3 .. 100]; - /// ``` #[stable(feature = "rust1", since = "1.0.0")] - impl ops::Index> for str { - type Output = str; - #[inline] - fn index(&self, index: ops::Range) -> &str { - index.index(self) - } - } - - /// Implements mutable substring slicing with syntax - /// `&mut self[begin .. end]`. - /// - /// Returns a mutable slice of the given string from the byte range - /// [`begin`..`end`). - /// - /// This operation is `O(1)`. - /// - /// # Panics - /// - /// Panics if `begin` or `end` does not point to the starting - /// byte offset of a character (as defined by `is_char_boundary`). - /// Requires that `begin <= end` and `end <= len` where `len` is the - /// length of the string. - #[stable(feature = "derefmut_for_string", since = "1.3.0")] - impl ops::IndexMut> for str { - #[inline] - fn index_mut(&mut self, index: ops::Range) -> &mut str { - index.index_mut(self) - } - } - - /// Implements substring slicing with syntax `&self[.. end]`. - /// - /// Returns a slice of the string from the beginning to byte offset - /// `end`. - /// - /// Equivalent to `&self[0 .. end]`. - #[stable(feature = "rust1", since = "1.0.0")] - impl ops::Index> for str { - type Output = str; - - #[inline] - fn index(&self, index: ops::RangeTo) -> &str { - index.index(self) - } - } - - /// Implements mutable substring slicing with syntax `&mut self[.. end]`. - /// - /// Returns a mutable slice of the string from the beginning to byte offset - /// `end`. - /// - /// Equivalent to `&mut self[0 .. end]`. - #[stable(feature = "derefmut_for_string", since = "1.3.0")] - impl ops::IndexMut> for str { - #[inline] - fn index_mut(&mut self, index: ops::RangeTo) -> &mut str { - index.index_mut(self) - } - } - - /// Implements substring slicing with syntax `&self[begin ..]`. - /// - /// Returns a slice of the string from byte offset `begin` - /// to the end of the string. - /// - /// Equivalent to `&self[begin .. len]`. - #[stable(feature = "rust1", since = "1.0.0")] - impl ops::Index> for str { - type Output = str; + impl ops::Index for str + where + I: SliceIndex, + { + type Output = I::Output; #[inline] - fn index(&self, index: ops::RangeFrom) -> &str { + fn index(&self, index: I) -> &I::Output { index.index(self) } } - /// Implements mutable substring slicing with syntax `&mut self[begin ..]`. - /// - /// Returns a mutable slice of the string from byte offset `begin` - /// to the end of the string. - /// - /// Equivalent to `&mut self[begin .. len]`. - #[stable(feature = "derefmut_for_string", since = "1.3.0")] - impl ops::IndexMut> for str { - #[inline] - fn index_mut(&mut self, index: ops::RangeFrom) -> &mut str { - index.index_mut(self) - } - } - - /// Implements substring slicing with syntax `&self[..]`. - /// - /// Returns a slice of the whole string. This operation can - /// never panic. - /// - /// Equivalent to `&self[0 .. len]`. #[stable(feature = "rust1", since = "1.0.0")] - impl ops::Index for str { - type Output = str; - - #[inline] - fn index(&self, _index: ops::RangeFull) -> &str { - self - } - } - - /// Implements mutable substring slicing with syntax `&mut self[..]`. - /// - /// Returns a mutable slice of the whole string. This operation can - /// never panic. - /// - /// Equivalent to `&mut self[0 .. len]`. - #[stable(feature = "derefmut_for_string", since = "1.3.0")] - impl ops::IndexMut for str { - #[inline] - fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str { - self - } - } - - #[stable(feature = "inclusive_range", since = "1.26.0")] - impl ops::Index> for str { - type Output = str; - - #[inline] - fn index(&self, index: ops::RangeInclusive) -> &str { - index.index(self) - } - } - - #[stable(feature = "inclusive_range", since = "1.26.0")] - impl ops::Index> for str { - type Output = str; - - #[inline] - fn index(&self, index: ops::RangeToInclusive) -> &str { - index.index(self) - } - } - - #[stable(feature = "inclusive_range", since = "1.26.0")] - impl ops::IndexMut> for str { - #[inline] - fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { - index.index_mut(self) - } - } - #[stable(feature = "inclusive_range", since = "1.26.0")] - impl ops::IndexMut> for str { + impl ops::IndexMut for str + where + I: SliceIndex, + { #[inline] - fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { + fn index_mut(&mut self, index: I) -> &mut I::Output { index.index_mut(self) } } @@ -1815,6 +1651,18 @@ mod traits { panic!("attempted to index str up to maximum usize"); } + /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`. + /// + /// Returns a slice of the whole string, i.e., returns `&self` or `&mut + /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike + /// other indexing operations, this can never panic. + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex for ops::RangeFull { type Output = str; @@ -1844,6 +1692,41 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut + /// self[begin .. end]`. + /// + /// Returns a slice of the given string from the byte range + /// [`begin`, `end`). + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// # Panics + /// + /// Panics if `begin` or `end` does not point to the starting byte offset of + /// a character (as defined by `is_char_boundary`), if `begin > end`, or if + /// `end > len`. + /// + /// # Examples + /// + /// ``` + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(&s[0 .. 1], "L"); + /// + /// assert_eq!(&s[1 .. 9], "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // &s[2 ..3]; + /// + /// // byte 8 lies within `老` + /// // &s[1 .. 8]; + /// + /// // byte 100 is outside the string + /// // &s[3 .. 100]; + /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex for ops::Range { type Output = str; @@ -1898,6 +1781,21 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[.. end]` or `&mut + /// self[.. end]`. + /// + /// Returns a slice of the given string from the byte range [`0`, `end`). + /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`. + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// # Panics + /// + /// Panics if `end` does not point to the starting byte offset of a + /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex for ops::RangeTo { type Output = str; @@ -1943,6 +1841,22 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[begin ..]` or `&mut + /// self[begin ..]`. + /// + /// Returns a slice of the given string from the byte range [`begin`, + /// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin .. + /// len]`. + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// # Panics + /// + /// Panics if `begin` does not point to the starting byte offset of + /// a character (as defined by `is_char_boundary`), or if `begin >= len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex for ops::RangeFrom { type Output = str; @@ -1990,6 +1904,22 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut + /// self[begin ..= end]`. + /// + /// Returns a slice of the given string from the byte range + /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut + /// self[begin .. end + 1]`, except if `end` has the maximum value for + /// `usize`. + /// + /// This operation is `O(1)`. + /// + /// # Panics + /// + /// Panics if `begin` does not point to the starting byte offset of + /// a character (as defined by `is_char_boundary`), if `end` does not point + /// to the ending byte offset of a character (`end + 1` is either a starting + /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex for ops::RangeInclusive { type Output = str; @@ -2023,8 +1953,20 @@ mod traits { } } - - + /// Implements substring slicing with syntax `&self[..= end]` or `&mut + /// self[..= end]`. + /// + /// Returns a slice of the given string from the byte range [0, `end`]. + /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum + /// value for `usize`. + /// + /// This operation is `O(1)`. + /// + /// # Panics + /// + /// Panics if `end` does not point to the ending byte offset of a character + /// (`end + 1` is either a starting byte offset as defined by + /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex for ops::RangeToInclusive { type Output = str; diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index c8b23d812e1b5..4c585a958c14b 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied +error[E0277]: the type `[{integer}]` cannot be indexed by `i32` --> $DIR/index-help.rs:3:5 | LL | x[0i32]; //~ ERROR E0277 diff --git a/src/test/ui/indexing-requires-a-uint.rs b/src/test/ui/indexing-requires-a-uint.rs index 2db3c58ec519f..dbe9b44a13890 100644 --- a/src/test/ui/indexing-requires-a-uint.rs +++ b/src/test/ui/indexing-requires-a-uint.rs @@ -3,7 +3,7 @@ fn main() { fn bar(_: T) {} - [0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied + [0][0u8]; //~ ERROR: the type `[{integer}]` cannot be indexed by `u8` [0][0]; // should infer to be a usize diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index 767f1af2c46e9..363c3d0d45853 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -1,7 +1,7 @@ -error[E0277]: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied +error[E0277]: the type `[{integer}]` cannot be indexed by `u8` --> $DIR/indexing-requires-a-uint.rs:6:5 | -LL | [0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied +LL | [0][0u8]; //~ ERROR: the type `[{integer}]` cannot be indexed by `u8` | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `u8` diff --git a/src/test/ui/integral-indexing.rs b/src/test/ui/integral-indexing.rs index 7bdbc45879b9d..f076dfcb0a42c 100644 --- a/src/test/ui/integral-indexing.rs +++ b/src/test/ui/integral-indexing.rs @@ -3,14 +3,14 @@ pub fn main() { let s: String = "abcdef".to_string(); v[3_usize]; v[3]; - v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied - v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied - v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied - v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3u8]; //~ERROR : the type `[isize]` cannot be indexed by `u8` + v[3i8]; //~ERROR : the type `[isize]` cannot be indexed by `i8` + v[3u32]; //~ERROR : the type `[isize]` cannot be indexed by `u32` + v[3i32]; //~ERROR : the type `[isize]` cannot be indexed by `i32` s.as_bytes()[3_usize]; s.as_bytes()[3]; - s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied - s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied - s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied - s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied + s.as_bytes()[3u8]; //~ERROR : the type `[u8]` cannot be indexed by `u8` + s.as_bytes()[3i8]; //~ERROR : the type `[u8]` cannot be indexed by `i8` + s.as_bytes()[3u32]; //~ERROR : the type `[u8]` cannot be indexed by `u32` + s.as_bytes()[3i32]; //~ERROR : the type `[u8]` cannot be indexed by `i32` } diff --git a/src/test/ui/integral-indexing.stderr b/src/test/ui/integral-indexing.stderr index 7f2dddcf7b8c3..efbad86c4d31b 100644 --- a/src/test/ui/integral-indexing.stderr +++ b/src/test/ui/integral-indexing.stderr @@ -1,70 +1,70 @@ -error[E0277]: the trait bound `u8: std::slice::SliceIndex<[isize]>` is not satisfied +error[E0277]: the type `[isize]` cannot be indexed by `u8` --> $DIR/integral-indexing.rs:6:5 | -LL | v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied +LL | v[3u8]; //~ERROR : the type `[isize]` cannot be indexed by `u8` | ^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u8` = note: required because of the requirements on the impl of `std::ops::Index` for `std::vec::Vec` -error[E0277]: the trait bound `i8: std::slice::SliceIndex<[isize]>` is not satisfied +error[E0277]: the type `[isize]` cannot be indexed by `i8` --> $DIR/integral-indexing.rs:7:5 | -LL | v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied +LL | v[3i8]; //~ERROR : the type `[isize]` cannot be indexed by `i8` | ^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i8` = note: required because of the requirements on the impl of `std::ops::Index` for `std::vec::Vec` -error[E0277]: the trait bound `u32: std::slice::SliceIndex<[isize]>` is not satisfied +error[E0277]: the type `[isize]` cannot be indexed by `u32` --> $DIR/integral-indexing.rs:8:5 | -LL | v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied +LL | v[3u32]; //~ERROR : the type `[isize]` cannot be indexed by `u32` | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u32` = note: required because of the requirements on the impl of `std::ops::Index` for `std::vec::Vec` -error[E0277]: the trait bound `i32: std::slice::SliceIndex<[isize]>` is not satisfied +error[E0277]: the type `[isize]` cannot be indexed by `i32` --> $DIR/integral-indexing.rs:9:5 | -LL | v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied +LL | v[3i32]; //~ERROR : the type `[isize]` cannot be indexed by `i32` | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i32` = note: required because of the requirements on the impl of `std::ops::Index` for `std::vec::Vec` -error[E0277]: the trait bound `u8: std::slice::SliceIndex<[u8]>` is not satisfied +error[E0277]: the type `[u8]` cannot be indexed by `u8` --> $DIR/integral-indexing.rs:12:5 | -LL | s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied +LL | s.as_bytes()[3u8]; //~ERROR : the type `[u8]` cannot be indexed by `u8` | ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u8` = note: required because of the requirements on the impl of `std::ops::Index` for `[u8]` -error[E0277]: the trait bound `i8: std::slice::SliceIndex<[u8]>` is not satisfied +error[E0277]: the type `[u8]` cannot be indexed by `i8` --> $DIR/integral-indexing.rs:13:5 | -LL | s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied +LL | s.as_bytes()[3i8]; //~ERROR : the type `[u8]` cannot be indexed by `i8` | ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i8` = note: required because of the requirements on the impl of `std::ops::Index` for `[u8]` -error[E0277]: the trait bound `u32: std::slice::SliceIndex<[u8]>` is not satisfied +error[E0277]: the type `[u8]` cannot be indexed by `u32` --> $DIR/integral-indexing.rs:14:5 | -LL | s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied +LL | s.as_bytes()[3u32]; //~ERROR : the type `[u8]` cannot be indexed by `u32` | ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u32` = note: required because of the requirements on the impl of `std::ops::Index` for `[u8]` -error[E0277]: the trait bound `i32: std::slice::SliceIndex<[u8]>` is not satisfied +error[E0277]: the type `[u8]` cannot be indexed by `i32` --> $DIR/integral-indexing.rs:15:5 | -LL | s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied +LL | s.as_bytes()[3i32]; //~ERROR : the type `[u8]` cannot be indexed by `i32` | ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i32` diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr index 3a32e13e0aa6c..7b45d848c97b7 100644 --- a/src/test/ui/on-unimplemented/slice-index.stderr +++ b/src/test/ui/on-unimplemented/slice-index.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied +error[E0277]: the type `[i32]` cannot be indexed by `i32` --> $DIR/slice-index.rs:11:5 | LL | x[1i32]; //~ ERROR E0277 @@ -7,7 +7,7 @@ LL | x[1i32]; //~ ERROR E0277 = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32` = note: required because of the requirements on the impl of `std::ops::Index` for `[i32]` -error[E0277]: the trait bound `std::ops::RangeTo: std::slice::SliceIndex<[i32]>` is not satisfied +error[E0277]: the type `[i32]` cannot be indexed by `std::ops::RangeTo` --> $DIR/slice-index.rs:12:5 | LL | x[..1i32]; //~ ERROR E0277 diff --git a/src/test/ui/str/str-idx.rs b/src/test/ui/str/str-idx.rs index 2ea80494e03cb..1b32ed5533d35 100644 --- a/src/test/ui/str/str-idx.rs +++ b/src/test/ui/str/str-idx.rs @@ -1,4 +1,7 @@ pub fn main() { let s: &str = "hello"; - let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}` + let _: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}` + let _ = s.get(4); //~ ERROR the type `str` cannot be indexed by `{integer}` + let _ = s.get_unchecked(4); //~ ERROR the type `str` cannot be indexed by `{integer}` + let _: u8 = s['c']; //~ ERROR the type `str` cannot be indexed by `char` } diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 71b1747492329..99df85d92fd96 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -1,13 +1,43 @@ error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-idx.rs:3:17 | -LL | let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}` - | ^^^^ `str` cannot be indexed by `{integer}` +LL | let _: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}` + | ^^^^ string indices are ranges of `usize` | - = help: the trait `std::ops::Index<{integer}>` is not implemented for `str` + = help: the trait `std::slice::SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book + = note: required because of the requirements on the impl of `std::ops::Index<{integer}>` for `str` -error: aborting due to previous error +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-idx.rs:4:15 + | +LL | let _ = s.get(4); //~ ERROR the type `str` cannot be indexed by `{integer}` + | ^^^ string indices are ranges of `usize` + | + = help: the trait `std::slice::SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + see chapter in The Book + +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-idx.rs:5:15 + | +LL | let _ = s.get_unchecked(4); //~ ERROR the type `str` cannot be indexed by `{integer}` + | ^^^^^^^^^^^^^ string indices are ranges of `usize` + | + = help: the trait `std::slice::SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + see chapter in The Book + +error[E0277]: the type `str` cannot be indexed by `char` + --> $DIR/str-idx.rs:6:17 + | +LL | let _: u8 = s['c']; //~ ERROR the type `str` cannot be indexed by `char` + | ^^^^^^ string indices are ranges of `usize` + | + = help: the trait `std::slice::SliceIndex` is not implemented for `char` + = note: required because of the requirements on the impl of `std::ops::Index` for `str` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/str/str-mut-idx.rs b/src/test/ui/str/str-mut-idx.rs index cebbbc3ccbf7d..575a9eae85946 100644 --- a/src/test/ui/str/str-mut-idx.rs +++ b/src/test/ui/str/str-mut-idx.rs @@ -5,7 +5,13 @@ fn mutate(s: &mut str) { //~^ ERROR the size for values of type //~| ERROR the size for values of type s[1usize] = bot(); - //~^ ERROR the type `str` cannot be mutably indexed by `usize` + //~^ ERROR the type `str` cannot be indexed by `usize` + s.get_mut(1); + //~^ ERROR the type `str` cannot be indexed by `{integer}` + s.get_unchecked_mut(1); + //~^ ERROR the type `str` cannot be indexed by `{integer}` + s['c']; + //~^ ERROR the type `str` cannot be indexed by `char` } pub fn main() {} diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index a1212c5a4fe10..beb2272452363 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -22,16 +22,44 @@ LL | s[1..2] = bot(); = note: to learn more, visit = note: the left-hand-side of an assignment must have a statically known size -error[E0277]: the type `str` cannot be mutably indexed by `usize` +error[E0277]: the type `str` cannot be indexed by `usize` --> $DIR/str-mut-idx.rs:7:5 | LL | s[1usize] = bot(); - | ^^^^^^^^^ `str` cannot be mutably indexed by `usize` + | ^^^^^^^^^ string indices are ranges of `usize` | - = help: the trait `std::ops::IndexMut` is not implemented for `str` + = help: the trait `std::slice::SliceIndex` is not implemented for `usize` + = note: required because of the requirements on the impl of `std::ops::Index` for `str` + +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-mut-idx.rs:9:7 + | +LL | s.get_mut(1); + | ^^^^^^^ string indices are ranges of `usize` + | + = help: the trait `std::slice::SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book -error: aborting due to 3 previous errors +error[E0277]: the type `str` cannot be indexed by `{integer}` + --> $DIR/str-mut-idx.rs:11:7 + | +LL | s.get_unchecked_mut(1); + | ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize` + | + = help: the trait `std::slice::SliceIndex` is not implemented for `{integer}` + = note: you can use `.chars().nth()` or `.bytes().nth()` + see chapter in The Book + +error[E0277]: the type `str` cannot be indexed by `char` + --> $DIR/str-mut-idx.rs:13:5 + | +LL | s['c']; + | ^^^^^^ string indices are ranges of `usize` + | + = help: the trait `std::slice::SliceIndex` is not implemented for `char` + = note: required because of the requirements on the impl of `std::ops::Index` for `str` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. From ab7bc3a23dfe0d40ea86e828dcd8ad105fcf5a3b Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 6 Jan 2019 16:01:45 +0000 Subject: [PATCH 0177/1064] Rename UserTypeAnnotation -> UserType --- src/librustc/ich/impls_ty.rs | 6 ++--- src/librustc/mir/mod.rs | 2 +- src/librustc/mir/visit.rs | 4 ++-- src/librustc/ty/context.rs | 24 +++++++++---------- src/librustc/ty/mod.rs | 2 +- src/librustc_mir/borrow_check/nll/renumber.rs | 4 ++-- .../borrow_check/nll/type_check/mod.rs | 10 ++++---- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/mod.rs | 10 ++++---- src/librustc_mir/hair/pattern/mod.rs | 4 ++-- src/librustc_mir/hair/util.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 10 ++++---- src/librustc_typeck/check/writeback.rs | 2 +- src/test/mir-opt/basic_assignment.rs | 2 +- 14 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index ef7fb0128ef4b..7a6852ddc55ed 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1240,16 +1240,16 @@ impl_stable_hash_for!( } ); -impl<'a, 'gcx> HashStable> for ty::UserTypeAnnotation<'gcx> { +impl<'a, 'gcx> HashStable> for ty::UserType<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - ty::UserTypeAnnotation::Ty(ref ty) => { + ty::UserType::Ty(ref ty) => { ty.hash_stable(hcx, hasher); } - ty::UserTypeAnnotation::TypeOf(ref def_id, ref substs) => { + ty::UserType::TypeOf(ref def_id, ref substs) => { def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a1a6e890b1292..9bd0efcbbb4b1 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -31,7 +31,7 @@ use ty::subst::{Subst, Substs}; use ty::layout::VariantIdx; use ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, - UserTypeAnnotationIndex, UserTypeAnnotation, + UserTypeAnnotationIndex, UserType, }; use util::ppaux; diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index a0fae3aa927ce..7ae77b221da75 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -221,7 +221,7 @@ macro_rules! make_mir_visitor { fn visit_user_type_annotation( &mut self, index: UserTypeAnnotationIndex, - ty: & $($mutability)* Canonical<'tcx, UserTypeAnnotation<'tcx>>, + ty: & $($mutability)* Canonical<'tcx, UserType<'tcx>>, ) { self.super_user_type_annotation(index, ty); } @@ -882,7 +882,7 @@ macro_rules! make_mir_visitor { fn super_user_type_annotation( &mut self, _index: UserTypeAnnotationIndex, - _ty: & $($mutability)* Canonical<'tcx, UserTypeAnnotation<'tcx>>, + _ty: & $($mutability)* Canonical<'tcx, UserType<'tcx>>, ) { } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index e37eab622df3f..32d2314bef190 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -800,7 +800,7 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { newtype_index! { pub struct UserTypeAnnotationIndex { - DEBUG_FORMAT = "UserTypeAnnotation({})", + DEBUG_FORMAT = "UserType({})", const START_INDEX = 0, } } @@ -810,15 +810,15 @@ pub type CanonicalUserTypeAnnotations<'tcx> = IndexVec)>; /// Canonicalized user type annotation. -pub type CanonicalUserTypeAnnotation<'gcx> = Canonical<'gcx, UserTypeAnnotation<'gcx>>; +pub type CanonicalUserTypeAnnotation<'gcx> = Canonical<'gcx, UserType<'gcx>>; impl CanonicalUserTypeAnnotation<'gcx> { /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`, /// i.e. each thing is mapped to a canonical variable with the same index. pub fn is_identity(&self) -> bool { match self.value { - UserTypeAnnotation::Ty(_) => false, - UserTypeAnnotation::TypeOf(_, user_substs) => { + UserType::Ty(_) => false, + UserType::TypeOf(_, user_substs) => { if user_substs.user_self_ty.is_some() { return false; } @@ -853,7 +853,7 @@ impl CanonicalUserTypeAnnotation<'gcx> { /// from constants that are named via paths, like `Foo::::new` and /// so forth. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub enum UserTypeAnnotation<'tcx> { +pub enum UserType<'tcx> { Ty(Ty<'tcx>), /// The canonical type is the result of `type_of(def_id)` with the @@ -862,17 +862,17 @@ pub enum UserTypeAnnotation<'tcx> { } EnumTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> { - (UserTypeAnnotation::Ty)(ty), - (UserTypeAnnotation::TypeOf)(def, substs), + impl<'tcx> TypeFoldable<'tcx> for UserType<'tcx> { + (UserType::Ty)(ty), + (UserType::TypeOf)(def, substs), } } EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for UserTypeAnnotation<'a> { - type Lifted = UserTypeAnnotation<'tcx>; - (UserTypeAnnotation::Ty)(ty), - (UserTypeAnnotation::TypeOf)(def, substs), + impl<'a, 'tcx> Lift<'tcx> for UserType<'a> { + type Lifted = UserType<'tcx>; + (UserType::Ty)(ty), + (UserType::TypeOf)(def, substs), } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f1b36e8def88b..ff7220deb768e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -73,7 +73,7 @@ pub use self::binding::BindingMode::*; pub use self::context::{TyCtxt, FreeRegionInfo, GlobalArenas, AllArenas, tls, keep_local}; pub use self::context::{Lift, TypeckTables, CtxtInterners}; pub use self::context::{ - UserTypeAnnotationIndex, UserTypeAnnotation, CanonicalUserTypeAnnotation, + UserTypeAnnotationIndex, UserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, }; diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 5c24da7621b2d..f6275230eebfb 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -1,7 +1,7 @@ use rustc::infer::canonical::Canonical; use rustc::ty::subst::Substs; use rustc::ty::{ - self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable, UserTypeAnnotation, + self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable, UserType, UserTypeAnnotationIndex, }; use rustc::mir::{Location, Mir}; @@ -62,7 +62,7 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { fn visit_user_type_annotation( &mut self, _index: UserTypeAnnotationIndex, - _ty: &mut Canonical<'tcx, UserTypeAnnotation<'tcx>>, + _ty: &mut Canonical<'tcx, UserType<'tcx>>, ) { // User type annotations represent the types that the user // wrote in the progarm. We don't want to erase the regions diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 180aa1907e8d1..7c3507e06cb1c 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -37,7 +37,7 @@ use rustc::traits::{ObligationCause, PredicateObligations}; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{ - self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind, UserTypeAnnotation, + self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind, UserType, UserTypeAnnotationIndex, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -748,7 +748,7 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> { /// annotations. Part of the reason for this setup is that it allows us to enforce basic /// WF criteria on the types even if the code that referenced them is dead /// code (see #54943). - instantiated_type_annotations: FxHashMap>, + instantiated_type_annotations: FxHashMap>, } struct BorrowCheckContext<'a, 'tcx: 'a> { @@ -925,7 +925,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { *span, &canonical_annotation ); match annotation { - UserTypeAnnotation::Ty(ref mut ty) => + UserType::Ty(ref mut ty) => *ty = self.normalize(ty, Locations::All(*span)), _ => {}, } @@ -1068,7 +1068,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { let type_annotation = self.instantiated_type_annotations[&user_ty.base]; match type_annotation { - UserTypeAnnotation::Ty(ty) => { + UserType::Ty(ty) => { // The `TypeRelating` code assumes that "unresolved inference // variables" appear in the "a" side, so flip `Contravariant` // ambient variance to get the right relationship. @@ -1107,7 +1107,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { self.relate_types(ty, v1, a, locations, category)?; } } - UserTypeAnnotation::TypeOf(def_id, user_substs) => { + UserType::TypeOf(def_id, user_substs) => { let projs = self.infcx.tcx.intern_projs(&user_ty.projs); self.fully_perform_op( locations, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index eb536fbcf69bb..e86e5f342597b 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -278,7 +278,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_ty = user_provided_types.get(fun.hir_id) .map(|u_ty| *u_ty) .map(|mut u_ty| { - if let UserTypeAnnotation::TypeOf(ref mut did, _) = &mut u_ty.value { + if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value { *did = adt_def.did; } u_ty diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index e902423cd30fc..f0f8acb31df42 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -9,7 +9,7 @@ use rustc::hir::def_id::DefId; use rustc::infer::canonical::Canonical; use rustc::middle::region; use rustc::ty::subst::Substs; -use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, LazyConst, UserTypeAnnotation}; +use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, LazyConst, UserType}; use rustc::ty::layout::VariantIdx; use rustc::hir; use syntax::ast; @@ -265,7 +265,7 @@ pub enum ExprKind<'tcx> { /// Optional user-given substs: for something like `let x = /// Bar:: { ... }`. - user_ty: Option>>, + user_ty: Option>>, fields: Vec>, base: Option> @@ -273,12 +273,12 @@ pub enum ExprKind<'tcx> { PlaceTypeAscription { source: ExprRef<'tcx>, /// Type that the user gave to this expression - user_ty: Option>>, + user_ty: Option>>, }, ValueTypeAscription { source: ExprRef<'tcx>, /// Type that the user gave to this expression - user_ty: Option>>, + user_ty: Option>>, }, Closure { closure_id: DefId, @@ -288,7 +288,7 @@ pub enum ExprKind<'tcx> { }, Literal { literal: &'tcx LazyConst<'tcx>, - user_ty: Option>>, + user_ty: Option>>, }, InlineAsm { asm: &'tcx hir::InlineAsm, diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 8991a90737c7e..cabc854510fa9 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -15,7 +15,7 @@ use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{ProjectionElem, UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift}; -use rustc::ty::{CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, UserTypeAnnotation}; +use rustc::ty::{CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, UserType}; use rustc::ty::subst::{Substs, Kind}; use rustc::ty::layout::VariantIdx; use rustc::hir::{self, PatKind, RangeEnd}; @@ -1040,7 +1040,7 @@ macro_rules! CloneImpls { CloneImpls!{ <'tcx> Span, Field, Mutability, ast::Name, ast::NodeId, usize, ty::Const<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode, &'tcx AdtDef, - &'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>, + &'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserType<'tcx>, UserTypeProjection<'tcx>, PatternTypeProjection<'tcx> } diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index f0f8263b64de5..2fd3a089a998f 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -1,5 +1,5 @@ use rustc::hir; -use rustc::ty::{self, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotation}; +use rustc::ty::{self, CanonicalUserTypeAnnotation, TyCtxt, UserType}; crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx>; @@ -18,7 +18,7 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty); match &self.tables().node_id_to_type(hir_id).sty { ty::Adt(adt_def, ..) => { - if let UserTypeAnnotation::TypeOf(ref mut did, _) = &mut user_ty.value { + if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value { *did = adt_def.did; } Some(user_ty) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 452fd248f5121..e4e4f1bc4d4d1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -104,7 +104,7 @@ use rustc::mir::interpret::{ConstValue, GlobalId}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::{ self, AdtKind, CanonicalUserTypeAnnotation, Ty, TyCtxt, GenericParamDefKind, Visibility, - ToPolyTraitRef, ToPredicate, RegionKind, UserTypeAnnotation + ToPolyTraitRef, ToPredicate, RegionKind, UserType }; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::fold::TypeFoldable; @@ -985,7 +985,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { }; let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation( - &UserTypeAnnotation::Ty(revealed_ty) + &UserType::Ty(revealed_ty) ); debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}", ty.hir_id, o_ty, revealed_ty, c_ty); @@ -2194,7 +2194,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { user_self_ty: None, // not relevant here }; - self.infcx.canonicalize_user_type_annotation(&UserTypeAnnotation::TypeOf( + self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf( method.def_id, user_substs, )) @@ -2239,7 +2239,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if !substs.is_noop() { let canonicalized = self.infcx.canonicalize_user_type_annotation( - &UserTypeAnnotation::TypeOf(def_id, UserSubsts { + &UserType::TypeOf(def_id, UserSubsts { substs, user_self_ty, }) @@ -2440,7 +2440,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // although I have my doubts). Other sorts of things are // already sufficiently enforced with erased regions. =) if ty.has_free_regions() || ty.has_projections() { - let c_ty = self.infcx.canonicalize_response(&UserTypeAnnotation::Ty(ty)); + let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty)); debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty); self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty); } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index c61159eb49481..238b087fe32f8 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -404,7 +404,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { .user_provided_types_mut() .insert(hir_id, c_ty.clone()); - if let ty::UserTypeAnnotation::TypeOf(_, user_substs) = c_ty.value { + if let ty::UserType::TypeOf(_, user_substs) = c_ty.value { if self.rustc_dump_user_substs { // This is a unit-testing mechanism. let node_id = self.tcx().hir().hir_to_node_id(hir_id); diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index 88fd53d4ba59d..1bbbe67a12cb8 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -37,7 +37,7 @@ fn main() { // StorageLive(_4); // _4 = std::option::Option>::None; // FakeRead(ForLet, _4); -// AscribeUserType(_4, o, UserTypeProjection { base: UserTypeAnnotation(1), projs: [] }); +// AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // StorageLive(_5); // StorageLive(_6); // _6 = move _4; From 5ca6bd50b584bc157eac783f2a2251424382351f Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 6 Jan 2019 16:04:00 +0000 Subject: [PATCH 0178/1064] Rename CanonicalUserTypeAnnotation -> CanonicalUserType We want the name `CanonicalUserTypeAnnotation` for our own use. --- src/librustc/ty/context.rs | 12 ++++++------ src/librustc/ty/mod.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/pattern/mod.rs | 6 +++--- src/librustc_mir/hair/util.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 32d2314bef190..ef8f7bd9a7561 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -350,7 +350,7 @@ pub struct TypeckTables<'tcx> { /// canonical substitutions would include only `for { Vec }`. /// /// See also `AscribeUserType` statement in MIR. - user_provided_types: ItemLocalMap>, + user_provided_types: ItemLocalMap>, /// Stores the canonicalized types provided by the user. See also /// `AscribeUserType` statement in MIR. @@ -493,7 +493,7 @@ impl<'tcx> TypeckTables<'tcx> { pub fn user_provided_types( &self - ) -> LocalTableInContext<'_, CanonicalUserTypeAnnotation<'tcx>> { + ) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> { LocalTableInContext { local_id_root: self.local_id_root, data: &self.user_provided_types @@ -502,7 +502,7 @@ impl<'tcx> TypeckTables<'tcx> { pub fn user_provided_types_mut( &mut self - ) -> LocalTableInContextMut<'_, CanonicalUserTypeAnnotation<'tcx>> { + ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> { LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.user_provided_types @@ -807,12 +807,12 @@ newtype_index! { /// Mapping of type annotation indices to canonical user type annotations. pub type CanonicalUserTypeAnnotations<'tcx> = - IndexVec)>; + IndexVec)>; /// Canonicalized user type annotation. -pub type CanonicalUserTypeAnnotation<'gcx> = Canonical<'gcx, UserType<'gcx>>; +pub type CanonicalUserType<'gcx> = Canonical<'gcx, UserType<'gcx>>; -impl CanonicalUserTypeAnnotation<'gcx> { +impl CanonicalUserType<'gcx> { /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`, /// i.e. each thing is mapped to a canonical variable with the same index. pub fn is_identity(&self) -> bool { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ff7220deb768e..a6e226302e51b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -73,7 +73,7 @@ pub use self::binding::BindingMode::*; pub use self::context::{TyCtxt, FreeRegionInfo, GlobalArenas, AllArenas, tls, keep_local}; pub use self::context::{Lift, TypeckTables, CtxtInterners}; pub use self::context::{ - UserTypeAnnotationIndex, UserType, CanonicalUserTypeAnnotation, + UserTypeAnnotationIndex, UserType, CanonicalUserType, CanonicalUserTypeAnnotations, }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index e86e5f342597b..8d64c9e9ada89 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -797,7 +797,7 @@ fn user_substs_applied_to_def( cx: &mut Cx<'a, 'gcx, 'tcx>, hir_id: hir::HirId, def: &Def, -) -> Option> { +) -> Option> { debug!("user_substs_applied_to_def: def={:?}", def); let user_provided_type = match def { // A reference to something callable -- e.g., a fn, method, or diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index cabc854510fa9..7aaf74ae18fb3 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -15,7 +15,7 @@ use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{ProjectionElem, UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift}; -use rustc::ty::{CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, UserType}; +use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotations, UserType}; use rustc::ty::subst::{Substs, Kind}; use rustc::ty::layout::VariantIdx; use rustc::hir::{self, PatKind, RangeEnd}; @@ -60,12 +60,12 @@ pub struct Pattern<'tcx> { #[derive(Clone, Debug)] pub struct PatternTypeProjection<'tcx> { - pub base: CanonicalUserTypeAnnotation<'tcx>, + pub base: CanonicalUserType<'tcx>, pub projs: Vec>, } impl<'tcx> PatternTypeProjection<'tcx> { - pub(crate) fn from_user_type(user_annotation: CanonicalUserTypeAnnotation<'tcx>) -> Self { + pub(crate) fn from_user_type(user_annotation: CanonicalUserType<'tcx>) -> Self { Self { base: user_annotation, projs: Vec::new(), diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index 2fd3a089a998f..cb4a72387fa16 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -1,5 +1,5 @@ use rustc::hir; -use rustc::ty::{self, CanonicalUserTypeAnnotation, TyCtxt, UserType}; +use rustc::ty::{self, CanonicalUserType, TyCtxt, UserType}; crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx>; @@ -12,7 +12,7 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { fn user_substs_applied_to_ty_of_hir_id( &self, hir_id: hir::HirId, - ) -> Option> { + ) -> Option> { let user_provided_types = self.tables().user_provided_types(); let mut user_ty = *user_provided_types.get(hir_id)?; debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e4e4f1bc4d4d1..54fd7de381f2a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -103,7 +103,7 @@ use rustc::middle::region; use rustc::mir::interpret::{ConstValue, GlobalId}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::{ - self, AdtKind, CanonicalUserTypeAnnotation, Ty, TyCtxt, GenericParamDefKind, Visibility, + self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPolyTraitRef, ToPredicate, RegionKind, UserType }; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; @@ -2252,7 +2252,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn write_user_type_annotation( &self, hir_id: hir::HirId, - canonical_user_type_annotation: CanonicalUserTypeAnnotation<'tcx>, + canonical_user_type_annotation: CanonicalUserType<'tcx>, ) { debug!( "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}", From ed871cb368f6b72dde644b0c21e0f9e62dba1810 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 6 Jan 2019 17:10:53 +0000 Subject: [PATCH 0179/1064] Use a struct for user type annotations --- src/librustc/ich/impls_ty.rs | 6 +++++ src/librustc/mir/mod.rs | 2 +- src/librustc/mir/visit.rs | 17 ++++++++------ src/librustc/ty/context.rs | 22 ++++++++++++++++++- src/librustc/ty/mod.rs | 2 +- src/librustc_mir/borrow_check/nll/renumber.rs | 7 +++--- .../borrow_check/nll/type_check/mod.rs | 9 ++++---- src/librustc_mir/build/expr/as_constant.rs | 6 ++++- src/librustc_mir/build/expr/as_place.rs | 6 ++--- src/librustc_mir/build/expr/as_rvalue.rs | 7 ++++-- src/librustc_mir/build/matches/mod.rs | 7 ++++-- src/librustc_mir/hair/pattern/mod.rs | 6 ++--- src/librustc_mir/util/pretty.rs | 4 ++-- 13 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 7a6852ddc55ed..9b613e3e1abad 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1240,6 +1240,12 @@ impl_stable_hash_for!( } ); +impl_stable_hash_for!( + struct ty::CanonicalUserTypeAnnotation<'tcx> { + user_ty, span + } +); + impl<'a, 'gcx> HashStable> for ty::UserType<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9bd0efcbbb4b1..f824ab7e5b395 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -31,7 +31,7 @@ use ty::subst::{Subst, Substs}; use ty::layout::VariantIdx; use ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, - UserTypeAnnotationIndex, UserType, + UserTypeAnnotationIndex, }; use util::ppaux; diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 7ae77b221da75..49a1e5046aa0e 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -1,7 +1,6 @@ use hir::def_id::DefId; -use infer::canonical::Canonical; use ty::subst::Substs; -use ty::{ClosureSubsts, GeneratorSubsts, Region, Ty}; +use ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, Region, Ty}; use mir::*; use syntax_pos::Span; @@ -221,7 +220,7 @@ macro_rules! make_mir_visitor { fn visit_user_type_annotation( &mut self, index: UserTypeAnnotationIndex, - ty: & $($mutability)* Canonical<'tcx, UserType<'tcx>>, + ty: & $($mutability)* CanonicalUserTypeAnnotation<'tcx>, ) { self.super_user_type_annotation(index, ty); } @@ -309,12 +308,15 @@ macro_rules! make_mir_visitor { self.visit_local_decl(local, & $($mutability)* mir.local_decls[local]); } - for index in mir.user_type_annotations.indices() { - let (span, annotation) = & $($mutability)* mir.user_type_annotations[index]; + macro_rules! type_annotations { + (mut) => (mir.user_type_annotations.iter_enumerated_mut()); + () => (mir.user_type_annotations.iter_enumerated()); + }; + + for (index, annotation) in type_annotations!($($mutability)*) { self.visit_user_type_annotation( index, annotation ); - self.visit_span(span); } self.visit_span(&$($mutability)* mir.span); @@ -882,8 +884,9 @@ macro_rules! make_mir_visitor { fn super_user_type_annotation( &mut self, _index: UserTypeAnnotationIndex, - _ty: & $($mutability)* Canonical<'tcx, UserType<'tcx>>, + ty: & $($mutability)* CanonicalUserTypeAnnotation<'tcx>, ) { + self.visit_span(& $($mutability)* ty.span); } fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ef8f7bd9a7561..59835afc84103 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -807,7 +807,27 @@ newtype_index! { /// Mapping of type annotation indices to canonical user type annotations. pub type CanonicalUserTypeAnnotations<'tcx> = - IndexVec)>; + IndexVec>; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct CanonicalUserTypeAnnotation<'tcx> { + pub user_ty: CanonicalUserType<'tcx>, + pub span: Span, +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for CanonicalUserTypeAnnotation<'tcx> { + user_ty, span + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for CanonicalUserTypeAnnotation<'a> { + type Lifted = CanonicalUserTypeAnnotation<'tcx>; + user_ty, span + } +} + /// Canonicalized user type annotation. pub type CanonicalUserType<'gcx> = Canonical<'gcx, UserType<'gcx>>; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a6e226302e51b..dc91a30ef9273 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -74,7 +74,7 @@ pub use self::context::{TyCtxt, FreeRegionInfo, GlobalArenas, AllArenas, tls, ke pub use self::context::{Lift, TypeckTables, CtxtInterners}; pub use self::context::{ UserTypeAnnotationIndex, UserType, CanonicalUserType, - CanonicalUserTypeAnnotations, + CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, }; pub use self::instance::{Instance, InstanceDef}; diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index f6275230eebfb..ade06bce4690b 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -1,8 +1,7 @@ -use rustc::infer::canonical::Canonical; use rustc::ty::subst::Substs; use rustc::ty::{ - self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable, UserType, - UserTypeAnnotationIndex, + self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable, + UserTypeAnnotationIndex, CanonicalUserTypeAnnotation }; use rustc::mir::{Location, Mir}; use rustc::mir::visit::{MutVisitor, TyContext}; @@ -62,7 +61,7 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { fn visit_user_type_annotation( &mut self, _index: UserTypeAnnotationIndex, - _ty: &mut Canonical<'tcx, UserType<'tcx>>, + _ty: &mut CanonicalUserTypeAnnotation, ) { // User type annotations represent the types that the user // wrote in the progarm. We don't want to erase the regions diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 7c3507e06cb1c..82ffafa4ce975 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -38,7 +38,7 @@ use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{ self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind, UserType, - UserTypeAnnotationIndex, + CanonicalUserTypeAnnotation, UserTypeAnnotationIndex, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -920,13 +920,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { self.mir.user_type_annotations ); for annotation_index in self.mir.user_type_annotations.indices() { - let (span, canonical_annotation) = &self.mir.user_type_annotations[annotation_index]; + let CanonicalUserTypeAnnotation { span, ref user_ty } = + self.mir.user_type_annotations[annotation_index]; let (mut annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars( - *span, &canonical_annotation + span, user_ty ); match annotation { UserType::Ty(ref mut ty) => - *ty = self.normalize(ty, Locations::All(*span)), + *ty = self.normalize(ty, Locations::All(span)), _ => {}, } self.instantiated_type_annotations.insert(annotation_index, annotation); diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index a431bfc61b37a..4f812f53745d7 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -3,6 +3,7 @@ use build::Builder; use hair::*; use rustc::mir::*; +use rustc::ty::CanonicalUserTypeAnnotation; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that @@ -31,7 +32,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } => this.as_constant(value), ExprKind::Literal { literal, user_ty } => { let user_ty = user_ty.map(|ty| { - this.canonical_user_type_annotations.push((span, ty)) + this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { + span, + user_ty: ty, + }) }); Constant { span, diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 3ed00d5797907..5429ce2a2e3df 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -6,7 +6,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use hair::*; use rustc::mir::interpret::EvalErrorKind::BoundsCheck; use rustc::mir::*; -use rustc::ty::Variance; +use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; use rustc_data_structures::indexed_vec::Idx; @@ -134,7 +134,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let place = unpack!(block = this.as_place(block, source)); if let Some(user_ty) = user_ty { let annotation_index = this.canonical_user_type_annotations.push( - (source_info.span, user_ty) + CanonicalUserTypeAnnotation { span: source_info.span, user_ty } ); this.cfg.push( block, @@ -157,7 +157,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ); if let Some(user_ty) = user_ty { let annotation_index = this.canonical_user_type_annotations.push( - (source_info.span, user_ty) + CanonicalUserTypeAnnotation { span: source_info.span, user_ty } ); this.cfg.push( block, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index e0fc90931696e..501a10cfbb900 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -9,7 +9,7 @@ use hair::*; use rustc::middle::region; use rustc::mir::interpret::EvalErrorKind; use rustc::mir::*; -use rustc::ty::{self, Ty, UpvarSubsts}; +use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts}; use syntax_pos::Span; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { @@ -332,7 +332,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; let user_ty = user_ty.map(|ty| { - this.canonical_user_type_annotations.push((expr_span, ty)) + this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { + span: source_info.span, + user_ty: ty, + }) }); let adt = box AggregateKind::Adt( adt_def, diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index d52ce9a67d29a..61d1216fd3ea8 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -9,7 +9,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use build::{GuardFrame, GuardFrameLocal, LocalsForNode}; use hair::*; use rustc::mir::*; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty}; use rustc::ty::layout::VariantIdx; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::fx::FxHashMap; @@ -570,7 +570,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // // Note that the variance doesn't apply here, as we are tracking the effect // of `user_ty` on any bindings contained with subpattern. - let annotation = (user_ty_span, user_ty.base); + let annotation = CanonicalUserTypeAnnotation { + span: user_ty_span, + user_ty: user_ty.base, + }; let projection = UserTypeProjection { base: self.canonical_user_type_annotations.push(annotation), projs: user_ty.projs.clone(), diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 7aaf74ae18fb3..8a5e6a581b332 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -14,8 +14,8 @@ use hair::constant::*; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{ProjectionElem, UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; -use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift}; -use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotations, UserType}; +use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; +use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc::ty::subst::{Substs, Kind}; use rustc::ty::layout::VariantIdx; use rustc::hir::{self, PatKind, RangeEnd}; @@ -78,7 +78,7 @@ impl<'tcx> PatternTypeProjection<'tcx> { span: Span, ) -> UserTypeProjection<'tcx> { UserTypeProjection { - base: annotations.push((span, self.base)), + base: annotations.push(CanonicalUserTypeAnnotation{ span, user_ty: self.base }), projs: self.projs } } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index fca208b340d2a..e99f2da73385d 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -632,8 +632,8 @@ fn write_user_type_annotations(mir: &Mir, w: &mut dyn Write) -> io::Result<()> { if !mir.user_type_annotations.is_empty() { writeln!(w, "| User Type Annotations")?; } - for (index, (span, annotation)) in mir.user_type_annotations.iter_enumerated() { - writeln!(w, "| {:?}: {:?} at {:?}", index.index(), annotation, span)?; + for (index, annotation) in mir.user_type_annotations.iter_enumerated() { + writeln!(w, "| {:?}: {:?} at {:?}", index.index(), annotation.user_ty, annotation.span)?; } if !mir.user_type_annotations.is_empty() { writeln!(w, "|")?; From 65fe2516346f10dc8d670e9fdfbd4e4f99a5b34b Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 12 Jan 2019 14:55:23 +0000 Subject: [PATCH 0180/1064] Handle lifetime annotations in unreachable code We equate the type in the annotation with the inferred type first so that we have a fully inferred type to perform the well-formedness check on. --- src/librustc/ich/impls_ty.rs | 2 +- src/librustc/mir/tcx.rs | 13 +- src/librustc/mir/visit.rs | 4 + .../traits/query/type_op/ascribe_user_type.rs | 15 +-- src/librustc/ty/context.rs | 5 +- .../borrow_check/nll/constraint_generation.rs | 11 +- src/librustc_mir/borrow_check/nll/renumber.rs | 17 +-- .../borrow_check/nll/type_check/mod.rs | 118 +++++++++--------- src/librustc_mir/build/expr/as_constant.rs | 5 +- src/librustc_mir/build/expr/as_place.rs | 12 +- src/librustc_mir/build/expr/as_rvalue.rs | 2 + src/librustc_mir/build/matches/mod.rs | 13 +- src/librustc_mir/hair/pattern/mod.rs | 17 +-- src/librustc_traits/type_op.rs | 43 +------ src/test/ui/issue-54943.rs | 6 +- src/test/ui/issue-54943.stderr | 11 ++ ...ection-where-clause-env-wrong-bound.stderr | 2 +- .../projection-where-clause-none.stderr | 2 +- src/test/ui/nll/ty-outlives/wf-unreachable.rs | 54 ++++++++ .../ui/nll/ty-outlives/wf-unreachable.stderr | 73 +++++++++++ .../ui/nll/user-annotations/downcast-infer.rs | 11 ++ ...n-supertrait-outlives-container.ast.stderr | 20 +++ ...n-supertrait-outlives-container.mir.stderr | 13 ++ ...c-type-in-supertrait-outlives-container.rs | 6 +- ...ons-free-region-ordering-caller.ast.stderr | 32 +++++ ...ons-free-region-ordering-caller.mir.stderr | 33 +++++ .../regions-free-region-ordering-caller.rs | 12 +- ...ns-free-region-ordering-caller1.nll.stderr | 19 ++- ...lives-projection-container-hrtb.ast.stderr | 37 ++++++ ...lives-projection-container-hrtb.mir.stderr | 24 ++++ ...ions-outlives-projection-container-hrtb.rs | 9 +- ...utlives-projection-container-wc.ast.stderr | 20 +++ ...utlives-projection-container-wc.mir.stderr | 13 ++ ...egions-outlives-projection-container-wc.rs | 6 +- 34 files changed, 514 insertions(+), 166 deletions(-) create mode 100644 src/test/ui/issue-54943.stderr create mode 100644 src/test/ui/nll/ty-outlives/wf-unreachable.rs create mode 100644 src/test/ui/nll/ty-outlives/wf-unreachable.stderr create mode 100644 src/test/ui/nll/user-annotations/downcast-infer.rs create mode 100644 src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.ast.stderr create mode 100644 src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.mir.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-hrtb.ast.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-hrtb.mir.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-wc.ast.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-wc.mir.stderr diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 9b613e3e1abad..79c2b89522dbf 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1242,7 +1242,7 @@ impl_stable_hash_for!( impl_stable_hash_for!( struct ty::CanonicalUserTypeAnnotation<'tcx> { - user_ty, span + user_ty, span, inferred_ty } ); diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index c5b884525da4b..649370059f0ea 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -75,8 +75,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> { - self.projection_ty_core(tcx, elem, |_, _, ty| -> Result, ()> { Ok(ty) }) - .unwrap() + self.projection_ty_core(tcx, elem, |_, _, ty| ty) } /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` @@ -84,12 +83,12 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { /// `Ty` or downcast variant corresponding to that projection. /// The `handle_field` callback must map a `Field` to its `Ty`, /// (which should be trivial when `T` = `Ty`). - pub fn projection_ty_core( + pub fn projection_ty_core( self, tcx: TyCtxt<'a, 'gcx, 'tcx>, elem: &ProjectionElem<'tcx, V, T>, - mut handle_field: impl FnMut(&Self, &Field, &T) -> Result, E>) - -> Result, E> + mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>) + -> PlaceTy<'tcx> where V: ::std::fmt::Debug, T: ::std::fmt::Debug { @@ -140,10 +139,10 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { } }, ProjectionElem::Field(ref f, ref fty) => - PlaceTy::Ty { ty: handle_field(&self, f, fty)? }, + PlaceTy::Ty { ty: handle_field(&self, f, fty) }, }; debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); - Ok(answer) + answer } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 49a1e5046aa0e..598303f29328f 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -887,6 +887,7 @@ macro_rules! make_mir_visitor { ty: & $($mutability)* CanonicalUserTypeAnnotation<'tcx>, ) { self.visit_span(& $($mutability)* ty.span); + self.visit_ty(& $($mutability)* ty.inferred_ty, TyContext::UserTy(ty.span)); } fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) { @@ -967,6 +968,9 @@ pub enum TyContext { source_info: SourceInfo, }, + /// The inferred type of a user type annotation. + UserTy(Span), + /// The return type of the function. ReturnTy(SourceInfo), diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index b2f30564de93a..15f627b3ee8c4 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -1,28 +1,23 @@ use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; use traits::query::Fallible; use hir::def_id::DefId; -use mir::ProjectionKind; -use ty::{self, ParamEnvAnd, Ty, TyCtxt}; +use ty::{ParamEnvAnd, Ty, TyCtxt}; use ty::subst::UserSubsts; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct AscribeUserType<'tcx> { pub mir_ty: Ty<'tcx>, - pub variance: ty::Variance, pub def_id: DefId, pub user_substs: UserSubsts<'tcx>, - pub projs: &'tcx ty::List>, } impl<'tcx> AscribeUserType<'tcx> { pub fn new( mir_ty: Ty<'tcx>, - variance: ty::Variance, def_id: DefId, user_substs: UserSubsts<'tcx>, - projs: &'tcx ty::List>, ) -> Self { - Self { mir_ty, variance, def_id, user_substs, projs } + Self { mir_ty, def_id, user_substs } } } @@ -52,19 +47,19 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for AscribeUserType<'tcx> BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for AscribeUserType<'tcx> { - mir_ty, variance, def_id, user_substs, projs + mir_ty, def_id, user_substs } } BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> { type Lifted = AscribeUserType<'tcx>; - mir_ty, variance, def_id, user_substs, projs + mir_ty, def_id, user_substs } } impl_stable_hash_for! { struct AscribeUserType<'tcx> { - mir_ty, variance, def_id, user_substs, projs + mir_ty, def_id, user_substs } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 59835afc84103..4c8f81411163c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -813,18 +813,19 @@ pub type CanonicalUserTypeAnnotations<'tcx> = pub struct CanonicalUserTypeAnnotation<'tcx> { pub user_ty: CanonicalUserType<'tcx>, pub span: Span, + pub inferred_ty: Ty<'tcx>, } BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for CanonicalUserTypeAnnotation<'tcx> { - user_ty, span + user_ty, span, inferred_ty } } BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for CanonicalUserTypeAnnotation<'a> { type Lifted = CanonicalUserTypeAnnotation<'tcx>; - user_ty, span + user_ty, span, inferred_ty } } diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index e1c2b611d0117..588f46cb77fe2 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -7,7 +7,7 @@ use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue}; -use rustc::mir::{Statement, Terminator}; +use rustc::mir::{SourceInfo, Statement, Terminator}; use rustc::mir::UserTypeProjection; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::Substs; @@ -66,11 +66,12 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx /// call. Make them live at the location where they appear. fn visit_ty(&mut self, ty: &ty::Ty<'tcx>, ty_context: TyContext) { match ty_context { - TyContext::ReturnTy(source_info) - | TyContext::YieldTy(source_info) - | TyContext::LocalDecl { source_info, .. } => { + TyContext::ReturnTy(SourceInfo { span, .. }) + | TyContext::YieldTy(SourceInfo { span, .. }) + | TyContext::UserTy(span) + | TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => { span_bug!( - source_info.span, + span, "should not be visiting outside of the CFG: {:?}", ty_context ); diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index ade06bce4690b..e6a974fd8cc94 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -1,8 +1,5 @@ use rustc::ty::subst::Substs; -use rustc::ty::{ - self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable, - UserTypeAnnotationIndex, CanonicalUserTypeAnnotation -}; +use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable}; use rustc::mir::{Location, Mir}; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; @@ -58,18 +55,6 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { debug!("visit_ty: ty={:?}", ty); } - fn visit_user_type_annotation( - &mut self, - _index: UserTypeAnnotationIndex, - _ty: &mut CanonicalUserTypeAnnotation, - ) { - // User type annotations represent the types that the user - // wrote in the progarm. We don't want to erase the regions - // from these types: rather, we want to add them as - // constraints at type-check time. - debug!("visit_user_type_annotation: skipping renumber"); - } - fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) { debug!("visit_substs(substs={:?}, location={:?})", substs, location); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 82ffafa4ce975..9ed1d49d05bd1 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -748,7 +748,7 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> { /// annotations. Part of the reason for this setup is that it allows us to enforce basic /// WF criteria on the types even if the code that referenced them is dead /// code (see #54943). - instantiated_type_annotations: FxHashMap>, + instantiated_type_annotations: FxHashMap>, } struct BorrowCheckContext<'a, 'tcx: 'a> { @@ -920,17 +920,58 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { self.mir.user_type_annotations ); for annotation_index in self.mir.user_type_annotations.indices() { - let CanonicalUserTypeAnnotation { span, ref user_ty } = + let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = self.mir.user_type_annotations[annotation_index]; - let (mut annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars( + let (annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars( span, user_ty ); match annotation { - UserType::Ty(ref mut ty) => - *ty = self.normalize(ty, Locations::All(span)), - _ => {}, + UserType::Ty(mut ty) => { + ty = self.normalize(ty, Locations::All(span)); + + if let Err(terr) = self.eq_types( + ty, + inferred_ty, + Locations::All(span), + ConstraintCategory::BoringNoLocation, + ) { + span_mirbug!( + self, + self.mir.user_type_annotations[annotation_index], + "bad user type ({:?} = {:?}): {:?}", + ty, + inferred_ty, + terr + ); + } + + self.prove_predicate( + ty::Predicate::WellFormed(inferred_ty), + Locations::All(span), + ConstraintCategory::TypeAnnotation, + ); + }, + UserType::TypeOf(def_id, user_substs) => { + if let Err(terr) = self.fully_perform_op( + Locations::All(span), + ConstraintCategory::BoringNoLocation, + self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( + inferred_ty, def_id, user_substs, + )), + ) { + span_mirbug!( + self, + self.mir.user_type_annotations[annotation_index], + "bad user type AscribeUserType({:?}, {:?} {:?}): {:?}", + inferred_ty, + def_id, + user_substs, + terr + ); + } + }, } - self.instantiated_type_annotations.insert(annotation_index, annotation); + self.instantiated_type_annotations.insert(annotation_index, inferred_ty); } debug!( "instantiate_user_type_annotations: instantiated_type_annotations={:?}", @@ -1067,58 +1108,23 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { a, v, user_ty, locations, ); - let type_annotation = self.instantiated_type_annotations[&user_ty.base]; - match type_annotation { - UserType::Ty(ty) => { - // The `TypeRelating` code assumes that "unresolved inference - // variables" appear in the "a" side, so flip `Contravariant` - // ambient variance to get the right relationship. - let v1 = ty::Contravariant.xform(v); - let tcx = self.infcx.tcx; + let annotated_type = self.instantiated_type_annotations[&user_ty.base]; + let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); - // We need to follow any provided projetions into the type. - // - // if we hit a ty var as we descend, then just skip the - // attempt to relate the mir local with any type. - #[derive(Debug)] struct HitTyVar; - let mut curr_projected_ty: Result; - - curr_projected_ty = Ok(PlaceTy::from_ty(ty)); - for proj in &user_ty.projs { - let projected_ty = if let Ok(projected_ty) = curr_projected_ty { - projected_ty - } else { - break; - }; - curr_projected_ty = projected_ty.projection_ty_core( - tcx, proj, |this, field, &()| { - if this.to_ty(tcx).is_ty_var() { - Err(HitTyVar) - } else { - let ty = this.field_ty(tcx, field); - Ok(self.normalize(ty, locations)) - } - }); - } - debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}", - user_ty.base, ty, user_ty.projs, curr_projected_ty); + let tcx = self.infcx.tcx; - if let Ok(projected_ty) = curr_projected_ty { - let ty = projected_ty.to_ty(tcx); - self.relate_types(ty, v1, a, locations, category)?; - } - } - UserType::TypeOf(def_id, user_substs) => { - let projs = self.infcx.tcx.intern_projs(&user_ty.projs); - self.fully_perform_op( - locations, - category, - self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( - a, v, def_id, user_substs, projs, - )), - )?; - } + for proj in &user_ty.projs { + let projected_ty = curr_projected_ty.projection_ty_core(tcx, proj, |this, field, &()| { + let ty = this.field_ty(tcx, field); + self.normalize(ty, locations) + }); + curr_projected_ty = projected_ty; } + debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}", + user_ty.base, annotated_type, user_ty.projs, curr_projected_ty); + + let ty = curr_projected_ty.to_ty(tcx); + self.relate_types(a, v, ty, locations, category)?; Ok(()) } diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index 4f812f53745d7..31e0c0daa3fa6 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -31,10 +31,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { value, } => this.as_constant(value), ExprKind::Literal { literal, user_ty } => { - let user_ty = user_ty.map(|ty| { + let user_ty = user_ty.map(|user_ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span, - user_ty: ty, + user_ty, + inferred_ty: ty, }) }); Constant { diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 5429ce2a2e3df..6bd61ab53fd21 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -134,7 +134,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let place = unpack!(block = this.as_place(block, source)); if let Some(user_ty) = user_ty { let annotation_index = this.canonical_user_type_annotations.push( - CanonicalUserTypeAnnotation { span: source_info.span, user_ty } + CanonicalUserTypeAnnotation { + span: source_info.span, + user_ty, + inferred_ty: expr.ty, + } ); this.cfg.push( block, @@ -157,7 +161,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ); if let Some(user_ty) = user_ty { let annotation_index = this.canonical_user_type_annotations.push( - CanonicalUserTypeAnnotation { span: source_info.span, user_ty } + CanonicalUserTypeAnnotation { + span: source_info.span, + user_ty, + inferred_ty: expr.ty, + } ); this.cfg.push( block, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 501a10cfbb900..3de2f47578650 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -331,10 +331,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { .collect() }; + let inferred_ty = expr.ty; let user_ty = user_ty.map(|ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span: source_info.span, user_ty: ty, + inferred_ty, }) }); let adt = box AggregateKind::Adt( diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 61d1216fd3ea8..2f1e8c03f2f7e 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -303,7 +303,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let ty_source_info = self.source_info(user_ty_span); let user_ty = box pat_ascription_ty.user_ty( - &mut self.canonical_user_type_annotations, ty_source_info.span + &mut self.canonical_user_type_annotations, + place.ty(&self.local_decls, self.hir.tcx()).to_ty(self.hir.tcx()), + ty_source_info.span, ); self.cfg.push( block, @@ -572,11 +574,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // of `user_ty` on any bindings contained with subpattern. let annotation = CanonicalUserTypeAnnotation { span: user_ty_span, - user_ty: user_ty.base, + user_ty: user_ty.user_ty, + inferred_ty: subpattern.ty, }; let projection = UserTypeProjection { base: self.canonical_user_type_annotations.push(annotation), - projs: user_ty.projs.clone(), + projs: Vec::new(), }; let subpattern_user_ty = pattern_user_ty.push_projection(&projection, user_ty_span); self.visit_bindings(subpattern, subpattern_user_ty, f) @@ -1340,7 +1343,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ); let user_ty = box ascription.user_ty.clone().user_ty( - &mut self.canonical_user_type_annotations, source_info.span + &mut self.canonical_user_type_annotations, + ascription.source.ty(&self.local_decls, self.hir.tcx()).to_ty(self.hir.tcx()), + source_info.span ); self.cfg.push( block, diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 8a5e6a581b332..9dcccba1a06b5 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -12,7 +12,7 @@ use hair::util::UserAnnotatedTyHelpers; use hair::constant::*; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; -use rustc::mir::{ProjectionElem, UserTypeProjection}; +use rustc::mir::{UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; @@ -60,26 +60,29 @@ pub struct Pattern<'tcx> { #[derive(Clone, Debug)] pub struct PatternTypeProjection<'tcx> { - pub base: CanonicalUserType<'tcx>, - pub projs: Vec>, + pub user_ty: CanonicalUserType<'tcx>, } impl<'tcx> PatternTypeProjection<'tcx> { pub(crate) fn from_user_type(user_annotation: CanonicalUserType<'tcx>) -> Self { Self { - base: user_annotation, - projs: Vec::new(), + user_ty: user_annotation, } } pub(crate) fn user_ty( self, annotations: &mut CanonicalUserTypeAnnotations<'tcx>, + inferred_ty: Ty<'tcx>, span: Span, ) -> UserTypeProjection<'tcx> { UserTypeProjection { - base: annotations.push(CanonicalUserTypeAnnotation{ span, user_ty: self.base }), - projs: self.projs + base: annotations.push(CanonicalUserTypeAnnotation { + span, + user_ty: self.user_ty, + inferred_ty, + }), + projs: Vec::new(), } } } diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs index 52fcb5b80f4ae..526637e108d40 100644 --- a/src/librustc_traits/type_op.rs +++ b/src/librustc_traits/type_op.rs @@ -2,8 +2,6 @@ use rustc::infer::at::ToTrace; use rustc::infer::canonical::{Canonical, QueryResponse}; use rustc::infer::InferCtxt; use rustc::hir::def_id::DefId; -use rustc::mir::ProjectionKind; -use rustc::mir::tcx::PlaceTy; use rustc::traits::query::type_op::ascribe_user_type::AscribeUserType; use rustc::traits::query::type_op::eq::Eq; use rustc::traits::query::type_op::normalize::Normalize; @@ -44,17 +42,16 @@ fn type_op_ascribe_user_type<'tcx>( tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { let ( - param_env, AscribeUserType { mir_ty, variance, def_id, user_substs, projs } + param_env, AscribeUserType { mir_ty, def_id, user_substs } ) = key.into_parts(); debug!( - "type_op_ascribe_user_type: mir_ty={:?} variance={:?} def_id={:?} \ - user_substs={:?} projs={:?}", - mir_ty, variance, def_id, user_substs, projs + "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}", + mir_ty, def_id, user_substs ); let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx }; - cx.relate_mir_and_user_ty(mir_ty, variance, def_id, user_substs, projs)?; + cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?; Ok(()) }) @@ -112,10 +109,8 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> { fn relate_mir_and_user_ty( &mut self, mir_ty: Ty<'tcx>, - variance: Variance, def_id: DefId, user_substs: UserSubsts<'tcx>, - projs: &[ProjectionKind<'tcx>], ) -> Result<(), NoSolution> { let UserSubsts { user_self_ty, @@ -128,35 +123,7 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> { debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); let ty = self.normalize(ty); - // We need to follow any provided projetions into the type. - // - // if we hit a ty var as we descend, then just skip the - // attempt to relate the mir local with any type. - - struct HitTyVar; - let mut curr_projected_ty: Result; - curr_projected_ty = Ok(PlaceTy::from_ty(ty)); - for proj in projs { - let projected_ty = if let Ok(projected_ty) = curr_projected_ty { - projected_ty - } else { - break; - }; - curr_projected_ty = projected_ty.projection_ty_core( - tcx, proj, |this, field, &()| { - if this.to_ty(tcx).is_ty_var() { - Err(HitTyVar) - } else { - let ty = this.field_ty(tcx, field); - Ok(self.normalize(ty)) - } - }); - } - - if let Ok(projected_ty) = curr_projected_ty { - let ty = projected_ty.to_ty(tcx); - self.relate(mir_ty, variance, ty)?; - } + self.relate(mir_ty, Variance::Invariant, ty)?; // Prove the predicates coming along with `def_id`. // diff --git a/src/test/ui/issue-54943.rs b/src/test/ui/issue-54943.rs index c720f62797580..ce4e010674359 100644 --- a/src/test/ui/issue-54943.rs +++ b/src/test/ui/issue-54943.rs @@ -1,7 +1,3 @@ -// compile-pass -// FIXME(#54943) This test targets the scenario where proving the WF requirements of a user -// type annotation requires checking dead code. This test should actually fail to compile. - #![feature(nll)] #![allow(warnings)] @@ -11,7 +7,7 @@ fn boo<'a>() { return; let x = foo::<&'a u32>(); - //~^ ERROR the type `&'a u32` does not fulfill the required lifetime [E0477] + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/issue-54943.stderr b/src/test/ui/issue-54943.stderr new file mode 100644 index 0000000000000..aa68177bcdb58 --- /dev/null +++ b/src/test/ui/issue-54943.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-54943.rs:9:13 + | +LL | fn boo<'a>() { + | -- lifetime `'a` defined here +... +LL | let x = foo::<&'a u32>(); + | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr index acb978b5d5a2c..597b096dbe607 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr @@ -2,7 +2,7 @@ error[E0309]: the associated type `>::Output` may not live long --> $DIR/projection-where-clause-env-wrong-bound.rs:17:5 | LL | bar::() //~ ERROR may not live long enough - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `>::Output: 'a`... diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr index 2d171a98789f8..3c2ac474778f9 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr @@ -2,7 +2,7 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-where-clause-none.rs:16:5 | LL | bar::() //~ ERROR the parameter type `T` may not live long enough - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'a`... diff --git a/src/test/ui/nll/ty-outlives/wf-unreachable.rs b/src/test/ui/nll/ty-outlives/wf-unreachable.rs new file mode 100644 index 0000000000000..a2e3ab41614f6 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/wf-unreachable.rs @@ -0,0 +1,54 @@ +// Test that we check that user type annotations are well-formed, even in dead +// code. + +#![feature(nll)] + +fn uninit<'a>() { + return; + let x: &'static &'a (); //~ ERROR lifetime may not live long enough +} + +fn var_type<'a>() { + return; + let x: &'static &'a () = &&(); //~ ERROR lifetime may not live long enough +} + +fn uninit_infer<'a>() { + let x: &'static &'a _; //~ ERROR lifetime may not live long enough + x = && (); +} + +fn infer<'a>() { + return; + let x: &'static &'a _ = &&(); //~ ERROR lifetime may not live long enough +} + +fn uninit_no_var<'a>() { + return; + let _: &'static &'a (); //~ ERROR lifetime may not live long enough +} + +fn no_var<'a>() { + return; + let _: &'static &'a () = &&(); //~ ERROR lifetime may not live long enough +} + +fn infer_no_var<'a>() { + return; + let _: &'static &'a _ = &&(); //~ ERROR lifetime may not live long enough +} + +trait X<'a, 'b> {} + +struct C<'a, 'b, T: X<'a, 'b>>(T, &'a (), &'b ()); + +impl X<'_, '_> for i32 {} +impl<'a> X<'a, 'a> for () {} + +// This type annotation is not well-formed because we substitute `()` for `_`. +fn required_substs<'a>() { + return; + let _: C<'static, 'a, _> = C((), &(), &()); //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/src/test/ui/nll/ty-outlives/wf-unreachable.stderr b/src/test/ui/nll/ty-outlives/wf-unreachable.stderr new file mode 100644 index 0000000000000..14642a1e615df --- /dev/null +++ b/src/test/ui/nll/ty-outlives/wf-unreachable.stderr @@ -0,0 +1,73 @@ +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:8:12 + | +LL | fn uninit<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let x: &'static &'a (); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:13:12 + | +LL | fn var_type<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let x: &'static &'a () = &&(); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:17:12 + | +LL | fn uninit_infer<'a>() { + | -- lifetime `'a` defined here +LL | let x: &'static &'a _; //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:23:12 + | +LL | fn infer<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let x: &'static &'a _ = &&(); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:28:12 + | +LL | fn uninit_no_var<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let _: &'static &'a (); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:33:12 + | +LL | fn no_var<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let _: &'static &'a () = &&(); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:38:12 + | +LL | fn infer_no_var<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let _: &'static &'a _ = &&(); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/wf-unreachable.rs:51:12 + | +LL | fn required_substs<'a>() { + | -- lifetime `'a` defined here +LL | return; +LL | let _: C<'static, 'a, _> = C((), &(), &()); //~ ERROR lifetime may not live long enough + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/nll/user-annotations/downcast-infer.rs b/src/test/ui/nll/user-annotations/downcast-infer.rs new file mode 100644 index 0000000000000..23b76bb196470 --- /dev/null +++ b/src/test/ui/nll/user-annotations/downcast-infer.rs @@ -0,0 +1,11 @@ +// compile-pass + +// Check that we don't try to downcast `_` when type-checking the annotation. +fn main() { + let x = Some(Some(Some(1))); + + match x { + Some::>(Some(Some(v))) => (), + _ => (), + } +} diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.ast.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.ast.stderr new file mode 100644 index 0000000000000..76ead4e94ef66 --- /dev/null +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.ast.stderr @@ -0,0 +1,20 @@ +error[E0491]: in type `&'a WithAssoc>`, reference has a longer lifetime than the data it references + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:45:13 + | +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the lifetime 'a as defined on the function body at 37:15 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:37:15 + | +LL | fn with_assoc<'a,'b>() { + | ^^ +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 37:18 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:37:18 + | +LL | fn with_assoc<'a,'b>() { + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0491`. diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.mir.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.mir.stderr new file mode 100644 index 0000000000000..ad94d375b5bb7 --- /dev/null +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.mir.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:45:13 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs index df7c1e0c7c78b..1d53492199230 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs @@ -3,6 +3,9 @@ // outlive the location in which the type appears, even when the // associted type is in a supertype. Issue #22246. +// revisions: ast mir +//[mir]compile-flags: -Z borrowck=mir + #![allow(dead_code)] /////////////////////////////////////////////////////////////////////////// @@ -40,7 +43,8 @@ fn with_assoc<'a,'b>() { // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if // `_x` is changed to `_` let _x: &'a WithAssoc> = loop { }; - //~^ ERROR reference has a longer lifetime + //[ast]~^ ERROR reference has a longer lifetime + //[mir]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr new file mode 100644 index 0000000000000..73266ab50fad0 --- /dev/null +++ b/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr @@ -0,0 +1,32 @@ +error[E0623]: lifetime mismatch + --> $DIR/regions-free-region-ordering-caller.rs:11:12 + | +LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { + | --------- --------- + | | + | these two types are declared with different lifetimes... +LL | let z: Option<&'b &'a usize> = None;//[ast]~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here + +error[E0623]: lifetime mismatch + --> $DIR/regions-free-region-ordering-caller.rs:17:12 + | +LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { + | --------- --------- + | | + | these two types are declared with different lifetimes... +LL | let y: Paramd<'a> = Paramd { x: a }; +LL | let z: Option<&'b Paramd<'a>> = None;//[ast]~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here + +error[E0623]: lifetime mismatch + --> $DIR/regions-free-region-ordering-caller.rs:22:12 + | +LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { + | --------- --------- these two types are declared with different lifetimes... +LL | let z: Option<&'a &'b usize> = None;//[ast]~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^ ...but data from `b` flows into `a` here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr new file mode 100644 index 0000000000000..abec468c9ea3e --- /dev/null +++ b/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr @@ -0,0 +1,33 @@ +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-caller.rs:11:12 + | +LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let z: Option<&'b &'a usize> = None;//[ast]~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-caller.rs:17:12 + | +LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let y: Paramd<'a> = Paramd { x: a }; +LL | let z: Option<&'b Paramd<'a>> = None;//[ast]~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-caller.rs:22:12 + | +LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let z: Option<&'a &'b usize> = None;//[ast]~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.rs b/src/test/ui/regions/regions-free-region-ordering-caller.rs index e26799fcc4711..621e6e78b4650 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller.rs +++ b/src/test/ui/regions/regions-free-region-ordering-caller.rs @@ -2,19 +2,25 @@ // than the thing it points at and ensure that they result in // errors. See also regions-free-region-ordering-callee.rs +// revisions: ast mir +//[mir]compile-flags: -Z borrowck=mir + struct Paramd<'a> { x: &'a usize } fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { - let z: Option<&'b &'a usize> = None;//~ ERROR E0623 + let z: Option<&'b &'a usize> = None;//[ast]~ ERROR E0623 + //[mir]~^ ERROR lifetime may not live long enough } fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { let y: Paramd<'a> = Paramd { x: a }; - let z: Option<&'b Paramd<'a>> = None;//~ ERROR E0623 + let z: Option<&'b Paramd<'a>> = None;//[ast]~ ERROR E0623 + //[mir]~^ ERROR lifetime may not live long enough } fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { - let z: Option<&'a &'b usize> = None;//~ ERROR E0623 + let z: Option<&'a &'b usize> = None;//[ast]~ ERROR E0623 + //[mir]~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr index 92c21fcb4aec5..539343a68294f 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr @@ -12,6 +12,21 @@ LL | let z: &'a & usize = &(&y); LL | } | - temporary value is freed at the end of this statement -error: aborting due to previous error +error[E0597]: `y` does not live long enough + --> $DIR/regions-free-region-ordering-caller1.rs:9:27 + | +LL | fn call1<'a>(x: &'a usize) { + | -- lifetime `'a` defined here +... +LL | let z: &'a & usize = &(&y); + | ----------- ^^^^ borrowed value does not live long enough + | | + | type annotation requires that `y` is borrowed for `'a` +... +LL | } + | - `y` dropped here while still borrowed + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0716`. +Some errors occurred: E0597, E0716. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.ast.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.ast.stderr new file mode 100644 index 0000000000000..d83301840088d --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.ast.stderr @@ -0,0 +1,37 @@ +error[E0491]: in type `&'a WithHrAssoc>`, reference has a longer lifetime than the data it references + --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12 + | +LL | let _: &'a WithHrAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the lifetime 'a as defined on the function body at 32:15 + --> $DIR/regions-outlives-projection-container-hrtb.rs:32:15 + | +LL | fn with_assoc<'a,'b>() { + | ^^ +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 32:18 + --> $DIR/regions-outlives-projection-container-hrtb.rs:32:18 + | +LL | fn with_assoc<'a,'b>() { + | ^^ + +error[E0491]: in type `&'a WithHrAssocSub>`, reference has a longer lifetime than the data it references + --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12 + | +LL | let _: &'a WithHrAssocSub> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the lifetime 'a as defined on the function body at 53:19 + --> $DIR/regions-outlives-projection-container-hrtb.rs:53:19 + | +LL | fn with_assoc_sub<'a,'b>() { + | ^^ +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 53:22 + --> $DIR/regions-outlives-projection-container-hrtb.rs:53:22 + | +LL | fn with_assoc_sub<'a,'b>() { + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0491`. diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.mir.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.mir.stderr new file mode 100644 index 0000000000000..5028663ba6d04 --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.mir.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithHrAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12 + | +LL | fn with_assoc_sub<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithHrAssocSub> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs b/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs index 3483f24ecbf66..2871d962c42c9 100644 --- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs +++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs @@ -1,6 +1,9 @@ // Test that structs with higher-ranked where clauses don't generate // "outlives" requirements. Issue #22246. +// revisions: ast mir +//[mir]compile-flags: -Z borrowck=mir + #![allow(dead_code)] @@ -30,7 +33,8 @@ fn with_assoc<'a,'b>() { // We get an error because 'b:'a does not hold: let _: &'a WithHrAssoc> = loop { }; - //~^ ERROR reference has a longer lifetime + //[ast]~^ ERROR reference has a longer lifetime + //[mir]~^^ ERROR lifetime may not live long enough } /////////////////////////////////////////////////////////////////////////// @@ -51,7 +55,8 @@ fn with_assoc_sub<'a,'b>() { // below to be well-formed, it is not related to the HR relation. let _: &'a WithHrAssocSub> = loop { }; - //~^ ERROR reference has a longer lifetime + //[ast]~^ ERROR reference has a longer lifetime + //[mir]~^^ ERROR lifetime may not live long enough } diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.ast.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.ast.stderr new file mode 100644 index 0000000000000..9e31065ca4eec --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.ast.stderr @@ -0,0 +1,20 @@ +error[E0491]: in type `&'a WithAssoc>`, reference has a longer lifetime than the data it references + --> $DIR/regions-outlives-projection-container-wc.rs:37:12 + | +LL | let _: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the lifetime 'a as defined on the function body at 31:15 + --> $DIR/regions-outlives-projection-container-wc.rs:31:15 + | +LL | fn with_assoc<'a,'b>() { + | ^^ +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 31:18 + --> $DIR/regions-outlives-projection-container-wc.rs:31:18 + | +LL | fn with_assoc<'a,'b>() { + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0491`. diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.mir.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.mir.stderr new file mode 100644 index 0000000000000..880fe17b740e4 --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.mir.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container-wc.rs:37:12 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.rs b/src/test/ui/regions/regions-outlives-projection-container-wc.rs index 91a0d8590ff34..37622211327c0 100644 --- a/src/test/ui/regions/regions-outlives-projection-container-wc.rs +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.rs @@ -3,6 +3,9 @@ // outlive the location in which the type appears, even when the // constraint is in a where clause not a bound. Issue #22246. +// revisions: ast mir +//[mir]compile-flags: -Z borrowck=mir + #![allow(dead_code)] /////////////////////////////////////////////////////////////////////////// @@ -32,7 +35,8 @@ fn with_assoc<'a,'b>() { // which is &'b (), must outlive 'a. let _: &'a WithAssoc> = loop { }; - //~^ ERROR reference has a longer lifetime + //[ast]~^ ERROR reference has a longer lifetime + //[mir]~^^ ERROR lifetime may not live long enough } fn main() { From c76e55747b88949634438b6ed2e3f4dd24e799fc Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 17 Jan 2019 21:07:27 +0000 Subject: [PATCH 0181/1064] Type check unnanotated constant items with NLL --- .../borrow_check/nll/type_check/mod.rs | 111 ++++++++---------- .../constant-in-expr-inherent-2.rs | 29 +++++ .../constant-in-expr-inherent-2.stderr | 50 ++++++++ 3 files changed, 128 insertions(+), 62 deletions(-) create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 9ed1d49d05bd1..3e6aa358ee0d1 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -35,7 +35,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp; use rustc::traits::query::{Fallible, NoSolution}; use rustc::traits::{ObligationCause, PredicateObligations}; use rustc::ty::fold::TypeFoldable; -use rustc::ty::subst::{Subst, Substs, UnpackedKind}; +use rustc::ty::subst::{Subst, Substs, UnpackedKind, UserSubsts}; use rustc::ty::{ self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind, UserType, CanonicalUserTypeAnnotation, UserTypeAnnotationIndex, @@ -283,7 +283,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { location.to_locations(), ConstraintCategory::Boring, ) { - let annotation = self.cx.instantiated_type_annotations[&annotation_index]; + let annotation = &self.mir.user_type_annotations[annotation_index]; span_mirbug!( self, constant, @@ -293,6 +293,39 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { terr, ); } + } else { + match *constant.literal { + ty::LazyConst::Unevaluated(def_id, substs) => { + if let Err(terr) = self.cx.fully_perform_op( + location.to_locations(), + ConstraintCategory::Boring, + self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( + constant.ty, def_id, UserSubsts { substs, user_self_ty: None }, + )), + ) { + span_mirbug!( + self, + constant, + "bad constant type {:?} ({:?})", + constant, + terr + ); + } + } + ty::LazyConst::Evaluated(lit) => { + if let ty::FnDef(def_id, substs) = lit.ty.sty { + let tcx = self.tcx(); + + let instantiated_predicates = tcx + .predicates_of(def_id) + .instantiate(tcx, substs); + self.cx.normalize_and_prove_instantiated_predicates( + instantiated_predicates, + location.to_locations(), + ); + } + } + } } } @@ -374,8 +407,9 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { } } - /// Checks that the constant's `ty` field matches up with what - /// would be expected from its literal. + /// Checks that the constant's `ty` field matches up with what would be + /// expected from its literal. Unevaluated constants and well-formed + /// constraints are checked by `visit_constant`. fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) { debug!( "sanitize_constant(constant={:?}, location={:?})", @@ -387,35 +421,6 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { ty::LazyConst::Unevaluated(..) => return, }; - // FIXME(#46702) -- We need some way to get the predicates - // associated with the "pre-evaluated" form of the - // constant. For example, consider that the constant - // may have associated constant projections (`>::SOME_CONST`) that impose - // constraints on `'a` and `'b`. These constraints - // would be lost if we just look at the normalized - // value. - if let ty::FnDef(def_id, substs) = literal.ty.sty { - let tcx = self.tcx(); - let type_checker = &mut self.cx; - - // FIXME -- For now, use the substitutions from - // `value.ty` rather than `value.val`. The - // renumberer will rewrite them to independent - // sets of regions; in principle, we ought to - // derive the type of the `value.val` from "first - // principles" and equate with value.ty, but as we - // are transitioning to the miri-based system, we - // don't have a handy function for that, so for - // now we just ignore `value.val` regions. - - let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); - type_checker.normalize_and_prove_instantiated_predicates( - instantiated_predicates, - location.to_locations(), - ); - } - debug!("sanitize_constant: expected_ty={:?}", literal.ty); if let Err(terr) = self.cx.eq_types( @@ -740,15 +745,6 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> { reported_errors: FxHashSet<(Ty<'tcx>, Span)>, borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>, universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>, - /// For each user-type annotation (identified by a UserTypeAnnotationIndex), we create - /// an "instantiated" version at the beginning of type check, which replaces each - /// canonical variable with a fresh inference variable. These instantiated versions are - /// stored either in this field or in user_substs, depending on the kind of user-type - /// annotation. They are then referenced by the code which has the job of enforcing these - /// annotations. Part of the reason for this setup is that it allows us to enforce basic - /// WF criteria on the types even if the code that referenced them is dead - /// code (see #54943). - instantiated_type_annotations: FxHashMap>, } struct BorrowCheckContext<'a, 'tcx: 'a> { @@ -905,23 +901,19 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { borrowck_context, reported_errors: Default::default(), universal_region_relations, - instantiated_type_annotations: Default::default(), }; - checker.instantiate_user_type_annotations(); + checker.check_user_type_annotations(); checker } - /// Instantiate canonical types from user type annotations in the `Mir` into the - /// `TypeChecker`. Used when relating user type annotations and when checking if - /// annotations are well-formed. - fn instantiate_user_type_annotations(&mut self) { + /// Equate the inferred type and the annotated type for user type annotations + fn check_user_type_annotations(&mut self) { debug!( - "instantiate_user_type_annotations: user_type_annotations={:?}", + "check_user_type_annotations: user_type_annotations={:?}", self.mir.user_type_annotations ); - for annotation_index in self.mir.user_type_annotations.indices() { - let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = - self.mir.user_type_annotations[annotation_index]; + for user_annotation in &self.mir.user_type_annotations { + let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; let (annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars( span, user_ty ); @@ -937,7 +929,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ) { span_mirbug!( self, - self.mir.user_type_annotations[annotation_index], + user_annotation, "bad user type ({:?} = {:?}): {:?}", ty, inferred_ty, @@ -961,7 +953,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ) { span_mirbug!( self, - self.mir.user_type_annotations[annotation_index], + user_annotation, "bad user type AscribeUserType({:?}, {:?} {:?}): {:?}", inferred_ty, def_id, @@ -971,12 +963,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } }, } - self.instantiated_type_annotations.insert(annotation_index, inferred_ty); } - debug!( - "instantiate_user_type_annotations: instantiated_type_annotations={:?}", - self.instantiated_type_annotations, - ); } /// Given some operation `op` that manipulates types, proves @@ -1108,7 +1095,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { a, v, user_ty, locations, ); - let annotated_type = self.instantiated_type_annotations[&user_ty.base]; + let annotated_type = self.mir.user_type_annotations[user_ty.base].inferred_ty; let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); let tcx = self.infcx.tcx; @@ -1293,7 +1280,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { location.to_locations(), ConstraintCategory::Boring, ) { - let annotation = self.instantiated_type_annotations[&annotation_index]; + let annotation = &mir.user_type_annotations[annotation_index]; span_mirbug!( self, stmt, @@ -1352,7 +1339,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { Locations::All(stmt.source_info.span), ConstraintCategory::TypeAnnotation, ) { - let annotation = self.instantiated_type_annotations[&projection.base]; + let annotation = &mir.user_type_annotations[projection.base]; span_mirbug!( self, stmt, diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs new file mode 100644 index 0000000000000..123be6b3e4098 --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs @@ -0,0 +1,29 @@ +// Test that we still check constants are well-formed, even when we there's no +// type annotation to check. + +#![feature(nll)] + +const FUN: fn(&'static ()) = |_| {}; +struct A; +impl A { + const ASSOCIATED_FUN: fn(&'static ()) = |_| {}; +} + +struct B<'a>(&'a ()); +impl B<'static> { + const ALSO_ASSOCIATED_FUN: fn(&'static ()) = |_| {}; +} + +trait Z: 'static { + const TRAIT_ASSOCIATED_FUN: fn(&'static Self) = |_| (); +} + +impl Z for () {} + +fn main() { + let x = (); + FUN(&x); //~ ERROR `x` does not live long enough + A::ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + B::ALSO_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + <_>::TRAIT_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough +} diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr new file mode 100644 index 0000000000000..57cfaa2db0432 --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr @@ -0,0 +1,50 @@ +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:25:9 + | +LL | FUN(&x); //~ ERROR `x` does not live long enough + | ----^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:26:23 + | +LL | A::ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + | ------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:27:28 + | +LL | B::ALSO_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + | -----------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +LL | <_>::TRAIT_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `x` does not live long enough + --> $DIR/constant-in-expr-inherent-2.rs:28:31 + | +LL | <_>::TRAIT_ASSOCIATED_FUN(&x); //~ ERROR `x` does not live long enough + | --------------------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `x` is borrowed for `'static` +LL | } + | - `x` dropped here while still borrowed + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0597`. From 1593ac9b9fc50ac60e44f242df14e464a6e8be65 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 19 Jan 2019 19:33:41 +0000 Subject: [PATCH 0182/1064] Don't ignore `_` in type casts and ascriptions --- src/librustc_typeck/check/mod.rs | 7 ++-- src/test/mir-opt/retag.rs | 14 +++---- .../issue-57731-ascibed-coupled-types.rs | 40 +++++++++++++++++++ .../issue-57731-ascibed-coupled-types.stderr | 38 ++++++++++++++++++ 4 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs create mode 100644 src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 54fd7de381f2a..19e3d6bcaab58 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2437,9 +2437,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // types that involve projections, since those can resolve to // `'static` bounds (modulo #54940, which hopefully will be // fixed by the time you see this comment, dear reader, - // although I have my doubts). Other sorts of things are - // already sufficiently enforced with erased regions. =) - if ty.has_free_regions() || ty.has_projections() { + // although I have my doubts). Also pass in types with inference + // types, because they may be repeated. Other sorts of things + // are already sufficiently enforced with erased regions. =) + if ty.has_free_regions() || ty.has_projections() || ty.has_infer_types() { let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty)); debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty); self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty); diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index 5b00c5c460316..bb794409ae01f 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -75,18 +75,18 @@ fn main() { // _10 = move _8; // Retag(_10); // ... -// _14 = &mut (*_10); -// Retag(_14); -// _13 = move _14 as *mut i32 (Misc); -// Retag([raw] _13); +// _15 = &mut (*_10); +// Retag(_15); +// _14 = move _15 as *mut i32 (Misc); +// Retag([raw] _14); // ... -// _17 = move _18(move _19) -> bb2; +// _18 = move _19(move _20) -> bb2; // } // // bb2: { -// Retag(_17); +// Retag(_18); // ... -// _21 = const Test::foo_shr(move _22, move _24) -> bb3; +// _22 = const Test::foo_shr(move _23, move _25) -> bb3; // } // // bb3: { diff --git a/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs new file mode 100644 index 0000000000000..f4969bb4067c7 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs @@ -0,0 +1,40 @@ +// Check that repeated type variables are correctly handled + +#![allow(unused)] +#![feature(nll, type_ascription)] + +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledTypes = (T, T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); + +fn uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),): (PairUncoupled<_>,); + y // OK +} + +fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,); + y //~ ERROR lifetime may not live long enough +} + +fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,); + y //~ ERROR lifetime may not live long enough +} + +fn cast_uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairUncoupled<_>,); + y // OK +} + +fn cast_coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,); + y //~ ERROR lifetime may not live long enough +} + +fn cast_coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,); + y //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr new file mode 100644 index 0000000000000..76be637220a15 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr @@ -0,0 +1,38 @@ +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:17:5 + | +LL | fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,); +LL | y //~ ERROR lifetime may not live long enough + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:22:5 + | +LL | fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,); +LL | y //~ ERROR lifetime may not live long enough + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:32:5 + | +LL | fn cast_coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,); +LL | y //~ ERROR lifetime may not live long enough + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-57731-ascibed-coupled-types.rs:37:5 + | +LL | fn cast_coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,); +LL | y //~ ERROR lifetime may not live long enough + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 4 previous errors + From c502a79fa1a15de88623bc01d9a1c38db3ea2c1b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 04:37:29 +0900 Subject: [PATCH 0183/1064] [WIP] Improve error behavior --- src/libsyntax/parse/lexer/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 2bf7ff4bd7a28..fcaa35d1fca73 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1408,9 +1408,10 @@ impl<'a> StringReader<'a> { // lifetimes shouldn't end with a single quote // if we find one, then this is an invalid character literal if self.ch_is('\'') { - self.fatal_span_verbose(start_with_quote, self.next_pos, - String::from("character literal may only contain one codepoint")) - .raise(); + self.err_span_(start_with_quote, self.next_pos, + "character literal may only contain one codepoint"); + self.bump(); + return Ok(token::Literal(token::Err(Symbol::intern("??")), None)) } @@ -1445,7 +1446,7 @@ impl<'a> StringReader<'a> { format!("\"{}\"", &self.src[start..end]), Applicability::MachineApplicable ).emit(); - return Ok(token::Literal(token::Char(Symbol::intern("??")), None)) + return Ok(token::Literal(token::Err(Symbol::intern("??")), None)) } if self.ch_is('\n') || self.is_eof() || self.ch_is('/') { // Only attempt to infer single line string literals. If we encounter @@ -1455,8 +1456,9 @@ impl<'a> StringReader<'a> { } } - self.fatal_span_verbose(start_with_quote, pos, - String::from("character literal may only contain one codepoint")).raise(); + self.err_span_(start_with_quote, pos, + "character literal may only contain one codepoint"); + self.bump(); } let id = if valid { From e9af312932baee90d260b41711f7ea95ad51bc07 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 04:37:58 +0900 Subject: [PATCH 0184/1064] [WIP] Fix tests --- src/test/ui/parser/lex-bad-char-literals-2.rs | 2 +- .../ui/parser/lex-bad-char-literals-2.stderr | 9 ++- src/test/ui/parser/lex-bad-char-literals-4.rs | 2 +- .../ui/parser/lex-bad-char-literals-4.stderr | 16 +++++- src/test/ui/parser/lex-bad-char-literals-6.rs | 12 ++++ .../ui/parser/lex-bad-char-literals-6.stderr | 56 +++++++++++++++++++ 6 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/parser/lex-bad-char-literals-6.rs create mode 100644 src/test/ui/parser/lex-bad-char-literals-6.stderr diff --git a/src/test/ui/parser/lex-bad-char-literals-2.rs b/src/test/ui/parser/lex-bad-char-literals-2.rs index 7f859995218d9..1e180f87fc186 100644 --- a/src/test/ui/parser/lex-bad-char-literals-2.rs +++ b/src/test/ui/parser/lex-bad-char-literals-2.rs @@ -1,4 +1,4 @@ // This test needs to the last one appearing in this file as it kills the parser static c: char = - 'nope' //~ ERROR: character literal may only contain one codepoint: 'nope' + 'nope' //~ ERROR: character literal may only contain one codepoint ; diff --git a/src/test/ui/parser/lex-bad-char-literals-2.stderr b/src/test/ui/parser/lex-bad-char-literals-2.stderr index a7075b7187812..80999a4afcf44 100644 --- a/src/test/ui/parser/lex-bad-char-literals-2.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-2.stderr @@ -1,8 +1,13 @@ -error: character literal may only contain one codepoint: 'nope' +error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-2.rs:3:5 | LL | 'nope' //~ ERROR: character literal may only contain one codepoint: 'nope' | ^^^^^^ -error: aborting due to previous error +error[E0601]: `main` function not found in crate `lex_bad_char_literals_2` + | + = note: consider adding a `main` function to `$DIR/lex-bad-char-literals-2.rs` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/parser/lex-bad-char-literals-4.rs b/src/test/ui/parser/lex-bad-char-literals-4.rs index 966e2bb949688..e13f11f36df48 100644 --- a/src/test/ui/parser/lex-bad-char-literals-4.rs +++ b/src/test/ui/parser/lex-bad-char-literals-4.rs @@ -1,5 +1,5 @@ // // This test needs to the last one appearing in this file as it kills the parser static c: char = - '● //~ ERROR: character literal may only contain one codepoint: '● + '● //~ ERROR: character literal may only contain one codepoint ; diff --git a/src/test/ui/parser/lex-bad-char-literals-4.stderr b/src/test/ui/parser/lex-bad-char-literals-4.stderr index 550cb5449df19..129f28aa3e8fd 100644 --- a/src/test/ui/parser/lex-bad-char-literals-4.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-4.stderr @@ -1,8 +1,20 @@ -error: character literal may only contain one codepoint: '● +error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-4.rs:4:5 | LL | '● //~ ERROR: character literal may only contain one codepoint: '● | ^^ -error: aborting due to previous error +error: character literal may only contain one codepoint + --> $DIR/lex-bad-char-literals-4.rs:4:70 + | +LL | '● //~ ERROR: character literal may only contain one codepoint: '● + | ^^ + +error: expected one of `.`, `;`, `?`, or an operator, found `~` + --> $DIR/lex-bad-char-literals-4.rs:4:11 + | +LL | '● //~ ERROR: character literal may only contain one codepoint: '● + | ^ expected one of `.`, `;`, `?`, or an operator here + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/lex-bad-char-literals-6.rs b/src/test/ui/parser/lex-bad-char-literals-6.rs new file mode 100644 index 0000000000000..8567a8680db26 --- /dev/null +++ b/src/test/ui/parser/lex-bad-char-literals-6.rs @@ -0,0 +1,12 @@ +fn main() { + let x: &str = 'ab'; //~ ERROR: character literal may only contain one codepoint + //~^ ERROR: mismatched types + let y: char = 'cd'; //~ ERROR: character literal may only contain one codepoint + let z = 'ef'; //~ ERROR: character literal may only contain one codepoint + + if x == y {} //~ ERROR: can't compare `&str` with `char` + if y == z {} // no error here + if x == z {} //~ ERROR: can't compare `&str` with `char` + + let a: usize = ""; //~ ERROR: mismatched types +} \ No newline at end of file diff --git a/src/test/ui/parser/lex-bad-char-literals-6.stderr b/src/test/ui/parser/lex-bad-char-literals-6.stderr new file mode 100644 index 0000000000000..f1fcaaf687c7f --- /dev/null +++ b/src/test/ui/parser/lex-bad-char-literals-6.stderr @@ -0,0 +1,56 @@ +error: character literal may only contain one codepoint + --> $DIR/lex-bad-char-literals-6.rs:2:19 + | +LL | let x: &str = 'ab'; //~ ERROR: character literal may only contain one codepoint + | ^^^^ + +error: character literal may only contain one codepoint + --> $DIR/lex-bad-char-literals-6.rs:3:19 + | +LL | let y: char = 'cd'; //~ ERROR: character literal may only contain one codepoint + | ^^^^ + +error: character literal may only contain one codepoint + --> $DIR/lex-bad-char-literals-6.rs:4:13 + | +LL | let z = 'ef'; //~ ERROR: character literal may only contain one codepoint + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/lex-bad-char-literals-6.rs:2:19 + | +LL | let x: &str = 'ab'; //~ ERROR: character literal may only contain one codepoint + | ^^^^ expected &str, found char + | + = note: expected type `&str` + found type `char` + +error[E0277]: can't compare `&str` with `char` + --> $DIR/lex-bad-char-literals-6.rs:6:10 + | +LL | if x == y {} // no error here + | ^^ no implementation for `&str == char` + | + = help: the trait `std::cmp::PartialEq` is not implemented for `&str` + +error[E0308]: mismatched types + --> $DIR/lex-bad-char-literals-6.rs:10:20 + | +LL | let a: usize = ""; // type error here to confirm we got past the parser + | ^^ expected usize, found reference + | + = note: expected type `usize` + found type `&'static str` + +error[E0277]: can't compare `&str` with `char` + --> $DIR/lex-bad-char-literals-6.rs:8:10 + | +LL | if x == z {} // no error here + | ^^ no implementation for `&str == char` + | + = help: the trait `std::cmp::PartialEq` is not implemented for `&str` + +error: aborting due to 7 previous errors + +Some errors occurred: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From c14508fd252742e6f7ad99b1519ef1039b1eb80c Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sun, 20 Jan 2019 00:04:28 +0100 Subject: [PATCH 0185/1064] Add missing #![feature(rustc_private)] annotation --- src/libfmt_macros/lib.rs | 1 + src/libtest/lib.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 32ae878909f30..5127c76b55c6d 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -11,6 +11,7 @@ test(attr(deny(warnings))))] #![feature(nll)] +#![feature(rustc_private)] pub use self::Piece::*; pub use self::Position::*; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 2cc80ddea2df4..fc03e685b6f54 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -25,7 +25,7 @@ #![feature(asm)] #![cfg_attr(stage0, feature(cfg_target_vendor))] #![feature(fnbox)] -#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))] +#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc, rustc_private))] #![feature(nll)] #![feature(set_stdio)] #![feature(panic_unwind)] From ff41abcf8bbeefae4df033d6a1bac1543d67c388 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sun, 20 Jan 2019 00:05:10 +0100 Subject: [PATCH 0186/1064] linkchecker: Update deprecated trim_left_matches usage --- src/tools/linkchecker/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 59662be349dcb..2cf0fcfd34cd6 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -78,7 +78,7 @@ impl FileEntry { fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut bool) { if self.ids.is_empty() { with_attrs_in_source(contents, " id", |fragment, i, _| { - let frag = fragment.trim_left_matches("#").to_owned(); + let frag = fragment.trim_start_matches("#").to_owned(); let encoded = small_url_encode(&frag); if !self.ids.insert(frag) { *errors = true; @@ -343,7 +343,7 @@ fn with_attrs_in_source(contents: &str, attr: &str, Some(i) => i, None => continue, }; - if rest[..pos_equals].trim_left_matches(" ") != "" { + if rest[..pos_equals].trim_start_matches(" ") != "" { continue; } @@ -355,7 +355,7 @@ fn with_attrs_in_source(contents: &str, attr: &str, }; let quote_delim = rest.as_bytes()[pos_quote] as char; - if rest[..pos_quote].trim_left_matches(" ") != "" { + if rest[..pos_quote].trim_start_matches(" ") != "" { continue; } let rest = &rest[pos_quote + 1..]; From d38e70036eee2187d93d8d760461a79aaa84489f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jan 2019 14:48:43 -0800 Subject: [PATCH 0187/1064] Continune parsing after encountering Trait with paren args --- src/librustc/hir/lowering.rs | 2 +- src/test/ui/error-codes/E0214.stderr | 11 +++++++++-- src/test/ui/issues/issue-23589.stderr | 11 +++++++++-- .../unboxed-closure-sugar-used-on-struct-1.stderr | 11 +++++++++-- .../unboxed-closure-sugar-used-on-struct-3.stderr | 11 +++++++++-- .../unboxed-closure-sugar-used-on-struct.stderr | 8 ++++---- 6 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2f7d8f0984e6f..b8aeb6032ba65 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1826,7 +1826,7 @@ impl<'a> LoweringContext<'a> { struct_span_err!(self.sess, data.span, E0214, "{}", msg) .span_label(data.span, "only traits may use parentheses") .emit(); - (hir::GenericArgs::none(), true) + (hir::GenericArgs::none(), false) } }, } diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr index 08a98b1c3bf3d..f87502efe1b10 100644 --- a/src/test/ui/error-codes/E0214.stderr +++ b/src/test/ui/error-codes/E0214.stderr @@ -4,6 +4,13 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let v: Vec(&str) = vec!["foo"]; | ^^^^^^ only traits may use parentheses -error: aborting due to previous error +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/E0214.rs:2:12 + | +LL | let v: Vec(&str) = vec!["foo"]; + | ^^^^^^^^^ expected 1 type argument + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0214`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr index e6e07c167f349..15f2c524a7a9f 100644 --- a/src/test/ui/issues/issue-23589.stderr +++ b/src/test/ui/issues/issue-23589.stderr @@ -4,6 +4,13 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let v: Vec(&str) = vec!['1', '2']; | ^^^^^^ only traits may use parentheses -error: aborting due to previous error +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/issue-23589.rs:2:12 + | +LL | let v: Vec(&str) = vec!['1', '2']; + | ^^^^^^^^^ expected 1 type argument + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0214`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr index 3f1b37c282b7c..ab2a6f03cf7e7 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr @@ -4,6 +4,13 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let x: Box = panic!(); | ^^ only traits may use parentheses -error: aborting due to previous error +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16 + | +LL | let x: Box = panic!(); + | ^^^^^ expected 1 type argument + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0214`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr index 395f6596cfd83..b4f7a97c3e5fb 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr @@ -4,6 +4,13 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) | ^^^^^^^^^^^^^^^^ only traits may use parentheses -error: aborting due to previous error +error[E0107]: wrong number of type arguments: expected 2, found 0 + --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:13 + | +LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected 2 type arguments + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0214`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr index d0267092030d8..7bcf86774c7be 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr @@ -4,13 +4,13 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | fn foo(b: Box) { | ^^ only traits may use parentheses -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15 | LL | fn foo(b: Box) { - | ^^^^^ not allowed in type signatures + | ^^^^^ expected 1 type argument error: aborting due to 2 previous errors -Some errors occurred: E0121, E0214. -For more information about an error, try `rustc --explain E0121`. +Some errors occurred: E0107, E0214. +For more information about an error, try `rustc --explain E0107`. From 3235446b397a06596063f237ae864de8d95799e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jan 2019 18:44:20 -0800 Subject: [PATCH 0188/1064] Accept parenthesized type args for error recovery --- src/librustc/hir/lowering.rs | 6 +++++- src/libsyntax/ast.rs | 10 ++++++++++ src/test/ui/error-codes/E0214.stderr | 11 ++--------- src/test/ui/issues/issue-23589.rs | 1 + src/test/ui/issues/issue-23589.stderr | 13 ++++++++----- .../unboxed-closure-sugar-used-on-struct-1.rs | 1 + .../unboxed-closure-sugar-used-on-struct-3.stderr | 11 ++--------- .../unboxed-closure-sugar-used-on-struct.rs | 2 +- 8 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b8aeb6032ba65..b7624b09eeea9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1826,7 +1826,11 @@ impl<'a> LoweringContext<'a> { struct_span_err!(self.sess, data.span, E0214, "{}", msg) .span_label(data.span, "only traits may use parentheses") .emit(); - (hir::GenericArgs::none(), false) + (self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + param_mode, + itctx).0, + false) } }, } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bbcaaacbab523..d57f9247c0520 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -192,6 +192,16 @@ pub struct ParenthesisedArgs { pub output: Option>, } +impl ParenthesisedArgs { + pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs { + AngleBracketedArgs { + span: self.span, + args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(), + bindings: vec![], + } + } +} + // hack to ensure that we don't try to access the private parts of `NodeId` in this module mod node_id_inner { use rustc_data_structures::indexed_vec::Idx; diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr index f87502efe1b10..08a98b1c3bf3d 100644 --- a/src/test/ui/error-codes/E0214.stderr +++ b/src/test/ui/error-codes/E0214.stderr @@ -4,13 +4,6 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let v: Vec(&str) = vec!["foo"]; | ^^^^^^ only traits may use parentheses -error[E0107]: wrong number of type arguments: expected 1, found 0 - --> $DIR/E0214.rs:2:12 - | -LL | let v: Vec(&str) = vec!["foo"]; - | ^^^^^^^^^ expected 1 type argument - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0107, E0214. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0214`. diff --git a/src/test/ui/issues/issue-23589.rs b/src/test/ui/issues/issue-23589.rs index a59710a1a3cde..fb765e453dcd6 100644 --- a/src/test/ui/issues/issue-23589.rs +++ b/src/test/ui/issues/issue-23589.rs @@ -1,4 +1,5 @@ fn main() { let v: Vec(&str) = vec!['1', '2']; //~^ ERROR parenthesized parameters may only be used with a trait + //~| ERROR mismatched types } diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr index 15f2c524a7a9f..c71061606df51 100644 --- a/src/test/ui/issues/issue-23589.stderr +++ b/src/test/ui/issues/issue-23589.stderr @@ -4,13 +4,16 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let v: Vec(&str) = vec!['1', '2']; | ^^^^^^ only traits may use parentheses -error[E0107]: wrong number of type arguments: expected 1, found 0 - --> $DIR/issue-23589.rs:2:12 +error[E0308]: mismatched types + --> $DIR/issue-23589.rs:2:29 | LL | let v: Vec(&str) = vec!['1', '2']; - | ^^^^^^^^^ expected 1 type argument + | ^^^ expected &str, found char + | + = note: expected type `&str` + found type `char` error: aborting due to 2 previous errors -Some errors occurred: E0107, E0214. -For more information about an error, try `rustc --explain E0107`. +Some errors occurred: E0214, E0308. +For more information about an error, try `rustc --explain E0214`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs index 5387dcb218cb9..2827e6eead5fd 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs @@ -7,6 +7,7 @@ struct Bar { fn bar() { let x: Box = panic!(); //~^ ERROR parenthesized parameters may only be used with a trait + //~| ERROR wrong number of type arguments: expected 1, found 0 } fn main() { } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr index b4f7a97c3e5fb..395f6596cfd83 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr @@ -4,13 +4,6 @@ error[E0214]: parenthesized parameters may only be used with a trait LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) | ^^^^^^^^^^^^^^^^ only traits may use parentheses -error[E0107]: wrong number of type arguments: expected 2, found 0 - --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:13 - | -LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected 2 type arguments - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0107, E0214. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0214`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs index e795650447cc4..6da53585c9c4c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs @@ -6,7 +6,7 @@ struct Bar { fn foo(b: Box) { //~^ ERROR parenthesized parameters may only be used with a trait - //~| ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR wrong number of type arguments: expected 1, found 0 } fn main() { } From d37a6d83e1626db51041b6337328cde603f1bc19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jan 2019 19:25:28 -0800 Subject: [PATCH 0189/1064] Suggest usage of angle brackets --- src/librustc/hir/lowering.rs | 15 ++++++++++++--- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/error-codes/E0214.stderr | 5 ++++- src/test/ui/issues/issue-23589.stderr | 5 ++++- src/test/ui/issues/issue-32995.stderr | 8 ++++---- .../parser/type-parameters-in-field-exprs.stderr | 12 ++++++------ src/test/ui/span/macro-ty-params.stderr | 8 ++++---- .../unboxed-closure-sugar-used-on-struct-1.stderr | 5 ++++- .../unboxed-closure-sugar-used-on-struct-3.stderr | 7 +++++-- .../unboxed-closure-sugar-used-on-struct.stderr | 5 ++++- 10 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b7624b09eeea9..9d3438289a0cd 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -31,6 +31,7 @@ //! in the HIR, especially for multiple identifiers. use dep_graph::DepGraph; +use errors::Applicability; use hir::{self, ParamName}; use hir::HirVec; use hir::map::{DefKey, DefPathData, Definitions}; @@ -1823,9 +1824,17 @@ impl<'a> LoweringContext<'a> { (hir::GenericArgs::none(), true) } ParenthesizedGenericArgs::Err => { - struct_span_err!(self.sess, data.span, E0214, "{}", msg) - .span_label(data.span, "only traits may use parentheses") - .emit(); + let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); + err.span_label(data.span, "only traits may use parentheses"); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { + err.span_suggestion_with_applicability( + data.span, + "use angle brackets instead", + format!("<{}>", &snippet[1..snippet.len() - 1]), + Applicability::MaybeIncorrect, + ); + }; + err.emit(); (self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), param_mode, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7e15b23127655..e09b7a9dd7b7f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2176,11 +2176,11 @@ impl<'a> Parser<'a> { style != PathStyle::Mod && self.check(&token::ModSep) && self.look_ahead(1, |t| is_args_start(t)) { // Generic arguments are found - `<`, `(`, `::<` or `::(`. - let lo = self.span; if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning { self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator") .span_label(self.prev_span, "try removing `::`").emit(); } + let lo = self.span; let args = if self.eat_lt() { // `<'a, T, A = U>` diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr index 08a98b1c3bf3d..0172dc706ac5f 100644 --- a/src/test/ui/error-codes/E0214.stderr +++ b/src/test/ui/error-codes/E0214.stderr @@ -2,7 +2,10 @@ error[E0214]: parenthesized parameters may only be used with a trait --> $DIR/E0214.rs:2:15 | LL | let v: Vec(&str) = vec!["foo"]; - | ^^^^^^ only traits may use parentheses + | ^^^^^^ + | | + | only traits may use parentheses + | help: use angle brackets instead: `<&str>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr index c71061606df51..932e8eedad1ca 100644 --- a/src/test/ui/issues/issue-23589.stderr +++ b/src/test/ui/issues/issue-23589.stderr @@ -2,7 +2,10 @@ error[E0214]: parenthesized parameters may only be used with a trait --> $DIR/issue-23589.rs:2:15 | LL | let v: Vec(&str) = vec!['1', '2']; - | ^^^^^^ only traits may use parentheses + | ^^^^^^ + | | + | only traits may use parentheses + | help: use angle brackets instead: `<&str>` error[E0308]: mismatched types --> $DIR/issue-23589.rs:2:29 diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr index 12551bb7f1f00..e27f2d9553a93 100644 --- a/src/test/ui/issues/issue-32995.stderr +++ b/src/test/ui/issues/issue-32995.stderr @@ -18,19 +18,19 @@ LL | let b: ::std::boxed()::Box<_> = Box::new(1); = note: for more information, see issue #42238 error: parenthesized parameters may only be used with a trait - --> $DIR/issue-32995.rs:12:23 + --> $DIR/issue-32995.rs:12:25 | LL | let p = ::std::str::()::from_utf8(b"foo").unwrap(); - | ^^^^ + | ^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 error: parenthesized parameters may only be used with a trait - --> $DIR/issue-32995.rs:16:34 + --> $DIR/issue-32995.rs:16:36 | LL | let p = ::std::str::from_utf8::()(b"foo").unwrap(); - | ^^^^ + | ^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr index e68e1f3204ade..2183c74da0acb 100644 --- a/src/test/ui/parser/type-parameters-in-field-exprs.stderr +++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr @@ -1,20 +1,20 @@ error: field expressions may not have generic arguments - --> $DIR/type-parameters-in-field-exprs.rs:13:8 + --> $DIR/type-parameters-in-field-exprs.rs:13:10 | LL | f.x::; - | ^^^^^^^^^ + | ^^^^^^^ error: field expressions may not have generic arguments - --> $DIR/type-parameters-in-field-exprs.rs:15:8 + --> $DIR/type-parameters-in-field-exprs.rs:15:10 | LL | f.x::<>; - | ^^^^ + | ^^ error: field expressions may not have generic arguments - --> $DIR/type-parameters-in-field-exprs.rs:17:8 + --> $DIR/type-parameters-in-field-exprs.rs:17:10 | LL | f.x::(); - | ^^^^ + | ^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr index 23fdde06e8f9d..965ca7000be80 100644 --- a/src/test/ui/span/macro-ty-params.stderr +++ b/src/test/ui/span/macro-ty-params.stderr @@ -1,14 +1,14 @@ error: generic arguments in macro path - --> $DIR/macro-ty-params.rs:10:8 + --> $DIR/macro-ty-params.rs:10:10 | LL | foo::!(); //~ ERROR generic arguments in macro path - | ^^^^^ + | ^^^ error: generic arguments in macro path - --> $DIR/macro-ty-params.rs:11:8 + --> $DIR/macro-ty-params.rs:11:10 | LL | foo::<>!(); //~ ERROR generic arguments in macro path - | ^^^^ + | ^^ error: unexpected generic arguments in path --> $DIR/macro-ty-params.rs:12:8 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr index ab2a6f03cf7e7..87832d839b949 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr @@ -2,7 +2,10 @@ error[E0214]: parenthesized parameters may only be used with a trait --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:19 | LL | let x: Box = panic!(); - | ^^ only traits may use parentheses + | ^^ + | | + | only traits may use parentheses + | help: use angle brackets instead: `<>` error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr index 395f6596cfd83..c9cc60717a610 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr @@ -1,8 +1,11 @@ error[E0214]: parenthesized parameters may only be used with a trait - --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:16 + --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:18 | LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) - | ^^^^^^^^^^^^^^^^ only traits may use parentheses + | ^^^^^^^^^^^^^^ + | | + | only traits may use parentheses + | help: use angle brackets instead: `` error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr index 7bcf86774c7be..a09c2b75386eb 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr @@ -2,7 +2,10 @@ error[E0214]: parenthesized parameters may only be used with a trait --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:18 | LL | fn foo(b: Box) { - | ^^ only traits may use parentheses + | ^^ + | | + | only traits may use parentheses + | help: use angle brackets instead: `<>` error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15 From b36bf76dec593269b3c5006c38063315bed5ad51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 19 Jan 2019 20:18:56 -0800 Subject: [PATCH 0190/1064] Suggest correct cast for struct fields with shorthand syntax --- src/librustc_typeck/check/demand.rs | 48 ++++++++++++++----- .../type-mismatch-struct-field-shorthand-2.rs | 9 ++++ ...e-mismatch-struct-field-shorthand-2.stderr | 30 ++++++++++++ ...type-mismatch-struct-field-shorthand.fixed | 12 +++++ .../type-mismatch-struct-field-shorthand.rs | 12 +++++ ...ype-mismatch-struct-field-shorthand.stderr | 33 +++++++++++++ 6 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs create mode 100644 src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr create mode 100644 src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed create mode 100644 src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs create mode 100644 src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index c0cedd77440d9..2aecc0f2ace6a 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -454,12 +454,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { false } - pub fn check_for_cast(&self, - err: &mut DiagnosticBuilder<'tcx>, - expr: &hir::Expr, - checked_ty: Ty<'tcx>, - expected_ty: Ty<'tcx>) - -> bool { + pub fn check_for_cast( + &self, + err: &mut DiagnosticBuilder<'tcx>, + expr: &hir::Expr, + checked_ty: Ty<'tcx>, + expected_ty: Ty<'tcx>, + ) -> bool { let parent_id = self.tcx.hir().get_parent_node(expr.id); if let Some(parent) = self.tcx.hir().find(parent_id) { // Shouldn't suggest `.into()` on `const`s. @@ -487,17 +488,40 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // For now, don't suggest casting with `as`. let can_cast = false; + let mut prefix = String::new(); + if let Some(hir::Node::Expr(hir::Expr { + node: hir::ExprKind::Struct(_, fields, _), + .. + })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.id)) { + // `expr` is a literal field for a struct, only suggest if appropriate + for field in fields { + if field.expr.id == expr.id { + // This is a field literal + prefix = format!("{}: ", field.ident); + break; + } + } + if &prefix == "" { + // Likely a field was meant, but this field wasn't found. Do not suggest anything. + return false; + } + } + let needs_paren = expr.precedence().order() < (PREC_POSTFIX as i8); if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) { let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty); - let cast_suggestion = format!("{}{}{} as {}", - if needs_paren { "(" } else { "" }, - src, - if needs_paren { ")" } else { "" }, - expected_ty); + let cast_suggestion = format!( + "{}{}{}{} as {}", + prefix, + if needs_paren { "(" } else { "" }, + src, + if needs_paren { ")" } else { "" }, + expected_ty, + ); let into_suggestion = format!( - "{}{}{}.into()", + "{}{}{}{}.into()", + prefix, if needs_paren { "(" } else { "" }, src, if needs_paren { ")" } else { "" }, diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs new file mode 100644 index 0000000000000..2ce12220723df --- /dev/null +++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs @@ -0,0 +1,9 @@ +struct RGB { r: f64, g: f64, b: f64 } + +fn main() { + let (r, g, c): (f32, f32, f32) = (0., 0., 0.); + let _ = RGB { r, g, c }; + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR struct `RGB` has no field named `c` +} diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr new file mode 100644 index 0000000000000..d0f9e1f7f7c8e --- /dev/null +++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr @@ -0,0 +1,30 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:19 + | +LL | let _ = RGB { r, g, c }; + | ^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +LL | let _ = RGB { r: r.into(), g, c }; + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:22 + | +LL | let _ = RGB { r, g, c }; + | ^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +LL | let _ = RGB { r, g: g.into(), c }; + | ^^^^^^^^^^^ + +error[E0560]: struct `RGB` has no field named `c` + --> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:25 + | +LL | let _ = RGB { r, g, c }; + | ^ help: a field with a similar name exists: `b` + +error: aborting due to 3 previous errors + +Some errors occurred: E0308, E0560. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed new file mode 100644 index 0000000000000..91758c0b21882 --- /dev/null +++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed @@ -0,0 +1,12 @@ +// run-rustfix +#![allow(dead_code)] + +struct RGB { r: f64, g: f64, b: f64 } + +fn main() { + let (r, g, b): (f32, f32, f32) = (0., 0., 0.); + let _ = RGB { r: r.into(), g: g.into(), b: b.into() }; + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types +} diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs new file mode 100644 index 0000000000000..9d3a17a72b21e --- /dev/null +++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs @@ -0,0 +1,12 @@ +// run-rustfix +#![allow(dead_code)] + +struct RGB { r: f64, g: f64, b: f64 } + +fn main() { + let (r, g, b): (f32, f32, f32) = (0., 0., 0.); + let _ = RGB { r, g, b }; + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types +} diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr new file mode 100644 index 0000000000000..6bc16ba8b70fa --- /dev/null +++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-struct-field-shorthand.rs:8:19 + | +LL | let _ = RGB { r, g, b }; + | ^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +LL | let _ = RGB { r: r.into(), g, b }; + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-mismatch-struct-field-shorthand.rs:8:22 + | +LL | let _ = RGB { r, g, b }; + | ^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +LL | let _ = RGB { r, g: g.into(), b }; + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-mismatch-struct-field-shorthand.rs:8:25 + | +LL | let _ = RGB { r, g, b }; + | ^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +LL | let _ = RGB { r, g, b: b.into() }; + | ^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From a4ff1dcc534e9ae132e5b201a8f6e7dd06fbd9ee Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 14:51:54 +0900 Subject: [PATCH 0191/1064] Mark incorrect recovered `char` literals as `TyErr` to avoid type errors --- src/librustc/ich/impls_syntax.rs | 1 + src/librustc_mir/hair/constant.rs | 8 ++++++++ src/librustc_typeck/check/mod.rs | 3 ++- src/libsyntax/ast.rs | 3 +++ src/libsyntax/attr/mod.rs | 1 + src/libsyntax/parse/mod.rs | 2 +- src/libsyntax/parse/token.rs | 3 +-- src/libsyntax/print/pprust.rs | 8 ++++++++ src/libsyntax_ext/concat.rs | 1 + 9 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 6ffb771ffcc4e..ef113b8424d2a 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -164,6 +164,7 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType { impl_stable_hash_for_spanned!(::syntax::ast::LitKind); impl_stable_hash_for!(enum ::syntax::ast::LitKind { Str(value, style), + Err(value), ByteStr(value), Byte(value), Char(value), diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs index 37d741d2606d5..f63c3e2ff6142 100644 --- a/src/librustc_mir/hair/constant.rs +++ b/src/librustc_mir/hair/constant.rs @@ -37,6 +37,14 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>( let id = tcx.allocate_bytes(s.as_bytes()); ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx) }, + LitKind::Err(ref s) => { + let s = s.as_str(); + let id = tcx.allocate_bytes(s.as_bytes()); + return Ok(ty::Const { + val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx), + ty: tcx.types.err, + }); + }, LitKind::ByteStr(ref data) => { let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::Ptr(id.into())) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..6c228670ff6ab 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3121,7 +3121,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { opt_ty.unwrap_or_else( || tcx.mk_float_var(self.next_float_var_id())) } - ast::LitKind::Bool(_) => tcx.types.bool + ast::LitKind::Bool(_) => tcx.types.bool, + ast::LitKind::Err(_) => tcx.types.err, } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 99ab9fbcf5fa0..1180c8c8c1c2b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1285,6 +1285,8 @@ pub enum LitKind { FloatUnsuffixed(Symbol), /// A boolean literal. Bool(bool), + /// A recovered character literal that contains mutliple `char`s, most likely a typo. + Err(Symbol), } impl LitKind { @@ -1321,6 +1323,7 @@ impl LitKind { | LitKind::ByteStr(..) | LitKind::Byte(..) | LitKind::Char(..) + | LitKind::Err(..) | LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::FloatUnsuffixed(..) | LitKind::Bool(..) => true, diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index d03563f8891aa..9c3ee0a3b023a 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -661,6 +661,7 @@ impl LitKind { } else { "false" })), false), + LitKind::Err(val) => Token::Literal(token::Lit::Err(val), None), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index cbb503f56bc4a..9e55f359b5ec2 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -466,7 +466,7 @@ crate fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Ha match lit { token::Byte(i) => (true, Some(LitKind::Byte(byte_lit(&i.as_str()).0))), token::Char(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), - token::Err(i) => (true, Some(LitKind::Char(char_lit(&i.as_str(), diag).0))), + token::Err(i) => (true, Some(LitKind::Err(i))), // There are some valid suffixes for integer and float literals, // so all the handling is done internally. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 99041fd7cd634..f06e975a6d95a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -473,8 +473,7 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | - Question | OpenDelim(..) | CloseDelim(..) => return None, - + Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) | Whitespace | Comment | Shebang(..) | Eof => return None, }) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 123f9b49692d9..383baffa266dd 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -604,6 +604,14 @@ pub trait PrintState<'a> { } match lit.node { ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), + ast::LitKind::Err(st) => { + let st = st.as_str().escape_debug(); + let mut res = String::with_capacity(st.len() + 2); + res.push('\''); + res.push_str(&st); + res.push('\''); + self.writer().word(res) + } ast::LitKind::Byte(byte) => { let mut res = String::from("b'"); res.extend(ascii::escape_default(byte).map(|c| c as char)); diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index 807f190cb6a1a..f148f8e003df3 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -23,6 +23,7 @@ pub fn expand_syntax_ext( match e.node { ast::ExprKind::Lit(ref lit) => match lit.node { ast::LitKind::Str(ref s, _) + | ast::LitKind::Err(ref s) | ast::LitKind::Float(ref s, _) | ast::LitKind::FloatUnsuffixed(ref s) => { accumulator.push_str(&s.as_str()); From 6e59c6432612f87c7cb1309e89c41e1f0d9e0e25 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 14:53:16 +0900 Subject: [PATCH 0192/1064] Revert change --- src/libsyntax/parse/lexer/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index fcaa35d1fca73..cf51d3ed58d53 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1456,9 +1456,8 @@ impl<'a> StringReader<'a> { } } - self.err_span_(start_with_quote, pos, - "character literal may only contain one codepoint"); - self.bump(); + self.fatal_span_verbose(start_with_quote, pos, + String::from("character literal may only contain one codepoint")).raise(); } let id = if valid { From 7ce25144195196d8b9f8d058490720ee0677798c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 14:53:28 +0900 Subject: [PATCH 0193/1064] Fix tests --- .../ui/parser/lex-bad-char-literals-2.stderr | 2 +- src/test/ui/parser/lex-bad-char-literals-3.rs | 11 +++---- .../ui/parser/lex-bad-char-literals-3.stderr | 28 +++++----------- .../ui/parser/lex-bad-char-literals-4.stderr | 18 ++-------- src/test/ui/parser/lex-bad-char-literals-5.rs | 11 +++---- .../ui/parser/lex-bad-char-literals-5.stderr | 28 +++++----------- src/test/ui/parser/lex-bad-char-literals-6.rs | 21 +++++++----- .../ui/parser/lex-bad-char-literals-6.stderr | 33 +++++++------------ 8 files changed, 56 insertions(+), 96 deletions(-) diff --git a/src/test/ui/parser/lex-bad-char-literals-2.stderr b/src/test/ui/parser/lex-bad-char-literals-2.stderr index 80999a4afcf44..7eadb8ebfe06d 100644 --- a/src/test/ui/parser/lex-bad-char-literals-2.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-2.stderr @@ -1,7 +1,7 @@ error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-2.rs:3:5 | -LL | 'nope' //~ ERROR: character literal may only contain one codepoint: 'nope' +LL | 'nope' //~ ERROR: character literal may only contain one codepoint | ^^^^^^ error[E0601]: `main` function not found in crate `lex_bad_char_literals_2` diff --git a/src/test/ui/parser/lex-bad-char-literals-3.rs b/src/test/ui/parser/lex-bad-char-literals-3.rs index 10a8cd4a53eab..efd597d11faa4 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.rs +++ b/src/test/ui/parser/lex-bad-char-literals-3.rs @@ -1,9 +1,8 @@ -// This test needs to the last one appearing in this file as it kills the parser -static c: char = - '●●' //~ ERROR: character literal may only contain one codepoint -; +static c: char = '●●'; +//~^ ERROR: character literal may only contain one codepoint + fn main() { - let ch: &str = '●●'; //~ ERROR: character literal may only contain one codepoint - //~^ ERROR: mismatched types + let ch: &str = '●●'; + //~^ ERROR: character literal may only contain one codepoint } diff --git a/src/test/ui/parser/lex-bad-char-literals-3.stderr b/src/test/ui/parser/lex-bad-char-literals-3.stderr index 9b4e69870cae8..1e7a386ca8b2a 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-3.stderr @@ -1,32 +1,22 @@ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-3.rs:3:5 + --> $DIR/lex-bad-char-literals-3.rs:1:18 | -LL | '●●' //~ ERROR: character literal may only contain one codepoint - | ^^^^ +LL | static c: char = '●●'; + | ^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | "●●" //~ ERROR: character literal may only contain one codepoint - | ^^^^ +LL | static c: char = "●●"; + | ^^^^ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-3.rs:7:20 + --> $DIR/lex-bad-char-literals-3.rs:6:20 | -LL | let ch: &str = '●●'; //~ ERROR: character literal may only contain one codepoint +LL | let ch: &str = '●●'; | ^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | let ch: &str = "●●"; //~ ERROR: character literal may only contain one codepoint +LL | let ch: &str = "●●"; | ^^^^ -error[E0308]: mismatched types - --> $DIR/lex-bad-char-literals-3.rs:7:20 - | -LL | let ch: &str = '●●'; //~ ERROR: character literal may only contain one codepoint - | ^^^^ expected &str, found char - | - = note: expected type `&str` - found type `char` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/lex-bad-char-literals-4.stderr b/src/test/ui/parser/lex-bad-char-literals-4.stderr index 129f28aa3e8fd..881e3d5276bb1 100644 --- a/src/test/ui/parser/lex-bad-char-literals-4.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-4.stderr @@ -1,20 +1,8 @@ -error: character literal may only contain one codepoint +error: character literal may only contain one codepoint: '● --> $DIR/lex-bad-char-literals-4.rs:4:5 | -LL | '● //~ ERROR: character literal may only contain one codepoint: '● +LL | '● //~ ERROR: character literal may only contain one codepoint | ^^ -error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-4.rs:4:70 - | -LL | '● //~ ERROR: character literal may only contain one codepoint: '● - | ^^ - -error: expected one of `.`, `;`, `?`, or an operator, found `~` - --> $DIR/lex-bad-char-literals-4.rs:4:11 - | -LL | '● //~ ERROR: character literal may only contain one codepoint: '● - | ^ expected one of `.`, `;`, `?`, or an operator here - -error: aborting due to 3 previous errors +error: aborting due to previous error diff --git a/src/test/ui/parser/lex-bad-char-literals-5.rs b/src/test/ui/parser/lex-bad-char-literals-5.rs index 964099c3fa98d..0c4339edc4fa7 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.rs +++ b/src/test/ui/parser/lex-bad-char-literals-5.rs @@ -1,10 +1,7 @@ -// -// This test needs to the last one appearing in this file as it kills the parser -static c: char = - '\x10\x10' //~ ERROR: character literal may only contain one codepoint -; +static c: char = '\x10\x10'; +//~^ ERROR: character literal may only contain one codepoint fn main() { - let ch: &str = '\x10\x10'; //~ ERROR: character literal may only contain one codepoint - //~^ ERROR: mismatched types + let ch: &str = '\x10\x10'; + //~^ ERROR: character literal may only contain one codepoint } diff --git a/src/test/ui/parser/lex-bad-char-literals-5.stderr b/src/test/ui/parser/lex-bad-char-literals-5.stderr index 177d8c599a894..ef02973310153 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-5.stderr @@ -1,32 +1,22 @@ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-5.rs:4:5 + --> $DIR/lex-bad-char-literals-5.rs:1:18 | -LL | '/x10/x10' //~ ERROR: character literal may only contain one codepoint - | ^^^^^^^^^^ +LL | static c: char = '/x10/x10'; + | ^^^^^^^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | "/x10/x10" //~ ERROR: character literal may only contain one codepoint - | ^^^^^^^^^^ +LL | static c: char = "/x10/x10"; + | ^^^^^^^^^^ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-5.rs:8:20 + --> $DIR/lex-bad-char-literals-5.rs:5:20 | -LL | let ch: &str = '/x10/x10'; //~ ERROR: character literal may only contain one codepoint +LL | let ch: &str = '/x10/x10'; | ^^^^^^^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | let ch: &str = "/x10/x10"; //~ ERROR: character literal may only contain one codepoint +LL | let ch: &str = "/x10/x10"; | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/lex-bad-char-literals-5.rs:8:20 - | -LL | let ch: &str = '/x10/x10'; //~ ERROR: character literal may only contain one codepoint - | ^^^^^^^^^^ expected &str, found char - | - = note: expected type `&str` - found type `char` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/lex-bad-char-literals-6.rs b/src/test/ui/parser/lex-bad-char-literals-6.rs index 8567a8680db26..4379b4fa6d777 100644 --- a/src/test/ui/parser/lex-bad-char-literals-6.rs +++ b/src/test/ui/parser/lex-bad-char-literals-6.rs @@ -1,12 +1,17 @@ fn main() { - let x: &str = 'ab'; //~ ERROR: character literal may only contain one codepoint - //~^ ERROR: mismatched types - let y: char = 'cd'; //~ ERROR: character literal may only contain one codepoint - let z = 'ef'; //~ ERROR: character literal may only contain one codepoint + let x: &str = 'ab'; + //~^ ERROR: character literal may only contain one codepoint + let y: char = 'cd'; + //~^ ERROR: character literal may only contain one codepoint + let z = 'ef'; + //~^ ERROR: character literal may only contain one codepoint - if x == y {} //~ ERROR: can't compare `&str` with `char` + if x == y {} + //~^ ERROR: can't compare `&str` with `char` if y == z {} // no error here - if x == z {} //~ ERROR: can't compare `&str` with `char` + if x == z {} + //~^ ERROR: can't compare `&str` with `char` - let a: usize = ""; //~ ERROR: mismatched types -} \ No newline at end of file + let a: usize = ""; + //~^ ERROR: mismatched types +} diff --git a/src/test/ui/parser/lex-bad-char-literals-6.stderr b/src/test/ui/parser/lex-bad-char-literals-6.stderr index f1fcaaf687c7f..df99726034878 100644 --- a/src/test/ui/parser/lex-bad-char-literals-6.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-6.stderr @@ -1,56 +1,47 @@ error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-6.rs:2:19 | -LL | let x: &str = 'ab'; //~ ERROR: character literal may only contain one codepoint +LL | let x: &str = 'ab'; | ^^^^ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-6.rs:3:19 + --> $DIR/lex-bad-char-literals-6.rs:4:19 | -LL | let y: char = 'cd'; //~ ERROR: character literal may only contain one codepoint +LL | let y: char = 'cd'; | ^^^^ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-6.rs:4:13 + --> $DIR/lex-bad-char-literals-6.rs:6:13 | -LL | let z = 'ef'; //~ ERROR: character literal may only contain one codepoint +LL | let z = 'ef'; | ^^^^ -error[E0308]: mismatched types - --> $DIR/lex-bad-char-literals-6.rs:2:19 - | -LL | let x: &str = 'ab'; //~ ERROR: character literal may only contain one codepoint - | ^^^^ expected &str, found char - | - = note: expected type `&str` - found type `char` - error[E0277]: can't compare `&str` with `char` - --> $DIR/lex-bad-char-literals-6.rs:6:10 + --> $DIR/lex-bad-char-literals-6.rs:9:10 | -LL | if x == y {} // no error here +LL | if x == y {} | ^^ no implementation for `&str == char` | = help: the trait `std::cmp::PartialEq` is not implemented for `&str` error[E0308]: mismatched types - --> $DIR/lex-bad-char-literals-6.rs:10:20 + --> $DIR/lex-bad-char-literals-6.rs:15:20 | -LL | let a: usize = ""; // type error here to confirm we got past the parser +LL | let a: usize = ""; | ^^ expected usize, found reference | = note: expected type `usize` found type `&'static str` error[E0277]: can't compare `&str` with `char` - --> $DIR/lex-bad-char-literals-6.rs:8:10 + --> $DIR/lex-bad-char-literals-6.rs:12:10 | -LL | if x == z {} // no error here +LL | if x == z {} | ^^ no implementation for `&str == char` | = help: the trait `std::cmp::PartialEq` is not implemented for `&str` -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors Some errors occurred: E0277, E0308. For more information about an error, try `rustc --explain E0277`. From 4005d3a8cb082f84f6bfb8c2168387a747aabf1e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 20 Jan 2019 14:59:10 +0900 Subject: [PATCH 0194/1064] Remove whitespace --- src/test/ui/parser/lex-bad-char-literals-3.rs | 3 +-- src/test/ui/parser/lex-bad-char-literals-3.stderr | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/ui/parser/lex-bad-char-literals-3.rs b/src/test/ui/parser/lex-bad-char-literals-3.rs index efd597d11faa4..5194ff4d9354f 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.rs +++ b/src/test/ui/parser/lex-bad-char-literals-3.rs @@ -1,7 +1,6 @@ -static c: char = '●●'; +static c: char = '●●'; //~^ ERROR: character literal may only contain one codepoint - fn main() { let ch: &str = '●●'; //~^ ERROR: character literal may only contain one codepoint diff --git a/src/test/ui/parser/lex-bad-char-literals-3.stderr b/src/test/ui/parser/lex-bad-char-literals-3.stderr index 1e7a386ca8b2a..6462a3c0e57ba 100644 --- a/src/test/ui/parser/lex-bad-char-literals-3.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-3.stderr @@ -1,15 +1,15 @@ error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-3.rs:1:18 | -LL | static c: char = '●●'; +LL | static c: char = '●●'; | ^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | static c: char = "●●"; +LL | static c: char = "●●"; | ^^^^ error: character literal may only contain one codepoint - --> $DIR/lex-bad-char-literals-3.rs:6:20 + --> $DIR/lex-bad-char-literals-3.rs:5:20 | LL | let ch: &str = '●●'; | ^^^^ From b1f169fe7a19cf10f70ee2aa2513276185c70e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 00:37:06 -0800 Subject: [PATCH 0195/1064] Recover from parse errors in struct literal fields Attempt to recover from parse errors while parsing a struct's literal fields by skipping tokens until a comma or the closing brace is found. This allows errors in other fields to be reported. --- src/libsyntax/parse/parser.rs | 47 ++++++++++++++--- src/test/ui/issues/issue-52496.rs | 13 +++++ src/test/ui/issues/issue-52496.stderr | 50 +++++++++++++++++++ .../ui/parser/removed-syntax-with-1.stderr | 4 +- .../ui/parser/removed-syntax-with-2.stderr | 4 +- .../parser/struct-field-numeric-shorthand.rs | 7 ++- .../struct-field-numeric-shorthand.stderr | 22 ++++++-- 7 files changed, 132 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/issues/issue-52496.rs create mode 100644 src/test/ui/issues/issue-52496.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7e15b23127655..9b20937cf933b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -100,6 +100,7 @@ pub enum PathStyle { enum SemiColonMode { Break, Ignore, + Comma, } #[derive(Clone, Copy, PartialEq, Debug)] @@ -2656,18 +2657,37 @@ impl<'a> Parser<'a> { break; } + let mut recovery_field = None; + if let token::Ident(ident, _) = self.token { + if !self.token.is_reserved_ident() { + let mut ident = ident.clone(); + ident.span = self.span; + recovery_field = Some(ast::Field { + ident, + span: self.span, + expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()), + is_shorthand: true, + attrs: ThinVec::new(), + }); + } + } match self.parse_field() { Ok(f) => fields.push(f), Err(mut e) => { e.span_label(struct_sp, "while parsing this struct"); e.emit(); + if let Some(f) = recovery_field { + fields.push(f); + } // If the next token is a comma, then try to parse // what comes next as additional fields, rather than // bailing out until next `}`. if self.token != token::Comma { - self.recover_stmt(); - break; + self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore); + if self.token != token::Comma { + break; + } } } } @@ -2676,9 +2696,10 @@ impl<'a> Parser<'a> { &[token::CloseDelim(token::Brace)]) { Ok(()) => {} Err(mut e) => { + e.span_label(struct_sp, "while parsing this struct"); e.emit(); - self.recover_stmt(); - break; + self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore); + self.eat(&token::Comma); } } } @@ -4538,13 +4559,13 @@ impl<'a> Parser<'a> { token::CloseDelim(token::DelimToken::Brace) => { if brace_depth == 0 { debug!("recover_stmt_ return - close delim {:?}", self.token); - return; + break; } brace_depth -= 1; self.bump(); if in_block && bracket_depth == 0 && brace_depth == 0 { debug!("recover_stmt_ return - block end {:?}", self.token); - return; + break; } } token::CloseDelim(token::DelimToken::Bracket) => { @@ -4556,7 +4577,7 @@ impl<'a> Parser<'a> { } token::Eof => { debug!("recover_stmt_ return - Eof"); - return; + break; } token::Semi => { self.bump(); @@ -4564,7 +4585,17 @@ impl<'a> Parser<'a> { brace_depth == 0 && bracket_depth == 0 { debug!("recover_stmt_ return - Semi"); - return; + break; + } + } + token::Comma => { + if break_on_semi == SemiColonMode::Comma && + brace_depth == 0 && + bracket_depth == 0 { + debug!("recover_stmt_ return - Semi"); + break; + } else { + self.bump(); } } _ => { diff --git a/src/test/ui/issues/issue-52496.rs b/src/test/ui/issues/issue-52496.rs new file mode 100644 index 0000000000000..d2636b7ecb3f8 --- /dev/null +++ b/src/test/ui/issues/issue-52496.rs @@ -0,0 +1,13 @@ +struct Foo { bar: f64, baz: i64, bat: i64 } + +fn main() { + let _ = Foo { bar: .5, baz: 42 }; + //~^ ERROR expected expression + //~| ERROR missing field `bat` in initializer of `Foo` + let bar = 1.5f32; + let _ = Foo { bar.into(), bat: -1, . }; + //~^ ERROR expected one of + //~| ERROR mismatched types + //~| ERROR missing field `baz` in initializer of `Foo` + //~| ERROR expected identifier, found `.` +} diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr new file mode 100644 index 0000000000000..c98de6ffbed40 --- /dev/null +++ b/src/test/ui/issues/issue-52496.stderr @@ -0,0 +1,50 @@ +error: expected expression, found `.` + --> $DIR/issue-52496.rs:4:24 + | +LL | let _ = Foo { bar: .5, baz: 42 }; + | --- ^ expected expression + | | + | while parsing this struct + +error: expected one of `,` or `}`, found `.` + --> $DIR/issue-52496.rs:8:22 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | --- ^ expected one of `,` or `}` here + | | + | while parsing this struct + +error: expected identifier, found `.` + --> $DIR/issue-52496.rs:8:40 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | --- ^ expected identifier + | | + | while parsing this struct + +error[E0063]: missing field `bat` in initializer of `Foo` + --> $DIR/issue-52496.rs:4:13 + | +LL | let _ = Foo { bar: .5, baz: 42 }; + | ^^^ missing `bat` + +error[E0308]: mismatched types + --> $DIR/issue-52496.rs:8:19 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | ^^^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +LL | let _ = Foo { bar: bar.into().into(), bat: -1, . }; + | ^^^^^^^^^^^^^^^ + +error[E0063]: missing field `baz` in initializer of `Foo` + --> $DIR/issue-52496.rs:8:13 + | +LL | let _ = Foo { bar.into(), bat: -1, . }; + | ^^^ missing `baz` + +error: aborting due to 6 previous errors + +Some errors occurred: E0063, E0308. +For more information about an error, try `rustc --explain E0063`. diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr index 77ed4fcea517c..b5956ad339db8 100644 --- a/src/test/ui/parser/removed-syntax-with-1.stderr +++ b/src/test/ui/parser/removed-syntax-with-1.stderr @@ -2,7 +2,9 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with` --> $DIR/removed-syntax-with-1.rs:8:25 | LL | let b = S { foo: () with a }; - | ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here + | - ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here + | | + | while parsing this struct error[E0063]: missing field `bar` in initializer of `main::S` --> $DIR/removed-syntax-with-1.rs:8:13 diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr index 5642d2f45ffce..ee7560017a675 100644 --- a/src/test/ui/parser/removed-syntax-with-2.stderr +++ b/src/test/ui/parser/removed-syntax-with-2.stderr @@ -2,7 +2,9 @@ error: expected one of `,` or `}`, found `a` --> $DIR/removed-syntax-with-2.rs:8:31 | LL | let b = S { foo: (), with a }; - | ^ expected one of `,` or `}` here + | - ^ expected one of `,` or `}` here + | | + | while parsing this struct error[E0425]: cannot find value `with` in this scope --> $DIR/removed-syntax-with-2.rs:8:26 diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.rs b/src/test/ui/parser/struct-field-numeric-shorthand.rs index 914588f51e1e3..58c40b3d96a49 100644 --- a/src/test/ui/parser/struct-field-numeric-shorthand.rs +++ b/src/test/ui/parser/struct-field-numeric-shorthand.rs @@ -1,6 +1,9 @@ struct Rgb(u8, u8, u8); fn main() { - let _ = Rgb { 0, 1, 2 }; //~ ERROR expected identifier, found `0` - //~| ERROR missing fields `0`, `1`, `2` in initializer of `Rgb` + let _ = Rgb { 0, 1, 2 }; + //~^ ERROR expected identifier, found `0` + //~| ERROR expected identifier, found `1` + //~| ERROR expected identifier, found `2` + //~| ERROR missing fields `0`, `1`, `2` in initializer of `Rgb` } diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.stderr b/src/test/ui/parser/struct-field-numeric-shorthand.stderr index f5dc226934ec6..cfb1f82014754 100644 --- a/src/test/ui/parser/struct-field-numeric-shorthand.stderr +++ b/src/test/ui/parser/struct-field-numeric-shorthand.stderr @@ -1,17 +1,33 @@ error: expected identifier, found `0` --> $DIR/struct-field-numeric-shorthand.rs:4:19 | -LL | let _ = Rgb { 0, 1, 2 }; //~ ERROR expected identifier, found `0` +LL | let _ = Rgb { 0, 1, 2 }; | --- ^ expected identifier | | | while parsing this struct +error: expected identifier, found `1` + --> $DIR/struct-field-numeric-shorthand.rs:4:22 + | +LL | let _ = Rgb { 0, 1, 2 }; + | --- ^ expected identifier + | | + | while parsing this struct + +error: expected identifier, found `2` + --> $DIR/struct-field-numeric-shorthand.rs:4:25 + | +LL | let _ = Rgb { 0, 1, 2 }; + | --- ^ expected identifier + | | + | while parsing this struct + error[E0063]: missing fields `0`, `1`, `2` in initializer of `Rgb` --> $DIR/struct-field-numeric-shorthand.rs:4:13 | -LL | let _ = Rgb { 0, 1, 2 }; //~ ERROR expected identifier, found `0` +LL | let _ = Rgb { 0, 1, 2 }; | ^^^ missing `0`, `1`, `2` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0063`. From acbda76f23b8945fd8f45332352269044ecbf2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 01:49:04 -0800 Subject: [PATCH 0196/1064] Recover with suggestion from writing `.42` instead of `0.42` --- src/libsyntax/parse/parser.rs | 26 +++++++++++++++++++++++ src/test/ui/issues/issue-52496.rs | 3 ++- src/test/ui/issues/issue-52496.stderr | 30 +++++++++++++++++---------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9b20937cf933b..43a263b8a6b0e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1989,6 +1989,32 @@ impl<'a> Parser<'a> { result.unwrap() } + token::Dot if self.look_ahead(1, |t| match t { + token::Literal(parse::token::Lit::Integer(_) , None) => true, + _ => false, + }) => { // recover from `let x = .4;` + let lo = self.span; + self.bump(); + if let token::Literal( + parse::token::Lit::Integer(val), + None + ) = self.token { + self.bump(); + let sp = lo.to(self.prev_span); + let mut err = self.diagnostic() + .struct_span_err(sp, "numeric float literals must have a significant"); + err.span_suggestion_with_applicability( + sp, + "numeric float literals must have a significant", + format!("0.{}", val), + Applicability::MachineApplicable, + ); + err.emit(); + return Ok(ast::LitKind::Float(val, ast::FloatTy::F32)); + } else { + unreachable!(); + }; + } _ => { return self.unexpected_last(&self.token); } }; diff --git a/src/test/ui/issues/issue-52496.rs b/src/test/ui/issues/issue-52496.rs index d2636b7ecb3f8..2e79079267540 100644 --- a/src/test/ui/issues/issue-52496.rs +++ b/src/test/ui/issues/issue-52496.rs @@ -2,8 +2,9 @@ struct Foo { bar: f64, baz: i64, bat: i64 } fn main() { let _ = Foo { bar: .5, baz: 42 }; - //~^ ERROR expected expression + //~^ ERROR numeric float literals must have a significant //~| ERROR missing field `bat` in initializer of `Foo` + //~| ERROR mismatched types let bar = 1.5f32; let _ = Foo { bar.into(), bat: -1, . }; //~^ ERROR expected one of diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr index c98de6ffbed40..3c8056316603b 100644 --- a/src/test/ui/issues/issue-52496.stderr +++ b/src/test/ui/issues/issue-52496.stderr @@ -1,13 +1,11 @@ -error: expected expression, found `.` +error: numeric float literals must have a significant --> $DIR/issue-52496.rs:4:24 | LL | let _ = Foo { bar: .5, baz: 42 }; - | --- ^ expected expression - | | - | while parsing this struct + | ^^ help: numeric float literals must have a significant: `0.5` error: expected one of `,` or `}`, found `.` - --> $DIR/issue-52496.rs:8:22 + --> $DIR/issue-52496.rs:9:22 | LL | let _ = Foo { bar.into(), bat: -1, . }; | --- ^ expected one of `,` or `}` here @@ -15,13 +13,23 @@ LL | let _ = Foo { bar.into(), bat: -1, . }; | while parsing this struct error: expected identifier, found `.` - --> $DIR/issue-52496.rs:8:40 + --> $DIR/issue-52496.rs:9:40 | LL | let _ = Foo { bar.into(), bat: -1, . }; | --- ^ expected identifier | | | while parsing this struct +error[E0308]: mismatched types + --> $DIR/issue-52496.rs:4:24 + | +LL | let _ = Foo { bar: .5, baz: 42 }; + | ^^ expected f64, found f32 +help: change the type of the numeric literal from `f32` to `f64` + | +LL | let _ = Foo { bar: .5f64, baz: 42 }; + | ^^^^^ + error[E0063]: missing field `bat` in initializer of `Foo` --> $DIR/issue-52496.rs:4:13 | @@ -29,22 +37,22 @@ LL | let _ = Foo { bar: .5, baz: 42 }; | ^^^ missing `bat` error[E0308]: mismatched types - --> $DIR/issue-52496.rs:8:19 + --> $DIR/issue-52496.rs:9:19 | LL | let _ = Foo { bar.into(), bat: -1, . }; | ^^^ expected f64, found f32 help: you can cast an `f32` to `f64` in a lossless way | -LL | let _ = Foo { bar: bar.into().into(), bat: -1, . }; - | ^^^^^^^^^^^^^^^ +LL | let _ = Foo { bar.into().into(), bat: -1, . }; + | ^^^^^^^^^^ error[E0063]: missing field `baz` in initializer of `Foo` - --> $DIR/issue-52496.rs:8:13 + --> $DIR/issue-52496.rs:9:13 | LL | let _ = Foo { bar.into(), bat: -1, . }; | ^^^ missing `baz` -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors Some errors occurred: E0063, E0308. For more information about an error, try `rustc --explain E0063`. From ad09d7fc794500709242d5b10daa6afd263d1410 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 20 Jan 2019 10:14:26 +0000 Subject: [PATCH 0197/1064] rustdoc: Don't modify library path for doctests It shouldn't be needed anymore because doctests are no longer compiled with `prefer-dynamic`. --- src/librustdoc/test.rs | 23 +++---------------- .../rustdoc-ui/failed-doctest-output.stdout | 4 ++-- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0b9fbc81da626..f4b67771c1663 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -5,12 +5,11 @@ use rustc_lint; use rustc_driver::{self, driver, target_features, Compilation}; use rustc_driver::driver::phase_2_configure_and_expand; use rustc_metadata::cstore::CStore; -use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc::hir; use rustc::hir::intravisit; use rustc::session::{self, CompileIncomplete, config}; use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions}; -use rustc::session::search_paths::{SearchPath, PathKind}; +use rustc::session::search_paths::SearchPath; use syntax::ast; use syntax::source_map::SourceMap; use syntax::edition::Edition; @@ -21,7 +20,6 @@ use tempfile::Builder as TempFileBuilder; use testing; use std::env; -use std::ffi::OsString; use std::io::prelude::*; use std::io; use std::path::PathBuf; @@ -265,7 +263,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, } } - let (libdir, outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| { + let (outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| { let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping())); let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()), Some(source_map.clone()), @@ -304,7 +302,6 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, .expect("rustdoc needs a tempdir")) } ); - let libdir = sess.target_filesearch(PathKind::All).get_lib_path(); let mut control = driver::CompileController::basic(); let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); @@ -336,7 +333,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, Err(_) | Ok(Err(CompileIncomplete::Errored(_))) => Err(()) }; - (libdir, outdir, compile_result) + (outdir, compile_result) }); match (compile_result, compile_fail) { @@ -362,21 +359,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, if no_run { return } // Run the code! - // - // We're careful to prepend the *target* dylib search path to the child's - // environment to ensure that the target loads the right libraries at - // runtime. It would be a sad day if the *host* libraries were loaded as a - // mistake. let mut cmd = Command::new(&outdir.lock().unwrap().path().join("rust_out")); - let var = DynamicLibrary::envvar(); - let newpath = { - let path = env::var_os(var).unwrap_or(OsString::new()); - let mut path = env::split_paths(&path).collect::>(); - path.insert(0, libdir); - env::join_paths(path).unwrap() - }; - cmd.env(var, &newpath); - match cmd.output() { Err(e) => panic!("couldn't run the test: {}{}", e, if e.kind() == io::ErrorKind::PermissionDenied { diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 8af05e9ca97b1..b7617ec556d20 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -12,7 +12,7 @@ error[E0425]: cannot find value `no` in this scope 3 | no | ^^ not found in this scope -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:354:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:351:13 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ---- @@ -21,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 11)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -', src/librustdoc/test.rs:389:17 +', src/librustdoc/test.rs:372:17 failures: From 2ab6cefccfe3c5f2c97bf8bcab080a26089257e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 02:45:38 -0800 Subject: [PATCH 0198/1064] Do not suggest angle brackets when there are no type arguments --- src/librustc/hir/lowering.rs | 19 +++++++++++-------- src/test/ui/error-codes/E0214.stderr | 4 ++-- src/test/ui/issues/issue-23589.rs | 2 +- src/test/ui/issues/issue-23589.stderr | 4 ++-- src/test/ui/issues/issue-32995-2.rs | 6 +++--- src/test/ui/issues/issue-32995-2.stderr | 6 +++--- src/test/ui/issues/issue-32995.rs | 14 +++++++------- src/test/ui/issues/issue-32995.stderr | 14 +++++++------- .../unboxed-closure-sugar-used-on-struct-1.rs | 2 +- ...oxed-closure-sugar-used-on-struct-1.stderr | 7 ++----- .../unboxed-closure-sugar-used-on-struct-3.rs | 2 +- ...oxed-closure-sugar-used-on-struct-3.stderr | 4 ++-- .../unboxed-closure-sugar-used-on-struct.rs | 2 +- ...nboxed-closure-sugar-used-on-struct.stderr | 7 ++----- 14 files changed, 45 insertions(+), 48 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 9d3438289a0cd..f7af135bc7605 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1807,7 +1807,7 @@ impl<'a> LoweringContext<'a> { explicit_owner: Option, ) -> hir::PathSegment { let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args { - let msg = "parenthesized parameters may only be used with a trait"; + let msg = "parenthesized type parameters may only be used with a `Fn` trait"; match **generic_args { GenericArgs::AngleBracketed(ref data) => { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) @@ -1825,14 +1825,17 @@ impl<'a> LoweringContext<'a> { } ParenthesizedGenericArgs::Err => { let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); - err.span_label(data.span, "only traits may use parentheses"); + err.span_label(data.span, "only `Fn` traits may use parentheses"); if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { - err.span_suggestion_with_applicability( - data.span, - "use angle brackets instead", - format!("<{}>", &snippet[1..snippet.len() - 1]), - Applicability::MaybeIncorrect, - ); + // Do not suggest going from `Trait()` to `Trait<>` + if data.inputs.len() > 0 { + err.span_suggestion_with_applicability( + data.span, + "use angle brackets instead", + format!("<{}>", &snippet[1..snippet.len() - 1]), + Applicability::MaybeIncorrect, + ); + } }; err.emit(); (self.lower_angle_bracketed_parameter_data( diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr index 0172dc706ac5f..a10f2c00578c6 100644 --- a/src/test/ui/error-codes/E0214.stderr +++ b/src/test/ui/error-codes/E0214.stderr @@ -1,10 +1,10 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/E0214.rs:2:15 | LL | let v: Vec(&str) = vec!["foo"]; | ^^^^^^ | | - | only traits may use parentheses + | only `Fn` traits may use parentheses | help: use angle brackets instead: `<&str>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23589.rs b/src/test/ui/issues/issue-23589.rs index fb765e453dcd6..1c640af8d02b9 100644 --- a/src/test/ui/issues/issue-23589.rs +++ b/src/test/ui/issues/issue-23589.rs @@ -1,5 +1,5 @@ fn main() { let v: Vec(&str) = vec!['1', '2']; - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| ERROR mismatched types } diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr index 932e8eedad1ca..bc2007ba39cc6 100644 --- a/src/test/ui/issues/issue-23589.stderr +++ b/src/test/ui/issues/issue-23589.stderr @@ -1,10 +1,10 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-23589.rs:2:15 | LL | let v: Vec(&str) = vec!['1', '2']; | ^^^^^^ | | - | only traits may use parentheses + | only `Fn` traits may use parentheses | help: use angle brackets instead: `<&str>` error[E0308]: mismatched types diff --git a/src/test/ui/issues/issue-32995-2.rs b/src/test/ui/issues/issue-32995-2.rs index a4e333ec20ae0..2234f68f24629 100644 --- a/src/test/ui/issues/issue-32995-2.rs +++ b/src/test/ui/issues/issue-32995-2.rs @@ -2,11 +2,11 @@ fn main() { { fn f() {} } - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted { fn f() -> impl ::std::marker()::Send { } } - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted } @@ -14,5 +14,5 @@ fn main() { struct X; impl ::std::marker()::Copy for X {} -//~^ ERROR parenthesized parameters may only be used with a trait +//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted diff --git a/src/test/ui/issues/issue-32995-2.stderr b/src/test/ui/issues/issue-32995-2.stderr index 0ac12b78d3842..104b76cba2df9 100644 --- a/src/test/ui/issues/issue-32995-2.stderr +++ b/src/test/ui/issues/issue-32995-2.stderr @@ -1,4 +1,4 @@ -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995-2.rs:4:28 | LL | { fn f() {} } @@ -8,7 +8,7 @@ LL | { fn f() {} } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995-2.rs:8:35 | LL | { fn f() -> impl ::std::marker()::Send { } } @@ -17,7 +17,7 @@ LL | { fn f() -> impl ::std::marker()::Send { } } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995-2.rs:16:19 | LL | impl ::std::marker()::Copy for X {} diff --git a/src/test/ui/issues/issue-32995.rs b/src/test/ui/issues/issue-32995.rs index 726cc85d3f479..c32fb63f1e584 100644 --- a/src/test/ui/issues/issue-32995.rs +++ b/src/test/ui/issues/issue-32995.rs @@ -2,32 +2,32 @@ fn main() { let x: usize() = 1; - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let b: ::std::boxed()::Box<_> = Box::new(1); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let p = ::std::str::()::from_utf8(b"foo").unwrap(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let p = ::std::str::from_utf8::()(b"foo").unwrap(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let o : Box<::std::marker()::Send> = Box::new(1); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted let o : Box = Box::new(1); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted } fn foo() { let d : X() = Default::default(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| WARN previously accepted } diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr index e27f2d9553a93..97b4b7fa76ca8 100644 --- a/src/test/ui/issues/issue-32995.stderr +++ b/src/test/ui/issues/issue-32995.stderr @@ -1,4 +1,4 @@ -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:4:17 | LL | let x: usize() = 1; @@ -8,7 +8,7 @@ LL | let x: usize() = 1; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:8:24 | LL | let b: ::std::boxed()::Box<_> = Box::new(1); @@ -17,7 +17,7 @@ LL | let b: ::std::boxed()::Box<_> = Box::new(1); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:12:25 | LL | let p = ::std::str::()::from_utf8(b"foo").unwrap(); @@ -26,7 +26,7 @@ LL | let p = ::std::str::()::from_utf8(b"foo").unwrap(); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:16:36 | LL | let p = ::std::str::from_utf8::()(b"foo").unwrap(); @@ -35,7 +35,7 @@ LL | let p = ::std::str::from_utf8::()(b"foo").unwrap(); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:20:30 | LL | let o : Box<::std::marker()::Send> = Box::new(1); @@ -44,7 +44,7 @@ LL | let o : Box<::std::marker()::Send> = Box::new(1); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:24:37 | LL | let o : Box = Box::new(1); @@ -53,7 +53,7 @@ LL | let o : Box = Box::new(1); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 -error: parenthesized parameters may only be used with a trait +error: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-32995.rs:30:14 | LL | let d : X() = Default::default(); diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs index 2827e6eead5fd..c96a6fa8b6c91 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs @@ -6,7 +6,7 @@ struct Bar { fn bar() { let x: Box = panic!(); - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| ERROR wrong number of type arguments: expected 1, found 0 } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr index 87832d839b949..fa52e66fb0349 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr @@ -1,11 +1,8 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:19 | LL | let x: Box = panic!(); - | ^^ - | | - | only traits may use parentheses - | help: use angle brackets instead: `<>` + | ^^ only `Fn` traits may use parentheses error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs index 3cada322b1ef2..79ced1ecfb1a0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs @@ -12,7 +12,7 @@ fn bar() { let b = Bar::::new(); // OK let b = Bar::(isize, usize)::new(); // OK too (for the parser) - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait } fn main() {} diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr index c9cc60717a610..7d05ca55ffdb0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr @@ -1,10 +1,10 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:18 | LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) | ^^^^^^^^^^^^^^ | | - | only traits may use parentheses + | only `Fn` traits may use parentheses | help: use angle brackets instead: `` error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs index 6da53585c9c4c..1af7f55674c6a 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs @@ -5,7 +5,7 @@ struct Bar { } fn foo(b: Box) { - //~^ ERROR parenthesized parameters may only be used with a trait + //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait //~| ERROR wrong number of type arguments: expected 1, found 0 } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr index a09c2b75386eb..b34237937ee1c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr @@ -1,11 +1,8 @@ -error[E0214]: parenthesized parameters may only be used with a trait +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:18 | LL | fn foo(b: Box) { - | ^^ - | | - | only traits may use parentheses - | help: use angle brackets instead: `<>` + | ^^ only `Fn` traits may use parentheses error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15 From a3383514d9db48295124b349323379952c33a2c4 Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Mon, 10 Dec 2018 23:45:33 +0900 Subject: [PATCH 0199/1064] reduce some code repetitions --- src/librustc_lint/types.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 642681a73a8a0..6e394f78226cd 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -21,6 +21,8 @@ use syntax::source_map; use rustc::hir; +use rustc::mir::interpret::{sign_extend, truncate}; + declare_lint! { UNUSED_COMPARISONS, Warn, @@ -368,14 +370,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { let (t, actually) = match ty { ty::Int(t) => { let ity = attr::IntType::SignedInt(t); - let bits = layout::Integer::from_attr(&cx.tcx, ity).size().bits(); - let actually = (val << (128 - bits)) as i128 >> (128 - bits); + let size = layout::Integer::from_attr(&cx.tcx, ity).size(); + let actually = sign_extend(val, size); (format!("{:?}", t), actually.to_string()) } ty::Uint(t) => { let ity = attr::IntType::UnsignedInt(t); - let bits = layout::Integer::from_attr(&cx.tcx, ity).size().bits(); - let actually = (val << (128 - bits)) >> (128 - bits); + let size = layout::Integer::from_attr(&cx.tcx, ity).size(); + let actually = truncate(val, size); (format!("{:?}", t), actually.to_string()) } _ => bug!(), From b80332ed4c142496096ff2bf9aa378cc6b3bf806 Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Sun, 20 Jan 2019 10:45:25 +0900 Subject: [PATCH 0200/1064] cast the sign_extend result to i128. --- src/librustc_lint/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 6e394f78226cd..9d3275ffde2c0 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -371,7 +371,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { ty::Int(t) => { let ity = attr::IntType::SignedInt(t); let size = layout::Integer::from_attr(&cx.tcx, ity).size(); - let actually = sign_extend(val, size); + let actually = sign_extend(val, size) as i128; (format!("{:?}", t), actually.to_string()) } ty::Uint(t) => { From 5b44b3cb1b2bc2f93520fe1339d93efe8439238c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 09:11:42 -0800 Subject: [PATCH 0201/1064] review comment --- src/librustc_typeck/check/demand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 2aecc0f2ace6a..d985bdae491d0 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -495,7 +495,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.id)) { // `expr` is a literal field for a struct, only suggest if appropriate for field in fields { - if field.expr.id == expr.id { + if field.expr.id == expr.id && field.is_shorthand { // This is a field literal prefix = format!("{}: ", field.ident); break; From 2200fd3c7caf19323e7bd4cf649e4ec53d1de369 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 Jan 2019 22:25:29 +0100 Subject: [PATCH 0202/1064] Add default rust logo for documentation --- src/librustdoc/html/layout.rs | 5 ++++- src/librustdoc/html/render.rs | 4 ++++ src/librustdoc/html/static/rust-logo.png | Bin 0 -> 5758 bytes src/librustdoc/html/static_files.rs | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/librustdoc/html/static/rust-logo.png diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 987cec6fbfa96..b7af28fbcc8ae 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -177,7 +177,10 @@ pub fn render( root_path = page.root_path, css_class = page.css_class, logo = if layout.logo.is_empty() { - String::new() + format!("\ + logo", + static_root_path=static_root_path, + suffix=page.resource_suffix) } else { format!("\ logo", diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 31e06cb1a045f..d050b706f1031 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -789,6 +789,10 @@ fn write_shared( themes.insert(theme.to_owned()); } + if (*cx.shared).layout.logo.is_empty() { + write(cx.dst.join(&format!("rust-logo{}.png", cx.shared.resource_suffix)), + static_files::RUST_LOGO)?; + } write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)), static_files::BRUSH_SVG)?; write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)), diff --git a/src/librustdoc/html/static/rust-logo.png b/src/librustdoc/html/static/rust-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..74b4bd695045ebc52c21af95301adc9311ca881c GIT binary patch literal 5758 zcmV-^7J=!BP)rlOar#xVHcKR}urj-85WU}*d52ce!FO;4x1(Dd{rLvS^kzaz+Qg+43&c`E^ z2A4h%FgKT)L-C6=0SiO%&803L%dQ&ad>le)iUzvAtx3hUp3qiqE4OmtpW{`0v8nBU z+vNFwgO#K7`BHl6Lk5HT&J zd0%5WX?GeMO2>h@YkR3UyYLB!%U`9zGx2pv`bl*gj{l2(jn1Mg!nL1jDhv@mJF-Z) z67J}KBA8uxsR*X=Sf`PpG*`ff8oxRCuGi#KZ;di+0mQR!BHISEExW1CGQBlHFEkNU z(hzW6fL~TqN}IfE{LRuTaMO61)5uVoEy2s0>}~aTd9vJ#3c3NFB;T~tqib}0T!03k zRgt=rZq*e6NSNg`GPKSp8t`0%sVfTb6iOXlX|k6#hX|N!eoNB^SLi}PkbuM0isxjy z)5uUb6|B7};Xr|h82+jxduUULfQwjMPa@4>-q38f5EGn6hWupPwaF{BhvVvGa)^K@ zX|>ns>X7FY7!n%W4tV3VU&m`b2j6q4zfYf_ujx$xnS4s6M$Tce%Fe$?pCG$c!>Hop z#?j*z!PbLgoZbtiBT7$|)|75(J=<@U1f0m=D|O^qtPFkyy`D~>hq97Bm~?7zZ;%T} z8~GfW&%P^pLJ%^7Od!{jl`1wwhao}S-B~I$U^|6yiKp9x6@U^ z9zfH$!pSPMb+)nuLoTjXL7Lv!-A_+SN{tY*DG~mHtPe-SxM*{NK7?`^%<$xScZYA$WuF!hmCsQ!r$to142By6i zR=<@Ur#d=6p?*&(k|W8E5R4!7oD1TUpQKR0^3WRd4*U)$s}T6UY~iUid|pbuC%>g% ztS(Jv{65eSeo$>r$QQ{oi4?F`D;Px6XYictg4f9s*3A!1gwGnUOKM4zj3oDxHRQj^ z)Y|ewE+M-TDG+UftD4PDC(A&81g*Sp;M-cjZ~8nL?KCKmQDj*X1=ym1{JWE7Aak*; z{PEuWO-_RYxhatXum${RZk_%8)>(zw`RU#nOvckw=~mI%iMqS$*5^2V5b!xEwgCDJ zTbMI7p7Q)p_h$REg5zp|-_AR`mgVQ~06z}?UGfE|j{^Au`M($iEN4Y^r1A<~=1JAJ z`wxo2C|lL}v1#}W{7t0I>BE4FcoWu6k?{)(aAXKz50K7!5&Fq3(ZaKFm0!|oM+J=BV z@cK=A9~X7g-jtW|b@($CC^*T$$Dp^o)=L6%<&j$_46L;SbQL22`rOa~tt7n-U&#{u zrBn*$=(BWw3$nw8%B@${-o)(ZZ)1sp`u9C_BX{9LQYiRE=sd2qs>8n3-LH1%w~21I ztbb@XnQ3RO$HycRaDXy~M)FV%-k}Fq4cy1xI69TwNMFU^`75a#dJJF$s%t(C zO=(0;O{Cyx>kMPSd0sp5jidvQBe+tnpA)`sp6&7sP>T5-_n9h5ZNQ&MAoRC?1S zUIq3Ye!N21VA6<+UJFO+tZsLB1pbsr4x}#URq3-=OBt2YCcG|Y1SkUtWJINUb&rBG zpsSU%v+c(8TM+_Qgy=F0F4Xz#D41Qz{dpYv0KRGe6%Fv&6Z|O1X#LGZEP9`_bMKC0 zad85`o{6gtEsuJnaxd_p{OkP0ygl`}j?L-42?UVpls-yIX3%3=@E-o8MZhDLc5KI8 z>^oFjUZCQtme-31_B8W<4!ej~04VQ0qrMRgVt(O4+&6VTLd&ndbOe#GeesUXSm8$RWFTOJ5A{O=@B~*BwBR%g{)Lt!v@)3hHyZ** zxF1zXz(ewi&saJbnid~%HyCdu2KkX0F5w6_Km}OFe~knMt1Ge|(d^I-Q!dR?A1qMBEgLCH$8m~@I` zW8)`UHbBK@M1VUKy^N}Z|AM||e|L50m-VcHzQJ9N?H;VQ0wR`I0p$`?MAw@W^XbE% z0CkUaK#dWsPTH#&jo!~a1+7J8A^J)Luecm((N=Q*l;AIhrc8VpOZodcg6!$NZw7@Vt9Sv>Q1PKh1suQvr~p@K?GQ;-*;lb75_c3#v~b4b$4kE6`N;8FRN# z#pMG&P^?dpfyv{l%ee{k!B&RhKZZ|Bx#7Y_K@ZVzS4AuGk4)P>V(<+C{3?!(=VV#> z^uj~n1wk!JR1DGnF6JDOSb% zGeWo~$o;(HkpumGK(A{V1Y=-nC# zSe8n_Tgc9lEOVr)03X!-J|2+lI6Q>7w*=6QM|gK-0;(?k(<-X1i|(kAg4UFjUS_|k z?lAwRDe!=RMd_F9es>|>NJ&p!kUK0UxQ&L&22?!0(=Y)2nw9XJ2 zM3(Y;LRC{?#sj*@fXW1*j0j+vzpVxWev_EO0cevocA$EKQUfS_dpb6;PCiAKvAQqY z%4mO@6dFdrK(wt|0@#`RC#29Se>Htj^~t>*g=!f!QmtS819hLdap+ACyvAd zmfrO>=s=Kg{WUT8ngY+(i}l!5ouN^*i&#^iK6^z*)aEsifWNPSfN#gH_R%g0SicNt zFMQmEM*;!M%p^D#<0cdu57Q}ru0n=?T6K1(R7Jo5^mYvtTok%?Jlc>pf|x5)MSy7= zV%tcYOghMrXj52VD*#qvXfMO7JbIUa84&_T z*PWsilgpg&Z*n|lg*z7&DvhK49A;0Ef!=${pG?33Xk*=JMh4_^(g#2boSwqpeZ56C zg^UP2kbrxWf*G-v;IX>XjO5Q1hCSEw5}D5qZClr(M+J!O4fGE9WCE_PJ54Be3BCpT zflTPS;?Rl&ankMu_ohDFz&-3yJ9OkjQu}N!0Cwh-k z{>TgmtNVpHyYBan4ValaIP!;j({2$(+F}ZF2VPAcB@-(>E#}f=Xa}7~J6*9u3+hc5 zsK;>v^dEKAeqM+W(~0J}9quu55TxfIwmjO7VZlrs{&F+{{S*4<4CGw&FNjtg9~jNf zIlrfLSZ+>5FUHCro*U)MDG#pwxxoQso6rGX8KMNd&8DXMSzttMm!+>?SapE5?ZbnU z-c_vTt5M?kVwXMrivlzfeW=x6zFJ_dE9AGZ>~`--0@{wQMdzV0XlN*Q7SV4!IaESt zq50^yT>Z4%=JZNHL#)BFH_)%y`0p7gVDUrI3RC(yD1B)D?786cYTGe#J-aMEudb4m zw?RA5M~POrS9TRa|CVs4577(gH4DD+{&;~w!GWx+r2=%Y?xPtT=ly7DPK*xZDlcQ} zg@86xX!bzVcj(EOHG=T{%<3PYe$dPjW65No9OJYM*vG$eG7l&~-4zMY-7*KN=O61`#I`)1j!(y@ljGTzM0}?fVGLU$?Ln?9Cp(w9{d0?T7RNXl z2W!ggYCU#%Ym)Kvp$oJXpNfumPe-TY>39~oh#p(_R$4i!S}3&YV#F!osZFVjGo6eB z`i%tpXejpgN(1C4H-7w+Z>5!GAoF=`%0YVoA}U1iW+a>U$?V+eWExm$Z;|&sJ`_LI zHh#!j;e@l>PEio>Dyv13f$;E4ijXX~ z)1$sxGlVn+IcQ_M3rB`Bv`(txE_9%iVL;!|2KK@b;a7|Mf#0X5^HlrgJ6Q$xjGdYx zlzr^H@e-ap>;Rq3n{uW}I?l;3pxboH8__2<{6cPrr~+y}6ADQ!^v%vG_vV|)Q`JQ( za8DalZWWmtjG?EX`=vXg`U>A;Q&1TM2J@QSPK(-3G$A*XNk{H2xSwZ?vptlbofYsq zJ^i#DRxK;6D>uuL!b1`8*^M4#Q=P;28TznX2U~#AZQ6O=>}^Ne0lW*3#`Et`9Okk4 z?6%d-uk`gFA9$<0JLwfzj1{n0MTqeWY*A}@eu<`|QML8%*%iOcZPE7Kq-RKwmC=KC z|Lx!ke5bq0+BV@uC#w(~o?q&(rZ9wr8d>J~8En^y% z2znU%-$b*zNVnsnRnr>n~(ysag2rk-8fK73;m5*i>~l;9b}t zQ}yxS#iX^df3QGjgtk=z2bAl9Bq3+RPpi$90mEnHh=R=zKNKnEvBos^FE+f{UU+Ar zEodh)7J-))&=7~3uG}HG<~P;c$vXo4o$glI!1YW7{J zD9;i!RSHsE(xB`27I`%rpE6d4-(xi|mf66RwXOsx{JgT!i&sSD8cr7J-NLi% zT3|NiA>VWRl^ zwH5xSEz5vNcWCqFXGBN$dQ~;_^F8y#*}t=G0_mnXOTUitSBgJnJj3a~p>T9zV$3!y zu`0$gJXjL5ksX=G7&pk+A!NCw>`M|T?$3X_n;iTp`d`V`o4;5i<3pQt9IxY>*jcj8 z@c#DxcsVHqgM$ymU-NbO%^{PyNdN!jgQ56lze}k42l=i#eB47}N?|*bK2`Mp2a}$;#7RWswg3PC07*qoM6N<$g8zmuE&u=k literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index f340590e5fe33..bd048d2ec9742 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -51,6 +51,9 @@ pub static LICENSE_APACHE: &'static [u8] = include_bytes!("static/LICENSE-APACHE /// The contents of `LICENSE-MIT.txt`, the text of the MIT License. pub static LICENSE_MIT: &'static [u8] = include_bytes!("static/LICENSE-MIT.txt"); +/// The contents of `rust-logo.png`, the default icon of the documentation. +pub static RUST_LOGO: &'static [u8] = include_bytes!("static/rust-logo.png"); + /// The built-in themes given to every documentation site. pub mod themes { /// The "light" theme, selected by default when no setting is available. Used as the basis for From 98d4f33626c4a18092cd015b4e1cc15381989677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 16 Jan 2019 20:45:53 +0100 Subject: [PATCH 0203/1064] const_eval: Predetermine the layout of all locals when pushing a stack frame Usually the layout of any locals is required at least three times, once when it becomes live, once when it is written to, and once it is read from. By adding a cache for them, we can reduce the number of layout queries speeding up code that is heavy on const_eval. --- src/librustc_mir/const_eval.rs | 1 + src/librustc_mir/interpret/eval_context.rs | 19 ++++++++++++++----- src/librustc_mir/interpret/operand.rs | 18 ++++++------------ src/librustc_mir/interpret/snapshot.rs | 4 +++- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index f5f4048167938..105856fecc729 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -72,6 +72,7 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( ecx.stack.push(interpret::Frame { block: mir::START_BLOCK, locals: IndexVec::new(), + local_layouts: IndexVec::new(), instance, span, mir, diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 19362b6cfdb1c..b2d3328a73fe8 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1,3 +1,4 @@ +use std::cell::Cell; use std::fmt::Write; use std::mem; @@ -76,6 +77,7 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=(), Extra=()> { /// `None` represents a local that is currently dead, while a live local /// can either directly contain `Scalar` or refer to some part of an `Allocation`. pub locals: IndexVec>, + pub local_layouts: IndexVec>>>, //////////////////////////////////////////////////////////////////////////////// // Current position within the function @@ -290,9 +292,15 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, local: mir::Local ) -> EvalResult<'tcx, TyLayout<'tcx>> { - let local_ty = frame.mir.local_decls[local].ty; - let local_ty = self.monomorphize(local_ty, frame.instance.substs); - self.layout_of(local_ty) + let cell = &frame.local_layouts[local]; + if cell.get().is_none() { + let local_ty = frame.mir.local_decls[local].ty; + let local_ty = self.monomorphize(local_ty, frame.instance.substs); + let layout = self.layout_of(local_ty)?; + cell.set(Some(layout)); + } + + Ok(cell.get().unwrap()) } pub fn str_to_immediate(&mut self, s: &str) -> EvalResult<'tcx, Immediate> { @@ -426,6 +434,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // empty local array, we fill it in below, after we are inside the stack frame and // all methods actually know about the frame locals: IndexVec::new(), + local_layouts: IndexVec::from_elem_n(Default::default(), mir.local_decls.len()), span, instance, stmt: 0, @@ -464,11 +473,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc }, } // Finally, properly initialize all those that still have the dummy value - for (local, decl) in locals.iter_mut().zip(mir.local_decls.iter()) { + for (idx, local) in locals.iter_enumerated_mut() { match *local { LocalValue::Live(_) => { // This needs to be peoperly initialized. - let layout = self.layout_of(self.monomorphize(decl.ty, instance.substs))?; + let layout = self.layout_of_local(self.frame(), idx)?; *local = LocalValue::Live(self.uninit_operand(layout)?); } LocalValue::Dead => { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 04e0955ad6172..b2648480f203c 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -457,36 +457,30 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local - /// - /// When you know the layout of the local in advance, you can pass it as last argument - pub fn access_local( + fn access_local( &self, frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, local: mir::Local, - layout: Option>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { assert_ne!(local, mir::RETURN_PLACE); let op = *frame.locals[local].access()?; - let layout = from_known_layout(layout, - || self.layout_of_local(frame, local))?; + let layout = self.layout_of_local(frame, local)?; Ok(OpTy { op, layout }) } // Evaluate a place with the goal of reading from it. This lets us sometimes - // avoid allocations. If you already know the layout, you can pass it in - // to avoid looking it up again. + // avoid allocations. fn eval_place_to_op( &self, mir_place: &mir::Place<'tcx>, - layout: Option>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { use rustc::mir::Place::*; let op = match *mir_place { Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), - Local(local) => self.access_local(self.frame(), local, layout)?, + Local(local) => self.access_local(self.frame(), local)?, Projection(ref proj) => { - let op = self.eval_place_to_op(&proj.base, None)?; + let op = self.eval_place_to_op(&proj.base)?; self.operand_projection(op, &proj.elem)? } @@ -510,7 +504,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // FIXME: do some more logic on `move` to invalidate the old location Copy(ref place) | Move(ref place) => - self.eval_place_to_op(place, layout)?, + self.eval_place_to_op(place)?, Constant(ref constant) => { let layout = from_known_layout(layout, || { diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index f9ce7b4319fac..53105266b3928 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -314,13 +314,14 @@ struct FrameSnapshot<'a, 'tcx: 'a> { stmt: usize, } -impl_stable_hash_for!(impl<'tcx, 'mir: 'tcx> for struct Frame<'mir, 'tcx> { +impl_stable_hash_for!(impl<'mir, 'tcx: 'mir> for struct Frame<'mir, 'tcx> { mir, instance, span, return_to_block, return_place -> (return_place.as_ref().map(|r| &**r)), locals, + local_layouts -> _, block, stmt, extra, @@ -339,6 +340,7 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> return_to_block, return_place, locals, + local_layouts: _, block, stmt, extra: _, From ce0e5558da1279baba8c744c56bd227b4d2d29d5 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 21 Jan 2019 04:52:16 +0900 Subject: [PATCH 0204/1064] Add span for bad doc comment --- src/libsyntax/parse/parser.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7e15b23127655..3195435bba5ad 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4483,13 +4483,17 @@ impl<'a> Parser<'a> { } /// Emit an expected item after attributes error. - fn expected_item_err(&self, attrs: &[Attribute]) { + fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> { let message = match attrs.last() { Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment", _ => "expected item after attributes", }; - self.span_err(self.prev_span, message); + let mut err = self.diagnostic().struct_span_err(self.prev_span, message); + if attrs.last().unwrap().is_sugared_doc { + err.span_label(self.prev_span, "this doc comment doesn't document anything"); + } + Err(err) } /// Parse a statement. This stops just before trailing semicolons on everything but items. @@ -7636,7 +7640,7 @@ impl<'a> Parser<'a> { } None => { if !attrs.is_empty() { - self.expected_item_err(&attrs); + self.expected_item_err(&attrs)?; } self.unexpected() @@ -7699,7 +7703,7 @@ impl<'a> Parser<'a> { } if !attributes_allowed && !attrs.is_empty() { - self.expected_item_err(&attrs); + self.expected_item_err(&attrs)?; } Ok(None) } From b97c9641f51c6897ddded240c87e84f065f55588 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 21 Jan 2019 04:52:30 +0900 Subject: [PATCH 0205/1064] Fix tests --- src/test/ui/parser/doc-before-eof.stderr | 2 +- src/test/ui/parser/doc-before-extern-rbrace.stderr | 2 +- src/test/ui/parser/doc-before-mod-rbrace.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/ui/parser/doc-before-eof.stderr b/src/test/ui/parser/doc-before-eof.stderr index b764e9f7ae102..5809d64e80678 100644 --- a/src/test/ui/parser/doc-before-eof.stderr +++ b/src/test/ui/parser/doc-before-eof.stderr @@ -2,7 +2,7 @@ error: expected item after doc comment --> $DIR/doc-before-eof.rs:3:1 | LL | /// hi //~ERROR expected item after doc comment - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-extern-rbrace.stderr b/src/test/ui/parser/doc-before-extern-rbrace.stderr index 47fab7b40f4cd..8cc9c916a7afd 100644 --- a/src/test/ui/parser/doc-before-extern-rbrace.stderr +++ b/src/test/ui/parser/doc-before-extern-rbrace.stderr @@ -2,7 +2,7 @@ error: expected item after doc comment --> $DIR/doc-before-extern-rbrace.rs:2:5 | LL | /// hi - | ^^^^^^ + | ^^^^^^ this doc comment doesn't document anything error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-mod-rbrace.stderr b/src/test/ui/parser/doc-before-mod-rbrace.stderr index 41c1d706b3a7e..4eaf351f676c8 100644 --- a/src/test/ui/parser/doc-before-mod-rbrace.stderr +++ b/src/test/ui/parser/doc-before-mod-rbrace.stderr @@ -2,7 +2,7 @@ error: expected item after doc comment --> $DIR/doc-before-mod-rbrace.rs:4:5 | LL | /// document - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ this doc comment doesn't document anything error: aborting due to previous error From b5d167f58a423cb0003714eceeb72172d1726473 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 Jan 2019 22:27:09 +0100 Subject: [PATCH 0206/1064] Add default favicon for documentation --- src/librustdoc/html/layout.rs | 4 +++- src/librustdoc/html/render.rs | 6 ++++-- src/librustdoc/html/static/favicon.ico | Bin 0 -> 23229 bytes src/librustdoc/html/static_files.rs | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 src/librustdoc/html/static/favicon.ico diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index b7af28fbcc8ae..c34dcbbb672e9 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -191,7 +191,9 @@ pub fn render( description = page.description, keywords = page.keywords, favicon = if layout.favicon.is_empty() { - String::new() + format!(r#""#, + static_root_path=static_root_path, + suffix=page.resource_suffix) } else { format!(r#""#, layout.favicon) }, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d050b706f1031..b64ac9509631b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -793,6 +793,10 @@ fn write_shared( write(cx.dst.join(&format!("rust-logo{}.png", cx.shared.resource_suffix)), static_files::RUST_LOGO)?; } + if (*cx.shared).layout.favicon.is_empty() { + write(cx.dst.join(&format!("favicon{}.ico", cx.shared.resource_suffix)), + static_files::RUST_FAVICON)?; + } write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)), static_files::BRUSH_SVG)?; write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)), @@ -1999,8 +2003,6 @@ impl Context { themes.push(PathBuf::from("settings.css")); let mut layout = self.shared.layout.clone(); layout.krate = String::new(); - layout.logo = String::new(); - layout.favicon = String::new(); try_err!(layout::render(&mut w, &layout, &page, &sidebar, &settings, self.shared.css_file_extension.is_some(), diff --git a/src/librustdoc/html/static/favicon.ico b/src/librustdoc/html/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b8ad23769ac8d06eb5973bfb3d2acbf385240f98 GIT binary patch literal 23229 zcmeHvc|28H|Nn80c^;Zf$(*SSWu`JD(V;RG>6p@BE^{)JxkzQmP>~SI(4dfxF(slB z5)PR%L}d!)x0ZYM{hrRHTlcx&;g8>bJ@5Nj>$5(?d#%0p+H0?)2Zf?QQKG7KHQB}0m;J^5csADJ;Ux=>OHY2a((G>5y2ee}sw(wi6T`3%ZKV`TrFyPF# zt&A6CYgvuX>mI3Y4iczsT`%x-^H<4K|4iTE5A( zW;pTj)bS=iyy&B$FLZTz6sqXlO(QRPaGH6uCn|hQsGKO}S@_hL9R`fA>g_4(3L74) z=Mhj5{S+k^;9h$yrFNWoZS_9MkBle@w7uv}e0VO(;)O~BN_s=I~%uGO3%LKPp+NC_VOjyiikz7Wk2r6 z?y}oVo2#KHaFYG54CD?V{U0f#D6deJ(I;O>8=(|PlNQygb8S{K1o10}pnz1B`0*i@@Sg+EVqi&Sp>fWfI-G0X^^q3yS z7IcPUOtbmMGonZH6ft-&(L(KE8mn4Qj0<&B11j?I=GmZA?qTQH-`$art_&Zcb9PQo zG0QgY8$X9r!P{{pK4q7mw;k*Tp%SM}MKtFE!;oThbJs zORbMuJC$t^=d_P``$YQNa31F8=u<4JeOjkJXsPq;bqM%)JjBVO(}HWxT)Rh0-c{gn z)s)>SmgjB)Iwm;tBNMrrXVw+p@v^sZ)Ft3>#T*Zt!bf;^-!%`}l4o64g0Xbh#d+fl z2nP4|PddH*ek-}Q0c%SyjhRbgaoiL|-QXf1VQPD@dt&7L({KlR{m6%oT=&oTJT&!_ zqpV87@R;29lTpQt3>x!spW?3)0~*VR#*xSQUCx*uV3n7fe$wEeA0}3G+4S6;(^0D` zr{_vBu6S!+@gUJay@HLKba{5S=}%;PZa=_?b>+@?bQjTpYVa zQxR2AD(!hy-&dB4S(rSj(hw07+1Qn;gE+|6Q9Y^juK`zGqWNJ z&Q^uw#K`wwZkX?3cAhLei_KHfQec)?Md3f{;wR~`UEqSt`N6B!Z$F8RW=ANwbDs~r z9d73)pocEO%%8w_5 zINB&w?%vVRYAXt;d^GeG+pC5*!RrJ@hx!kH$F8pGV2z6vMI}+Zz_j=_-}Y+vtS&s} z5|Sj{l*eyb>EY=7MEUIjOLt4X%i(4Zwzi+15&oh&Zcf-w$S^4hp$&C86_Mf=*|U$( zg6BxUoJ6;lRep1(I5?gif4^i<%cSZI%@n2jY3*T?dR6_aLsP3t;xP9qL_)4Q7NmUT zcfxqwt`PIF=Bo%l$u%>U&`urbD>LB5sS^7%t=R;#T|An@F=Ap88RN*@G=hfA|#>lbNTDBHD3Z^a}2)@(uJa2 z1pM(erS6|p2vxGNB0;N$`3hoF6)o{1iLdGkMO*LEi99`+`Le6t^4^89vUuyuAG2;OiPC>^h?*>zPN>H#OS^pWzyR5Y+sBDTF%C4V`Te#=bIs?Ji;C($TzLB zoV=gS1zsem65Qvnqh35J5}$C!@)TapH(NXLpNt+qG-;`Hktse>dlxMq9cF$-B8Xe& zVGUO0*$ws!w|MAyP`Tlwj`LhewJltkeOhnInQ2D%Y&(7$FWx=6PgzY4c4Hc49@koR zlAxG3%O`waMu66LeJCb#??>w=3qH-y;(~mSFjMrEDcj?8xVi0j1ehM^HTI8CyY`Hy z%)Q=)uJ{GNrTERxgQ#||W*xn3|0?#VASWgZi#;56egl`+`_-=S&~2%OiFZxTehUO(tOY$aNH^|NWHbP;A^jVcUNCvoA-d}y$1dY zzHxp1_nEv51-mYPH7mO(fSI%`xAu1u&u=IbO~;f3O?~}TD9h4*#$welW;aVU6<)@2 zvg?k#QIaO5_M?49caCmK&J65$G=$lFSFOiYfZIyKoi8i(>o(k@T!}O8*ldOLwf5r) z&-LCj3bV;e7iC`2+<9GWx95HR&;;ycXuaC~o105|Jm#45W-0HN9QZ&j@Fr70PPOmG zrqJa@< z2HvsFF=t{30z9;=;SiP3`fQ(GM;He3cdL*W=p06eca&dD5apWqHHu+8Yg}j^}?nbJe$b zK`eWZ=x3#ociv6U$Fm=DSbFG5?lnFh9@3jjJ1^*x$?>ow{A6L+&PPLbX2o4;H`7^+ z`&i@mcBJRVRnbb4(06r}@^2TtBk29}|sh_~cUeIQofh+od5^Y_A?ZI&k_# zZhC5qH%04)W1SE3gJN~vrG+8+uf0m|H`Szq*Ba&0W$ zK63L-sne||uRCfq$WHUC?|jert;(lYWxEd#UHWGR+@_38SHe}9n_|7gxOduJ;P|Rh zQ<#I&TX{sEM)qp((-Bsy3+`5LJ~OG+eXvSPj^Lmugi7S)8^wE!bYXx!-G;a z*63s5t^zq$;azq88_ljh*WVCI`<0zJJ+Z(_bK1qo%*o(c%leIIk1#5H;6696yBAbW zROWQDBws4J5^}|w30EYfK>f5KFZLKSN;J4EAu`SSa>F&HFOAM8mAn0}X3kr9Dp>nT zD+DWQ)#}Y_>*p7xZW+A9!|r9yC*P8w4qgxkCB+pyQVaC4wg!@V*gfA_^tP!m9dC%n zUCb+%quVTGQ;p5;pu_4lRJv)Zh8|JfMH#1iq|(xIvN&DAbnUwVt+iFwi9HX{ijuv0 zhou%yNg9=owzZ`XWIkbHT=BVThvq)}5>PCS;2r!RFF%H|Jg7hv3x%Vv*DHT} zUHu?1Fi^3*aNesqHa~o1Ab+B|KrB$A=h5!fLB$6z$(^jsS^H{;5oI|koHuJMdBd5# zCRE*YO|a4#j>`cb9@I?MYU5i}g2#NCTf#eQ+rY$MpA`Ej($udZ=X<6OPwZj48nODvHWt_U=_#x2<5Vbm+aSf_Jk@ z{`J$9H?7m&GLm zE_%10XB50$&w|SwOPe`~RoPByW!2Nbl~^XxLs+mhE8V-oTr_vfaavD?9BV(1ql1+N zLVlVfs1=)I4p1xdm-{W~577B^?aEa#d=fI~ET|r>x6@zioncM*3N`f1x;LRVxBh98sF}~*6f|XRp|$CVXg5b$ta6odify782stoPy)kjV{wsceTYVk& zr4nAsEbUWTTu~fqgR6iqX243q=z77~cpZ*Mr#hb1Q?5%4%Mr4`aIw zzt`d4VtbP;-Dev^v9=8Qsm_^b2Zug&{p0d+RVvL^G++1k91J(kXKhs$FLrH8)4n%i zgc&xuoLe1Uy4u&w_-2v{%gi-XKjn&y8~Jypbi4K&SmziY+tXm){ld)a$rnQc);-H* z^$0`O#fPmMJdfu_So1Qx#KE(A0uj;zQY#%n}T%5Y*^Z4le<^p;`!}&Xk`0^ zoo9Dv8EO;uqiXNA=*qD?pgDK1N2^9LhR*8C5w46d1;YYPg^Rc@@W?YbMATDRZfwt@ zJw-DTBY)00gHR^@=^^b*=%#aawyRuLiL|ff+}F1AfM$j)N6}gCHC`8ejImcJ?|;s| zIkCUeaL$E5i@PVwc&t(w&%e!P>cFL&b(`oT&E|dfNbGeJo!T_JYkyk>*8r>6c<-brx&Z+8#s2NR7~kKJ{HeuIe8^Fb`$gN^?B$L zpXQRtEJ@WJo;4>D>7VL0RZN!-d8%|625X)bemwG30#Ajv%}Z2?)_Ttx{Ap9Z?>?o+ znqe~q`115EYhFh+zn8sa;<{GAS#|ave!u198G+=~ROz)fFL~m77;$ujM?=k1el6SCab~{;X6L@krdJ2VWrtk4_ z8uTt>v`Fbwbz@;|kI&ipuCvixAAOrE726ae#JqbdyYiWEOV{~xx@LEe#^&yE`&Qtm z6t0;ZmSUZBu|0WellM?@{6^&%O>u|3+=q2Mxhz-Lc-rJ@dNpfXy359S&SuZwm#Wz* z{JPDM$3BGhqxgEw-dS-RCQn%@T*Ip;6FjWQ4`rMnPQhF0~*~*If`S%=C238dNibP{LQBgiHBP%ym?vk zW~WtSDR15K_?)i&SwzHWe50j%!MU;r->=-13k|`#3B=<#@}li-ispMn6?W8k^e$BB zSPeufJkfgW(QwR&LJ~7CNcZNG&3a$|_gKm53e9~I>w8qIDD}6CNEG=rYuM>*zc3WS z(T18)&o_vfJVda{OO&|qI-K!5wp~Fgsrp9mtsYgaO9aO~N7>ScR+bJ4TDl+9e=u6l zwX3Z${A^CaH=*9qNbuh5WV|>m+}tr@Upf?w-?lkPM$GaOdruJKHAQ)Cv-2%^+ty+jx)D8lvH$C53ab(BT(Bok5&{vR#};~-ytXd z>juN8y7%QBc;m2lE(lHIEThn;*k%tOl@-=6zdLjDpygpD7<{Q;^IW^>GZF>o!UF@7@v6jp(-<9 zZmmSR*rooeci9O+ZcWdgquMud4EK69x8&38ssgJ&w=t(Vey&$VhyvCOx{Z&!wmE_KL&i6bd2gJbEt`s<12KxdkG4^=|v8e;P=9 zdjLI?!l6_heuA;)xWF)&xdp97%5BMK1e4NJxs7>*l)b=$nrYP7u%mmMWKC97YX4z< zvynBTZkt`W$K!D?hFWE3Me`@v+EIjlwkM%|y1&ji*OqB;IZ=-OOAguaQ`PFWJ^h zGdG%vhKoQ!*b=CxthDum+YETs*9SVI=S0OD^Ve|lSg#PFdiz4NRU&}Tr+MzeJB!Pj z0Z$L0UkGhz9N+L#nKFRmVPFqO^aT4cpXMs7F5~1-uOwXSbAe%pu)f>HOj$9Pk0kTc z1uJW{mgfqj6?F5`>$*2zKl>tWyd%7VMx}n2W2>o79b2iv&&(#` zxf)~qVR{o~>5#<4bpD5L342#uV1JmUP$h$RqH1nFf2FI%acliZ$YlAuUJqK)LQa?c z6!$mT4k);DH&P|9nzi2WS>%8P^8>~~mDoY2ikt@grtsOzHv;N<1YF+N&V?v4ygKQa zb@k$~{56JFl%kvgmA8?CeEHoVu3}W4kA#a|hsOzU>3a3{j<+wm^eRW?+w%(d{JKSE(kx^NH6M!5)n~ge|);7U{jM^piaeO77TbB zML9p&dHsMn9lbLq;rNKQUp9l9W(+e0K}(+cRK(MXY2^V-i*<_sebf30>fCz%{dDw4 zqYVw;qzW`_@RZP2)_Uh@E>D#qln{KQdjI*Nv_0$@>D4(KTm(#UG+}OXPB_9g-0-^A zX4Y*n4Y48lN+!LZ-bh5cga{d3$W(qVr*4XieILjWK|gqOebji0#nys|k2Jz7x$5+c z!`oS|&Ai@6v%8TyGu05AKBKzon2lf7iR?tpcLqw_-jM;A(xchD`$Y?xrI{00-i;X_ z+*p3U3>^K@SVZ+bl}P+xx!IF1+i%aPmPh#stGXU0oPC~;j@F!n)$A2>t7pyTm|HYE z`>mf+8q^iLHG#(~R;Kz=^Lh%j}}(Fzh^UYmm!OdbCT5DKve=lQr+zjA_tuoJ#q$ck|cOD5-#? zf_XMOw~MCr+3L)%N5H33Wdh})mCvjDwd(q^Y<%;4e78+aP-1&`67FzDFk5$xs^QD< za}jrQFi9aU)A~l)#Z4g`J8wUZU0FN8h)X->r+J>~t%A*`riAP%)2s&0YrX2miQsu^ z&N^&&ZR=;DYh&8?uP4*FT;^e&H4(e?HKg_IXStTu^&wc>>f&=*=L^{hm!4iQ>kf;zMrNgr8hFGc6zg zu^KHZc=a{b7TvF}eIjaa=~1>WZ-F68k6m@*RIg>i)Vh^>j2E=#)GlmJuH8@7+BB-g z#AGns3%-Edx#BLR(?-lRFkElvv9_jgSM4@FxYKLw8{5@s%?QH!&>h7xO83^OELt4n z5vXch9Wz@L)^&4rydVchPf6Ou-3w7o11oGB4q3N$RwI^n_9LZ=)qa51)O53^D$t^6+GDQy+`lMrp$-OknTlY^0Xe-(mz5Kwm zhP$jsD^A3Ge(#C{at>VK%oO9J`4O+<@+bXwhkmZJ+I>eb7VC_^t}$^`6iXFh;Wfw= zIv8QslCL`SLOrW%?cVSdMID?MH%h$SXIhorg^vZ&mXq93e;Kac)z%I zJZmZvUv4=WBH#CzhUZ}Zkvxi=D&5)@+YCm)9F!`M?vYK1ye0A|kSXTnp(Jm%8BUiN zQzExG=UpKuTH10_hE5i821mrs54z!X;u_#DwV@hx+_ny%1WqJWf1+byz24y zl0jR4ZH|!OIV+_qU#sR33Cqd(LhcXroQah4YUOIDTR#r+n&CS=v(yu(1iJ@BvAs@` zyPr-K0CwOIp%}i3zZ75Q-cpiqVUW{zJ{U^-gr@S zgS8=Q8IIBe3A86KdA?ZfT-kGZRh*-R0pn$YV`eJ{_w~-`n^q^1ZIxo|3)Vk(vSEF- z)(_>y79`Nu6m&IF3|nn;=c}2bD0V$EY{p#hl@y(cLe2DjtX}Lh{Nq}>_s`lMqR6!JuS~ymb8Nr(qY+kJG)1OO z_w!-zW)7K@mY0>7?W|iWWv5Rvv}2UkB*a~NS9oK;v4C0$3!6yu3!7t8l@IA=iad5U zVQtx6c0KJsw?e(oc=epQQcQ}B?o*G7N``>u&)GJYwDZClg+xZC)>f)0t1|@ZNz1&$ z7JiV+$#*_8jw@k#G{jdrxh!C`}G(teoo)wb8ITM&z@?Eja?1D zF*anpD&|yHYrJM%4Zrdi)%;M?jx}Z+bywdUv!FP+Zl1a1;{3bv>wTABKib61RzDWF zE2Lp%D9^DilFiv}Gu@3J)bo_7RJN-KZ+m#3V<-muSXnFcP7_1E=0u5a^W%G#NH-F}IW^_V?$=shKfneNqg`gZGSMV)fkvi}md-|&b%!&+(cW=D2 zvYZ^Ca~u&%v}<8jjB#!K+Ihrs^C!dFaEsHt{bN=B=uk#~@Wnr7qm+8lWj}4wVW}+T*IFwToOa((RZ6#ujC{raUjyhW%vozZdX%~68vcU`qq>}lN@ ztvM~7qt?#}jF(V4ZeqOd8pi0=OohMUxZxXTtBS>#(J6WtyHNAnQ`s$|`Br0%{Vp4L zFN`_t(0R|=_LX9+v$U9{y(%dwf4=GNivnp;i%4Nf)JW8ga;}~xoVg}-qLLPKa;vbU$o-m8#NZq%(d6gw_%iS&MCW+adJzOes)PhzV!r#Fx-9pcpyi~ zwpGW|FSPS>am|JwVs2_|)OgRz#3Z$8`C`QaP4%%yslo?z9)Ta`QM%e#t=k&7p!J{( ze(^`)0N~I1%Uuf#3#k8(|NSvo?*9Cao{vw^2|yk30p)yv0+PBqv_b0si6oyh|0EXR zq6Q!UeSus7Fb6ONpaftHut0=paft6K=}Qql9d<}#uogQ{``~i2eHo(Id=h>MJ)fP+@U{= z1!KbUng2%q0mK~t2Iu8s1pJ%)0bhRrI6lV!ZUHQpcOJA=0GtAV^FRuKj|f;c0Pq7S z2Y|NA#mNJ0Fc-|}zg%B_b^Z|JkmpJPdP{(Q0N54{ux7bjFyKT8VhNO}HhCd~U)3rn__`ZVoM*e61qLp42fNp3Bd&o@*+9A9V33Z^&1c03XU-mYC#~+D_ND#9I02$|{WEW_sfEgHRQ`|1(vj7h!vpc z1|Ypxkee}VMtCC<>Oh+^06G5=pgRNb=l99a_#^R_k{|{t7t(SWXrqA~;04OE0OC9PpX>%lnIH3(wF<&!IGk`inph--+vB{bxLgZR?;d2?U7xPN4fspGkCZe+S<| z(8i0H+l8bZa$A9LfH4t39lSvMK@$6EP;Mfr|19@^+6Lzf6_LYJVovh@{<&5myb($C z699hX^X)(7^{f6@AqRK?4yHu@ zUTToDe2Kh}%kO-@|Lpt(p3}g8MEc7Yd0&@ugfRgM0hYUWzjJ;9&qz)K1OO~`u2c;4 zY)kR@Cpr)duA3zQiiJq=>gCpwIwZsHY$MQ0A{3m@-k@G z0U!X7bBA>Ya(kryEB6%If*5}}2O`S_-|=!tT%r#K=x&hM1(CKBZDc_^^j(TKqWd?_ zZ~Z|I*oVJ6KYs>nJOMTXBmqDU@Jtz*7m=W>2mozf03aO6WgcjQxnNFz@_r-rUmbtM zo;YT3E|TY4u3ka(f%l^OH~a!fb1ql@hy2eFd2|8!ck}8!uz_p2Fu)|ha{YvQ7z@UP z<^Rs#j|4${xVBOPz<1owIKejfJInW9uww-_FeZ%s!#eYCjz4)UkgE>>?nw>;knUUI z9vuSdA9>xE=mUNK$9_LufJ)sgue+W!+kMqn*;bi@%!}> z{ej;=|0{n#K>j@c|N4J@8~rzr1q=_r!-(>`{~z^!`$hR3N9_;WzoSr#l7K?dz&awY zv5Zr}I(p0eRwzUKzjp&UkM{q*bqkOv|L-U$Sr!(?q2yawm;rJeg_=Qu9WjvOP|iTf zwB!Z)_@ZU!aNH>70B^<7Q8C7pJxex5l#*A^0xcqC z7yt!80uitbbqc>62pEEqTEyS^fVhkRuK?hlG!p=>zeNDZJMcbH2iu?xv}OFexPO-) z#DM4Z767UM$eRDF68b=2`2W(gA+`qy$#2z_ggfU>OFmfJ0$q((3IPjjreM~<9jywi=9oQTPfct3p z-H7b5VXOplTk`zC2HtNt=A`|G=Tx=;@EyPS8zp%h(mJq#&&L>m0|5LML;3+@!q|V# zhb8jE`GVL(3HPUPEb0Irk>**h4D4XPs{vr&VLr&4G^PdOOPU|pz-J83S<<<7AF=s6 z31cp01L7giCgcEP!yJpxCSnhLfet>iq&$DAjKl!G`~dJ=`d9p3k@6+xhwH|#`2Jvn zeA?w|~x_djzZdPI`8!7|j7UO-0! z@R{5W)J*`^0+6l?NS-i~_!PhfuIEVGCL}(zA<-|k6LoM+fLIN1iQER%`;i!+Y){q> zb5W4wCtYt~4sOJEsr+QI5YFV%6^Q}tc>&DH{1V9WlRkH=5Z`~8AD)+y|LzIDc}Y2v z<|iNjE5KG1a`=b&VIEJU51_09kPm?5Cm(;(`8NRUt^s@_86U)NQ9?cG1#H=u;z{EF z71%@ri~u09Navpd(8Ff}ww(olB>t2F&&6^G9scA-2r{ z*+MMCXKI>Q{(-}<=!l#cfbB_uSgCEq_po(Dkt54n&z@Vk;2j|apfki|T(I4IyhNKB*- z?3UVpbOHTF#O7Be@Yw(WeUbj)LHVcq4c*8VgbOH+8-Av z!}$i!d}aWU+))1Q{);5Wa{JG55a%L*9st}|z_V32Zy}Ez05Jfh&p6Br`wjc^%ll6f z9+AKg##nAnN`N*^q77+ZNqv5M|4ot~&IbzsIA_V@!+JXa=^m5R2KqqXKlhtRTtt%3 zKSWP1K@9k8!f}Rc6!I(=fif~Kuncp;xV}QbGStccU`$d0ZOi~S z07&O5eCI)s>YxoXi7UMK&=>g)AHEw;1Bd{iiGXFOL-wN3_RkogjO2yS4L@mY(lTrV zfHsiN4cG=G>@UI(?zOLxK@`+E0pNUuZKV5gWULVXrQ}xN1J|#m+K_REZN30-eMRgV zKp6+H8sIfi51&g907qiI3rKi>riguk`)0%+t{;%^0}>q`+QAFxrU0NX#8;w@)E|jM zDi1F@|KShc9ncqYfHuMar2fUAz77EX22uh5ZRP=>4%)&x^i3p|n}Mt%mSG$G=4%9i zYYws=LA?|}AOI{wU()*rb<1G}v;_e`KFB;;oX?3rfVPYC zhd6Ge^LGNY1ptVUj1}xJ Date: Sun, 20 Jan 2019 20:26:46 +0100 Subject: [PATCH 0207/1064] Add "dereference boxed value" suggestion. This commit adds a `help: consider dereferencing the boxed value` suggestion to discriminants of match statements when the match arms have type `T` and the discriminant has type `Box`. --- src/librustc/infer/error_reporting/mod.rs | 21 +++++++- src/test/ui/issues/issue-57741-1.rs | 18 +++++++ src/test/ui/issues/issue-57741-1.stderr | 25 ++++++++++ src/test/ui/issues/issue-57741.fixed | 31 ++++++++++++ src/test/ui/issues/issue-57741.rs | 31 ++++++++++++ src/test/ui/issues/issue-57741.stderr | 59 +++++++++++++++++++++++ 6 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issues/issue-57741-1.rs create mode 100644 src/test/ui/issues/issue-57741-1.stderr create mode 100644 src/test/ui/issues/issue-57741.fixed create mode 100644 src/test/ui/issues/issue-57741.rs create mode 100644 src/test/ui/issues/issue-57741.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 2995b25308d4c..35f6e6aa610ad 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -485,12 +485,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>) { + fn note_error_origin( + &self, + err: &mut DiagnosticBuilder<'tcx>, + cause: &ObligationCause<'tcx>, + exp_found: Option>>, + ) { match cause.code { ObligationCauseCode::MatchExpressionArmPattern { span, ty } => { if ty.is_suggestable() { // don't show type `_` err.span_label(span, format!("this match expression has type `{}`", ty)); } + if let Some(ty::error::ExpectedFound { found, .. }) = exp_found { + if ty.is_box() && ty.boxed_ty() == found { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + err.span_suggestion_with_applicability( + span, + "consider dereferencing the boxed value", + format!("*{}", snippet), + Applicability::MachineApplicable, + ); + } + } + } } ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source { hir::MatchSource::IfLetDesugar { .. } => { @@ -1013,7 +1030,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // It reads better to have the error origin as the final // thing. - self.note_error_origin(diag, &cause); + self.note_error_origin(diag, &cause, exp_found); } /// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate, diff --git a/src/test/ui/issues/issue-57741-1.rs b/src/test/ui/issues/issue-57741-1.rs new file mode 100644 index 0000000000000..d0aae23b2fce6 --- /dev/null +++ b/src/test/ui/issues/issue-57741-1.rs @@ -0,0 +1,18 @@ +#![allow(warnings)] + +// This tests that the `help: consider dereferencing the boxed value` suggestion isn't made +// because the box doesn't deref to the type of the arm. + +enum S { + A { a: usize }, + B { b: usize }, +} + +fn main() { + let x = Box::new(3u32); + let y = match x { + S::A { a } | S::B { b: a } => a, + //~^ ERROR mismatched types [E0308] + //~^^ ERROR mismatched types [E0308] + }; +} diff --git a/src/test/ui/issues/issue-57741-1.stderr b/src/test/ui/issues/issue-57741-1.stderr new file mode 100644 index 0000000000000..d36424b83b4e1 --- /dev/null +++ b/src/test/ui/issues/issue-57741-1.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/issue-57741-1.rs:14:9 + | +LL | let y = match x { + | - this match expression has type `std::boxed::Box` +LL | S::A { a } | S::B { b: a } => a, + | ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` + | + = note: expected type `std::boxed::Box` + found type `S` + +error[E0308]: mismatched types + --> $DIR/issue-57741-1.rs:14:22 + | +LL | let y = match x { + | - this match expression has type `std::boxed::Box` +LL | S::A { a } | S::B { b: a } => a, + | ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` + | + = note: expected type `std::boxed::Box` + found type `S` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-57741.fixed b/src/test/ui/issues/issue-57741.fixed new file mode 100644 index 0000000000000..4cae080033ca2 --- /dev/null +++ b/src/test/ui/issues/issue-57741.fixed @@ -0,0 +1,31 @@ +// run-rustfix + +#![allow(warnings)] + +// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works. + +enum S { + A { a: usize }, + B { b: usize }, +} + +enum T { + A(usize), + B(usize), +} + +fn main() { + let x = Box::new(T::A(3)); + let y = match *x { + T::A(a) | T::B(a) => a, + //~^ ERROR mismatched types [E0308] + //~^^ ERROR mismatched types [E0308] + }; + + let x = Box::new(S::A { a: 3 }); + let y = match *x { + S::A { a } | S::B { b: a } => a, + //~^ ERROR mismatched types [E0308] + //~^^ ERROR mismatched types [E0308] + }; +} diff --git a/src/test/ui/issues/issue-57741.rs b/src/test/ui/issues/issue-57741.rs new file mode 100644 index 0000000000000..e2658295af791 --- /dev/null +++ b/src/test/ui/issues/issue-57741.rs @@ -0,0 +1,31 @@ +// run-rustfix + +#![allow(warnings)] + +// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works. + +enum S { + A { a: usize }, + B { b: usize }, +} + +enum T { + A(usize), + B(usize), +} + +fn main() { + let x = Box::new(T::A(3)); + let y = match x { + T::A(a) | T::B(a) => a, + //~^ ERROR mismatched types [E0308] + //~^^ ERROR mismatched types [E0308] + }; + + let x = Box::new(S::A { a: 3 }); + let y = match x { + S::A { a } | S::B { b: a } => a, + //~^ ERROR mismatched types [E0308] + //~^^ ERROR mismatched types [E0308] + }; +} diff --git a/src/test/ui/issues/issue-57741.stderr b/src/test/ui/issues/issue-57741.stderr new file mode 100644 index 0000000000000..a26b1d20ca3cb --- /dev/null +++ b/src/test/ui/issues/issue-57741.stderr @@ -0,0 +1,59 @@ +error[E0308]: mismatched types + --> $DIR/issue-57741.rs:20:9 + | +LL | let y = match x { + | - + | | + | this match expression has type `std::boxed::Box` + | help: consider dereferencing the boxed value: `*x` +LL | T::A(a) | T::B(a) => a, + | ^^^^^^^ expected struct `std::boxed::Box`, found enum `T` + | + = note: expected type `std::boxed::Box` + found type `T` + +error[E0308]: mismatched types + --> $DIR/issue-57741.rs:20:19 + | +LL | let y = match x { + | - + | | + | this match expression has type `std::boxed::Box` + | help: consider dereferencing the boxed value: `*x` +LL | T::A(a) | T::B(a) => a, + | ^^^^^^^ expected struct `std::boxed::Box`, found enum `T` + | + = note: expected type `std::boxed::Box` + found type `T` + +error[E0308]: mismatched types + --> $DIR/issue-57741.rs:27:9 + | +LL | let y = match x { + | - + | | + | this match expression has type `std::boxed::Box` + | help: consider dereferencing the boxed value: `*x` +LL | S::A { a } | S::B { b: a } => a, + | ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` + | + = note: expected type `std::boxed::Box` + found type `S` + +error[E0308]: mismatched types + --> $DIR/issue-57741.rs:27:22 + | +LL | let y = match x { + | - + | | + | this match expression has type `std::boxed::Box` + | help: consider dereferencing the boxed value: `*x` +LL | S::A { a } | S::B { b: a } => a, + | ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` + | + = note: expected type `std::boxed::Box` + found type `S` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From c4b8df5df25aa8859d751ec0a7af3e7a0d6d699a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Nov 2018 13:05:06 -0800 Subject: [PATCH 0208/1064] Remove unnecessary dummy span checks The emitter already verifies wether a given span note or span label can be emitted to the output. If it can't, because it is a dummy span, it will be either elided for labels or emitted as an unspanned note/help when applicable. --- src/librustc_errors/emitter.rs | 2 +- src/librustc_resolve/lib.rs | 14 +++++--------- src/libsyntax_pos/lib.rs | 10 ++++++++++ src/test/ui/consts/const-size_of-cycle.stderr | 4 ++-- src/test/ui/impl-trait/auto-trait-leak.stderr | 6 +++--- src/test/ui/issues/issue-26548.stderr | 2 +- src/test/ui/issues/issue-44415.stderr | 4 ++-- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 0443b2228e5b4..25d09a33c154f 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -959,7 +959,7 @@ impl EmitterWriter { Style::MainHeaderMsg }; - if msp.primary_spans().is_empty() && msp.span_labels().is_empty() && is_secondary + if !msp.has_primary_spans() && !msp.has_span_labels() && is_secondary && !self.short_message { // This is a secondary message with no span info for _ in 0..max_line_num_len { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 1cd44042c1de9..4c9347afa611d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -5013,11 +5013,7 @@ impl<'a> Resolver<'a> { )) } - if b.span.is_dummy() { - err.note(¬e_msg); - } else { - err.span_note(b.span, ¬e_msg); - } + err.span_note(b.span, ¬e_msg); for (i, help_msg) in help_msgs.iter().enumerate() { let or = if i == 0 { "" } else { "or " }; err.help(&format!("{}{}", or, help_msg)); @@ -5132,10 +5128,10 @@ impl<'a> Resolver<'a> { container)); err.span_label(span, format!("`{}` re{} here", name, new_participle)); - if !old_binding.span.is_dummy() { - err.span_label(self.session.source_map().def_span(old_binding.span), - format!("previous {} of the {} `{}` here", old_noun, old_kind, name)); - } + err.span_label( + self.session.source_map().def_span(old_binding.span), + format!("previous {} of the {} `{}` here", old_noun, old_kind, name), + ); // See https://github.com/rust-lang/rust/issues/32354 if old_binding.is_import() || new_binding.is_import() { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 6a41a93f0b4fd..240b86d142ab7 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -668,6 +668,11 @@ impl MultiSpan { &self.primary_spans } + /// Returns wether any of the primary spans is displayable. + pub fn has_primary_spans(&self) -> bool { + self.primary_spans.iter().any(|sp| *sp != DUMMY_SP) + } + /// Returns `true` if this contains only a dummy primary span with any hygienic context. pub fn is_dummy(&self) -> bool { let mut is_dummy = true; @@ -726,6 +731,11 @@ impl MultiSpan { span_labels } + + /// Returns wether any of the span labels is displayable. + pub fn has_span_labels(&self) -> bool { + self.span_labels.iter().any(|(sp, _)| *sp != DUMMY_SP) + } } impl From for MultiSpan { diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 8f9498e834d8f..8f8eb38e93873 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -9,8 +9,8 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... | LL | intrinsics::size_of::() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires computing layout of `Foo`... -note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... + = note: ...which requires computing layout of `Foo`... + = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`... --> $DIR/const-size_of-cycle.rs:6:17 | diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 4acc400f8e799..b936fed85f48e 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -9,7 +9,7 @@ note: ...which requires processing `cycle1`... | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... + = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires processing `cycle2::{{impl-Trait}}`... --> $DIR/auto-trait-leak.rs:23:16 | @@ -20,7 +20,7 @@ note: ...which requires processing `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... + = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:3:1 @@ -45,7 +45,7 @@ note: ...which requires processing `cycle1`... | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... + = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires processing `cycle2::{{impl-Trait}}`... --> $DIR/auto-trait-leak.rs:23:16 | diff --git a/src/test/ui/issues/issue-26548.stderr b/src/test/ui/issues/issue-26548.stderr index 84604f31d1e7f..ff197eeeb0fe9 100644 --- a/src/test/ui/issues/issue-26548.stderr +++ b/src/test/ui/issues/issue-26548.stderr @@ -1,6 +1,6 @@ error[E0391]: cycle detected when computing layout of `std::option::Option` | -note: ...which requires computing layout of `S`... + = note: ...which requires computing layout of `S`... = note: ...which again requires computing layout of `std::option::Option`, completing the cycle note: cycle used when processing `main` --> $DIR/issue-26548.rs:9:1 diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr index 441f1b2a06960..3f377fd27e7db 100644 --- a/src/test/ui/issues/issue-44415.stderr +++ b/src/test/ui/issues/issue-44415.stderr @@ -9,8 +9,8 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires computing layout of `Foo`... -note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... + = note: ...which requires computing layout of `Foo`... + = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`... --> $DIR/issue-44415.rs:6:17 | From 8f4da0e7ee7cc5039e6f419c7482198d94d04eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 13:53:13 -0800 Subject: [PATCH 0209/1064] Use is_dummy instead of comparing against DUMMY_SP --- src/libsyntax_pos/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 240b86d142ab7..7f52d1335f728 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -670,7 +670,7 @@ impl MultiSpan { /// Returns wether any of the primary spans is displayable. pub fn has_primary_spans(&self) -> bool { - self.primary_spans.iter().any(|sp| *sp != DUMMY_SP) + self.primary_spans.iter().any(|sp| !sp.is_dummy()) } /// Returns `true` if this contains only a dummy primary span with any hygienic context. @@ -734,7 +734,7 @@ impl MultiSpan { /// Returns wether any of the span labels is displayable. pub fn has_span_labels(&self) -> bool { - self.span_labels.iter().any(|(sp, _)| *sp != DUMMY_SP) + self.span_labels.iter().any(|(sp, _)| !sp.is_dummy()) } } From e387597a8f789ab6e37e6ce1bf67c8c45d4827c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 13:59:35 -0800 Subject: [PATCH 0210/1064] Reword message for incorrect float literal --- src/libsyntax/parse/parser.rs | 4 ++-- src/test/ui/issues/issue-52496.rs | 2 +- src/test/ui/issues/issue-52496.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 43a263b8a6b0e..fe6fa5e97d721 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2002,10 +2002,10 @@ impl<'a> Parser<'a> { self.bump(); let sp = lo.to(self.prev_span); let mut err = self.diagnostic() - .struct_span_err(sp, "numeric float literals must have a significant"); + .struct_span_err(sp, "float literals must have an integer part"); err.span_suggestion_with_applicability( sp, - "numeric float literals must have a significant", + "must have an integer part", format!("0.{}", val), Applicability::MachineApplicable, ); diff --git a/src/test/ui/issues/issue-52496.rs b/src/test/ui/issues/issue-52496.rs index 2e79079267540..e734e9bc51332 100644 --- a/src/test/ui/issues/issue-52496.rs +++ b/src/test/ui/issues/issue-52496.rs @@ -2,7 +2,7 @@ struct Foo { bar: f64, baz: i64, bat: i64 } fn main() { let _ = Foo { bar: .5, baz: 42 }; - //~^ ERROR numeric float literals must have a significant + //~^ ERROR float literals must have an integer part //~| ERROR missing field `bat` in initializer of `Foo` //~| ERROR mismatched types let bar = 1.5f32; diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr index 3c8056316603b..e69b9b7c87f40 100644 --- a/src/test/ui/issues/issue-52496.stderr +++ b/src/test/ui/issues/issue-52496.stderr @@ -1,8 +1,8 @@ -error: numeric float literals must have a significant +error: float literals must have an integer part --> $DIR/issue-52496.rs:4:24 | LL | let _ = Foo { bar: .5, baz: 42 }; - | ^^ help: numeric float literals must have a significant: `0.5` + | ^^ help: must have an integer part: `0.5` error: expected one of `,` or `}`, found `.` --> $DIR/issue-52496.rs:9:22 From 15bad8bbfd3125b1e94d04f274910e24d0bb63eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 14:25:53 -0800 Subject: [PATCH 0211/1064] Extend incorrect float literal recovery to account for suffixes --- src/libsyntax/parse/parser.rs | 20 +++++++-- src/test/ui/issues/issue-52496.rs | 1 - src/test/ui/issues/issue-52496.stderr | 20 +++------ .../ui/suggestions/recover-invalid-float.rs | 11 +++++ .../suggestions/recover-invalid-float.stderr | 42 +++++++++++++++++++ 5 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 src/test/ui/suggestions/recover-invalid-float.rs create mode 100644 src/test/ui/suggestions/recover-invalid-float.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fe6fa5e97d721..038d949d24aa6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1990,15 +1990,23 @@ impl<'a> Parser<'a> { result.unwrap() } token::Dot if self.look_ahead(1, |t| match t { - token::Literal(parse::token::Lit::Integer(_) , None) => true, + token::Literal(parse::token::Lit::Integer(_) , _) => true, _ => false, }) => { // recover from `let x = .4;` let lo = self.span; self.bump(); if let token::Literal( parse::token::Lit::Integer(val), - None + suffix, ) = self.token { + let suffix = suffix.and_then(|s| { + let s = s.as_str().get(); + if ["f32", "f64"].contains(&s) { + Some(s) + } else { + None + } + }).unwrap_or(""); self.bump(); let sp = lo.to(self.prev_span); let mut err = self.diagnostic() @@ -2006,11 +2014,15 @@ impl<'a> Parser<'a> { err.span_suggestion_with_applicability( sp, "must have an integer part", - format!("0.{}", val), + format!("0.{}{}", val, suffix), Applicability::MachineApplicable, ); err.emit(); - return Ok(ast::LitKind::Float(val, ast::FloatTy::F32)); + return Ok(match suffix { + "f32" => ast::LitKind::Float(val, ast::FloatTy::F32), + "f64" => ast::LitKind::Float(val, ast::FloatTy::F64), + _ => ast::LitKind::FloatUnsuffixed(val), + }); } else { unreachable!(); }; diff --git a/src/test/ui/issues/issue-52496.rs b/src/test/ui/issues/issue-52496.rs index e734e9bc51332..e9ffeaf6c8901 100644 --- a/src/test/ui/issues/issue-52496.rs +++ b/src/test/ui/issues/issue-52496.rs @@ -4,7 +4,6 @@ fn main() { let _ = Foo { bar: .5, baz: 42 }; //~^ ERROR float literals must have an integer part //~| ERROR missing field `bat` in initializer of `Foo` - //~| ERROR mismatched types let bar = 1.5f32; let _ = Foo { bar.into(), bat: -1, . }; //~^ ERROR expected one of diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr index e69b9b7c87f40..12fe7e7fc1f05 100644 --- a/src/test/ui/issues/issue-52496.stderr +++ b/src/test/ui/issues/issue-52496.stderr @@ -5,7 +5,7 @@ LL | let _ = Foo { bar: .5, baz: 42 }; | ^^ help: must have an integer part: `0.5` error: expected one of `,` or `}`, found `.` - --> $DIR/issue-52496.rs:9:22 + --> $DIR/issue-52496.rs:8:22 | LL | let _ = Foo { bar.into(), bat: -1, . }; | --- ^ expected one of `,` or `}` here @@ -13,23 +13,13 @@ LL | let _ = Foo { bar.into(), bat: -1, . }; | while parsing this struct error: expected identifier, found `.` - --> $DIR/issue-52496.rs:9:40 + --> $DIR/issue-52496.rs:8:40 | LL | let _ = Foo { bar.into(), bat: -1, . }; | --- ^ expected identifier | | | while parsing this struct -error[E0308]: mismatched types - --> $DIR/issue-52496.rs:4:24 - | -LL | let _ = Foo { bar: .5, baz: 42 }; - | ^^ expected f64, found f32 -help: change the type of the numeric literal from `f32` to `f64` - | -LL | let _ = Foo { bar: .5f64, baz: 42 }; - | ^^^^^ - error[E0063]: missing field `bat` in initializer of `Foo` --> $DIR/issue-52496.rs:4:13 | @@ -37,7 +27,7 @@ LL | let _ = Foo { bar: .5, baz: 42 }; | ^^^ missing `bat` error[E0308]: mismatched types - --> $DIR/issue-52496.rs:9:19 + --> $DIR/issue-52496.rs:8:19 | LL | let _ = Foo { bar.into(), bat: -1, . }; | ^^^ expected f64, found f32 @@ -47,12 +37,12 @@ LL | let _ = Foo { bar.into().into(), bat: -1, . }; | ^^^^^^^^^^ error[E0063]: missing field `baz` in initializer of `Foo` - --> $DIR/issue-52496.rs:9:13 + --> $DIR/issue-52496.rs:8:13 | LL | let _ = Foo { bar.into(), bat: -1, . }; | ^^^ missing `baz` -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors Some errors occurred: E0063, E0308. For more information about an error, try `rustc --explain E0063`. diff --git a/src/test/ui/suggestions/recover-invalid-float.rs b/src/test/ui/suggestions/recover-invalid-float.rs new file mode 100644 index 0000000000000..506ef8900b881 --- /dev/null +++ b/src/test/ui/suggestions/recover-invalid-float.rs @@ -0,0 +1,11 @@ +fn main() { + let _: usize = .3; + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types + let _: usize = .42f32; + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types + let _: usize = .5f64; + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} diff --git a/src/test/ui/suggestions/recover-invalid-float.stderr b/src/test/ui/suggestions/recover-invalid-float.stderr new file mode 100644 index 0000000000000..c464676b444cc --- /dev/null +++ b/src/test/ui/suggestions/recover-invalid-float.stderr @@ -0,0 +1,42 @@ +error: float literals must have an integer part + --> $DIR/recover-invalid-float.rs:2:20 + | +LL | let _: usize = .3; + | ^^ help: must have an integer part: `0.3` + +error: float literals must have an integer part + --> $DIR/recover-invalid-float.rs:5:20 + | +LL | let _: usize = .42f32; + | ^^^^^^ help: must have an integer part: `0.42f32` + +error: float literals must have an integer part + --> $DIR/recover-invalid-float.rs:8:20 + | +LL | let _: usize = .5f64; + | ^^^^^ help: must have an integer part: `0.5f64` + +error[E0308]: mismatched types + --> $DIR/recover-invalid-float.rs:2:20 + | +LL | let _: usize = .3; + | ^^ expected usize, found floating-point number + | + = note: expected type `usize` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-invalid-float.rs:5:20 + | +LL | let _: usize = .42f32; + | ^^^^^^ expected usize, found f32 + +error[E0308]: mismatched types + --> $DIR/recover-invalid-float.rs:8:20 + | +LL | let _: usize = .5f64; + | ^^^^^ expected usize, found f64 + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. From defa61f3fb2612358b57c206c5e16da2751e6deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 15:16:36 -0800 Subject: [PATCH 0212/1064] Tweak field parse error recovery --- src/libsyntax/parse/parser.rs | 25 +++++-------------- src/test/ui/issues/issue-52496.rs | 3 +-- src/test/ui/issues/issue-52496.stderr | 19 +++----------- src/test/ui/parser/removed-syntax-with-1.rs | 2 +- .../ui/parser/removed-syntax-with-1.stderr | 4 +-- src/test/ui/parser/removed-syntax-with-2.rs | 3 +-- .../ui/parser/removed-syntax-with-2.stderr | 19 ++++---------- 7 files changed, 20 insertions(+), 55 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 038d949d24aa6..a2d3595b47206 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2695,28 +2695,12 @@ impl<'a> Parser<'a> { break; } - let mut recovery_field = None; - if let token::Ident(ident, _) = self.token { - if !self.token.is_reserved_ident() { - let mut ident = ident.clone(); - ident.span = self.span; - recovery_field = Some(ast::Field { - ident, - span: self.span, - expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()), - is_shorthand: true, - attrs: ThinVec::new(), - }); - } - } + let mut parsed_field = None; match self.parse_field() { - Ok(f) => fields.push(f), + Ok(f) => parsed_field = Some(f), Err(mut e) => { e.span_label(struct_sp, "while parsing this struct"); e.emit(); - if let Some(f) = recovery_field { - fields.push(f); - } // If the next token is a comma, then try to parse // what comes next as additional fields, rather than @@ -2732,7 +2716,10 @@ impl<'a> Parser<'a> { match self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) { - Ok(()) => {} + Ok(()) => if let Some(f) = parsed_field { + // only include the field if there's no parse error + fields.push(f); + } Err(mut e) => { e.span_label(struct_sp, "while parsing this struct"); e.emit(); diff --git a/src/test/ui/issues/issue-52496.rs b/src/test/ui/issues/issue-52496.rs index e9ffeaf6c8901..4e9453653735a 100644 --- a/src/test/ui/issues/issue-52496.rs +++ b/src/test/ui/issues/issue-52496.rs @@ -7,7 +7,6 @@ fn main() { let bar = 1.5f32; let _ = Foo { bar.into(), bat: -1, . }; //~^ ERROR expected one of - //~| ERROR mismatched types - //~| ERROR missing field `baz` in initializer of `Foo` + //~| ERROR missing fields `bar`, `baz` in initializer of `Foo` //~| ERROR expected identifier, found `.` } diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr index 12fe7e7fc1f05..43009a15bd49a 100644 --- a/src/test/ui/issues/issue-52496.stderr +++ b/src/test/ui/issues/issue-52496.stderr @@ -26,23 +26,12 @@ error[E0063]: missing field `bat` in initializer of `Foo` LL | let _ = Foo { bar: .5, baz: 42 }; | ^^^ missing `bat` -error[E0308]: mismatched types - --> $DIR/issue-52496.rs:8:19 - | -LL | let _ = Foo { bar.into(), bat: -1, . }; - | ^^^ expected f64, found f32 -help: you can cast an `f32` to `f64` in a lossless way - | -LL | let _ = Foo { bar.into().into(), bat: -1, . }; - | ^^^^^^^^^^ - -error[E0063]: missing field `baz` in initializer of `Foo` +error[E0063]: missing fields `bar`, `baz` in initializer of `Foo` --> $DIR/issue-52496.rs:8:13 | LL | let _ = Foo { bar.into(), bat: -1, . }; - | ^^^ missing `baz` + | ^^^ missing `bar`, `baz` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors occurred: E0063, E0308. -For more information about an error, try `rustc --explain E0063`. +For more information about this error, try `rustc --explain E0063`. diff --git a/src/test/ui/parser/removed-syntax-with-1.rs b/src/test/ui/parser/removed-syntax-with-1.rs index 57cbe8d5be655..add024ea3907f 100644 --- a/src/test/ui/parser/removed-syntax-with-1.rs +++ b/src/test/ui/parser/removed-syntax-with-1.rs @@ -7,5 +7,5 @@ fn main() { let a = S { foo: (), bar: () }; let b = S { foo: () with a }; //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with` - //~| ERROR missing field `bar` in initializer of `main::S` + //~| ERROR missing fields `bar`, `foo` in initializer of `main::S` } diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr index b5956ad339db8..aae29efa85e54 100644 --- a/src/test/ui/parser/removed-syntax-with-1.stderr +++ b/src/test/ui/parser/removed-syntax-with-1.stderr @@ -6,11 +6,11 @@ LL | let b = S { foo: () with a }; | | | while parsing this struct -error[E0063]: missing field `bar` in initializer of `main::S` +error[E0063]: missing fields `bar`, `foo` in initializer of `main::S` --> $DIR/removed-syntax-with-1.rs:8:13 | LL | let b = S { foo: () with a }; - | ^ missing `bar` + | ^ missing `bar`, `foo` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/removed-syntax-with-2.rs b/src/test/ui/parser/removed-syntax-with-2.rs index 11db391c5489a..f666da49696ba 100644 --- a/src/test/ui/parser/removed-syntax-with-2.rs +++ b/src/test/ui/parser/removed-syntax-with-2.rs @@ -7,6 +7,5 @@ fn main() { let a = S { foo: (), bar: () }; let b = S { foo: (), with a }; //~^ ERROR expected one of `,` or `}`, found `a` - //~| ERROR cannot find value `with` in this scope - //~| ERROR struct `main::S` has no field named `with` + //~| ERROR missing field `bar` in initializer of `main::S` } diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr index ee7560017a675..7717b49d3a2c7 100644 --- a/src/test/ui/parser/removed-syntax-with-2.stderr +++ b/src/test/ui/parser/removed-syntax-with-2.stderr @@ -6,21 +6,12 @@ LL | let b = S { foo: (), with a }; | | | while parsing this struct -error[E0425]: cannot find value `with` in this scope - --> $DIR/removed-syntax-with-2.rs:8:26 +error[E0063]: missing field `bar` in initializer of `main::S` + --> $DIR/removed-syntax-with-2.rs:8:13 | LL | let b = S { foo: (), with a }; - | ^^^^ not found in this scope + | ^ missing `bar` -error[E0560]: struct `main::S` has no field named `with` - --> $DIR/removed-syntax-with-2.rs:8:26 - | -LL | let b = S { foo: (), with a }; - | ^^^^ `main::S` does not have this field - | - = note: available fields are: `foo`, `bar` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0425, E0560. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0063`. From c949d8ee69268c5c176c89834782b2654e0766ad Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 20 Jan 2019 15:31:43 -0800 Subject: [PATCH 0213/1064] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index ffe65875fd050..907c0febe7045 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit ffe65875fd05018599ad07e7389e99050c7915be +Subproject commit 907c0febe7045fa02dff2a35c5e36d3bd59ea50d From 3ecbe1efa02b68f62e4646b6cb853f24ad0615a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 17:14:15 -0800 Subject: [PATCH 0214/1064] Add regression test for #54582 --- src/test/ui/issues/issue-54582.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/ui/issues/issue-54582.rs diff --git a/src/test/ui/issues/issue-54582.rs b/src/test/ui/issues/issue-54582.rs new file mode 100644 index 0000000000000..c2dbf361911b5 --- /dev/null +++ b/src/test/ui/issues/issue-54582.rs @@ -0,0 +1,16 @@ +// run-pass + +pub trait Stage: Sync {} + +pub enum Enum { + A, + B, +} + +impl Stage for Enum {} + +pub static ARRAY: [(&Stage, &str); 1] = [ + (&Enum::A, ""), +]; + +fn main() {} From 8c4a7a97016fc83fae232f60b5378853bc1d710b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 21 Jan 2019 02:58:57 +0100 Subject: [PATCH 0215/1064] submodules: update clippy from 1b89724b to 1838bfe5 Changes: ```` Fixing typo in CONTRIBUTING.md Fix breakage due to rust-lang/rust#57651 Run rustfmt Fixed breakage due to rust-lang/rust#57489 Fix breakage due to rust-lang/rust#57755 Catch up with `format_args` change Fix bad `while_let_on_iterator` suggestion. rustup https://github.com/rust-lang/rust/pull/57747 Fixing issues pointed out by dogfood tests. Update to collect all the files then throw the error. Adding a test for checking if test files are missing. Remove bors.toml add applicability to lint name suggestion ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 1b89724b4889a..1838bfe5a9ff9 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 1b89724b4889aef631b40d52c0943bdc28e04d1d +Subproject commit 1838bfe5a9ff951ffd716e4632156113d95d14a4 From e33f7f7de1df090f890063296608dca65be55ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 18:42:10 -0800 Subject: [PATCH 0216/1064] Explain type mismatch cause pointing to return type when it is `impl Trait` --- src/librustc_typeck/check/coercion.rs | 29 +++++++++++++++---- src/test/ui/impl-trait/equality.stderr | 5 +++- ...type-err-cause-on-impl-trait-return.stderr | 14 +++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index dd63b4f20fa55..e3aae21584c21 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1199,7 +1199,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> (self.final_ty.unwrap_or(self.expected_ty), expression_ty) }; - let reason_label = "expected because of this statement"; let mut db; match cause.code { ObligationCauseCode::ReturnNoExpression => { @@ -1244,9 +1243,19 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> // as prior return coercions would not be relevant (#57664). let parent_id = fcx.tcx.hir().get_parent_node(blk_id); let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); - if fcx.get_node_fn_decl(parent).is_some() && !pointing_at_return_type { + if let (Some((fn_decl, _, _)), false) = ( + fcx.get_node_fn_decl(parent), + pointing_at_return_type, + ) { if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { - db.span_label(*sp, reason_label); + db.span_label( + fn_decl.output.span(), + "expected because this return type...", + ); + db.span_label(*sp, format!( + "...is found to be `{}` here", + fcx.resolve_type_vars_with_obligations(expected), + )); } } } @@ -1254,16 +1263,26 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> db = fcx.report_mismatched_types(cause, expected, found, err); let _id = fcx.tcx.hir().get_parent_node(_id); let mut pointing_at_return_type = false; + let mut return_sp = None; if let Some((fn_decl, can_suggest)) = fcx.get_fn_decl(_id) { pointing_at_return_type = fcx.suggest_missing_return_type( &mut db, &fn_decl, expected, found, can_suggest); + if !pointing_at_return_type { + return_sp = Some(fn_decl.output.span()); // `impl Trait` return type + } } if let (Some(sp), false) = ( fcx.ret_coercion_span.borrow().as_ref(), pointing_at_return_type, ) { - if !sp.overlaps(cause.span) { - db.span_label(*sp, reason_label); + if let Some(return_sp) = return_sp { + db.span_label(return_sp, "expected because this return type..."); + db.span_label( *sp, format!( + "...is found to be `{}` here", + fcx.resolve_type_vars_with_obligations(expected), + )); + } else if !sp.overlaps(cause.span) { + db.span_label(*sp, "expected because of this statement"); } } } diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 57bd70de7c68f..6cd9d07748c27 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -1,8 +1,11 @@ error[E0308]: mismatched types --> $DIR/equality.rs:15:5 | +LL | fn two(x: bool) -> impl Foo { + | -------- expected because this return type... +LL | if x { LL | return 1_i32; - | ----- expected because of this statement + | ----- ...is found to be `i32` here LL | } LL | 0_u32 | ^^^^^ expected i32, found u32 diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 62da0787b02a9..5ebe00e624fc1 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -1,8 +1,11 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 | +LL | fn foo() -> impl std::fmt::Display { + | ---------------------- expected because this return type... +LL | if false { LL | return 0i32; - | ---- expected because of this statement + | ---- ...is found to be `i32` here LL | } LL | 1u32 | ^^^^ expected i32, found u32 @@ -13,8 +16,11 @@ LL | 1u32 error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 | +LL | fn bar() -> impl std::fmt::Display { + | ---------------------- expected because this return type... +LL | if false { LL | return 0i32; - | ---- expected because of this statement + | ---- ...is found to be `i32` here LL | } else { LL | return 1u32; | ^^^^ expected i32, found u32 @@ -25,10 +31,12 @@ LL | return 1u32; error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5 | +LL | fn baz() -> impl std::fmt::Display { + | ---------------------- expected because this return type... LL | / if false { LL | | //~^ ERROR mismatched types LL | | return 0i32; - | | ---- expected because of this statement + | | ---- ...is found to be `i32` here LL | | } else { LL | | 1u32 LL | | } From 45a95b512c6fb491518d6a3f4b667d6dd82cd56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 20 Jan 2019 19:37:38 -0800 Subject: [PATCH 0217/1064] Use structured suggestion in stead of notes --- src/librustc_typeck/check/method/suggest.rs | 14 ++++++++++++-- src/libsyntax/parse/parser.rs | 13 ++++++++++--- src/test/ui/auto-ref-slice-plus-ref.stderr | 3 +-- src/test/ui/block-result/issue-3563.stderr | 4 +--- src/test/ui/empty/empty-struct-braces-expr.stderr | 10 ++++------ src/test/ui/issues/issue-23217.stderr | 5 ++--- src/test/ui/issues/issue-28344.stderr | 6 ++---- src/test/ui/issues/issue-28971.stderr | 7 ++++--- .../result-deref-err.stderr | 3 +-- src/test/ui/parser/issue-17718-const-mut.rs | 2 +- src/test/ui/parser/issue-17718-const-mut.stderr | 6 +++--- src/test/ui/suggestions/suggest-methods.stderr | 12 +++--------- 12 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 23bcd88d6afb5..f71a163cee261 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -304,7 +304,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); if let Some(suggestion) = suggestion { // enum variant - err.help(&format!("did you mean `{}`?", suggestion)); + err.span_suggestion_with_applicability( + item_name.span, + "did you mean", + suggestion.to_string(), + Applicability::MaybeIncorrect, + ); } err } @@ -440,7 +445,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if let Some(lev_candidate) = lev_candidate { - err.help(&format!("did you mean `{}`?", lev_candidate.ident)); + err.span_suggestion_with_applicability( + span, + "did you mean", + lev_candidate.ident.to_string(), + Applicability::MaybeIncorrect, + ); } err.emit(); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7e15b23127655..d4a3411f463d0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7271,9 +7271,16 @@ impl<'a> Parser<'a> { // CONST ITEM if self.eat_keyword(keywords::Mut) { let prev_span = self.prev_span; - self.diagnostic().struct_span_err(prev_span, "const globals cannot be mutable") - .help("did you mean to declare a static?") - .emit(); + let mut err = self.diagnostic() + .struct_span_err(prev_span, "const globals cannot be mutable"); + err.span_label(prev_span, "cannot be mutable"); + err.span_suggestion_with_applicability( + const_span, + "you might want to declare a static instead", + "static".to_owned(), + Applicability::MaybeIncorrect, + ); + err.emit(); } let (ident, item_, extra_attrs) = self.parse_item_const(None)?; let prev_span = self.prev_span; diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index ab57fec0e7337..356e24d18a78f 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -2,12 +2,11 @@ error[E0599]: no method named `test_mut` found for type `std::vec::Vec<{integer} --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); //~ ERROR no method named `test_mut` found - | ^^^^^^^^ + | ^^^^^^^^ help: did you mean: `get_mut` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `test_mut`, perhaps you need to implement it: candidate #1: `MyIter` - = help: did you mean `get_mut`? error[E0599]: no method named `test` found for type `std::vec::Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 diff --git a/src/test/ui/block-result/issue-3563.stderr b/src/test/ui/block-result/issue-3563.stderr index 7f386630de590..a6346a5233f4c 100644 --- a/src/test/ui/block-result/issue-3563.stderr +++ b/src/test/ui/block-result/issue-3563.stderr @@ -2,9 +2,7 @@ error[E0599]: no method named `b` found for type `&Self` in the current scope --> $DIR/issue-3563.rs:3:17 | LL | || self.b() - | ^ - | - = help: did you mean `a`? + | ^ help: did you mean: `a` error: aborting due to previous error diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index e595e0ccb9293..19844503a4804 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -51,20 +51,18 @@ error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the | LL | let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type | ----^^^^^^ - | | + | | | + | | help: did you mean: `XEmpty3` | variant not found in `empty_struct::XE` - | - = help: did you mean `XEmpty3`? error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:23:19 | LL | let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type | ----^^^^^^ - | | + | | | + | | help: did you mean: `XEmpty3` | variant not found in `empty_struct::XE` - | - = help: did you mean `XEmpty3`? error: aborting due to 8 previous errors diff --git a/src/test/ui/issues/issue-23217.stderr b/src/test/ui/issues/issue-23217.stderr index 208d0cc499a80..9cad002036fff 100644 --- a/src/test/ui/issues/issue-23217.stderr +++ b/src/test/ui/issues/issue-23217.stderr @@ -5,10 +5,9 @@ LL | pub enum SomeEnum { | ----------------- variant `A` not found here LL | B = SomeEnum::A, | ----------^ - | | + | | | + | | help: did you mean: `B` | variant not found in `SomeEnum` - | - = help: did you mean `B`? error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 146ebad6ce175..b6f520c644b32 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -11,8 +11,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | --------^^^^^ | | | function or associated item not found in `dyn std::ops::BitXor<_>` - | - = help: did you mean `bitxor`? + | help: did you mean: `bitxor` error[E0191]: the value of the associated type `Output` (from the trait `std::ops::BitXor`) must be specified --> $DIR/issue-28344.rs:8:13 @@ -27,8 +26,7 @@ LL | let g = BitXor::bitor; | --------^^^^^ | | | function or associated item not found in `dyn std::ops::BitXor<_>` - | - = help: did you mean `bitxor`? + | help: did you mean: `bitxor` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-28971.stderr b/src/test/ui/issues/issue-28971.stderr index d5dbd5f64885c..77d0b53ad216b 100644 --- a/src/test/ui/issues/issue-28971.stderr +++ b/src/test/ui/issues/issue-28971.stderr @@ -5,9 +5,10 @@ LL | enum Foo { | -------- variant `Baz` not found here ... LL | Foo::Baz(..) => (), - | -----^^^---- variant not found in `Foo` - | - = help: did you mean `Bar`? + | -----^^^---- + | | | + | | help: did you mean: `Bar` + | variant not found in `Foo` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr index 99c4a5b03b320..96d6814b0fe93 100644 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr @@ -2,11 +2,10 @@ error[E0599]: no method named `deref_err` found for type `std::result::Result<_, --> $DIR/result-deref-err.rs:4:28 | LL | let _result = &Err(41).deref_err(); - | ^^^^^^^^^ + | ^^^^^^^^^ help: did you mean: `deref_ok` | = note: the method `deref_err` exists but the following trait bounds were not satisfied: `{integer} : std::ops::Deref` - = help: did you mean `deref_ok`? error: aborting due to previous error diff --git a/src/test/ui/parser/issue-17718-const-mut.rs b/src/test/ui/parser/issue-17718-const-mut.rs index 4e74516d6b6fb..795a8c7631d9a 100644 --- a/src/test/ui/parser/issue-17718-const-mut.rs +++ b/src/test/ui/parser/issue-17718-const-mut.rs @@ -1,6 +1,6 @@ const mut //~ ERROR: const globals cannot be mutable -//~^ HELP did you mean to declare a static? +//~^^ HELP you might want to declare a static instead FOO: usize = 3; fn main() { diff --git a/src/test/ui/parser/issue-17718-const-mut.stderr b/src/test/ui/parser/issue-17718-const-mut.stderr index 29a65ebe41889..19f9fe19ef5ab 100644 --- a/src/test/ui/parser/issue-17718-const-mut.stderr +++ b/src/test/ui/parser/issue-17718-const-mut.stderr @@ -1,10 +1,10 @@ error: const globals cannot be mutable --> $DIR/issue-17718-const-mut.rs:2:1 | +LL | const + | ----- help: you might want to declare a static instead: `static` LL | mut //~ ERROR: const globals cannot be mutable - | ^^^ - | - = help: did you mean to declare a static? + | ^^^ cannot be mutable error: aborting due to previous error diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr index 39d96a943a18a..b7727cf03a4e7 100644 --- a/src/test/ui/suggestions/suggest-methods.stderr +++ b/src/test/ui/suggestions/suggest-methods.stderr @@ -5,25 +5,19 @@ LL | struct Foo; | ----------- method `bat` not found for this ... LL | f.bat(1.0); //~ ERROR no method named - | ^^^ - | - = help: did you mean `bar`? + | ^^^ help: did you mean: `bar` error[E0599]: no method named `is_emtpy` found for type `std::string::String` in the current scope --> $DIR/suggest-methods.rs:21:15 | LL | let _ = s.is_emtpy(); //~ ERROR no method named - | ^^^^^^^^ - | - = help: did you mean `is_empty`? + | ^^^^^^^^ help: did you mean: `is_empty` error[E0599]: no method named `count_eos` found for type `u32` in the current scope --> $DIR/suggest-methods.rs:25:19 | LL | let _ = 63u32.count_eos(); //~ ERROR no method named - | ^^^^^^^^^ - | - = help: did you mean `count_zeros`? + | ^^^^^^^^^ help: did you mean: `count_zeros` error[E0599]: no method named `count_o` found for type `u32` in the current scope --> $DIR/suggest-methods.rs:28:19 From 64afc6b51779c32b3d68a45b956b76b8899a135e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 7 Dec 2018 18:25:55 +0100 Subject: [PATCH 0218/1064] Differentiate between closure and function bodies --- src/librustc/hir/map/mod.rs | 13 +++++++++++-- src/librustc/hir/mod.rs | 12 ++++++++++++ src/librustc/middle/region.rs | 4 ++-- src/librustc_mir/borrow_check/mod.rs | 5 +---- .../borrow_check/nll/universal_regions.rs | 1 + src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/build/scope.rs | 1 + src/librustc_mir/hair/cx/mod.rs | 1 + src/librustc_mir/transform/inline.rs | 12 ++++-------- src/librustc_mir/transform/qualify_consts.rs | 1 + src/librustc_mir/util/pretty.rs | 2 ++ src/librustc_passes/rvalue_promotion.rs | 1 + 12 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d9ca37c937bc7..c3e4f0c05014c 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -455,11 +455,20 @@ impl<'hir> Map<'hir> { Node::AnonConst(_) => { BodyOwnerKind::Const } + Node::Variant(&Spanned { node: VariantKind { data: VariantData::Tuple(..), .. }, .. }) | + Node::StructCtor(..) | + Node::Item(&Item { node: ItemKind::Fn(..), .. }) | + Node::TraitItem(&TraitItem { node: TraitItemKind::Method(..), .. }) | + Node::ImplItem(&ImplItem { node: ImplItemKind::Method(..), .. }) => { + BodyOwnerKind::Fn + } Node::Item(&Item { node: ItemKind::Static(_, m, _), .. }) => { BodyOwnerKind::Static(m) } - // Default to function if it's not a constant or static. - _ => BodyOwnerKind::Fn + Node::Expr(&Expr { node: ExprKind::Closure(..), .. }) => { + BodyOwnerKind::Closure + } + node => bug!("{:#?} is not a body node", node), } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 65d9d5a4f363f..b58b1d359f98b 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1270,6 +1270,9 @@ pub enum BodyOwnerKind { /// Functions and methods. Fn, + /// Closures + Closure, + /// Constants and associated constants. Const, @@ -1277,6 +1280,15 @@ pub enum BodyOwnerKind { Static(Mutability), } +impl BodyOwnerKind { + pub fn is_fn_or_closure(self) -> bool { + match self { + BodyOwnerKind::Fn | BodyOwnerKind::Closure => true, + BodyOwnerKind::Const | BodyOwnerKind::Static(_) => false, + } + } +} + /// A constant (expression) that's not an item or associated item, /// but needs its own `DefId` for type-checking, const-eval, etc. /// These are usually found nested inside types (e.g., array lengths) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 819dd8aa7d53e..31f91a1bae57f 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1268,8 +1268,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { // The body of the every fn is a root scope. self.cx.parent = self.cx.var_parent; - if let hir::BodyOwnerKind::Fn = self.tcx.hir().body_owner_kind(owner_id) { - self.visit_expr(&body.value); + if self.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() { + self.visit_expr(&body.value) } else { // Only functions have an outer terminating (drop) scope, while // temporaries in constant initializers may be 'static, but only diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 45632245b61de..9d49814c35a34 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -163,10 +163,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), )); - let locals_are_invalidated_at_exit = match tcx.hir().body_owner_kind(id) { - hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false, - hir::BodyOwnerKind::Fn => true, - }; + let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure(); let borrow_set = Rc::new(BorrowSet::build( tcx, mir, locals_are_invalidated_at_exit, &mdpe.move_data)); diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index c63d45ce1d272..0a214e60bdd78 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -476,6 +476,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); match tcx.hir().body_owner_kind(self.mir_node_id) { + BodyOwnerKind::Closure | BodyOwnerKind::Fn => { let defining_ty = if self.mir_def_id == closure_base_def_id { tcx.type_of(closure_base_def_id) diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 2bf2824d835cc..420ae113ad330 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -75,7 +75,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t let cx = Cx::new(&infcx, id); let mut mir = if cx.tables().tainted_by_errors { build::construct_error(cx, body_id) - } else if let hir::BodyOwnerKind::Fn = cx.body_owner_kind { + } else if cx.body_owner_kind.is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) let fn_hir_id = tcx.hir().node_to_hir_id(id); diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index b44c2cc9c166a..78abba5f885b2 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -613,6 +613,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { hir::BodyOwnerKind::Static(_) => // No need to free storage in this context. None, + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => Some(self.topmost_scope()), } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 6113d88e09591..f514cac6326be 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -61,6 +61,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { let constness = match body_owner_kind { hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => hir::Constness::Const, + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => hir::Constness::NotConst, }; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 8b970c1408e37..9f0907adc9892 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -1,6 +1,5 @@ //! Inlining pass for MIR functions -use rustc::hir; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::DefId; @@ -74,15 +73,12 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // Only do inlining into fn bodies. let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap(); - let body_owner_kind = self.tcx.hir().body_owner_kind(id); - - if let (hir::BodyOwnerKind::Fn, None) = (body_owner_kind, self.source.promoted) { - + if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() { for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() { if let Some(callsite) = self.get_valid_function_call(bb, - bb_data, - caller_mir, - param_env) { + bb_data, + caller_mir, + param_env) { callsites.push_back(callsite); } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 78cf7153500c9..2d941902debc3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1152,6 +1152,7 @@ impl MirPass for QualifyAndPromoteConstants { let id = tcx.hir().as_local_node_id(def_id).unwrap(); let mut const_promoted_temps = None; let mode = match tcx.hir().body_owner_kind(id) { + hir::BodyOwnerKind::Closure => Mode::Fn, hir::BodyOwnerKind::Fn => { if tcx.is_const_fn(def_id) { Mode::ConstFn diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index fca208b340d2a..f4685e0ddc909 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -573,6 +573,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> i let body_owner_kind = tcx.hir().body_owner_kind(id); match (body_owner_kind, src.promoted) { (_, Some(i)) => write!(w, "{:?} in", i)?, + (hir::BodyOwnerKind::Closure, _) | (hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?, (hir::BodyOwnerKind::Const, _) => write!(w, "const")?, (hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?, @@ -585,6 +586,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> i })?; match (body_owner_kind, src.promoted) { + (hir::BodyOwnerKind::Closure, None) | (hir::BodyOwnerKind::Fn, None) => { write!(w, "(")?; diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 49914dc7078fd..c11b1af97766d 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -191,6 +191,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { self.in_static = false; match self.tcx.hir().body_owner_kind(item_id) { + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => self.in_fn = true, hir::BodyOwnerKind::Static(_) => self.in_static = true, _ => {} From 1db42756f7fec98d3705a0f975a1c92d10e88cd7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 21 Jan 2019 13:25:15 +0100 Subject: [PATCH 0219/1064] Print visible name for types as well as modules. This commit extends previous work in #55007 where the name from the visible parent was used for modules. Now, we also print the name from the visible parent for types. --- src/librustc/ty/item_path.rs | 28 ++++++++++----------- src/test/ui/issues/auxiliary/issue-56943.rs | 3 +++ src/test/ui/issues/issue-56943.rs | 8 ++++++ src/test/ui/issues/issue-56943.stderr | 12 +++++++++ 4 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/issues/auxiliary/issue-56943.rs create mode 100644 src/test/ui/issues/issue-56943.rs create mode 100644 src/test/ui/issues/issue-56943.stderr diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 9328de4f6a0a1..0ddc5ae87208d 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -210,12 +210,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let visible_parent = visible_parent_map.get(&cur_def).cloned(); let actual_parent = self.parent(cur_def); - debug!( - "try_push_visible_item_path: visible_parent={:?} actual_parent={:?}", - visible_parent, actual_parent, - ); let data = cur_def_key.disambiguated_data.data; + debug!( + "try_push_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", + data, visible_parent, actual_parent, + ); let symbol = match data { // In order to output a path that could actually be imported (valid and visible), // we need to handle re-exports correctly. @@ -248,16 +248,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // the children of the visible parent (as was done when computing // `visible_parent_map`), looking for the specific child we currently have and then // have access to the re-exported name. - DefPathData::Module(module_name) if visible_parent != actual_parent => { - let mut name: Option = None; - if let Some(visible_parent) = visible_parent { - for child in self.item_children(visible_parent).iter() { - if child.def.def_id() == cur_def { - name = Some(child.ident); - } - } - } - name.map(|n| n.as_str()).unwrap_or(module_name.as_str()) + DefPathData::Module(actual_name) | + DefPathData::TypeNs(actual_name) if visible_parent != actual_parent => { + visible_parent + .and_then(|parent| { + self.item_children(parent) + .iter() + .find(|child| child.def.def_id() == cur_def) + .map(|child| child.ident.as_str()) + }) + .unwrap_or_else(|| actual_name.as_str()) }, _ => { data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { diff --git a/src/test/ui/issues/auxiliary/issue-56943.rs b/src/test/ui/issues/auxiliary/issue-56943.rs new file mode 100644 index 0000000000000..65b9beb91f90c --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-56943.rs @@ -0,0 +1,3 @@ +pub struct S; +mod m { pub struct S; } +pub use crate::m::S as S2; diff --git a/src/test/ui/issues/issue-56943.rs b/src/test/ui/issues/issue-56943.rs new file mode 100644 index 0000000000000..8fc77abdbf588 --- /dev/null +++ b/src/test/ui/issues/issue-56943.rs @@ -0,0 +1,8 @@ +// aux-build:issue-56943.rs + +extern crate issue_56943; + +fn main() { + let _: issue_56943::S = issue_56943::S2; + //~^ ERROR mismatched types [E0308] +} diff --git a/src/test/ui/issues/issue-56943.stderr b/src/test/ui/issues/issue-56943.stderr new file mode 100644 index 0000000000000..27202051524c9 --- /dev/null +++ b/src/test/ui/issues/issue-56943.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/issue-56943.rs:6:29 + | +LL | let _: issue_56943::S = issue_56943::S2; + | ^^^^^^^^^^^^^^^ expected struct `issue_56943::S`, found struct `issue_56943::S2` + | + = note: expected type `issue_56943::S` + found type `issue_56943::S2` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From aedc3a51dfab0fa7205f1c0fd68a4e62dd6df712 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 7 Dec 2018 18:26:46 +0100 Subject: [PATCH 0220/1064] Declare some unconst operations as unsafe in const fn --- src/librustc_mir/transform/check_unsafety.rs | 97 +++++++++++++++---- src/test/ui/cast/cast-ptr-to-int-const.rs | 8 +- src/test/ui/cast/cast-ptr-to-int-const.stderr | 12 +-- .../ui/consts/const-eval/const_raw_ptr_ops.rs | 8 +- .../const-eval/const_raw_ptr_ops.stderr | 16 +-- .../ui/consts/min_const_fn/cmp_fn_pointers.rs | 2 +- .../min_const_fn/min_const_fn.nll.stderr | 52 ++++++---- .../ui/consts/min_const_fn/min_const_fn.rs | 8 +- .../consts/min_const_fn/min_const_fn.stderr | 50 ++++++---- src/test/ui/error-codes/E0395.rs | 2 +- src/test/ui/error-codes/E0395.stderr | 6 +- src/test/ui/issues/issue-17458.rs | 2 +- src/test/ui/issues/issue-17458.stderr | 6 +- src/test/ui/issues/issue-18294.rs | 2 +- src/test/ui/issues/issue-18294.stderr | 6 +- src/test/ui/issues/issue-25826.rs | 2 +- src/test/ui/issues/issue-25826.stderr | 6 +- 17 files changed, 187 insertions(+), 98 deletions(-) diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index eb151b56bed65..ab8da2f352c1c 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -4,6 +4,7 @@ use rustc_data_structures::sync::Lrc; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt}; +use rustc::ty::cast::CastTy; use rustc::hir; use rustc::hir::Node; use rustc::hir::def_id::DefId; @@ -20,6 +21,7 @@ use util; pub struct UnsafetyChecker<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, + const_context: bool, min_const_fn: bool, source_scope_local_data: &'a IndexVec, violations: Vec, @@ -33,14 +35,20 @@ pub struct UnsafetyChecker<'a, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> { fn new( + const_context: bool, min_const_fn: bool, mir: &'a Mir<'tcx>, source_scope_local_data: &'a IndexVec, tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Self { + // sanity check + if min_const_fn { + assert!(const_context); + } Self { mir, + const_context, min_const_fn, source_scope_local_data, violations: vec![], @@ -124,29 +132,70 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { rvalue: &Rvalue<'tcx>, location: Location) { - if let &Rvalue::Aggregate(box ref aggregate, _) = rvalue { - match aggregate { - &AggregateKind::Array(..) | - &AggregateKind::Tuple => {} - &AggregateKind::Adt(ref def, ..) => { - match self.tcx.layout_scalar_valid_range(def.did) { - (Bound::Unbounded, Bound::Unbounded) => {}, - _ => self.require_unsafe( - "initializing type with `rustc_layout_scalar_valid_range` attr", - "initializing a layout restricted type's field with a value outside \ - the valid range is undefined behavior", - UnsafetyViolationKind::GeneralAndConstFn, - ), + match rvalue { + Rvalue::Aggregate(box ref aggregate, _) => { + match aggregate { + &AggregateKind::Array(..) | + &AggregateKind::Tuple => {} + &AggregateKind::Adt(ref def, ..) => { + match self.tcx.layout_scalar_valid_range(def.did) { + (Bound::Unbounded, Bound::Unbounded) => {}, + _ => self.require_unsafe( + "initializing type with `rustc_layout_scalar_valid_range` attr", + "initializing a layout restricted type's field with a value \ + outside the valid range is undefined behavior", + UnsafetyViolationKind::GeneralAndConstFn, + ), + } + } + &AggregateKind::Closure(def_id, _) | + &AggregateKind::Generator(def_id, _, _) => { + let UnsafetyCheckResult { + violations, unsafe_blocks + } = self.tcx.unsafety_check_result(def_id); + self.register_violations(&violations, &unsafe_blocks); } } - &AggregateKind::Closure(def_id, _) | - &AggregateKind::Generator(def_id, _, _) => { - let UnsafetyCheckResult { - violations, unsafe_blocks - } = self.tcx.unsafety_check_result(def_id); - self.register_violations(&violations, &unsafe_blocks); + }, + // casting pointers to ints is unsafe in const fn because the const evaluator cannot + // possibly know what the result of various operations like `address / 2` would be + // pointers during const evaluation have no integral address, only an abstract one + Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) + if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast => { + let operand_ty = operand.ty(self.mir, self.tcx); + let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast"); + let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); + match (cast_in, cast_out) { + (CastTy::Ptr(_), CastTy::Int(_)) | + (CastTy::FnPtr, CastTy::Int(_)) => { + self.register_violations(&[UnsafetyViolation { + source_info: self.source_info, + description: Symbol::intern("cast of pointer to int").as_interned_str(), + details: Symbol::intern("casting pointers to integers in constants") + .as_interned_str(), + kind: UnsafetyViolationKind::General, + }], &[]); + }, + _ => {}, } } + // raw pointer and fn pointer operations are unsafe as it is not clear whether one + // pointer would be "less" or "equal" to another, because we cannot know where llvm + // or the linker will place various statics in memory. Without this information the + // result of a comparison of addresses would differ between runtime and compile-time. + Rvalue::BinaryOp(_, ref lhs, _) + if self.const_context && self.tcx.features().const_compare_raw_pointers => { + if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty { + self.register_violations(&[UnsafetyViolation { + source_info: self.source_info, + description: Symbol::intern("pointer operation").as_interned_str(), + details: Symbol::intern("operations on pointers in constants") + .as_interned_str(), + kind: UnsafetyViolationKind::General, + }], &[]); + } + } + _ => {}, } self.super_rvalue(rvalue, location); } @@ -484,8 +533,16 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) }; let param_env = tcx.param_env(def_id); + + let id = tcx.hir().as_local_node_id(def_id).unwrap(); + let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) { + hir::BodyOwnerKind::Closure => (false, false), + hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)), + hir::BodyOwnerKind::Const | + hir::BodyOwnerKind::Static(_) => (true, false), + }; let mut checker = UnsafetyChecker::new( - tcx.is_min_const_fn(def_id), + const_context, min_const_fn, mir, source_scope_local_data, tcx, param_env); checker.visit_mir(mir); diff --git a/src/test/ui/cast/cast-ptr-to-int-const.rs b/src/test/ui/cast/cast-ptr-to-int-const.rs index 70b4869ef63ce..ac153cb57423f 100644 --- a/src/test/ui/cast/cast-ptr-to-int-const.rs +++ b/src/test/ui/cast/cast-ptr-to-int-const.rs @@ -1,7 +1,11 @@ // gate-test-const_raw_ptr_to_usize_cast fn main() { - const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable + const X: u32 = unsafe { + main as u32 //~ ERROR casting pointers to integers in constants is unstable + }; const Y: u32 = 0; - const Z: u32 = &Y as *const u32 as u32; //~ ERROR is unstable + const Z: u32 = unsafe { + &Y as *const u32 as u32 //~ ERROR is unstable + }; } diff --git a/src/test/ui/cast/cast-ptr-to-int-const.stderr b/src/test/ui/cast/cast-ptr-to-int-const.stderr index 3cce07d64ecd0..d04595ee4e887 100644 --- a/src/test/ui/cast/cast-ptr-to-int-const.stderr +++ b/src/test/ui/cast/cast-ptr-to-int-const.stderr @@ -1,16 +1,16 @@ error[E0658]: casting pointers to integers in constants is unstable (see issue #51910) - --> $DIR/cast-ptr-to-int-const.rs:4:20 + --> $DIR/cast-ptr-to-int-const.rs:5:9 | -LL | const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable - | ^^^^^^^^^^^ +LL | main as u32 //~ ERROR casting pointers to integers in constants is unstable + | ^^^^^^^^^^^ | = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable error[E0658]: casting pointers to integers in constants is unstable (see issue #51910) - --> $DIR/cast-ptr-to-int-const.rs:6:20 + --> $DIR/cast-ptr-to-int-const.rs:9:9 | -LL | const Z: u32 = &Y as *const u32 as u32; //~ ERROR is unstable - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | &Y as *const u32 as u32 //~ ERROR is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs index 63bac17f1c0f3..44266682a5c6c 100644 --- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs +++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs @@ -3,13 +3,13 @@ fn main() {} // unconst and bad, will thus error in miri -const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause +const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this // unconst and fine -const X2: bool = 42 as *const i32 == 43 as *const i32; +const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; // unconst and fine -const Y: usize = 42usize as *const i32 as usize + 1; +const Y: usize = unsafe { 42usize as *const i32 as usize + 1 }; // unconst and bad, will thus error in miri -const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause +const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this // unconst and fine const Z: i32 = unsafe { *(&1 as *const i32) }; // unconst and bad, will thus error in miri diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr index ea11359af85ed..6be54c0bad4f9 100644 --- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr +++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr @@ -1,20 +1,20 @@ error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:6:1 | -LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause - | ^^^^^^^^^^^^^^^^------------------------------------^ - | | - | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants +LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this + | ^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants | = note: #[deny(const_err)] on by default error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:12:1 | -LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause - | ^^^^^^^^^^^^^^^^^^-----------------------------^ - | | - | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants +LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------^^^ + | | + | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:16:1 diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs index d8abd97655805..c2600f894dc42 100644 --- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs +++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.rs @@ -1,5 +1,5 @@ const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointers in const fn are unstable - x == y + unsafe { x == y } } fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr index 91b076097b018..763c69e805030 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -95,97 +95,109 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize } | ^^^^^^^^^^ error: casting pointers to ints is unstable in const fn - --> $DIR/min_const_fn.rs:94:42 + --> $DIR/min_const_fn.rs:94:63 + | +LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } + | ^^^^^^^^^^ + +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:96:42 | LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } | ^^^^^^^^^^ +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:98:63 + | +LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } + | ^^^^^^^^^^ + error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:96:38 + --> $DIR/min_const_fn.rs:100:38 | LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } | ^^^^^^^^^^^^^^^^^^^^^^ error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:98:29 + --> $DIR/min_const_fn.rs:102:29 | LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:100:44 + --> $DIR/min_const_fn.rs:104:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } | ^^^^^^ error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:102:44 + --> $DIR/min_const_fn.rs:106:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } | ^^^^^^ error: mutable references in const fn are unstable - --> $DIR/min_const_fn.rs:104:14 + --> $DIR/min_const_fn.rs:108:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:109:6 + --> $DIR/min_const_fn.rs:113:6 | LL | impl Foo { | ^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:114:6 + --> $DIR/min_const_fn.rs:118:6 | LL | impl Foo { | ^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:119:6 + --> $DIR/min_const_fn.rs:123:6 | LL | impl Foo { | ^ error: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:125:24 + --> $DIR/min_const_fn.rs:129:24 | LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:127:34 + --> $DIR/min_const_fn.rs:131:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:129:22 + --> $DIR/min_const_fn.rs:133:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` | ^^^^^^^^^^^^^^^^^^^^ error: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:130:23 + --> $DIR/min_const_fn.rs:134:23 | LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable | ^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:131:23 + --> $DIR/min_const_fn.rs:135:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` | ^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:132:32 + --> $DIR/min_const_fn.rs:136:32 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning[E0515]: cannot return reference to temporary value - --> $DIR/min_const_fn.rs:132:63 + --> $DIR/min_const_fn.rs:136:63 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^-- @@ -197,24 +209,24 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:137:41 + --> $DIR/min_const_fn.rs:141:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:140:21 + --> $DIR/min_const_fn.rs:144:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ error: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:142:27 + --> $DIR/min_const_fn.rs:146:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 34 previous errors +error: aborting due to 36 previous errors Some errors occurred: E0493, E0515. For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 05cf3d5f1f173..ee3ffcd4026d3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -90,9 +90,13 @@ static BAR: u32 = 42; const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items const fn foo30(x: *const u32) -> usize { x as usize } -//~^ ERROR casting pointers to int +//~^ ERROR casting pointers to ints is unstable +const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } +//~^ ERROR casting pointers to ints is unstable const fn foo30_2(x: *mut u32) -> usize { x as usize } -//~^ ERROR casting pointers to int +//~^ ERROR casting pointers to ints is unstable +const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } +//~^ ERROR casting pointers to ints is unstable const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 2cae714fbf727..52c60c57b8fb3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -95,113 +95,125 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize } | ^^^^^^^^^^ error: casting pointers to ints is unstable in const fn - --> $DIR/min_const_fn.rs:94:42 + --> $DIR/min_const_fn.rs:94:63 + | +LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } + | ^^^^^^^^^^ + +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:96:42 | LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } | ^^^^^^^^^^ +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:98:63 + | +LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } + | ^^^^^^^^^^ + error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:96:38 + --> $DIR/min_const_fn.rs:100:38 | LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } | ^^^^^^^^^^^^^^^^^^^^^^ error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:98:29 + --> $DIR/min_const_fn.rs:102:29 | LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:100:44 + --> $DIR/min_const_fn.rs:104:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } | ^^^^^^ error: `if`, `match`, `&&` and `||` are not stable in const fn - --> $DIR/min_const_fn.rs:102:44 + --> $DIR/min_const_fn.rs:106:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } | ^^^^^^ error: mutable references in const fn are unstable - --> $DIR/min_const_fn.rs:104:14 + --> $DIR/min_const_fn.rs:108:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:109:6 + --> $DIR/min_const_fn.rs:113:6 | LL | impl Foo { | ^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:114:6 + --> $DIR/min_const_fn.rs:118:6 | LL | impl Foo { | ^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:119:6 + --> $DIR/min_const_fn.rs:123:6 | LL | impl Foo { | ^ error: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:125:24 + --> $DIR/min_const_fn.rs:129:24 | LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:127:34 + --> $DIR/min_const_fn.rs:131:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:129:22 + --> $DIR/min_const_fn.rs:133:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` | ^^^^^^^^^^^^^^^^^^^^ error: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:130:23 + --> $DIR/min_const_fn.rs:134:23 | LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable | ^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:131:23 + --> $DIR/min_const_fn.rs:135:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` | ^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:132:32 + --> $DIR/min_const_fn.rs:136:32 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:137:41 + --> $DIR/min_const_fn.rs:141:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:140:21 + --> $DIR/min_const_fn.rs:144:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ error: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:142:27 + --> $DIR/min_const_fn.rs:146:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 34 previous errors +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/src/test/ui/error-codes/E0395.rs b/src/test/ui/error-codes/E0395.rs index c2de56c413f05..9657bbdeadc17 100644 --- a/src/test/ui/error-codes/E0395.rs +++ b/src/test/ui/error-codes/E0395.rs @@ -3,6 +3,6 @@ static FOO: i32 = 42; static BAR: i32 = 42; -static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020 +static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020 fn main() { } diff --git a/src/test/ui/error-codes/E0395.stderr b/src/test/ui/error-codes/E0395.stderr index 45e1ba05ff996..cc7d94e22eb6b 100644 --- a/src/test/ui/error-codes/E0395.stderr +++ b/src/test/ui/error-codes/E0395.stderr @@ -1,8 +1,8 @@ error[E0658]: comparing raw pointers inside static (see issue #53020) - --> $DIR/E0395.rs:6:22 + --> $DIR/E0395.rs:6:29 | -LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable diff --git a/src/test/ui/issues/issue-17458.rs b/src/test/ui/issues/issue-17458.rs index d7a1752b96c44..444e94d829bf8 100644 --- a/src/test/ui/issues/issue-17458.rs +++ b/src/test/ui/issues/issue-17458.rs @@ -1,4 +1,4 @@ -static X: usize = 0 as *const usize as usize; +static X: usize = unsafe { 0 as *const usize as usize }; //~^ ERROR: casting pointers to integers in statics is unstable fn main() { diff --git a/src/test/ui/issues/issue-17458.stderr b/src/test/ui/issues/issue-17458.stderr index 04921419ae01a..a1a8ed9f0cdcb 100644 --- a/src/test/ui/issues/issue-17458.stderr +++ b/src/test/ui/issues/issue-17458.stderr @@ -1,8 +1,8 @@ error[E0658]: casting pointers to integers in statics is unstable (see issue #51910) - --> $DIR/issue-17458.rs:1:19 + --> $DIR/issue-17458.rs:1:28 | -LL | static X: usize = 0 as *const usize as usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | static X: usize = unsafe { 0 as *const usize as usize }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable diff --git a/src/test/ui/issues/issue-18294.rs b/src/test/ui/issues/issue-18294.rs index df4fd1642f2bc..1c2229fb9eae4 100644 --- a/src/test/ui/issues/issue-18294.rs +++ b/src/test/ui/issues/issue-18294.rs @@ -1,5 +1,5 @@ fn main() { const X: u32 = 1; - const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable + const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR is unstable println!("{}", Y); } diff --git a/src/test/ui/issues/issue-18294.stderr b/src/test/ui/issues/issue-18294.stderr index 2af7f45628e37..f3e8ab1a31307 100644 --- a/src/test/ui/issues/issue-18294.stderr +++ b/src/test/ui/issues/issue-18294.stderr @@ -1,8 +1,8 @@ error[E0658]: casting pointers to integers in constants is unstable (see issue #51910) - --> $DIR/issue-18294.rs:3:22 + --> $DIR/issue-18294.rs:3:31 | -LL | const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable diff --git a/src/test/ui/issues/issue-25826.rs b/src/test/ui/issues/issue-25826.rs index e6022653d9c3b..36a69cf4c22ff 100644 --- a/src/test/ui/issues/issue-25826.rs +++ b/src/test/ui/issues/issue-25826.rs @@ -1,6 +1,6 @@ fn id(t: T) -> T { t } fn main() { - const A: bool = id:: as *const () < id:: as *const (); + const A: bool = unsafe { id:: as *const () < id:: as *const () }; //~^ ERROR comparing raw pointers inside constant println!("{}", A); } diff --git a/src/test/ui/issues/issue-25826.stderr b/src/test/ui/issues/issue-25826.stderr index 73ebf29d08e78..dc547f7c32c94 100644 --- a/src/test/ui/issues/issue-25826.stderr +++ b/src/test/ui/issues/issue-25826.stderr @@ -1,8 +1,8 @@ error[E0658]: comparing raw pointers inside constant (see issue #53020) - --> $DIR/issue-25826.rs:3:21 + --> $DIR/issue-25826.rs:3:30 | -LL | const A: bool = id:: as *const () < id:: as *const (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const A: bool = unsafe { id:: as *const () < id:: as *const () }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable From fcb3d0d6ae03c12cbd6d1e8c2917c96de9ba0fe0 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 21 Jan 2019 21:02:48 +0530 Subject: [PATCH 0221/1064] Expose alloc/dealloc properly for SGX libunwind --- src/libstd/sys/sgx/rwlock.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 47874158ed9df..43ceae7d33b8d 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -1,3 +1,4 @@ +use alloc::{self, Layout}; use num::NonZeroUsize; use slice; use str; @@ -147,6 +148,7 @@ impl RWLock { self.__write_unlock(rguard, wguard); } + // only used by __rust_rwlock_unlock below #[inline] unsafe fn unlock(&self) { let rguard = self.readers.lock(); @@ -164,6 +166,7 @@ impl RWLock { const EINVAL: i32 = 22; +// used by libunwind port #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 { if p.is_null() { @@ -190,6 +193,8 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { return 0; } +// the following functions are also used by the libunwind port. They're +// included here to make sure parallel codegen and LTO don't mess things up. #[no_mangle] pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { if s < 0 { @@ -206,6 +211,16 @@ pub unsafe extern "C" fn __rust_abort() { ::sys::abort_internal(); } +#[no_mangle] +pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { + alloc::alloc(Layout::from_size_align_unchecked(size, align)) +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { + alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) +} + #[cfg(test)] mod tests { From 6abba95045e28e768a2b553f6b0cd2f04a71bfe0 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 21 Jan 2019 18:50:36 +0530 Subject: [PATCH 0222/1064] Update libunwind for SGX target --- src/ci/docker/dist-various-2/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 906255533ad29..952c1ba2ccb76 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -32,7 +32,7 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc COPY dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/ # We pass the commit id of the port of LLVM's libunwind to the build script. # Any update to the commit id here, should cause the container image to be re-built from this point on. -RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "bbe23902411be88d7388f381becefadd6e3ef819" +RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "13fad13f8ea83a8da58d04a5faa45943151b3398" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh From e195ce654a570606a85ead6cefb36042a206205a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 21 Jan 2019 16:55:32 +0100 Subject: [PATCH 0223/1064] Fix some non-determinism in help messages for E0277 errors. The diagnostic for this error prints `the following implementations were found` followed by the first N relevant impls, sorted. This commit makes the sort happen before slicing, so that the set of impls being printed is deterministic when the input is not. --- src/librustc/traits/error_reporting.rs | 10 +++++++--- .../issue-21659-show-relevant-trait-impls-2.stderr | 2 +- .../did_you_mean/issue-39802-show-5-trait-impls.stderr | 4 ++-- src/test/ui/try-block/try-block-bad-type.stderr | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 367a7eacdfcaf..1c92e2da588a0 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -471,7 +471,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } fn report_similar_impl_candidates(&self, - mut impl_candidates: Vec>, + impl_candidates: Vec>, err: &mut DiagnosticBuilder<'_>) { if impl_candidates.is_empty() { @@ -497,14 +497,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }); // Sort impl candidates so that ordering is consistent for UI tests. - let normalized_impl_candidates = &mut impl_candidates[0..end] + let mut normalized_impl_candidates = impl_candidates .iter() .map(normalize) .collect::>(); + + // Sort before taking the `..end` range, + // because the ordering of `impl_candidates` may not be deterministic: + // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 normalized_impl_candidates.sort(); err.help(&format!("the following implementations were found:{}{}", - normalized_impl_candidates.join(""), + normalized_impl_candidates[..end].join(""), if len > 5 { format!("\nand {} others", len - 4) } else { diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index 140f98b40382a..d6d5ce4d1a7d2 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr @@ -8,7 +8,7 @@ LL | f1.foo(1usize); > > > - > + > and 2 others error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index 23466980f9252..3411958be62a9 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -40,10 +40,10 @@ LL | Foo::::bar(&true); //~ ERROR is not satisfied | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `bool` | = help: the following implementations were found: + > + > > > - > - > and 2 others note: required by `Foo::bar` --> $DIR/issue-39802-show-5-trait-impls.rs:2:5 diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr index c2f9e9b52bee6..df8e646280c9a 100644 --- a/src/test/ui/try-block/try-block-bad-type.stderr +++ b/src/test/ui/try-block/try-block-bad-type.stderr @@ -5,10 +5,10 @@ LL | Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` | ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32` | = help: the following implementations were found: + > > > > - > and 2 others = note: required by `std::convert::From::from` From 58b02000c51c1bd460f089368481e1552e0f86ac Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 21 Jan 2019 18:50:54 +0100 Subject: [PATCH 0224/1064] Add powerpc64-unknown-freebsd --- src/librustc_target/spec/mod.rs | 1 + .../spec/powerpc64_unknown_freebsd.rs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/librustc_target/spec/powerpc64_unknown_freebsd.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 3a21ca19b176b..e47da3cff95b6 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -367,6 +367,7 @@ supported_targets! { ("aarch64-unknown-freebsd", aarch64_unknown_freebsd), ("i686-unknown-freebsd", i686_unknown_freebsd), + ("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd), ("x86_64-unknown-freebsd", x86_64_unknown_freebsd), ("i686-unknown-dragonfly", i686_unknown_dragonfly), diff --git a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs b/src/librustc_target/spec/powerpc64_unknown_freebsd.rs new file mode 100644 index 0000000000000..cc7b87bfdebc3 --- /dev/null +++ b/src/librustc_target/spec/powerpc64_unknown_freebsd.rs @@ -0,0 +1,22 @@ +use spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::freebsd_base::opts(); + base.cpu = "ppc64".to_string(); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.max_atomic_width = Some(64); + + Ok(Target { + llvm_target: "powerpc64-unknown-freebsd".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-i64:64-n32:64".to_string(), + arch: "powerpc64".to_string(), + target_os: "freebsd".to_string(), + target_env: String::new(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} From 400e28d27af3c4e0f7fca2274cb1817651d7ba37 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 21 Jan 2019 14:48:07 +0000 Subject: [PATCH 0225/1064] fix validation range printing when encountering undef --- src/librustc_mir/interpret/validity.rs | 9 +++++++-- src/test/ui/consts/const-eval/ub-nonnull.rs | 7 +++++++ src/test/ui/consts/const-eval/ub-nonnull.stderr | 14 +++++++++++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index a5fb44587400a..8f5a5bf8ee312 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -449,8 +449,13 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> } // At least one value is excluded. Get the bits. let value = try_validation!(value.not_undef(), - value, self.path, - format!("something in the range {:?}", layout.valid_range)); + value, + self.path, + format!( + "something {}", + wrapping_range_format(&layout.valid_range, max_hi), + ) + ); let bits = match value { Scalar::Ptr(ptr) => { if lo == 1 && hi == max_hi { diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs index 7fbcab8245a0f..3e0b0948ef3c3 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.rs +++ b/src/test/ui/consts/const-eval/ub-nonnull.rs @@ -13,6 +13,13 @@ const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; //~^ ERROR it is undefined behavior to use this value +union Transmute { + uninit: (), + out: NonZeroU8, +} +const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out }; +//~^ ERROR it is undefined behavior to use this value + // Also test other uses of rustc_layout_scalar_valid_range_start #[rustc_layout_scalar_valid_range_start(10)] diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index 5f8e0c73fbb2a..6230712ad6f23 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -23,7 +23,15 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:21:1 + --> $DIR/ub-nonnull.rs:20:1 + | +LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:28:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 @@ -31,13 +39,13 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:27:1 + --> $DIR/ub-nonnull.rs:34:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0080`. From 5a7cd848f740291f94f2400b50f41136fc8657bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Mon, 21 Jan 2019 19:36:27 +0100 Subject: [PATCH 0226/1064] Speed up the fast path for assert_eq! and assert_ne! Currently, the panic!() calls directly borrow the value bindings. This causes those bindings to always be initialized, i.e. they're initialized even before the values are even compared. This causes noticeable overhead in what should be a really cheap operation. By performing a reborrow of the value in the call to panic!(), we allow LLVM to optimize that code, so that the extra borrow only happens in the error case. We could achieve the same result by dereferencing the values passed to panic!(), as the format machinery borrows them anyway, but this causes assertions to fail to compile if one of the values is unsized, i.e. it would be a breaking change. --- src/libcore/macros.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 2f350df2f5c18..5eaefb7d1cc51 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -45,9 +45,12 @@ macro_rules! assert_eq { match (&$left, &$right) { (left_val, right_val) => { if !(*left_val == *right_val) { + // The reborrows below are intentional. Without them, the stack slot for the + // borrow is initialized even before the values are compared, leading to a + // noticeable slow down. panic!(r#"assertion failed: `(left == right)` left: `{:?}`, - right: `{:?}`"#, left_val, right_val) + right: `{:?}`"#, &*left_val, &*right_val) } } } @@ -59,9 +62,12 @@ macro_rules! assert_eq { match (&($left), &($right)) { (left_val, right_val) => { if !(*left_val == *right_val) { + // The reborrows below are intentional. Without them, the stack slot for the + // borrow is initialized even before the values are compared, leading to a + // noticeable slow down. panic!(r#"assertion failed: `(left == right)` left: `{:?}`, - right: `{:?}`: {}"#, left_val, right_val, + right: `{:?}`: {}"#, &*left_val, &*right_val, format_args!($($arg)+)) } } @@ -96,9 +102,12 @@ macro_rules! assert_ne { match (&$left, &$right) { (left_val, right_val) => { if *left_val == *right_val { + // The reborrows below are intentional. Without them, the stack slot for the + // borrow is initialized even before the values are compared, leading to a + // noticeable slow down. panic!(r#"assertion failed: `(left != right)` left: `{:?}`, - right: `{:?}`"#, left_val, right_val) + right: `{:?}`"#, &*left_val, &*right_val) } } } @@ -110,9 +119,12 @@ macro_rules! assert_ne { match (&($left), &($right)) { (left_val, right_val) => { if *left_val == *right_val { + // The reborrows below are intentional. Without them, the stack slot for the + // borrow is initialized even before the values are compared, leading to a + // noticeable slow down. panic!(r#"assertion failed: `(left != right)` left: `{:?}`, - right: `{:?}`: {}"#, left_val, right_val, + right: `{:?}`: {}"#, &*left_val, &*right_val, format_args!($($arg)+)) } } From 2aa52035d5d1886bd44ac65d353defd2d766264e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 21 Jan 2019 22:25:02 +0100 Subject: [PATCH 0227/1064] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 97f4cff8e904c..1cd85d2a2767b 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 97f4cff8e904c268569d37922a27835209deff5d +Subproject commit 1cd85d2a2767b37f9869b719a74e3da99087c31a From e7998bf6a6e5cb3c12604d97c72435c1b4cea492 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 21 Jan 2019 22:30:52 +0100 Subject: [PATCH 0228/1064] un-deprecate mem::zeroed --- src/libcore/mem.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 8fcbb73d9ce46..9e100d0a58d17 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -489,7 +489,6 @@ pub const fn needs_drop() -> bool { /// assert_eq!(0, x); /// ``` #[inline] -#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::zeroed` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn zeroed() -> T { #[cfg(not(stage0))] From 6c399d155c6307563a2022fe98bc2e596af1cfc4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 21 Jan 2019 19:42:06 +0100 Subject: [PATCH 0229/1064] Add error for trailing angle brackets. This commit adds a error (and accompanying machine applicable suggestion) for trailing angle brackets on function calls with a turbofish. --- src/libsyntax/ast.rs | 14 ++++ src/libsyntax/parse/parser.rs | 97 +++++++++++++++++++++++++++ src/test/ui/issues/issue-54521-1.rs | 16 +++++ src/test/ui/issues/issue-54521.fixed | 22 ++++++ src/test/ui/issues/issue-54521.rs | 22 ++++++ src/test/ui/issues/issue-54521.stderr | 26 +++++++ 6 files changed, 197 insertions(+) create mode 100644 src/test/ui/issues/issue-54521-1.rs create mode 100644 src/test/ui/issues/issue-54521.fixed create mode 100644 src/test/ui/issues/issue-54521.rs create mode 100644 src/test/ui/issues/issue-54521.stderr diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 405cf612543fb..e520ac3bdd499 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -140,6 +140,20 @@ pub enum GenericArgs { } impl GenericArgs { + pub fn is_parenthesized(&self) -> bool { + match *self { + Parenthesized(..) => true, + _ => false, + } + } + + pub fn is_angle_bracketed(&self) -> bool { + match *self { + AngleBracketed(..) => true, + _ => false, + } + } + pub fn span(&self) -> Span { match *self { AngleBracketed(ref data) => data.span, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 439eec5b0c48d..d7c209d12a8fc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2757,6 +2757,8 @@ impl<'a> Parser<'a> { // Assuming we have just parsed `.`, continue parsing into an expression. fn parse_dot_suffix(&mut self, self_arg: P, lo: Span) -> PResult<'a, P> { let segment = self.parse_path_segment(PathStyle::Expr, true)?; + self.check_trailing_angle_brackets(&segment); + Ok(match self.token { token::OpenDelim(token::Paren) => { // Method call `expr.f()` @@ -2784,6 +2786,101 @@ impl<'a> Parser<'a> { }) } + /// This function checks if there are trailing angle brackets and produces + /// a diagnostic to suggest removing them. + /// + /// ```ignore (diagnostic) + /// let _ = vec![1, 2, 3].into_iter().collect::>>>(); + /// ^^ help: remove extra angle brackets + /// ``` + fn check_trailing_angle_brackets(&mut self, segment: &PathSegment) { + // This function is intended to be invoked from `parse_dot_suffix` where there are two + // cases: + // + // - A field access (eg. `x.foo`) + // - A method call (eg. `x.foo()`) + // + // This function is called after parsing `.foo` and before parsing any parenthesis (if + // present). This includes any angle bracket arguments, such as `.foo::`. + + // We only care about trailing angle brackets if we previously parsed angle bracket + // arguments. This helps stop us incorrectly suggesting that extra angle brackets be + // removed in this case: + // + // `x.foo >> (3)` (where `x.foo` is a `u32` for example) + // + // This case is particularly tricky as we won't notice it just looking at the tokens - + // it will appear the same (in terms of upcoming tokens) as below (since the `::` will + // have already been parsed): + // + // `x.foo::>>(3)` + let parsed_angle_bracket_args = segment.args + .as_ref() + .map(|args| args.is_angle_bracketed()) + .unwrap_or(false); + + debug!( + "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}", + parsed_angle_bracket_args, + ); + if !parsed_angle_bracket_args { + return; + } + + // Keep the span at the start so we can highlight the sequence of `>` characters to be + // removed. + let lo = self.span; + + // We need to look-ahead to see if we have `>` characters without moving the cursor forward + // (since we might have the field access case and the characters we're eating are + // actual operators and not trailing characters - ie `x.foo >> 3`). + let mut position = 0; + + // The first tokens we will encounter are shift right tokens (`>>`) since pairs of `>` + // characters will have been grouped together by the tokenizer. + let mut number_of_shr = 0; + while self.look_ahead(position, |t| *t == token::BinOp(token::BinOpToken::Shr)) { + number_of_shr += 1; + position += 1; + } + + // Afterwards, there will be at most one `>` character remaining (more than one and it'd + // have shown up as a `>>`). + let encountered_gt = self.look_ahead(position, |t| *t == token::Gt); + if encountered_gt { + position += 1; + } + + // If we didn't find any trailing `>>` characters or a trailing `>`, then we have + // nothing to error about. + debug!( + "check_trailing_angle_brackets: encountered_gt={:?} number_of_shr={:?}", + encountered_gt, number_of_shr, + ); + if !encountered_gt && number_of_shr < 1 { + return; + } + + // Finally, double check that we have a left parenthesis next as otherwise this is the + // field case. + if self.look_ahead(position, |t| *t == token::OpenDelim(token::Paren)) { + // Eat from where we started until the left parenthesis so that parsing can continue + // as if we didn't have those extra angle brackets. + self.eat_to_tokens(&[&token::OpenDelim(token::Paren)]); + let span = lo.until(self.span); + + self.diagnostic() + .struct_span_err(span, "unmatched angle bracket") + .span_suggestion_with_applicability( + span, + "remove extra angle bracket", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + } + } + fn parse_dot_or_call_expr_with_(&mut self, e0: P, lo: Span) -> PResult<'a, P> { let mut e = e0; let mut hi; diff --git a/src/test/ui/issues/issue-54521-1.rs b/src/test/ui/issues/issue-54521-1.rs new file mode 100644 index 0000000000000..d6a14a6e11f67 --- /dev/null +++ b/src/test/ui/issues/issue-54521-1.rs @@ -0,0 +1,16 @@ +// compile-pass + +// This test checks that the `remove extra angle brackets` error doesn't happen for some +// potential edge-cases.. + +struct X { + len: u32, +} + +fn main() { + let x = X { len: 3 }; + + let _ = x.len > (3); + + let _ = x.len >> (3); +} diff --git a/src/test/ui/issues/issue-54521.fixed b/src/test/ui/issues/issue-54521.fixed new file mode 100644 index 0000000000000..84ab6866cf133 --- /dev/null +++ b/src/test/ui/issues/issue-54521.fixed @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::>>>(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/issues/issue-54521.rs b/src/test/ui/issues/issue-54521.rs new file mode 100644 index 0000000000000..f1d6850417880 --- /dev/null +++ b/src/test/ui/issues/issue-54521.rs @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::>>>(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::>>>>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>>>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>>>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>>(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/issues/issue-54521.stderr b/src/test/ui/issues/issue-54521.stderr new file mode 100644 index 0000000000000..a67e9ca8daf40 --- /dev/null +++ b/src/test/ui/issues/issue-54521.stderr @@ -0,0 +1,26 @@ +error: unmatched angle bracket + --> $DIR/issue-54521.rs:11:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::>>>>>(); + | ^^^^ help: remove extra angle bracket + +error: unmatched angle bracket + --> $DIR/issue-54521.rs:14:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::>>>>(); + | ^^^ help: remove extra angle bracket + +error: unmatched angle bracket + --> $DIR/issue-54521.rs:17:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::>>>(); + | ^^ help: remove extra angle bracket + +error: unmatched angle bracket + --> $DIR/issue-54521.rs:20:60 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::>>(); + | ^ help: remove extra angle bracket + +error: aborting due to 4 previous errors + From 3f0fc9b03569e03dbdf5fdc3a67f246aad3b40b8 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 21 Jan 2019 21:16:46 +0100 Subject: [PATCH 0230/1064] Pluralize error messages. This commit pluralizes error messages when more than a single trailing `>` character is present. --- src/libsyntax/parse/parser.rs | 11 +++++++++-- src/test/ui/issues/issue-54521.stderr | 12 ++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d7c209d12a8fc..6a881eb624196 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2869,11 +2869,18 @@ impl<'a> Parser<'a> { self.eat_to_tokens(&[&token::OpenDelim(token::Paren)]); let span = lo.until(self.span); + // We needn't check `encountered_gt` to determine if we should pluralize "bracket". + // `encountered_gt` can only represent a single `>` character, if `number_of_shr >= 1` + // then there is either `>>` or `>>>` - in either case a plural is warranted. + let plural = number_of_shr >= 1; self.diagnostic() - .struct_span_err(span, "unmatched angle bracket") + .struct_span_err( + span, + &format!("unmatched angle bracket{}", if plural { "s" } else { "" }), + ) .span_suggestion_with_applicability( span, - "remove extra angle bracket", + &format!("remove extra angle bracket{}", if plural { "s" } else { "" }), String::new(), Applicability::MachineApplicable, ) diff --git a/src/test/ui/issues/issue-54521.stderr b/src/test/ui/issues/issue-54521.stderr index a67e9ca8daf40..ffefbfd0348a8 100644 --- a/src/test/ui/issues/issue-54521.stderr +++ b/src/test/ui/issues/issue-54521.stderr @@ -1,20 +1,20 @@ -error: unmatched angle bracket +error: unmatched angle brackets --> $DIR/issue-54521.rs:11:60 | LL | let _ = vec![1, 2, 3].into_iter().collect::>>>>>(); - | ^^^^ help: remove extra angle bracket + | ^^^^ help: remove extra angle brackets -error: unmatched angle bracket +error: unmatched angle brackets --> $DIR/issue-54521.rs:14:60 | LL | let _ = vec![1, 2, 3].into_iter().collect::>>>>(); - | ^^^ help: remove extra angle bracket + | ^^^ help: remove extra angle brackets -error: unmatched angle bracket +error: unmatched angle brackets --> $DIR/issue-54521.rs:17:60 | LL | let _ = vec![1, 2, 3].into_iter().collect::>>>(); - | ^^ help: remove extra angle bracket + | ^^ help: remove extra angle brackets error: unmatched angle bracket --> $DIR/issue-54521.rs:20:60 From ab2479b00db475b7b8fe3b9e93d2e92dbe72bff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 21 Jan 2019 15:13:59 -0800 Subject: [PATCH 0231/1064] Move logic to its own method --- src/librustc_typeck/check/coercion.rs | 136 ++++++++++++-------------- 1 file changed, 63 insertions(+), 73 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index e3aae21584c21..d1dfe9469fb77 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1208,83 +1208,20 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> db.span_label(cause.span, "return type is not `()`"); } ObligationCauseCode::BlockTailExpression(blk_id) => { - db = fcx.report_mismatched_types(cause, expected, found, err); - - let expr = expression.unwrap_or_else(|| { - span_bug!(cause.span, - "supposed to be part of a block tail expression, but the \ - expression is empty"); - }); - let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail( - &mut db, - expr, + let parent_id = fcx.tcx.hir().get_parent_node(blk_id); + db = self.report_return_mismatched_types( + cause, expected, found, - cause.span, - blk_id, + err, + fcx, + parent_id, + expression.map(|expr| (expr, blk_id)), ); - // FIXME: replace with navigating up the chain until hitting an fn or - // bailing if no "pass-through" Node is found, in order to provide a - // suggestion when encountering something like: - // ``` - // fn foo(a: bool) -> impl Debug { - // if a { - // bar()?; - // } - // { - // let x = unsafe { bar() }; - // x - // } - // } - // ``` - // - // Verify that this is a tail expression of a function, otherwise the - // label pointing out the cause for the type coercion will be wrong - // as prior return coercions would not be relevant (#57664). - let parent_id = fcx.tcx.hir().get_parent_node(blk_id); - let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); - if let (Some((fn_decl, _, _)), false) = ( - fcx.get_node_fn_decl(parent), - pointing_at_return_type, - ) { - if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { - db.span_label( - fn_decl.output.span(), - "expected because this return type...", - ); - db.span_label(*sp, format!( - "...is found to be `{}` here", - fcx.resolve_type_vars_with_obligations(expected), - )); - } - } } - ObligationCauseCode::ReturnType(_id) => { - db = fcx.report_mismatched_types(cause, expected, found, err); - let _id = fcx.tcx.hir().get_parent_node(_id); - let mut pointing_at_return_type = false; - let mut return_sp = None; - if let Some((fn_decl, can_suggest)) = fcx.get_fn_decl(_id) { - pointing_at_return_type = fcx.suggest_missing_return_type( - &mut db, &fn_decl, expected, found, can_suggest); - if !pointing_at_return_type { - return_sp = Some(fn_decl.output.span()); // `impl Trait` return type - } - } - if let (Some(sp), false) = ( - fcx.ret_coercion_span.borrow().as_ref(), - pointing_at_return_type, - ) { - if let Some(return_sp) = return_sp { - db.span_label(return_sp, "expected because this return type..."); - db.span_label( *sp, format!( - "...is found to be `{}` here", - fcx.resolve_type_vars_with_obligations(expected), - )); - } else if !sp.overlaps(cause.span) { - db.span_label(*sp, "expected because of this statement"); - } - } + ObligationCauseCode::ReturnType(id) => { + db = self.report_return_mismatched_types( + cause, expected, found, err, fcx, id, None); } _ => { db = fcx.report_mismatched_types(cause, expected, found, err); @@ -1302,6 +1239,59 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> } } + fn report_return_mismatched_types<'a>( + &self, + cause: &ObligationCause<'tcx>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + err: TypeError<'tcx>, + fcx: &FnCtxt<'a, 'gcx, 'tcx>, + id: syntax::ast::NodeId, + expression: Option<(&'gcx hir::Expr, syntax::ast::NodeId)>, + ) -> DiagnosticBuilder<'a> { + let mut db = fcx.report_mismatched_types(cause, expected, found, err); + + let mut pointing_at_return_type = false; + let mut return_sp = None; + + // Verify that this is a tail expression of a function, otherwise the + // label pointing out the cause for the type coercion will be wrong + // as prior return coercions would not be relevant (#57664). + let parent_id = fcx.tcx.hir().get_parent_node(id); + let fn_decl = if let Some((expr, blk_id)) = expression { + pointing_at_return_type = fcx.suggest_mismatched_types_on_tail( + &mut db, + expr, + expected, + found, + cause.span, + blk_id, + ); + let parent = fcx.tcx.hir().get(parent_id); + fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main)) + } else { + fcx.get_fn_decl(parent_id) + }; + + if let (Some((fn_decl, can_suggest)), _) = (fn_decl, pointing_at_return_type) { + if expression.is_none() { + pointing_at_return_type |= fcx.suggest_missing_return_type( + &mut db, &fn_decl, expected, found, can_suggest); + } + if !pointing_at_return_type { + return_sp = Some(fn_decl.output.span()); // `impl Trait` return type + } + } + if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) { + db.span_label(return_sp, "expected because this return type..."); + db.span_label( *sp, format!( + "...is found to be `{}` here", + fcx.resolve_type_vars_with_obligations(expected), + )); + } + db + } + pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> { if let Some(final_ty) = self.final_ty { final_ty From 914d142c02b558a597055c66a0e7e09115416211 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 22 Jan 2019 00:35:31 +0100 Subject: [PATCH 0232/1064] Extend trailing `>` detection for paths. This commit extends the trailing `>` detection to also work for paths such as `Foo::>:Baz`. This involves making the existing check take the token that is expected to follow the path being checked as a parameter. Care is taken to ensure that this only happens on the construction of a whole path segment and not a partial path segment (during recursion). Through this enhancement, it was also observed that the ordering of right shift token and greater than tokens was overfitted to the examples being tested. In practice, given a sequence of `>` characters: `>>>>>>>>>` ..then they will be split into `>>` eagerly: `>> >> >> >> >`. ..but when a `<` is prepended, then the first `>>` is split: ` > >> >> >> >` ..and then when another `<` is prepended, a right shift is first again: `Vec<> >> >> >> >` In the previous commits, a example that had two `<<` characters was always used and therefore it was incorrectly assumed that `>>` would always be first - but when there is a single `<`, this is not the case. --- src/libsyntax/parse/parser.rs | 94 ++++++++++++++++--------- src/test/ui/issues/issue-54521-2.fixed | 22 ++++++ src/test/ui/issues/issue-54521-2.rs | 22 ++++++ src/test/ui/issues/issue-54521-2.stderr | 26 +++++++ 4 files changed, 131 insertions(+), 33 deletions(-) create mode 100644 src/test/ui/issues/issue-54521-2.fixed create mode 100644 src/test/ui/issues/issue-54521-2.rs create mode 100644 src/test/ui/issues/issue-54521-2.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6a881eb624196..d380948b8913d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2149,7 +2149,27 @@ impl<'a> Parser<'a> { enable_warning: bool) -> PResult<'a, ()> { loop { - segments.push(self.parse_path_segment(style, enable_warning)?); + let segment = self.parse_path_segment(style, enable_warning)?; + if style == PathStyle::Expr { + // In order to check for trailing angle brackets, we must have finished + // recursing (`parse_path_segment` can indirectly call this function), + // that is, the next token must be the highlighted part of the below example: + // + // `Foo::>::Qux` + // ^ here + // + // As opposed to the below highlight (if we had only finished the first + // recursion): + // + // `Foo::>::Qux` + // ^ here + // + // `PathStyle::Expr` is only provided at the root invocation and never in + // `parse_path_segment` to recurse and therefore can be checked to maintain + // this invariant. + self.check_trailing_angle_brackets(&segment, token::ModSep); + } + segments.push(segment); if self.is_import_coupler() || !self.eat(&token::ModSep) { return Ok(()); @@ -2757,7 +2777,7 @@ impl<'a> Parser<'a> { // Assuming we have just parsed `.`, continue parsing into an expression. fn parse_dot_suffix(&mut self, self_arg: P, lo: Span) -> PResult<'a, P> { let segment = self.parse_path_segment(PathStyle::Expr, true)?; - self.check_trailing_angle_brackets(&segment); + self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren)); Ok(match self.token { token::OpenDelim(token::Paren) => { @@ -2793,15 +2813,19 @@ impl<'a> Parser<'a> { /// let _ = vec![1, 2, 3].into_iter().collect::>>>(); /// ^^ help: remove extra angle brackets /// ``` - fn check_trailing_angle_brackets(&mut self, segment: &PathSegment) { - // This function is intended to be invoked from `parse_dot_suffix` where there are two + fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, end: token::Token) { + // This function is intended to be invoked after parsing a path segment where there are two // cases: // - // - A field access (eg. `x.foo`) - // - A method call (eg. `x.foo()`) + // 1. A specific token is expected after the path segment. + // eg. `x.foo(`, `x.foo::(` (parenthesis - method call), + // `Foo::`, or `Foo::::` (mod sep - continued path). + // 2. No specific token is expected after the path segment. + // eg. `x.foo` (field access) // - // This function is called after parsing `.foo` and before parsing any parenthesis (if - // present). This includes any angle bracket arguments, such as `.foo::`. + // This function is called after parsing `.foo` and before parsing the token `end` (if + // present). This includes any angle bracket arguments, such as `.foo::` or + // `Foo::`. // We only care about trailing angle brackets if we previously parsed angle bracket // arguments. This helps stop us incorrectly suggesting that extra angle brackets be @@ -2836,43 +2860,47 @@ impl<'a> Parser<'a> { // actual operators and not trailing characters - ie `x.foo >> 3`). let mut position = 0; - // The first tokens we will encounter are shift right tokens (`>>`) since pairs of `>` - // characters will have been grouped together by the tokenizer. + // We can encounter `>` or `>>` tokens in any order, so we need to keep track of how + // many of each (so we can correctly pluralize our error messages) and continue to + // advance. let mut number_of_shr = 0; - while self.look_ahead(position, |t| *t == token::BinOp(token::BinOpToken::Shr)) { - number_of_shr += 1; - position += 1; - } - - // Afterwards, there will be at most one `>` character remaining (more than one and it'd - // have shown up as a `>>`). - let encountered_gt = self.look_ahead(position, |t| *t == token::Gt); - if encountered_gt { + let mut number_of_gt = 0; + while self.look_ahead(position, |t| { + trace!("check_trailing_angle_brackets: t={:?}", t); + if *t == token::BinOp(token::BinOpToken::Shr) { + number_of_shr += 1; + true + } else if *t == token::Gt { + number_of_gt += 1; + true + } else { + false + } + }) { position += 1; } - // If we didn't find any trailing `>>` characters or a trailing `>`, then we have - // nothing to error about. + // If we didn't find any trailing `>` characters, then we have nothing to error about. debug!( - "check_trailing_angle_brackets: encountered_gt={:?} number_of_shr={:?}", - encountered_gt, number_of_shr, + "check_trailing_angle_brackets: number_of_gt={:?} number_of_shr={:?}", + number_of_gt, number_of_shr, ); - if !encountered_gt && number_of_shr < 1 { + if number_of_gt < 1 && number_of_shr < 1 { return; } - // Finally, double check that we have a left parenthesis next as otherwise this is the - // field case. - if self.look_ahead(position, |t| *t == token::OpenDelim(token::Paren)) { - // Eat from where we started until the left parenthesis so that parsing can continue + // Finally, double check that we have our end token as otherwise this is the + // second case. + if self.look_ahead(position, |t| { + trace!("check_trailing_angle_brackets: t={:?}", t); + *t == end + }) { + // Eat from where we started until the end token so that parsing can continue // as if we didn't have those extra angle brackets. - self.eat_to_tokens(&[&token::OpenDelim(token::Paren)]); + self.eat_to_tokens(&[&end]); let span = lo.until(self.span); - // We needn't check `encountered_gt` to determine if we should pluralize "bracket". - // `encountered_gt` can only represent a single `>` character, if `number_of_shr >= 1` - // then there is either `>>` or `>>>` - in either case a plural is warranted. - let plural = number_of_shr >= 1; + let plural = number_of_gt > 1 || number_of_shr >= 1; self.diagnostic() .struct_span_err( span, diff --git a/src/test/ui/issues/issue-54521-2.fixed b/src/test/ui/issues/issue-54521-2.fixed new file mode 100644 index 0000000000000..a91c4fe43ea46 --- /dev/null +++ b/src/test/ui/issues/issue-54521-2.fixed @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = Vec::>>::new(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = Vec::::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::::new(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/issues/issue-54521-2.rs b/src/test/ui/issues/issue-54521-2.rs new file mode 100644 index 0000000000000..3639aac87ee7f --- /dev/null +++ b/src/test/ui/issues/issue-54521-2.rs @@ -0,0 +1,22 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = Vec::>>::new(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = Vec::>>>>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::>>>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::>>::new(); + //~^ ERROR unmatched angle bracket + + let _ = Vec::>::new(); + //~^ ERROR unmatched angle bracket +} diff --git a/src/test/ui/issues/issue-54521-2.stderr b/src/test/ui/issues/issue-54521-2.stderr new file mode 100644 index 0000000000000..9556b83b730a4 --- /dev/null +++ b/src/test/ui/issues/issue-54521-2.stderr @@ -0,0 +1,26 @@ +error: unmatched angle brackets + --> $DIR/issue-54521-2.rs:11:25 + | +LL | let _ = Vec::>>>>::new(); + | ^^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-54521-2.rs:14:25 + | +LL | let _ = Vec::>>>::new(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-54521-2.rs:17:25 + | +LL | let _ = Vec::>>::new(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-54521-2.rs:20:25 + | +LL | let _ = Vec::>::new(); + | ^ help: remove extra angle bracket + +error: aborting due to 4 previous errors + From 4745b86202f0e96b4c0d0de05220a5ac4b5308ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 21 Jan 2019 15:28:51 -0800 Subject: [PATCH 0233/1064] Accept more invalid code that is close to correct fields --- src/libsyntax/parse/parser.rs | 22 +++++++++++++++++-- src/test/ui/parser/removed-syntax-with-1.rs | 3 +-- .../ui/parser/removed-syntax-with-1.stderr | 11 ++-------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a2d3595b47206..745f2c7dc19e4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2695,6 +2695,21 @@ impl<'a> Parser<'a> { break; } + let mut recovery_field = None; + if let token::Ident(ident, _) = self.token { + if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) { + // Use in case of error after field-looking code: `S { foo: () with a }` + let mut ident = ident.clone(); + ident.span = self.span; + recovery_field = Some(ast::Field { + ident, + span: self.span, + expr: self.mk_expr(self.span, ExprKind::Err, ThinVec::new()), + is_shorthand: false, + attrs: ThinVec::new(), + }); + } + } let mut parsed_field = None; match self.parse_field() { Ok(f) => parsed_field = Some(f), @@ -2716,11 +2731,14 @@ impl<'a> Parser<'a> { match self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) { - Ok(()) => if let Some(f) = parsed_field { - // only include the field if there's no parse error + Ok(()) => if let Some(f) = parsed_field.or(recovery_field) { + // only include the field if there's no parse error for the field name fields.push(f); } Err(mut e) => { + if let Some(f) = recovery_field { + fields.push(f); + } e.span_label(struct_sp, "while parsing this struct"); e.emit(); self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore); diff --git a/src/test/ui/parser/removed-syntax-with-1.rs b/src/test/ui/parser/removed-syntax-with-1.rs index add024ea3907f..2c1e152dcee75 100644 --- a/src/test/ui/parser/removed-syntax-with-1.rs +++ b/src/test/ui/parser/removed-syntax-with-1.rs @@ -5,7 +5,6 @@ fn main() { } let a = S { foo: (), bar: () }; - let b = S { foo: () with a }; + let b = S { foo: () with a, bar: () }; //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with` - //~| ERROR missing fields `bar`, `foo` in initializer of `main::S` } diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr index aae29efa85e54..a157873916a64 100644 --- a/src/test/ui/parser/removed-syntax-with-1.stderr +++ b/src/test/ui/parser/removed-syntax-with-1.stderr @@ -1,17 +1,10 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with` --> $DIR/removed-syntax-with-1.rs:8:25 | -LL | let b = S { foo: () with a }; +LL | let b = S { foo: () with a, bar: () }; | - ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here | | | while parsing this struct -error[E0063]: missing fields `bar`, `foo` in initializer of `main::S` - --> $DIR/removed-syntax-with-1.rs:8:13 - | -LL | let b = S { foo: () with a }; - | ^ missing `bar`, `foo` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0063`. From 1d6e5e71089cc4001639757b9f75ee6fc4744e1e Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 21 Jan 2019 15:53:45 -0800 Subject: [PATCH 0234/1064] Fix typo Co-Authored-By: estebank --- src/libsyntax_pos/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 7f52d1335f728..b6b9b608531e4 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -732,7 +732,7 @@ impl MultiSpan { span_labels } - /// Returns wether any of the span labels is displayable. + /// Returns whether any of the span labels is displayable. pub fn has_span_labels(&self) -> bool { self.span_labels.iter().any(|(sp, _)| !sp.is_dummy()) } From f077990ed4e7fadd0197d00d65a198e02544ab07 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 21 Jan 2019 15:53:56 -0800 Subject: [PATCH 0235/1064] Fix typo Co-Authored-By: estebank --- src/libsyntax_pos/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index b6b9b608531e4..d9d7f9b0cb492 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -668,7 +668,7 @@ impl MultiSpan { &self.primary_spans } - /// Returns wether any of the primary spans is displayable. + /// Returns whether any of the primary spans is displayable. pub fn has_primary_spans(&self) -> bool { self.primary_spans.iter().any(|sp| !sp.is_dummy()) } From 051835b903181ac0a2e549327de9e8d89cf3d457 Mon Sep 17 00:00:00 2001 From: Marcel Hellwig Date: Mon, 21 Jan 2019 08:09:56 +0100 Subject: [PATCH 0236/1064] Corrected spelling inconsistency resolves #57773 --- src/librustc/hir/lowering.rs | 4 ++-- src/libsyntax/ast.rs | 8 ++++---- src/libsyntax/fold.rs | 12 ++++++------ src/libsyntax/parse/parser.rs | 4 ++-- ...ggestion.rs => parenthesized-deref-suggestion.rs} | 0 ....stderr => parenthesized-deref-suggestion.stderr} | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) rename src/test/ui/{parenthesised-deref-suggestion.rs => parenthesized-deref-suggestion.rs} (100%) rename src/test/ui/{parenthesised-deref-suggestion.stderr => parenthesized-deref-suggestion.stderr} (88%) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f7af135bc7605..905a3ceed81c9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1931,7 +1931,7 @@ impl<'a> LoweringContext<'a> { fn lower_parenthesized_parameter_data( &mut self, - data: &ParenthesisedArgs, + data: &ParenthesizedArgs, ) -> (hir::GenericArgs, bool) { // Switch to `PassThrough` mode for anonymous lifetimes: this // means that we permit things like `&Ref`, where `Ref` has @@ -1941,7 +1941,7 @@ impl<'a> LoweringContext<'a> { self.with_anonymous_lifetime_mode( AnonymousLifetimeMode::PassThrough, |this| { - let &ParenthesisedArgs { ref inputs, ref output, span } = data; + let &ParenthesizedArgs { ref inputs, ref output, span } = data; let inputs = inputs .iter() .map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 405cf612543fb..798f14dcba955 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -136,7 +136,7 @@ pub enum GenericArgs { /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` AngleBracketed(AngleBracketedArgs), /// The `(A,B)` and `C` in `Foo(A,B) -> C` - Parenthesized(ParenthesisedArgs), + Parenthesized(ParenthesizedArgs), } impl GenericArgs { @@ -173,7 +173,7 @@ impl Into>> for AngleBracketedArgs { } } -impl Into>> for ParenthesisedArgs { +impl Into>> for ParenthesizedArgs { fn into(self) -> Option> { Some(P(GenericArgs::Parenthesized(self))) } @@ -181,7 +181,7 @@ impl Into>> for ParenthesisedArgs { /// A path like `Foo(A,B) -> C` #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct ParenthesisedArgs { +pub struct ParenthesizedArgs { /// Overall span pub span: Span, @@ -192,7 +192,7 @@ pub struct ParenthesisedArgs { pub output: Option>, } -impl ParenthesisedArgs { +impl ParenthesizedArgs { pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs { AngleBracketedArgs { span: self.span, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index a4c3b38f691ed..fdcbbb939a6cf 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -207,8 +207,8 @@ pub trait Folder : Sized { noop_fold_angle_bracketed_parameter_data(p, self) } - fn fold_parenthesized_parameter_data(&mut self, p: ParenthesisedArgs) - -> ParenthesisedArgs + fn fold_parenthesized_parameter_data(&mut self, p: ParenthesizedArgs) + -> ParenthesizedArgs { noop_fold_parenthesized_parameter_data(p, self) } @@ -504,12 +504,12 @@ pub fn noop_fold_angle_bracketed_parameter_data(data: AngleBracketedA } } -pub fn noop_fold_parenthesized_parameter_data(data: ParenthesisedArgs, +pub fn noop_fold_parenthesized_parameter_data(data: ParenthesizedArgs, fld: &mut T) - -> ParenthesisedArgs + -> ParenthesizedArgs { - let ParenthesisedArgs { inputs, output, span } = data; - ParenthesisedArgs { + let ParenthesizedArgs { inputs, output, span } = data; + ParenthesizedArgs { inputs: inputs.move_map(|ty| fld.fold_ty(ty)), output: output.map(|ty| fld.fold_ty(ty)), span: fld.new_span(span) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 439eec5b0c48d..09ea099525326 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1,5 +1,5 @@ use rustc_target::spec::abi::{self, Abi}; -use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy}; +use ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy}; use ast::{GenericBound, TraitBoundModifier}; use ast::Unsafety; use ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind}; @@ -2203,7 +2203,7 @@ impl<'a> Parser<'a> { } else { None }; - ParenthesisedArgs { inputs, output, span }.into() + ParenthesizedArgs { inputs, output, span }.into() }; PathSegment { ident, args, id: ast::DUMMY_NODE_ID } diff --git a/src/test/ui/parenthesised-deref-suggestion.rs b/src/test/ui/parenthesized-deref-suggestion.rs similarity index 100% rename from src/test/ui/parenthesised-deref-suggestion.rs rename to src/test/ui/parenthesized-deref-suggestion.rs diff --git a/src/test/ui/parenthesised-deref-suggestion.stderr b/src/test/ui/parenthesized-deref-suggestion.stderr similarity index 88% rename from src/test/ui/parenthesised-deref-suggestion.stderr rename to src/test/ui/parenthesized-deref-suggestion.stderr index 71a2bf67f06ae..fd9b0e8216b41 100644 --- a/src/test/ui/parenthesised-deref-suggestion.stderr +++ b/src/test/ui/parenthesized-deref-suggestion.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `opts` on type `*const Session` - --> $DIR/parenthesised-deref-suggestion.rs:7:30 + --> $DIR/parenthesized-deref-suggestion.rs:7:30 | LL | (sess as *const Session).opts; //~ ERROR no field `opts` on type `*const Session` | ^^^^ @@ -9,7 +9,7 @@ LL | (*(sess as *const Session)).opts; //~ ERROR no field `opts` on type `*c | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0609]: no field `0` on type `[u32; 1]` - --> $DIR/parenthesised-deref-suggestion.rs:10:21 + --> $DIR/parenthesized-deref-suggestion.rs:10:21 | LL | (x as [u32; 1]).0; //~ ERROR no field `0` on type `[u32; 1]` | ----------------^ From 9aa1ca2f462d16c5f6d49830b72af91888bc8ab4 Mon Sep 17 00:00:00 2001 From: James Duley Date: Thu, 17 Jan 2019 23:17:21 +0000 Subject: [PATCH 0237/1064] Ignore aarch64 in simd-intrinsic-generic-reduction This fails on AArch64 see https://github.com/rust-lang/rust/issues/54510 --- src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs index b39f54a5efbb4..e3faa7c625ccc 100644 --- a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs @@ -2,6 +2,7 @@ #![allow(non_camel_case_types)] // ignore-emscripten +// ignore-aarch64 FIXME: https://github.com/rust-lang/rust/issues/54510 // Test that the simd_reduce_{op} intrinsics produce the correct results. From 785f529d6e91b787d94b44726a5d6018e8fe181b Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 2 Jan 2019 16:49:30 +0100 Subject: [PATCH 0238/1064] Add intrinsic to create an integer bitmask from the MSB of integer vectors --- src/librustc_codegen_llvm/intrinsic.rs | 46 ++++++++++ src/librustc_typeck/check/intrinsic.rs | 1 + .../codegen/simd-intrinsic-generic-bitmask.rs | 57 ++++++++++++ .../simd/simd-intrinsic-generic-bitmask.rs | 61 +++++++++++++ .../simd-intrinsic-generic-bitmask.rs | 90 +++++++++++++++++++ .../simd-intrinsic-generic-bitmask.stderr | 33 +++++++ 6 files changed, 288 insertions(+) create mode 100644 src/test/codegen/simd-intrinsic-generic-bitmask.rs create mode 100644 src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs create mode 100644 src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs create mode 100644 src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index f5680b295477a..c49d54dbb0d7d 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1303,6 +1303,52 @@ fn generic_simd_intrinsic( return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } + if name == "simd_bitmask" { + // The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a + // vector mask and returns an unsigned integer containing the most + // significant bit (MSB) of each lane. + use rustc_target::abi::HasDataLayout; + + // If the vector has less than 8 lanes, an u8 is returned with zeroed + // trailing bits. + let expected_int_bits = in_len.max(8); + match ret_ty.sty { + ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => (), + _ => return_error!( + "bitmask `{}`, expected `u{}`", + ret_ty, expected_int_bits + ), + } + + // Integer vector : + let (i_xn, in_elem_bitwidth) = match in_elem.sty { + ty::Int(i) => ( + args[0].immediate(), + i.bit_width().unwrap_or(bx.data_layout().pointer_size.bits() as _) + ), + ty::Uint(i) => ( + args[0].immediate(), + i.bit_width().unwrap_or(bx.data_layout().pointer_size.bits() as _) + ), + _ => return_error!( + "vector argument `{}`'s element type `{}`, expected integer element type", + in_ty, in_elem + ), + }; + + // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. + let shift_indices = vec![ + bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _); in_len + ]; + let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice())); + // Truncate vector to an + let i1xn = bx.trunc(i_xn_msb, bx.type_vector(bx.type_i1(), in_len as _)); + // Bitcast to iN: + let i_ = bx.bitcast(i1xn, bx.type_ix(in_len as _)); + // Zero-extend iN to the bitmask type: + return Ok(bx.zext(i_, bx.type_ix(expected_int_bits as _))); + } + fn simd_simple_float_intrinsic( name: &str, in_elem: &::rustc::ty::TyS, diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index a36b21921436e..168fddac97f16 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -425,6 +425,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), + "simd_bitmask" => (2, vec![param(0)], param(1)), "simd_select" | "simd_select_bitmask" => (2, vec![param(0), param(1), param(1)], param(1)), "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), diff --git a/src/test/codegen/simd-intrinsic-generic-bitmask.rs b/src/test/codegen/simd-intrinsic-generic-bitmask.rs new file mode 100644 index 0000000000000..cd8130f923148 --- /dev/null +++ b/src/test/codegen/simd-intrinsic-generic-bitmask.rs @@ -0,0 +1,57 @@ +// compile-flags: -C no-prepopulate-passes +// ignore-tidy-linelength + +#![crate_type = "lib"] + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x2(u32, u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct i32x2(i32, i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct i8x16( + i8, i8, i8, i8, i8, i8, i8, i8, + i8, i8, i8, i8, i8, i8, i8, i8, +); + + +extern "platform-intrinsic" { + fn simd_bitmask(x: T) -> U; +} + +// CHECK-LABEL: @bitmask_int +#[no_mangle] +pub unsafe fn bitmask_int(x: i32x2) -> u8 { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{[0-9]+}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: [[C:%[0-9]+]] = bitcast <2 x i1> [[B]] to i2 + // CHECK: %{{[0-9]+}} = zext i2 [[C]] to i8 + simd_bitmask(x) +} + +// CHECK-LABEL: @bitmask_uint +#[no_mangle] +pub unsafe fn bitmask_uint(x: u32x2) -> u8 { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{[0-9]+}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: [[C:%[0-9]+]] = bitcast <2 x i1> [[B]] to i2 + // CHECK: %{{[0-9]+}} = zext i2 [[C]] to i8 + simd_bitmask(x) +} + +// CHECK-LABEL: @bitmask_int16 +#[no_mangle] +pub unsafe fn bitmask_int16(x: i8x16) -> u16 { + // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{[0-9]+}}, + // CHECK: [[B:%[0-9]+]] = trunc <16 x i8> [[A]] to <16 x i1> + // CHECK: %{{[0-9]+}} = bitcast <16 x i1> [[B]] to i16 + // CHECK-NOT: zext + simd_bitmask(x) +} diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs b/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs new file mode 100644 index 0000000000000..b28f742a92e94 --- /dev/null +++ b/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs @@ -0,0 +1,61 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten + +// Test that the simd_bitmask intrinsic produces correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u8x4(pub u8, pub u8, pub u8, pub u8); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct Tx4(pub T, pub T, pub T, pub T); + +extern "platform-intrinsic" { + fn simd_bitmask(x: T) -> U; +} + +fn main() { + let z = u32x4(0, 0, 0, 0); + let ez = 0_u8; + + let o = u32x4(!0, !0, !0, !0); + let eo = 0b_1111_u8; + + let m0 = u32x4(!0, 0, !0, 0); + let e0 = 0b_0000_0101_u8; + + // Check that the MSB is extracted: + let m = u8x4(0b_1000_0000, 0b_0100_0001, 0b_1100_0001, 0b_1111_1111); + let e = 0b_1101; + + // Check usize / isize + let msize: Tx4 = Tx4(usize::max_value(), 0, usize::max_value(), usize::max_value()); + + unsafe { + let r: u8 = simd_bitmask(z); + assert_eq!(r, ez); + + let r: u8 = simd_bitmask(o); + assert_eq!(r, eo); + + let r: u8 = simd_bitmask(m0); + assert_eq!(r, e0); + + let r: u8 = simd_bitmask(m); + assert_eq!(r, e); + + let r: u8 = simd_bitmask(msize); + assert_eq!(r, e); + + } +} diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs new file mode 100644 index 0000000000000..931ee9db1fe15 --- /dev/null +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -0,0 +1,90 @@ +// Test that the simd_bitmask intrinsic produces ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x2(pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x8( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x16( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x32( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x64( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +extern "platform-intrinsic" { + fn simd_bitmask(x: T) -> U; +} + +fn main() { + let m2 = u32x2(0, 0); + let m4 = u32x4(0, 0, 0, 0); + let m8 = u8x8(0, 0, 0, 0, 0, 0, 0, 0); + let m16 = u8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + let m32 = u8x32(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + let m64 = u8x64(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + unsafe { + let _: u8 = simd_bitmask(m2); + let _: u8 = simd_bitmask(m4); + let _: u8 = simd_bitmask(m8); + let _: u16 = simd_bitmask(m16); + let _: u32 = simd_bitmask(m32); + let _: u64 = simd_bitmask(m64); + + let _: u16 = simd_bitmask(m2); + //~^ ERROR bitmask `u16`, expected `u8` + + let _: u16 = simd_bitmask(m8); + //~^ ERROR bitmask `u16`, expected `u8` + + let _: u32 = simd_bitmask(m16); + //~^ ERROR bitmask `u32`, expected `u16` + + let _: u64 = simd_bitmask(m32); + //~^ ERROR bitmask `u64`, expected `u32` + + let _: u128 = simd_bitmask(m64); + //~^ ERROR bitmask `u128`, expected `u64` + + } +} diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr new file mode 100644 index 0000000000000..d016838d098d4 --- /dev/null +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr @@ -0,0 +1,33 @@ +error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8` + --> $DIR/simd-intrinsic-generic-bitmask.rs:74:22 + | +LL | let _: u16 = simd_bitmask(m2); + | ^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8` + --> $DIR/simd-intrinsic-generic-bitmask.rs:77:22 + | +LL | let _: u16 = simd_bitmask(m8); + | ^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u32`, expected `u16` + --> $DIR/simd-intrinsic-generic-bitmask.rs:80:22 + | +LL | let _: u32 = simd_bitmask(m16); + | ^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u64`, expected `u32` + --> $DIR/simd-intrinsic-generic-bitmask.rs:83:22 + | +LL | let _: u64 = simd_bitmask(m32); + | ^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u128`, expected `u64` + --> $DIR/simd-intrinsic-generic-bitmask.rs:86:23 + | +LL | let _: u128 = simd_bitmask(m64); + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0511`. From 86d5cb4110d7944e2ea1850ff3522372400a04e8 Mon Sep 17 00:00:00 2001 From: danielhenrymantilla Date: Tue, 22 Jan 2019 11:30:59 +0100 Subject: [PATCH 0239/1064] Fixed Deref coercion explanation for DerefMut using shared references --- src/libcore/ops/deref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs index 075c3a084f41d..bec3a155c18a8 100644 --- a/src/libcore/ops/deref.rs +++ b/src/libcore/ops/deref.rs @@ -109,7 +109,7 @@ impl Deref for &mut T { /// then: /// /// * In mutable contexts, `*x` on non-pointer types is equivalent to -/// `*Deref::deref(&x)`. +/// `*DerefMut::deref_mut(&mut x)`. /// * Values of type `&mut T` are coerced to values of type `&mut U` /// * `T` implicitly implements all the (mutable) methods of the type `U`. /// From 2ec0e85305e69d7f6e1bc0c704a6566ad38232a4 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 22 Jan 2019 18:51:54 +0530 Subject: [PATCH 0240/1064] Print a slightly clearer message when failing to spawn a thread --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index a55b32c08a303..eb8e0c1c8ac66 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -607,7 +607,7 @@ impl Builder { pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static { - Builder::new().spawn(f).unwrap() + Builder::new().spawn(f).expect("failed to spawn thread") } /// Gets a handle to the thread that invokes it. From fb5d3c1f379e42b9d31887b744982159a0dc651b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 22 Jan 2019 14:25:27 +0100 Subject: [PATCH 0241/1064] Stabilize Any::get_type_id and rename to type_id FCP: https://github.com/rust-lang/rust/issues/27745#issuecomment-373906749 --- src/libcore/any.rs | 16 ++++++---------- src/test/ui/traits/trait-privacy.rs | 3 +-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 6a863ff369a87..2afd9e0c07237 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -81,12 +81,10 @@ pub trait Any: 'static { /// # Examples /// /// ``` - /// #![feature(get_type_id)] - /// /// use std::any::{Any, TypeId}; /// /// fn is_string(s: &dyn Any) -> bool { - /// TypeId::of::() == s.get_type_id() + /// TypeId::of::() == s.type_id() /// } /// /// fn main() { @@ -94,15 +92,13 @@ pub trait Any: 'static { /// assert_eq!(is_string(&"cookie monster".to_string()), true); /// } /// ``` - #[unstable(feature = "get_type_id", - reason = "this method will likely be replaced by an associated static", - issue = "27745")] - fn get_type_id(&self) -> TypeId; + #[stable(feature = "get_type_id", since = "1.34.0")] + fn type_id(&self) -> TypeId; } #[stable(feature = "rust1", since = "1.0.0")] impl Any for T { - fn get_type_id(&self) -> TypeId { TypeId::of::() } + fn type_id(&self) -> TypeId { TypeId::of::() } } /////////////////////////////////////////////////////////////////////////////// @@ -161,10 +157,10 @@ impl dyn Any { let t = TypeId::of::(); // Get TypeId of the type in the trait object - let boxed = self.get_type_id(); + let concrete = self.type_id(); // Compare both TypeIds on equality - t == boxed + t == concrete } /// Returns some reference to the boxed value if it is of type `T`, or diff --git a/src/test/ui/traits/trait-privacy.rs b/src/test/ui/traits/trait-privacy.rs index 523211fea9368..6254157e25da3 100644 --- a/src/test/ui/traits/trait-privacy.rs +++ b/src/test/ui/traits/trait-privacy.rs @@ -1,5 +1,4 @@ // compile-pass -#![feature(get_type_id)] #![allow(dead_code)] mod foo { pub use self::bar::T; @@ -18,7 +17,7 @@ fn g() { fn f() { let error = ::std::thread::spawn(|| {}).join().unwrap_err(); - error.get_type_id(); // Regression test for #21670 + error.type_id(); // Regression test for #21670 } From 2dea8ec630eebabee46bc51b3ea14fe5e88834c1 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 22 Jan 2019 13:51:30 +0100 Subject: [PATCH 0242/1064] Do not initiate nested probe within `assemble_probe`. In particular, the table entries (associated with type-variables created during the probe) must persist as long as the candidates assembled during the probe. If you make a nested probe without creating a nested `ProbeContext`, the table entries are popped at the end of the nested probe, while the type-variables would leak out via the assembled candidates attached to `self` (the outer `ProbeContext`). This causes an ICE (*if you are lucky*)! --- src/librustc_typeck/check/method/probe.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 9a828ce01775c..b849be52a9223 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -506,15 +506,13 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { match self_ty.value.value.sty { ty::Dynamic(ref data, ..) => { if let Some(p) = data.principal() { - self.fcx.probe(|_| { - let InferOk { value: self_ty, obligations: _ } = - self.fcx.probe_instantiate_query_response( - self.span, &self.orig_steps_var_values, self_ty) - .unwrap_or_else(|_| { - span_bug!(self.span, "{:?} was applicable but now isn't?", self_ty) - }); - self.assemble_inherent_candidates_from_object(self_ty); - }); + let InferOk { value: instantiated_self_ty, obligations: _ } = + self.fcx.probe_instantiate_query_response( + self.span, &self.orig_steps_var_values, self_ty) + .unwrap_or_else(|_| { + span_bug!(self.span, "{:?} was applicable but now isn't?", self_ty) + }); + self.assemble_inherent_candidates_from_object(instantiated_self_ty); self.assemble_inherent_impl_candidates_for_type(p.def_id()); } } From 33c2ceb3a2b769fb3f2f6019b1071439f0dc6444 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 22 Jan 2019 14:49:18 +0100 Subject: [PATCH 0243/1064] unit test for issue 57673. --- .../issue-57673-ice-on-deref-of-boxed-trait.rs | 7 +++++++ .../issue-57673-ice-on-deref-of-boxed-trait.stderr | 14 ++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs create mode 100644 src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs new file mode 100644 index 0000000000000..0a4e7da2bff50 --- /dev/null +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs @@ -0,0 +1,7 @@ +//extern crate has_assoc_type; + +//fn ice(x: Box>) { +fn ice(x: Box>) { + *x //~ ERROR mismatched types [E0308] +} +fn main() {} diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr new file mode 100644 index 0000000000000..bb63917fc0860 --- /dev/null +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-57673-ice-on-deref-of-boxed-trait.rs:5:5 + | +LL | fn ice(x: Box>) { + | - possibly return type missing here? +LL | *x //~ ERROR mismatched types [E0308] + | ^^ expected (), found trait std::iter::Iterator + | + = note: expected type `()` + found type `(dyn std::iter::Iterator + 'static)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 26edb28d317fa54aec3358ec3179884d2b35ca98 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 22 Jan 2019 15:08:31 +0100 Subject: [PATCH 0244/1064] Fix some cross crate existential type ICEs --- src/librustc_metadata/decoder.rs | 3 +++ src/librustc_resolve/build_reduced_graph.rs | 1 + src/librustc_typeck/check/wfcheck.rs | 4 ++-- .../auxiliary/cross_crate_ice.rs | 13 +++++++++++ .../auxiliary/cross_crate_ice2.rs | 22 +++++++++++++++++++ .../ui/existential_types/cross_crate_ice.rs | 16 ++++++++++++++ .../ui/existential_types/cross_crate_ice2.rs | 11 ++++++++++ 7 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/existential_types/auxiliary/cross_crate_ice.rs create mode 100644 src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs create mode 100644 src/test/ui/existential_types/cross_crate_ice.rs create mode 100644 src/test/ui/existential_types/cross_crate_ice2.rs diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 1f07e8f478b5a..ad6296e1a3bd8 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -893,6 +893,9 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::AssociatedType(container) => { (ty::AssociatedKind::Type, container, false) } + EntryKind::AssociatedExistential(container) => { + (ty::AssociatedKind::Existential, container, false) + } _ => bug!("cannot get associated-item of `{:?}`", def_key) }; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 35616cc03a936..3db73800d640a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -680,6 +680,7 @@ impl<'a> Resolver<'a> { } module.populated.set(true); } + Def::Existential(..) | Def::TraitAlias(..) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 53e44d53e6a9b..6cae8d6fc5b94 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -608,8 +608,8 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( if let ty::Opaque(def_id, substs) = ty.sty { trace!("check_existential_types: opaque_ty, {:?}, {:?}", def_id, substs); let generics = tcx.generics_of(def_id); - // only check named existential types - if generics.parent.is_none() { + // only check named existential types defined in this crate + if generics.parent.is_none() && def_id.is_local() { let opaque_node_id = tcx.hir().as_local_node_id(def_id).unwrap(); if may_define_existential_type(tcx, fn_def_id, opaque_node_id) { trace!("check_existential_types may define. Generics: {:#?}", generics); diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs new file mode 100644 index 0000000000000..c6fba2c33a81f --- /dev/null +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs @@ -0,0 +1,13 @@ +// Crate that exports an existential type. Used for testing cross-crate. + +#![feature(const_fn)] +#![crate_type="rlib"] + +#![feature(existential_type)] + +pub existential type Foo: std::fmt::Debug; + +pub fn foo() -> Foo { + 5 +} + diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs new file mode 100644 index 0000000000000..c23fa6b5dea01 --- /dev/null +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs @@ -0,0 +1,22 @@ +// Crate that exports an existential type. Used for testing cross-crate. + +#![feature(const_fn)] +#![crate_type="rlib"] + +#![feature(existential_type)] + +pub trait View { + type Tmp: Iterator; + + fn test(&self) -> Self::Tmp; +} + +pub struct X; + +impl View for X { + existential type Tmp: Iterator; + + fn test(&self) -> Self::Tmp { + vec![1,2,3].into_iter() + } +} diff --git a/src/test/ui/existential_types/cross_crate_ice.rs b/src/test/ui/existential_types/cross_crate_ice.rs new file mode 100644 index 0000000000000..c5d5ca916a48a --- /dev/null +++ b/src/test/ui/existential_types/cross_crate_ice.rs @@ -0,0 +1,16 @@ +// aux-build:cross_crate_ice.rs +// compile-pass + +extern crate cross_crate_ice; + +struct Bar(cross_crate_ice::Foo); + +impl Bar { + fn zero(&self) -> &cross_crate_ice::Foo { + &self.0 + } +} + +fn main() { + let _ = cross_crate_ice::foo(); +} diff --git a/src/test/ui/existential_types/cross_crate_ice2.rs b/src/test/ui/existential_types/cross_crate_ice2.rs new file mode 100644 index 0000000000000..a0f3933ce33b2 --- /dev/null +++ b/src/test/ui/existential_types/cross_crate_ice2.rs @@ -0,0 +1,11 @@ +// aux-build:cross_crate_ice2.rs +// compile-pass + +extern crate cross_crate_ice2; + +use cross_crate_ice2::View; + +fn main() { + let v = cross_crate_ice2::X; + v.test(); +} From a59eabbc36d7b96bb9e42d9bc6691d28b62c4187 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 14 Jan 2019 17:54:00 +0100 Subject: [PATCH 0245/1064] Get rid of the fake stack frame --- src/librustc_codegen_ssa/mir/constant.rs | 1 - src/librustc_mir/const_eval.rs | 80 ++++-------------------- src/librustc_mir/hair/pattern/_match.rs | 23 +++++-- src/librustc_mir/hair/pattern/mod.rs | 4 +- src/librustc_mir/transform/const_prop.rs | 6 +- src/test/ui/consts/match_ice.rs | 11 ++++ 6 files changed, 44 insertions(+), 81 deletions(-) create mode 100644 src/test/ui/consts/match_ice.rs diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index e6d6ef1d7a38b..56d4342e6e161 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -59,7 +59,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let field = const_field( bx.tcx(), ty::ParamEnv::reveal_all(), - self.instance, None, mir::Field::new(field as usize), c, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 105856fecc729..25b0d1424ca47 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -10,16 +10,15 @@ use rustc::hir::{self, def_id::DefId}; use rustc::hir::def::Def; use rustc::mir::interpret::{ConstEvalErr, ErrorHandled}; use rustc::mir; -use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt}; +use rustc::ty::{self, TyCtxt, query::TyCtxtAt}; use rustc::ty::layout::{self, LayoutOf, TyLayout, VariantIdx}; use rustc::ty::subst::Subst; use rustc::traits::Reveal; -use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::FxHashMap; use rustc::util::common::ErrorReported; use syntax::ast::Mutability; -use syntax::source_map::{Span, DUMMY_SP}; +use syntax::source_map::DUMMY_SP; use crate::interpret::{self, PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, RawConst, ConstValue, Pointer, @@ -35,56 +34,6 @@ const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000; /// Should be a power of two for performance reasons. const DETECTOR_SNAPSHOT_PERIOD: isize = 256; -/// Warning: do not use this function if you expect to start interpreting the given `Mir`. -/// The `EvalContext` is only meant to be used to query values from constants and statics. -/// -/// This function is used during const propagation. We cannot use `mk_eval_cx`, because copy -/// propagation happens *during* the computation of the MIR of the current function. So if we -/// tried to call the `optimized_mir` query, we'd get a cycle error because we are (transitively) -/// inside the `optimized_mir` query of the `Instance` given. -/// -/// Since we are looking at the MIR of the function in an abstract manner, we don't have a -/// `ParamEnv` available to us. This function creates a `ParamEnv` for the given instance. -pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: Instance<'tcx>, - mir: &'mir mir::Mir<'tcx>, - span: Span, -) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> { - debug!("mk_borrowck_eval_cx: {:?}", instance); - let param_env = tcx.param_env(instance.def_id()); - mk_eval_cx_inner(tcx, instance, mir, span, param_env) -} - -/// This is just a helper function to reduce code duplication between `mk_borrowck_eval_cx` and -/// `mk_eval_cx`. Do not call this function directly. -fn mk_eval_cx_inner<'a, 'mir, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: Instance<'tcx>, - mir: &'mir mir::Mir<'tcx>, - span: Span, - param_env: ty::ParamEnv<'tcx>, -) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> { - let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new()); - // Insert a stack frame so any queries have the correct substs. - // We also avoid all the extra work performed by push_stack_frame, - // like initializing local variables - ecx.stack.push(interpret::Frame { - block: mir::START_BLOCK, - locals: IndexVec::new(), - local_layouts: IndexVec::new(), - instance, - span, - mir, - return_place: None, - return_to_block: StackPopCleanup::Goto(None), // never pop - stmt: 0, - extra: (), - }); - Ok(ecx) -} - -/// Warning: do not use this function if you expect to start interpreting the given `Mir`. /// The `EvalContext` is only meant to be used to do field and index projections into constants for /// `simd_shuffle` and const patterns in match arms. /// @@ -92,15 +41,12 @@ fn mk_eval_cx_inner<'a, 'mir, 'tcx>( /// that inform us about the generic bounds of the constant. E.g. using an associated constant /// of a function's generic parameter will require knowledge about the bounds on the generic /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. -fn mk_eval_cx<'a, 'tcx>( +pub(crate) fn mk_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: Instance<'tcx>, param_env: ty::ParamEnv<'tcx>, -) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'tcx, 'tcx>> { - debug!("mk_eval_cx: {:?}, {:?}", instance, param_env); - let span = tcx.def_span(instance.def_id()); - let mir = tcx.optimized_mir(instance.def.def_id()); - mk_eval_cx_inner(tcx, instance, mir, span, param_env) +) -> CompileTimeEvalContext<'a, 'mir, 'tcx> { + debug!("mk_eval_cx: {:?}", param_env); + EvalContext::new(tcx.at(DUMMY_SP), param_env, CompileTimeInterpreter::new()) } pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( @@ -109,7 +55,7 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( mir: &'mir mir::Mir<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> EvalResult<'tcx, MPlaceTy<'tcx>> { - let mut ecx = mk_borrowck_eval_cx(tcx, cid.instance, mir, DUMMY_SP).unwrap(); + let mut ecx = mk_eval_cx(tcx, param_env); eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env) } @@ -530,13 +476,12 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx> pub fn const_field<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, - instance: ty::Instance<'tcx>, variant: Option, field: mir::Field, value: ty::Const<'tcx>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { - trace!("const_field: {:?}, {:?}, {:?}", instance, field, value); - let ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); + trace!("const_field: {:?}, {:?}", field, value); + let ecx = mk_eval_cx(tcx, param_env); let result = (|| { // get the operand again let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(value), value.ty)?; @@ -561,11 +506,10 @@ pub fn const_field<'a, 'tcx>( pub fn const_variant_index<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, - instance: ty::Instance<'tcx>, val: ty::Const<'tcx>, ) -> EvalResult<'tcx, VariantIdx> { - trace!("const_variant_index: {:?}, {:?}", instance, val); - let ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); + trace!("const_variant_index: {:?}", val); + let ecx = mk_eval_cx(tcx, param_env); let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(val), val.ty)?; Ok(ecx.read_discriminant(op)?.1) } @@ -585,7 +529,7 @@ fn validate_and_turn_into_const<'a, 'tcx>( key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { let cid = key.value; - let ecx = mk_eval_cx(tcx, cid.instance, key.param_env).unwrap(); + let ecx = mk_eval_cx(tcx, key.param_env); let val = (|| { let op = ecx.raw_const_to_mplace(constant)?.into(); // FIXME: Once the visitor infrastructure landed, change validation to diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 188a112044298..9cc5c93de41d8 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -427,13 +427,24 @@ pub enum Constructor<'tcx> { } impl<'tcx> Constructor<'tcx> { - fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx { + fn variant_index_for_adt<'a>( + &self, + cx: &MatchCheckCtxt<'a, 'tcx>, + adt: &'tcx ty::AdtDef, + ) -> VariantIdx { match self { &Variant(vid) => adt.variant_index_with_id(vid), &Single => { assert!(!adt.is_enum()); VariantIdx::new(0) } + &ConstantValue(c) => { + ::const_eval::const_variant_index( + cx.tcx, + cx.param_env, + c, + ).unwrap() + }, _ => bug!("bad constructor {:?} for adt {:?}", self, adt) } } @@ -567,7 +578,7 @@ impl<'tcx> Witness<'tcx> { PatternKind::Variant { adt_def: adt, substs, - variant_index: ctor.variant_index_for_adt(adt), + variant_index: ctor.variant_index_for_adt(cx, adt), subpatterns: pats } } else { @@ -1329,7 +1340,7 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>, /// /// For instance, a tuple pattern (_, 42, Some([])) has the arity of 3. /// A struct pattern's arity is the number of fields it contains, etc. -fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { +fn constructor_arity(cx: &MatchCheckCtxt<'a, 'tcx>, ctor: &Constructor<'tcx>, ty: Ty<'tcx>) -> u64 { debug!("constructor_arity({:#?}, {:?})", ctor, ty); match ty.sty { ty::Tuple(ref fs) => fs.len() as u64, @@ -1340,7 +1351,7 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { }, ty::Ref(..) => 1, ty::Adt(adt, _) => { - adt.variants[ctor.variant_index_for_adt(adt)].fields.len() as u64 + adt.variants[ctor.variant_index_for_adt(cx, adt)].fields.len() as u64 } _ => 0 } @@ -1351,7 +1362,7 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { /// /// For instance, a tuple pattern (43u32, 'a') has sub pattern types [u32, char]. fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, - ctor: &Constructor, + ctor: &Constructor<'tcx>, ty: Ty<'tcx>) -> Vec> { debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty); @@ -1368,7 +1379,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, // Use T as the sub pattern type of Box. vec![substs.type_at(0)] } else { - adt.variants[ctor.variant_index_for_adt(adt)].fields.iter().map(|field| { + adt.variants[ctor.variant_index_for_adt(cx, adt)].fields.iter().map(|field| { let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); if is_visible { diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 8991a90737c7e..cdaffe5d45673 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -885,7 +885,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { let adt_subpattern = |i, variant_opt| { let field = Field::new(i); let val = const_field( - self.tcx, self.param_env, instance, + self.tcx, self.param_env, variant_opt, field, cv, ).expect("field access failed"); self.const_to_pat(instance, val, id, span) @@ -928,7 +928,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { }, ty::Adt(adt_def, substs) if adt_def.is_enum() => { let variant_index = const_variant_index( - self.tcx, self.param_env, instance, cv + self.tcx, self.param_env, cv ).expect("const_variant_index failed"); let subpatterns = adt_subpatterns( adt_def.variants[variant_index].fields.len(), diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 03d6d3868c9f0..fba74514f044f 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -20,7 +20,7 @@ use rustc::ty::layout::{ use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind}; use const_eval::{ - CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_borrowck_eval_cx, + CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx, lazy_const_to_op, }; use transform::{MirPass, MirSource}; @@ -110,9 +110,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { source: MirSource, ) -> ConstPropagator<'a, 'mir, 'tcx> { let param_env = tcx.param_env(source.def_id); - let substs = Substs::identity_for_item(tcx, source.def_id); - let instance = Instance::new(source.def_id, substs); - let ecx = mk_borrowck_eval_cx(tcx, instance, mir, DUMMY_SP).unwrap(); + let ecx = mk_eval_cx(tcx, param_env); ConstPropagator { ecx, mir, diff --git a/src/test/ui/consts/match_ice.rs b/src/test/ui/consts/match_ice.rs new file mode 100644 index 0000000000000..c785317778b3c --- /dev/null +++ b/src/test/ui/consts/match_ice.rs @@ -0,0 +1,11 @@ +// compile-pass +// https://github.com/rust-lang/rust/issues/53708 + +struct S; + +fn main() { + const C: &S = &S; + match C { + C => {} + } +} From db2978a73cc4ab71c8839e70d12bc87d5279e632 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 14 Jan 2019 17:54:35 +0100 Subject: [PATCH 0246/1064] Bail out on overly generic substitutions --- src/librustc_mir/interpret/cast.rs | 6 +--- src/librustc_mir/interpret/eval_context.rs | 42 ++++++++++++++++------ src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/place.rs | 5 +-- src/librustc_mir/interpret/step.rs | 4 +-- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 190a381cf52a5..c3b71be8354da 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -109,11 +109,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // The src operand does not matter, just its type match src.layout.ty.sty { ty::Closure(def_id, substs) => { - let substs = self.tcx.subst_and_normalize_erasing_regions( - self.substs(), - ty::ParamEnv::reveal_all(), - &substs, - ); + let substs = self.subst_and_normalize_erasing_regions(substs)?; let instance = ty::Instance::resolve_closure( *self.tcx, def_id, diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b2d3328a73fe8..b2db0fea3d09a 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -216,11 +216,21 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc self.frame().mir } - pub fn substs(&self) -> &'tcx Substs<'tcx> { - if let Some(frame) = self.stack.last() { - frame.instance.substs - } else { - Substs::empty() + pub(super) fn subst_and_normalize_erasing_regions>( + &self, + substs: T, + ) -> EvalResult<'tcx, T> { + match self.stack.last() { + Some(frame) => Ok(self.tcx.subst_and_normalize_erasing_regions( + frame.instance.substs, + self.param_env, + &substs, + )), + None => if substs.needs_subst() { + err!(TooGeneric).into() + } else { + Ok(substs) + }, } } @@ -230,13 +240,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc substs: &'tcx Substs<'tcx> ) -> EvalResult<'tcx, ty::Instance<'tcx>> { trace!("resolve: {:?}, {:#?}", def_id, substs); - trace!("substs: {:#?}", self.substs()); trace!("param_env: {:#?}", self.param_env); - let substs = self.tcx.subst_and_normalize_erasing_regions( - self.substs(), - self.param_env, - &substs, - ); + let substs = self.subst_and_normalize_erasing_regions(substs)?; + trace!("substs: {:#?}", substs); ty::Instance::resolve( *self.tcx, self.param_env, @@ -276,6 +282,20 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } } + pub fn monomorphize_in_frame + Subst<'tcx>>( + &self, + t: T, + ) -> EvalResult<'tcx, T> { + match self.stack.last() { + Some(frame) => Ok(self.monomorphize(t, frame.instance.substs)), + None => if t.needs_subst() { + err!(TooGeneric).into() + } else { + Ok(t) + }, + } + } + pub fn monomorphize + Subst<'tcx>>( &self, t: T, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b2648480f203c..8995d091aaab6 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -508,7 +508,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> Constant(ref constant) => { let layout = from_known_layout(layout, || { - let ty = self.monomorphize(mir_op.ty(self.mir(), *self.tcx), self.substs()); + let ty = self.monomorphize_in_frame(mir_op.ty(self.mir(), *self.tcx))?; self.layout_of(ty) })?; let op = self.const_value_to_op(*constant.literal)?; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 962e0b7a74201..f3a948a6ca3e7 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -9,6 +9,7 @@ use rustc::hir; use rustc::mir; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; +use rustc::ty::TypeFoldable; use super::{ GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic, @@ -583,8 +584,8 @@ where } Static(ref static_) => { - let ty = self.monomorphize(static_.ty, self.substs()); - let layout = self.layout_of(ty)?; + assert!(!static_.ty.needs_subst()); + let layout = self.layout_of(static_.ty)?; let instance = ty::Instance::mono(*self.tcx, static_.def_id); let cid = GlobalId { instance, diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 2de8b3c1afdf3..f1b4e6a5055b6 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -248,7 +248,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } NullaryOp(mir::NullOp::SizeOf, ty) => { - let ty = self.monomorphize(ty, self.substs()); + let ty = self.monomorphize_in_frame(ty)?; let layout = self.layout_of(ty)?; assert!(!layout.is_unsized(), "SizeOf nullary MIR operator called for unsized type"); @@ -260,7 +260,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } Cast(kind, ref operand, cast_ty) => { - debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest.layout.ty); + debug_assert_eq!(self.monomorphize_in_frame(cast_ty)?, dest.layout.ty); let src = self.eval_operand(operand, None)?; self.cast(src, kind, dest)?; } From f6da141b5f1d30f11be503db9783fa61a276c87b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 14 Jan 2019 19:50:49 +0100 Subject: [PATCH 0247/1064] Span fixup --- src/librustc_mir/const_eval.rs | 14 ++++++++------ src/librustc_mir/transform/const_prop.rs | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 25b0d1424ca47..45c6c1b42496a 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -18,7 +18,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc::util::common::ErrorReported; use syntax::ast::Mutability; -use syntax::source_map::DUMMY_SP; +use syntax::source_map::{Span, DUMMY_SP}; use crate::interpret::{self, PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, RawConst, ConstValue, Pointer, @@ -43,10 +43,11 @@ const DETECTOR_SNAPSHOT_PERIOD: isize = 256; /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. pub(crate) fn mk_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, + span: Span, param_env: ty::ParamEnv<'tcx>, ) -> CompileTimeEvalContext<'a, 'mir, 'tcx> { debug!("mk_eval_cx: {:?}", param_env); - EvalContext::new(tcx.at(DUMMY_SP), param_env, CompileTimeInterpreter::new()) + EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new()) } pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( @@ -55,7 +56,8 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( mir: &'mir mir::Mir<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> EvalResult<'tcx, MPlaceTy<'tcx>> { - let mut ecx = mk_eval_cx(tcx, param_env); + let span = tcx.def_span(cid.instance.def_id()); + let mut ecx = mk_eval_cx(tcx, span, param_env); eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env) } @@ -481,7 +483,7 @@ pub fn const_field<'a, 'tcx>( value: ty::Const<'tcx>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { trace!("const_field: {:?}, {:?}", field, value); - let ecx = mk_eval_cx(tcx, param_env); + let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); let result = (|| { // get the operand again let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(value), value.ty)?; @@ -509,7 +511,7 @@ pub fn const_variant_index<'a, 'tcx>( val: ty::Const<'tcx>, ) -> EvalResult<'tcx, VariantIdx> { trace!("const_variant_index: {:?}", val); - let ecx = mk_eval_cx(tcx, param_env); + let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(val), val.ty)?; Ok(ecx.read_discriminant(op)?.1) } @@ -529,7 +531,7 @@ fn validate_and_turn_into_const<'a, 'tcx>( key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { let cid = key.value; - let ecx = mk_eval_cx(tcx, key.param_env); + let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env); let val = (|| { let op = ecx.raw_const_to_mplace(constant)?.into(); // FIXME: Once the visitor infrastructure landed, change validation to diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index fba74514f044f..dc556a15cd855 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -110,7 +110,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { source: MirSource, ) -> ConstPropagator<'a, 'mir, 'tcx> { let param_env = tcx.param_env(source.def_id); - let ecx = mk_eval_cx(tcx, param_env); + let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id), param_env); ConstPropagator { ecx, mir, From 2c57d1d256b84d3bd7f4a1d9613091bd9ec3ca02 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 14 Jan 2019 19:51:00 +0100 Subject: [PATCH 0248/1064] Add regression test --- src/test/ui/consts/match_ice.rs | 5 ++--- src/test/ui/consts/match_ice.stderr | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/consts/match_ice.stderr diff --git a/src/test/ui/consts/match_ice.rs b/src/test/ui/consts/match_ice.rs index c785317778b3c..53c5782a4c70e 100644 --- a/src/test/ui/consts/match_ice.rs +++ b/src/test/ui/consts/match_ice.rs @@ -1,11 +1,10 @@ -// compile-pass // https://github.com/rust-lang/rust/issues/53708 struct S; fn main() { const C: &S = &S; - match C { - C => {} + match C { //~ ERROR non-exhaustive + C => {} // this is a common bug around constants and references in patterns } } diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr new file mode 100644 index 0000000000000..e6e04e2c46276 --- /dev/null +++ b/src/test/ui/consts/match_ice.stderr @@ -0,0 +1,9 @@ +error[E0004]: non-exhaustive patterns: `&S` not covered + --> $DIR/match_ice.rs:7:11 + | +LL | match C { //~ ERROR non-exhaustive + | ^ pattern `&S` not covered + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. From 4781c6f8e75fec74ab519d819499aa2148380518 Mon Sep 17 00:00:00 2001 From: Jacob Kiesel Date: Tue, 22 Jan 2019 09:39:19 -0700 Subject: [PATCH 0249/1064] Remove unused links --- src/libstd/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 5a33f3e7a37df..93ce8a1495f46 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -155,7 +155,6 @@ //! [TCP]: net/struct.TcpStream.html //! [The Rust Prelude]: prelude/index.html //! [UDP]: net/struct.UdpSocket.html -//! [`::std::env::args`]: env/fn.args.html //! [`Arc`]: sync/struct.Arc.html //! [owned slice]: boxed/index.html //! [`Cell`]: cell/struct.Cell.html @@ -189,7 +188,6 @@ //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html //! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#the-use-keyword-to-bring-paths-into-a-scope -//! [crate root]: ../book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html //! [crates.io]: https://crates.io //! [deref-coercions]: ../book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods //! [files]: fs/struct.File.html From 696fb8faa9bb8dee2f014f6445df937fab346d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 21 Jan 2019 16:32:43 +0100 Subject: [PATCH 0250/1064] submodules: update rls from ae0d89a to c9d25b6 Changes: ```` Remove state.analysis due to Rust PR #57476 Improve missing nightly readme info Bump languageserver-types to v0.54.0 and renam crate name to lsp-types Delete bors.toml Fix tests Fix https://github.com/rust-lang/rls/issues/1231 Implement asynchronous message reading Use typed requests Implement Tokio-based test LSP client Update README.md to account for Travis url change Simplify wait_for_all recv calls Update dependencies Revert NLL bug workaround Remove old test_data entry in .gitignore Reorganize some tests Don't test RLS binary target directly Move tooltip tests to integration tests Simplify tooltip test harness Only use FIXTURES_DIR to determine fixtures Remove src/test/mod.rs Centralise FIXTURES_DIR across unit and integration tests Move lens test to tests/ Suppress unused warnings in tests/* Beautify main.rs and lib.rs WIP: Move tests Move src/test/harness to tests/support/harness Split RLS into bin/lib Update Clippy Change all mentions of `rls-preview` to `rls` Make config mutex borrow scope explicit Fallback to racer definition ```` Fixes rls build. --- Cargo.lock | 446 +++++++++++++++++++++- src/tools/rls | 2 +- src/tools/rustc-workspace-hack/Cargo.toml | 1 + 3 files changed, 427 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4593c1ad234b..01216deabba31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,11 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arc-swap" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arena" version = "0.0.0" @@ -183,6 +188,15 @@ name = "byteorder" version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bytes" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bytesize" version = "1.0.0" @@ -520,6 +534,18 @@ dependencies = [ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-channel" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-deque" version = "0.2.0" @@ -529,6 +555,15 @@ dependencies = [ "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-deque" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-epoch" version = "0.3.1" @@ -556,6 +591,19 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-epoch" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" version = "0.2.2" @@ -1054,6 +1102,15 @@ dependencies = [ "xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "iovec" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "is-match" version = "0.1.0" @@ -1067,6 +1124,14 @@ dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.3" @@ -1118,21 +1183,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "languageserver-types" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lazy_static" version = "0.2.11" @@ -1232,6 +1282,31 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lsp-codec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lsp-types" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lzma-sys" version = "0.1.10" @@ -1366,6 +1441,56 @@ dependencies = [ "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio" +version = "0.6.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miow" version = "0.3.3" @@ -1391,6 +1516,16 @@ dependencies = [ "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "new_debug_unreachable" version = "1.0.1" @@ -1544,6 +1679,15 @@ dependencies = [ "parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.3.0" @@ -1555,6 +1699,18 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" version = "1.0.1" @@ -1960,20 +2116,22 @@ dependencies = [ "cargo 0.34.0", "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.212", - "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "languageserver-types 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-types 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "racer 2.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-analysis 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1990,6 +2148,9 @@ dependencies = [ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-process 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2860,11 +3021,25 @@ name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "signal-hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "siphasher" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "smallvec" version = "0.6.7" @@ -3154,6 +3329,194 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-executor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-fs" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-io" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-process" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-reactor" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-signal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tcp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-threadpool" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.4.10" @@ -3365,6 +3728,15 @@ dependencies = [ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "xattr" version = "0.2.2" @@ -3391,6 +3763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" "checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" @@ -3404,6 +3777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" +"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" "checksum cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8dfe3adeb30f7938e6c1dd5327f29235d8ada3e898aeb08c343005ec2915a2" "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" @@ -3424,9 +3798,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" "checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" +"checksum crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2a9ea8f77c7f9efd317a8a5645f515d903a2d86ee14d2337a5facd1bd52c12" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" +"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" +"checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72" @@ -3480,15 +3857,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec" "checksum ignore 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36ecfc5ad80f0b1226df948c562e2cddd446096be3f644c95106400eae8a5e01" "checksum im-rc 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4591152fd573cf453a890b5f9fdc5c328a751a0785539316739d5f85e5c468c" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" +"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" "checksum jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "dd80e58f77e0cdea53ba96acc5e04479e5ffc5d869626a6beafe50fed867eace" "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be" "checksum jsonrpc-core 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e9cbeda300803d381390fb65e8158437728c39e6987ed23bee82728b73511a7" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum languageserver-types 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68de833188ada4e175d04a028f03f244f6370eedbcc75a05604d47d925933f69" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" @@ -3500,6 +3878,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd" +"checksum lsp-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b29e3d1632fef13c1286b0b2f8545a7d894ae565a7fac013b90a17ee5bfbc91" +"checksum lsp-types 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a252cc2be87d9329dd91c505a951996b3263582ba304870960faaae77b642183" "checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2c4deaccc2ead6a28c16c0ba82f07d52b6475397415ce40876e559b0b0ea510" @@ -3514,7 +3894,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649" "checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" "checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" +"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d" @@ -3532,7 +3917,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum packed_simd 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25d36de864f7218ec5633572a800109bbe5a1cc8d9d95a967f3daf93ea7e6ddc" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06a2b6aae052309c2fd2161ef58f5067bc17bb758377a0de9d4b279d603fdd8a" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" "checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" @@ -3613,7 +4000,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +"checksum signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f272d1b7586bec132ed427f532dd418d8beca1ca7f2caf7df35569b1415a4b4" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" @@ -3636,6 +4025,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4790d0be6f4ba6ae4f48190efa2ed7780c9e3567796abdb285003cf39840d9c5" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" +"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" +"checksum tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9cbbc8a3698b7ab652340f46633364f9eaa928ddaaee79d8b8f356dd79a09d" +"checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f" +"checksum tokio-process 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88e1281e412013f1ff5787def044a9577a0bed059f451e835f1643201f8b777d" +"checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f" +"checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" +"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" +"checksum tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17465013014410310f9f61fa10bf4724803c149ea1d51efece131c38efca93aa" +"checksum tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4f37f0111d76cc5da132fe9bc0590b9b9cfd079bc7e75ac3846278430a299ff8" +"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" @@ -3665,6 +4068,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" "checksum xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "df8bf41d3030c3577c9458fd6640a05afbf43b150d0b531b16bd77d3f794f27a" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/src/tools/rls b/src/tools/rls index ae0d89a08d091..c9d25b667af76 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit ae0d89a08d091ba1563b571739768a09d4cd3d69 +Subproject commit c9d25b667af766e8fe6d3b6168a5f99a0e4d722a diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index c4499ef95ad8e..f5eeddda036fd 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -45,6 +45,7 @@ features = [ "sspi", "synchapi", "sysinfoapi", + "threadpoollegacyapiset", "timezoneapi", "userenv", "winbase", From 7f8e4aae12afe9b017ba620f9f692fa709339b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 22 Jan 2019 18:03:40 +0100 Subject: [PATCH 0251/1064] submodules: update clippy from 1838bfe5 to 280069dd Changes: ```` Rustfmt all the things Don't make decisions on values that don't represent the decision Rustup Actually check for constants. formatting fix Update clippy_lints/src/needless_bool.rs formatting fix needless bool lint suggestion is wrapped in brackets if it is an "else" clause of an "if-else" statement Remove negative integer literal checks. Fix `implicit_return` false positives. ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 1838bfe5a9ff9..280069ddc750d 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 1838bfe5a9ff951ffd716e4632156113d95d14a4 +Subproject commit 280069ddc750d8a20d075c76322c45d5db4a48f8 From 1c95f5a34c14f08d65cdd198827e3a2fcb63cf39 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 22 Jan 2019 11:13:53 -0700 Subject: [PATCH 0252/1064] Fix issue 57762 Issue 57762 points out a compiler crash when the compiler was built using a stock LLVM 7. LLVM 7 was released without a necessary fix for a bug in the DWARF discriminant code. This patch changes rustc to use the fallback mode on (non-Rust) LLVM 7. Closes #57762 --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 6deedd0b5ea33..a354eef6887ae 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1164,7 +1164,11 @@ fn use_enum_fallback(cx: &CodegenCx) -> bool { // On MSVC we have to use the fallback mode, because LLVM doesn't // lower variant parts to PDB. return cx.sess().target.target.options.is_like_msvc - || llvm_util::get_major_version() < 7; + || llvm_util::get_major_version() < 7 + // LLVM version 7 did not release with an important bug fix; + // but the required patch is in the equivalent Rust LLVM. + // See https://github.com/rust-lang/rust/issues/57762. + || (llvm_util::get_major_version() == 7 && unsafe { !llvm::LLVMRustIsRustLLVM() }); } // Describes the members of an enum value: An enum is described as a union of From 9452a8dfa3ba3575d5cf090a4e2305ee106d259e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 22 Jan 2019 11:44:23 -0700 Subject: [PATCH 0253/1064] Simplify the version check Address the review comments by simplifying the version check to just "< 8". --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index a354eef6887ae..9f63038c3623b 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1164,11 +1164,10 @@ fn use_enum_fallback(cx: &CodegenCx) -> bool { // On MSVC we have to use the fallback mode, because LLVM doesn't // lower variant parts to PDB. return cx.sess().target.target.options.is_like_msvc - || llvm_util::get_major_version() < 7 // LLVM version 7 did not release with an important bug fix; - // but the required patch is in the equivalent Rust LLVM. - // See https://github.com/rust-lang/rust/issues/57762. - || (llvm_util::get_major_version() == 7 && unsafe { !llvm::LLVMRustIsRustLLVM() }); + // but the required patch is in the LLVM 8. Rust LLVM reports + // 8 as well. + || llvm_util::get_major_version() < 8; } // Describes the members of an enum value: An enum is described as a union of From 4e649ccc3a6ee5bd910ae41fd0bc6df4be234b4c Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 22 Jan 2019 16:15:02 -0500 Subject: [PATCH 0254/1064] use port 80 for retrieving GPG key This works around firewalls blocking port 11371. See https://unix.stackexchange.com/questions/75892/keyserver-timed-out-when-trying-to-add-a-gpg-public-key. --- src/ci/docker/dist-various-1/install-x86_64-redox.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-various-1/install-x86_64-redox.sh b/src/ci/docker/dist-various-1/install-x86_64-redox.sh index 29222ff60f2a0..c39be14941c90 100755 --- a/src/ci/docker/dist-various-1/install-x86_64-redox.sh +++ b/src/ci/docker/dist-various-1/install-x86_64-redox.sh @@ -6,7 +6,7 @@ set -ex apt-get update apt-get install -y --no-install-recommends software-properties-common apt-transport-https -apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys AA12E97F0881517F +apt-key adv --batch --yes --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys AA12E97F0881517F add-apt-repository -y 'deb https://static.redox-os.org/toolchain/apt /' apt-get update From b1542341da756013a4a2126cd7628bbc2a8c3ba7 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 22 Jan 2019 15:40:27 -0600 Subject: [PATCH 0255/1064] don't call get_macro on proc-macro stubs --- src/librustdoc/passes/collect_intra_doc_links.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3d6096b07ce43..13ad05101e4b6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -431,8 +431,12 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { let parent_scope = resolver.dummy_parent_scope(); if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang, &parent_scope, false, false) { - if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) { - return Some(def); + if let Def::Macro(_, MacroKind::ProcMacroStub) = def { + // skip proc-macro stubs, they'll cause `get_macro` to crash + } else { + if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) { + return Some(def); + } } } if let Some(def) = resolver.all_macros.get(&Symbol::intern(path_str)) { From b876694734cfc5919b8c12527c287aea1a8d8cfd Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 22 Jan 2019 15:44:19 -0600 Subject: [PATCH 0256/1064] add intra-doc link test to proc-macro test --- src/test/rustdoc/proc-macro.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/rustdoc/proc-macro.rs b/src/test/rustdoc/proc-macro.rs index d4d70d04f5b4e..1e396f1be0e04 100644 --- a/src/test/rustdoc/proc-macro.rs +++ b/src/test/rustdoc/proc-macro.rs @@ -4,6 +4,11 @@ #![crate_type="proc-macro"] #![crate_name="some_macros"] +// @has some_macros/index.html +// @has - '//a/[@href="attr.some_proc_attr.html"]' 'some_proc_attr' + +//! include a link to [some_proc_attr] to make sure it works. + extern crate proc_macro; use proc_macro::TokenStream; From aff7772a1da244af8a37c786c6c7cb87747b9d02 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:23:12 -0500 Subject: [PATCH 0257/1064] Move core::iter adapters to adapters.rs --- src/libcore/iter/adapters/mod.rs | 2772 +++++++++++++++++++++++++++++ src/libcore/iter/mod.rs | 2787 +----------------------------- 2 files changed, 2790 insertions(+), 2769 deletions(-) create mode 100644 src/libcore/iter/adapters/mod.rs diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs new file mode 100644 index 0000000000000..abeb13180c335 --- /dev/null +++ b/src/libcore/iter/adapters/mod.rs @@ -0,0 +1,2772 @@ +use cmp; +use fmt; +use iter_private::TrustedRandomAccess; +use ops::Try; +use usize; +use intrinsics; +use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; +use super::LoopState; + +/// A double-ended iterator with the direction inverted. +/// +/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`rev`]: trait.Iterator.html#method.rev +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Rev { + pub(super) iter: T +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Rev where I: DoubleEndedIterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { self.iter.next_back() } + #[inline] + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn nth(&mut self, n: usize) -> Option<::Item> { self.iter.nth_back(n) } + + fn try_fold(&mut self, init: B, f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + self.iter.try_rfold(init, f) + } + + fn fold(self, init: Acc, f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.iter.rfold(init, f) + } + + #[inline] + fn find

(&mut self, predicate: P) -> Option + where P: FnMut(&Self::Item) -> bool + { + self.iter.rfind(predicate) + } + + #[inline] + fn rposition

(&mut self, predicate: P) -> Option where + P: FnMut(Self::Item) -> bool + { + self.iter.position(predicate) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Rev where I: DoubleEndedIterator { + #[inline] + fn next_back(&mut self) -> Option<::Item> { self.iter.next() } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option<::Item> { self.iter.nth(n) } + + fn try_rfold(&mut self, init: B, f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + self.iter.try_fold(init, f) + } + + fn rfold(self, init: Acc, f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.iter.fold(init, f) + } + + fn rfind

(&mut self, predicate: P) -> Option + where P: FnMut(&Self::Item) -> bool + { + self.iter.find(predicate) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Rev + where I: ExactSizeIterator + DoubleEndedIterator +{ + fn len(&self) -> usize { + self.iter.len() + } + + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Rev + where I: FusedIterator + DoubleEndedIterator {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Rev + where I: TrustedLen + DoubleEndedIterator {} + +/// An iterator that copies the elements of an underlying iterator. +/// +/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`copied`]: trait.Iterator.html#method.copied +/// [`Iterator`]: trait.Iterator.html +#[unstable(feature = "iter_copied", issue = "57127")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[derive(Clone, Debug)] +pub struct Copied { + pub(super) it: I, +} + +#[unstable(feature = "iter_copied", issue = "57127")] +impl<'a, I, T: 'a> Iterator for Copied + where I: Iterator, T: Copy +{ + type Item = T; + + fn next(&mut self) -> Option { + self.it.next().copied() + } + + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } + + fn try_fold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + self.it.try_fold(init, move |acc, &elt| f(acc, elt)) + } + + fn fold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.it.fold(init, move |acc, &elt| f(acc, elt)) + } +} + +#[unstable(feature = "iter_copied", issue = "57127")] +impl<'a, I, T: 'a> DoubleEndedIterator for Copied + where I: DoubleEndedIterator, T: Copy +{ + fn next_back(&mut self) -> Option { + self.it.next_back().copied() + } + + fn try_rfold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + self.it.try_rfold(init, move |acc, &elt| f(acc, elt)) + } + + fn rfold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.it.rfold(init, move |acc, &elt| f(acc, elt)) + } +} + +#[unstable(feature = "iter_copied", issue = "57127")] +impl<'a, I, T: 'a> ExactSizeIterator for Copied + where I: ExactSizeIterator, T: Copy +{ + fn len(&self) -> usize { + self.it.len() + } + + fn is_empty(&self) -> bool { + self.it.is_empty() + } +} + +#[unstable(feature = "iter_copied", issue = "57127")] +impl<'a, I, T: 'a> FusedIterator for Copied + where I: FusedIterator, T: Copy +{} + +#[doc(hidden)] +unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Copied + where I: TrustedRandomAccess, T: Copy +{ + unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { + *self.it.get_unchecked(i) + } + + #[inline] + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } +} + +#[unstable(feature = "iter_copied", issue = "57127")] +unsafe impl<'a, I, T: 'a> TrustedLen for Copied + where I: TrustedLen, + T: Copy +{} + +/// An iterator that clones the elements of an underlying iterator. +/// +/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cloned`]: trait.Iterator.html#method.cloned +/// [`Iterator`]: trait.Iterator.html +#[stable(feature = "iter_cloned", since = "1.1.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[derive(Clone, Debug)] +pub struct Cloned { + pub(super) it: I, +} + +#[stable(feature = "iter_cloned", since = "1.1.0")] +impl<'a, I, T: 'a> Iterator for Cloned + where I: Iterator, T: Clone +{ + type Item = T; + + fn next(&mut self) -> Option { + self.it.next().cloned() + } + + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } + + fn try_fold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + self.it.try_fold(init, move |acc, elt| f(acc, elt.clone())) + } + + fn fold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.it.fold(init, move |acc, elt| f(acc, elt.clone())) + } +} + +#[stable(feature = "iter_cloned", since = "1.1.0")] +impl<'a, I, T: 'a> DoubleEndedIterator for Cloned + where I: DoubleEndedIterator, T: Clone +{ + fn next_back(&mut self) -> Option { + self.it.next_back().cloned() + } + + fn try_rfold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + self.it.try_rfold(init, move |acc, elt| f(acc, elt.clone())) + } + + fn rfold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.it.rfold(init, move |acc, elt| f(acc, elt.clone())) + } +} + +#[stable(feature = "iter_cloned", since = "1.1.0")] +impl<'a, I, T: 'a> ExactSizeIterator for Cloned + where I: ExactSizeIterator, T: Clone +{ + fn len(&self) -> usize { + self.it.len() + } + + fn is_empty(&self) -> bool { + self.it.is_empty() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl<'a, I, T: 'a> FusedIterator for Cloned + where I: FusedIterator, T: Clone +{} + +#[doc(hidden)] +unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned + where I: TrustedRandomAccess, T: Clone +{ + default unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { + self.it.get_unchecked(i).clone() + } + + #[inline] + default fn may_have_side_effect() -> bool { true } +} + +#[doc(hidden)] +unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned + where I: TrustedRandomAccess, T: Copy +{ + unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { + *self.it.get_unchecked(i) + } + + #[inline] + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl<'a, I, T: 'a> TrustedLen for Cloned + where I: TrustedLen, + T: Clone +{} + +/// An iterator that repeats endlessly. +/// +/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cycle`]: trait.Iterator.html#method.cycle +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Cycle { + pub(super) orig: I, + pub(super) iter: I, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Cycle where I: Clone + Iterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { + match self.iter.next() { + None => { self.iter = self.orig.clone(); self.iter.next() } + y => y + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + // the cycle iterator is either empty or infinite + match self.orig.size_hint() { + sz @ (0, Some(0)) => sz, + (0, _) => (0, None), + _ => (usize::MAX, None) + } + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Cycle where I: Clone + Iterator {} + +/// An iterator for stepping iterators by a custom amount. +/// +/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See +/// its documentation for more. +/// +/// [`step_by`]: trait.Iterator.html#method.step_by +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "iterator_step_by", since = "1.28.0")] +#[derive(Clone, Debug)] +pub struct StepBy { + pub(super) iter: I, + pub(super) step: usize, + pub(super) first_take: bool, +} + +#[stable(feature = "iterator_step_by", since = "1.28.0")] +impl Iterator for StepBy where I: Iterator { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.first_take { + self.first_take = false; + self.iter.next() + } else { + self.iter.nth(self.step) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let inner_hint = self.iter.size_hint(); + + if self.first_take { + let f = |n| if n == 0 { 0 } else { 1 + (n-1)/(self.step+1) }; + (f(inner_hint.0), inner_hint.1.map(f)) + } else { + let f = |n| n / (self.step+1); + (f(inner_hint.0), inner_hint.1.map(f)) + } + } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option { + if self.first_take { + self.first_take = false; + let first = self.iter.next(); + if n == 0 { + return first; + } + n -= 1; + } + // n and self.step are indices, we need to add 1 to get the amount of elements + // When calling `.nth`, we need to subtract 1 again to convert back to an index + // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1` + let mut step = self.step + 1; + // n + 1 could overflow + // thus, if n is usize::MAX, instead of adding one, we call .nth(step) + if n == usize::MAX { + self.iter.nth(step - 1); + } else { + n += 1; + } + + // overflow handling + loop { + let mul = n.checked_mul(step); + if unsafe { intrinsics::likely(mul.is_some()) } { + return self.iter.nth(mul.unwrap() - 1); + } + let div_n = usize::MAX / n; + let div_step = usize::MAX / step; + let nth_n = div_n * n; + let nth_step = div_step * step; + let nth = if nth_n > nth_step { + step -= div_n; + nth_n + } else { + n -= div_step; + nth_step + }; + self.iter.nth(nth - 1); + } + } +} + +// StepBy can only make the iterator shorter, so the len will still fit. +#[stable(feature = "iterator_step_by", since = "1.28.0")] +impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} + +/// An iterator that strings two iterators together. +/// +/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`chain`]: trait.Iterator.html#method.chain +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Chain { + pub(super) a: A, + pub(super) b: B, + pub(super) state: ChainState, +} + +// The iterator protocol specifies that iteration ends with the return value +// `None` from `.next()` (or `.next_back()`) and it is unspecified what +// further calls return. The chain adaptor must account for this since it uses +// two subiterators. +// +// It uses three states: +// +// - Both: `a` and `b` are remaining +// - Front: `a` remaining +// - Back: `b` remaining +// +// The fourth state (neither iterator is remaining) only occurs after Chain has +// returned None once, so we don't need to store this state. +#[derive(Clone, Debug)] +pub(super) enum ChainState { + // both front and back iterator are remaining + Both, + // only front is remaining + Front, + // only back is remaining + Back, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Chain where + A: Iterator, + B: Iterator +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + match self.state { + ChainState::Both => match self.a.next() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Back; + self.b.next() + } + }, + ChainState::Front => self.a.next(), + ChainState::Back => self.b.next(), + } + } + + #[inline] + #[rustc_inherit_overflow_checks] + fn count(self) -> usize { + match self.state { + ChainState::Both => self.a.count() + self.b.count(), + ChainState::Front => self.a.count(), + ChainState::Back => self.b.count(), + } + } + + fn try_fold(&mut self, init: Acc, mut f: F) -> R where + Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Front => { + accum = self.a.try_fold(accum, &mut f)?; + if let ChainState::Both = self.state { + self.state = ChainState::Back; + } + } + _ => { } + } + if let ChainState::Back = self.state { + accum = self.b.try_fold(accum, &mut f)?; + } + Try::from_ok(accum) + } + + fn fold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Front => { + accum = self.a.fold(accum, &mut f); + } + _ => { } + } + match self.state { + ChainState::Both | ChainState::Back => { + accum = self.b.fold(accum, &mut f); + } + _ => { } + } + accum + } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option { + match self.state { + ChainState::Both | ChainState::Front => { + for x in self.a.by_ref() { + if n == 0 { + return Some(x) + } + n -= 1; + } + if let ChainState::Both = self.state { + self.state = ChainState::Back; + } + } + ChainState::Back => {} + } + if let ChainState::Back = self.state { + self.b.nth(n) + } else { + None + } + } + + #[inline] + fn find

(&mut self, mut predicate: P) -> Option where + P: FnMut(&Self::Item) -> bool, + { + match self.state { + ChainState::Both => match self.a.find(&mut predicate) { + None => { + self.state = ChainState::Back; + self.b.find(predicate) + } + v => v + }, + ChainState::Front => self.a.find(predicate), + ChainState::Back => self.b.find(predicate), + } + } + + #[inline] + fn last(self) -> Option { + match self.state { + ChainState::Both => { + // Must exhaust a before b. + let a_last = self.a.last(); + let b_last = self.b.last(); + b_last.or(a_last) + }, + ChainState::Front => self.a.last(), + ChainState::Back => self.b.last() + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = a_lower.saturating_add(b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Chain where + A: DoubleEndedIterator, + B: DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option { + match self.state { + ChainState::Both => match self.b.next_back() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Front; + self.a.next_back() + } + }, + ChainState::Front => self.a.next_back(), + ChainState::Back => self.b.next_back(), + } + } + + fn try_rfold(&mut self, init: Acc, mut f: F) -> R where + Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Back => { + accum = self.b.try_rfold(accum, &mut f)?; + if let ChainState::Both = self.state { + self.state = ChainState::Front; + } + } + _ => { } + } + if let ChainState::Front = self.state { + accum = self.a.try_rfold(accum, &mut f)?; + } + Try::from_ok(accum) + } + + fn rfold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Back => { + accum = self.b.rfold(accum, &mut f); + } + _ => { } + } + match self.state { + ChainState::Both | ChainState::Front => { + accum = self.a.rfold(accum, &mut f); + } + _ => { } + } + accum + } + +} + +// Note: *both* must be fused to handle double-ended iterators. +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Chain + where A: FusedIterator, + B: FusedIterator, +{} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Chain + where A: TrustedLen, B: TrustedLen, +{} + +/// An iterator that iterates two other iterators simultaneously. +/// +/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`zip`]: trait.Iterator.html#method.zip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Zip { + a: A, + b: B, + // index and len are only used by the specialized version of zip + index: usize, + len: usize, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Zip where A: Iterator, B: Iterator +{ + type Item = (A::Item, B::Item); + + #[inline] + fn next(&mut self) -> Option { + ZipImpl::next(self) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + ZipImpl::size_hint(self) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + ZipImpl::nth(self, n) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Zip where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, +{ + #[inline] + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { + ZipImpl::next_back(self) + } +} + +// Zip specialization trait +#[doc(hidden)] +pub(super) trait ZipImpl { + type Item; + fn new(a: A, b: B) -> Self; + fn next(&mut self) -> Option; + fn size_hint(&self) -> (usize, Option); + fn nth(&mut self, n: usize) -> Option; + fn super_nth(&mut self, mut n: usize) -> Option { + while let Some(x) = self.next() { + if n == 0 { return Some(x) } + n -= 1; + } + None + } + fn next_back(&mut self) -> Option + where A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator; +} + +// General Zip impl +#[doc(hidden)] +impl ZipImpl for Zip + where A: Iterator, B: Iterator +{ + type Item = (A::Item, B::Item); + default fn new(a: A, b: B) -> Self { + Zip { + a, + b, + index: 0, // unused + len: 0, // unused + } + } + + #[inline] + default fn next(&mut self) -> Option<(A::Item, B::Item)> { + self.a.next().and_then(|x| { + self.b.next().and_then(|y| { + Some((x, y)) + }) + }) + } + + #[inline] + default fn nth(&mut self, n: usize) -> Option { + self.super_nth(n) + } + + #[inline] + default fn next_back(&mut self) -> Option<(A::Item, B::Item)> + where A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator + { + let a_sz = self.a.len(); + let b_sz = self.b.len(); + if a_sz != b_sz { + // Adjust a, b to equal length + if a_sz > b_sz { + for _ in 0..a_sz - b_sz { self.a.next_back(); } + } else { + for _ in 0..b_sz - a_sz { self.b.next_back(); } + } + } + match (self.a.next_back(), self.b.next_back()) { + (Some(x), Some(y)) => Some((x, y)), + (None, None) => None, + _ => unreachable!(), + } + } + + #[inline] + default fn size_hint(&self) -> (usize, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = cmp::min(a_lower, b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None + }; + + (lower, upper) + } +} + +#[doc(hidden)] +impl ZipImpl for Zip + where A: TrustedRandomAccess, B: TrustedRandomAccess +{ + fn new(a: A, b: B) -> Self { + let len = cmp::min(a.len(), b.len()); + Zip { + a, + b, + index: 0, + len, + } + } + + #[inline] + fn next(&mut self) -> Option<(A::Item, B::Item)> { + if self.index < self.len { + let i = self.index; + self.index += 1; + unsafe { + Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) + } + } else if A::may_have_side_effect() && self.index < self.a.len() { + // match the base implementation's potential side effects + unsafe { + self.a.get_unchecked(self.index); + } + self.index += 1; + None + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len - self.index; + (len, Some(len)) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + let delta = cmp::min(n, self.len - self.index); + let end = self.index + delta; + while self.index < end { + let i = self.index; + self.index += 1; + if A::may_have_side_effect() { + unsafe { self.a.get_unchecked(i); } + } + if B::may_have_side_effect() { + unsafe { self.b.get_unchecked(i); } + } + } + + self.super_nth(n - delta) + } + + #[inline] + fn next_back(&mut self) -> Option<(A::Item, B::Item)> + where A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator + { + // Adjust a, b to equal length + if A::may_have_side_effect() { + let sz = self.a.len(); + if sz > self.len { + for _ in 0..sz - cmp::max(self.len, self.index) { + self.a.next_back(); + } + } + } + if B::may_have_side_effect() { + let sz = self.b.len(); + if sz > self.len { + for _ in 0..sz - self.len { + self.b.next_back(); + } + } + } + if self.index < self.len { + self.len -= 1; + let i = self.len; + unsafe { + Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) + } + } else { + None + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Zip + where A: ExactSizeIterator, B: ExactSizeIterator {} + +#[doc(hidden)] +unsafe impl TrustedRandomAccess for Zip + where A: TrustedRandomAccess, + B: TrustedRandomAccess, +{ + unsafe fn get_unchecked(&mut self, i: usize) -> (A::Item, B::Item) { + (self.a.get_unchecked(i), self.b.get_unchecked(i)) + } + + fn may_have_side_effect() -> bool { + A::may_have_side_effect() || B::may_have_side_effect() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Zip + where A: FusedIterator, B: FusedIterator, {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Zip + where A: TrustedLen, B: TrustedLen, +{} + +/// An iterator that maps the values of `iter` with `f`. +/// +/// This `struct` is created by the [`map`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`map`]: trait.Iterator.html#method.map +/// [`Iterator`]: trait.Iterator.html +/// +/// # Notes about side effects +/// +/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that +/// you can also [`map`] backwards: +/// +/// ```rust +/// let v: Vec = vec![1, 2, 3].into_iter().map(|x| x + 1).rev().collect(); +/// +/// assert_eq!(v, [4, 3, 2]); +/// ``` +/// +/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html +/// +/// But if your closure has state, iterating backwards may act in a way you do +/// not expect. Let's go through an example. First, in the forward direction: +/// +/// ```rust +/// let mut c = 0; +/// +/// for pair in vec!['a', 'b', 'c'].into_iter() +/// .map(|letter| { c += 1; (letter, c) }) { +/// println!("{:?}", pair); +/// } +/// ``` +/// +/// This will print "('a', 1), ('b', 2), ('c', 3)". +/// +/// Now consider this twist where we add a call to `rev`. This version will +/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed, +/// but the values of the counter still go in order. This is because `map()` is +/// still being called lazily on each item, but we are popping items off the +/// back of the vector now, instead of shifting them from the front. +/// +/// ```rust +/// let mut c = 0; +/// +/// for pair in vec!['a', 'b', 'c'].into_iter() +/// .map(|letter| { c += 1; (letter, c) }) +/// .rev() { +/// println!("{:?}", pair); +/// } +/// ``` +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Map { + pub(super) iter: I, + pub(super) f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Map { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Map") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Map where F: FnMut(I::Item) -> B { + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().map(&mut self.f) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + + fn try_fold(&mut self, init: Acc, mut g: G) -> R where + Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try + { + let f = &mut self.f; + self.iter.try_fold(init, move |acc, elt| g(acc, f(elt))) + } + + fn fold(self, init: Acc, mut g: G) -> Acc + where G: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter.fold(init, move |acc, elt| g(acc, f(elt))) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Map where + F: FnMut(I::Item) -> B, +{ + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back().map(&mut self.f) + } + + fn try_rfold(&mut self, init: Acc, mut g: G) -> R where + Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try + { + let f = &mut self.f; + self.iter.try_rfold(init, move |acc, elt| g(acc, f(elt))) + } + + fn rfold(self, init: Acc, mut g: G) -> Acc + where G: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter.rfold(init, move |acc, elt| g(acc, f(elt))) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Map + where F: FnMut(I::Item) -> B +{ + fn len(&self) -> usize { + self.iter.len() + } + + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Map + where F: FnMut(I::Item) -> B {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Map + where I: TrustedLen, + F: FnMut(I::Item) -> B {} + +#[doc(hidden)] +unsafe impl TrustedRandomAccess for Map + where I: TrustedRandomAccess, + F: FnMut(I::Item) -> B, +{ + unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { + (self.f)(self.iter.get_unchecked(i)) + } + #[inline] + fn may_have_side_effect() -> bool { true } +} + +/// An iterator that filters the elements of `iter` with `predicate`. +/// +/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter`]: trait.Iterator.html#method.filter +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Filter { + pub(super) iter: I, + pub(super) predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Filter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Filter") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Filter where P: FnMut(&I::Item) -> bool { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + for x in &mut self.iter { + if (self.predicate)(&x) { + return Some(x); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } + + // this special case allows the compiler to make `.filter(_).count()` + // branchless. Barring perfect branch prediction (which is unattainable in + // the general case), this will be much faster in >90% of cases (containing + // virtually all real workloads) and only a tiny bit slower in the rest. + // + // Having this specialization thus allows us to write `.filter(p).count()` + // where we would otherwise write `.map(|x| p(x) as usize).sum()`, which is + // less readable and also less backwards-compatible to Rust before 1.10. + // + // Using the branchless version will also simplify the LLVM byte code, thus + // leaving more budget for LLVM optimizations. + #[inline] + fn count(mut self) -> usize { + let mut count = 0; + for x in &mut self.iter { + count += (self.predicate)(&x) as usize; + } + count + } + + #[inline] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let predicate = &mut self.predicate; + self.iter.try_fold(init, move |acc, item| if predicate(&item) { + fold(acc, item) + } else { + Try::from_ok(acc) + }) + } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut predicate = self.predicate; + self.iter.fold(init, move |acc, item| if predicate(&item) { + fold(acc, item) + } else { + acc + }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Filter + where P: FnMut(&I::Item) -> bool, +{ + #[inline] + fn next_back(&mut self) -> Option { + for x in self.iter.by_ref().rev() { + if (self.predicate)(&x) { + return Some(x); + } + } + None + } + + #[inline] + fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let predicate = &mut self.predicate; + self.iter.try_rfold(init, move |acc, item| if predicate(&item) { + fold(acc, item) + } else { + Try::from_ok(acc) + }) + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut predicate = self.predicate; + self.iter.rfold(init, move |acc, item| if predicate(&item) { + fold(acc, item) + } else { + acc + }) + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Filter + where P: FnMut(&I::Item) -> bool {} + +/// An iterator that uses `f` to both filter and map elements from `iter`. +/// +/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter_map`]: trait.Iterator.html#method.filter_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct FilterMap { + pub(super) iter: I, + pub(super) f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for FilterMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FilterMap") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for FilterMap + where F: FnMut(I::Item) -> Option, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + for x in self.iter.by_ref() { + if let Some(y) = (self.f)(x) { + return Some(y); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } + + #[inline] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let f = &mut self.f; + self.iter.try_fold(init, move |acc, item| match f(item) { + Some(x) => fold(acc, x), + None => Try::from_ok(acc), + }) + } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter.fold(init, move |acc, item| match f(item) { + Some(x) => fold(acc, x), + None => acc, + }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for FilterMap + where F: FnMut(I::Item) -> Option, +{ + #[inline] + fn next_back(&mut self) -> Option { + for x in self.iter.by_ref().rev() { + if let Some(y) = (self.f)(x) { + return Some(y); + } + } + None + } + + #[inline] + fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let f = &mut self.f; + self.iter.try_rfold(init, move |acc, item| match f(item) { + Some(x) => fold(acc, x), + None => Try::from_ok(acc), + }) + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter.rfold(init, move |acc, item| match f(item) { + Some(x) => fold(acc, x), + None => acc, + }) + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for FilterMap + where F: FnMut(I::Item) -> Option {} + +/// An iterator that yields the current count and the element during iteration. +/// +/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`enumerate`]: trait.Iterator.html#method.enumerate +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Enumerate { + pub(super) iter: I, + pub(super) count: usize, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Enumerate where I: Iterator { + type Item = (usize, ::Item); + + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so enumerating more than + /// `usize::MAX` elements either produces the wrong result or panics. If + /// debug assertions are enabled, a panic is guaranteed. + /// + /// # Panics + /// + /// Might panic if the index of the element overflows a `usize`. + #[inline] + #[rustc_inherit_overflow_checks] + fn next(&mut self) -> Option<(usize, ::Item)> { + self.iter.next().map(|a| { + let ret = (self.count, a); + // Possible undefined overflow. + self.count += 1; + ret + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + + #[inline] + #[rustc_inherit_overflow_checks] + fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { + self.iter.nth(n).map(|a| { + let i = self.count + n; + self.count = i + 1; + (i, a) + }) + } + + #[inline] + fn count(self) -> usize { + self.iter.count() + } + + #[inline] + #[rustc_inherit_overflow_checks] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let count = &mut self.count; + self.iter.try_fold(init, move |acc, item| { + let acc = fold(acc, (*count, item)); + *count += 1; + acc + }) + } + + #[inline] + #[rustc_inherit_overflow_checks] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut count = self.count; + self.iter.fold(init, move |acc, item| { + let acc = fold(acc, (count, item)); + count += 1; + acc + }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Enumerate where + I: ExactSizeIterator + DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option<(usize, ::Item)> { + self.iter.next_back().map(|a| { + let len = self.iter.len(); + // Can safely add, `ExactSizeIterator` promises that the number of + // elements fits into a `usize`. + (self.count + len, a) + }) + } + + #[inline] + fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + // Can safely add and subtract the count, as `ExactSizeIterator` promises + // that the number of elements fits into a `usize`. + let mut count = self.count + self.iter.len(); + self.iter.try_rfold(init, move |acc, item| { + count -= 1; + fold(acc, (count, item)) + }) + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + // Can safely add and subtract the count, as `ExactSizeIterator` promises + // that the number of elements fits into a `usize`. + let mut count = self.count + self.iter.len(); + self.iter.rfold(init, move |acc, item| { + count -= 1; + fold(acc, (count, item)) + }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Enumerate where I: ExactSizeIterator { + fn len(&self) -> usize { + self.iter.len() + } + + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +#[doc(hidden)] +unsafe impl TrustedRandomAccess for Enumerate + where I: TrustedRandomAccess +{ + unsafe fn get_unchecked(&mut self, i: usize) -> (usize, I::Item) { + (self.count + i, self.iter.get_unchecked(i)) + } + + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Enumerate where I: FusedIterator {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Enumerate + where I: TrustedLen, +{} + + +/// An iterator with a `peek()` that returns an optional reference to the next +/// element. +/// +/// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`peekable`]: trait.Iterator.html#method.peekable +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Peekable { + pub(super) iter: I, + /// Remember a peeked value, even if it was None. + pub(super) peeked: Option>, +} + +// Peekable must remember if a None has been seen in the `.peek()` method. +// It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the +// underlying iterator at most once. This does not by itself make the iterator +// fused. +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Peekable { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + match self.peeked.take() { + Some(v) => v, + None => self.iter.next(), + } + } + + #[inline] + #[rustc_inherit_overflow_checks] + fn count(mut self) -> usize { + match self.peeked.take() { + Some(None) => 0, + Some(Some(_)) => 1 + self.iter.count(), + None => self.iter.count(), + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + match self.peeked.take() { + Some(None) => None, + Some(v @ Some(_)) if n == 0 => v, + Some(Some(_)) => self.iter.nth(n - 1), + None => self.iter.nth(n), + } + } + + #[inline] + fn last(mut self) -> Option { + let peek_opt = match self.peeked.take() { + Some(None) => return None, + Some(v) => v, + None => None, + }; + self.iter.last().or(peek_opt) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let peek_len = match self.peeked { + Some(None) => return (0, Some(0)), + Some(Some(_)) => 1, + None => 0, + }; + let (lo, hi) = self.iter.size_hint(); + let lo = lo.saturating_add(peek_len); + let hi = hi.and_then(|x| x.checked_add(peek_len)); + (lo, hi) + } + + #[inline] + fn try_fold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + let acc = match self.peeked.take() { + Some(None) => return Try::from_ok(init), + Some(Some(v)) => f(init, v)?, + None => init, + }; + self.iter.try_fold(acc, f) + } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let acc = match self.peeked { + Some(None) => return init, + Some(Some(v)) => fold(init, v), + None => init, + }; + self.iter.fold(acc, fold) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Peekable {} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Peekable {} + +impl Peekable { + /// Returns a reference to the next() value without advancing the iterator. + /// + /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`. + /// But if the iteration is over, `None` is returned. + /// + /// [`next`]: trait.Iterator.html#tymethod.next + /// + /// Because `peek()` returns a reference, and many iterators iterate over + /// references, there can be a possibly confusing situation where the + /// return value is a double reference. You can see this effect in the + /// examples below. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // peek() lets us see into the future + /// assert_eq!(iter.peek(), Some(&&1)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), Some(&2)); + /// + /// // The iterator does not advance even if we `peek` multiple times + /// assert_eq!(iter.peek(), Some(&&3)); + /// assert_eq!(iter.peek(), Some(&&3)); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// + /// // After the iterator is finished, so is `peek()` + /// assert_eq!(iter.peek(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn peek(&mut self) -> Option<&I::Item> { + let iter = &mut self.iter; + self.peeked.get_or_insert_with(|| iter.next()).as_ref() + } +} + +/// An iterator that rejects elements while `predicate` is true. +/// +/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip_while`]: trait.Iterator.html#method.skip_while +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct SkipWhile { + pub(super) iter: I, + pub(super) flag: bool, + pub(super) predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for SkipWhile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SkipWhile") + .field("iter", &self.iter) + .field("flag", &self.flag) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for SkipWhile + where P: FnMut(&I::Item) -> bool +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + let flag = &mut self.flag; + let pred = &mut self.predicate; + self.iter.find(move |x| { + if *flag || !pred(x) { + *flag = true; + true + } else { + false + } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } + + #[inline] + fn try_fold(&mut self, mut init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if !self.flag { + match self.next() { + Some(v) => init = fold(init, v)?, + None => return Try::from_ok(init), + } + } + self.iter.try_fold(init, fold) + } + + #[inline] + fn fold(mut self, mut init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + if !self.flag { + match self.next() { + Some(v) => init = fold(init, v), + None => return init, + } + } + self.iter.fold(init, fold) + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for SkipWhile + where I: FusedIterator, P: FnMut(&I::Item) -> bool {} + +/// An iterator that only accepts elements while `predicate` is true. +/// +/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take_while`]: trait.Iterator.html#method.take_while +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct TakeWhile { + pub(super) iter: I, + pub(super) flag: bool, + pub(super) predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for TakeWhile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("TakeWhile") + .field("iter", &self.iter) + .field("flag", &self.flag) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for TakeWhile + where P: FnMut(&I::Item) -> bool +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.flag { + None + } else { + self.iter.next().and_then(|x| { + if (self.predicate)(&x) { + Some(x) + } else { + self.flag = true; + None + } + }) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + if self.flag { + (0, Some(0)) + } else { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } + } + + #[inline] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if self.flag { + Try::from_ok(init) + } else { + let flag = &mut self.flag; + let p = &mut self.predicate; + self.iter.try_fold(init, move |acc, x|{ + if p(&x) { + LoopState::from_try(fold(acc, x)) + } else { + *flag = true; + LoopState::Break(Try::from_ok(acc)) + } + }).into_try() + } + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for TakeWhile + where I: FusedIterator, P: FnMut(&I::Item) -> bool {} + +/// An iterator that skips over `n` elements of `iter`. +/// +/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip`]: trait.Iterator.html#method.skip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Skip { + pub(super) iter: I, + pub(super) n: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Skip where I: Iterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.n == 0 { + self.iter.next() + } else { + let old_n = self.n; + self.n = 0; + self.iter.nth(old_n) + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + // Can't just add n + self.n due to overflow. + if self.n == 0 { + self.iter.nth(n) + } else { + let to_skip = self.n; + self.n = 0; + // nth(n) skips n+1 + if self.iter.nth(to_skip-1).is_none() { + return None; + } + self.iter.nth(n) + } + } + + #[inline] + fn count(self) -> usize { + self.iter.count().saturating_sub(self.n) + } + + #[inline] + fn last(mut self) -> Option { + if self.n == 0 { + self.iter.last() + } else { + let next = self.next(); + if next.is_some() { + // recurse. n should be 0. + self.last().or(next) + } else { + None + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = lower.saturating_sub(self.n); + let upper = upper.map(|x| x.saturating_sub(self.n)); + + (lower, upper) + } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let n = self.n; + self.n = 0; + if n > 0 { + // nth(n) skips n+1 + if self.iter.nth(n - 1).is_none() { + return Try::from_ok(init); + } + } + self.iter.try_fold(init, fold) + } + + #[inline] + fn fold(mut self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + if self.n > 0 { + // nth(n) skips n+1 + if self.iter.nth(self.n - 1).is_none() { + return init; + } + } + self.iter.fold(init, fold) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Skip where I: ExactSizeIterator {} + +#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")] +impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSizeIterator { + fn next_back(&mut self) -> Option { + if self.len() > 0 { + self.iter.next_back() + } else { + None + } + } + + fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let mut n = self.len(); + if n == 0 { + Try::from_ok(init) + } else { + self.iter.try_rfold(init, move |acc, x| { + n -= 1; + let r = fold(acc, x); + if n == 0 { LoopState::Break(r) } + else { LoopState::from_try(r) } + }).into_try() + } + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Skip where I: FusedIterator {} + +/// An iterator that only iterates over the first `n` iterations of `iter`. +/// +/// This `struct` is created by the [`take`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take`]: trait.Iterator.html#method.take +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Take { + pub(super) iter: I, + pub(super) n: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Take where I: Iterator{ + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { + if self.n != 0 { + self.n -= 1; + self.iter.next() + } else { + None + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + if self.n > n { + self.n -= n + 1; + self.iter.nth(n) + } else { + if self.n > 0 { + self.iter.nth(self.n - 1); + self.n = 0; + } + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + if self.n == 0 { + return (0, Some(0)); + } + + let (lower, upper) = self.iter.size_hint(); + + let lower = cmp::min(lower, self.n); + + let upper = match upper { + Some(x) if x < self.n => Some(x), + _ => Some(self.n) + }; + + (lower, upper) + } + + #[inline] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if self.n == 0 { + Try::from_ok(init) + } else { + let n = &mut self.n; + self.iter.try_fold(init, move |acc, x| { + *n -= 1; + let r = fold(acc, x); + if *n == 0 { LoopState::Break(r) } + else { LoopState::from_try(r) } + }).into_try() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Take where I: ExactSizeIterator {} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Take where I: FusedIterator {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Take {} + +/// An iterator to maintain state while iterating another iterator. +/// +/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`scan`]: trait.Iterator.html#method.scan +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Scan { + pub(super) iter: I, + pub(super) f: F, + pub(super) state: St, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Scan { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Scan") + .field("iter", &self.iter) + .field("state", &self.state) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Scan where + I: Iterator, + F: FnMut(&mut St, I::Item) -> Option, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().and_then(|a| (self.f)(&mut self.state, a)) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the scan function + } + + #[inline] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let state = &mut self.state; + let f = &mut self.f; + self.iter.try_fold(init, move |acc, x| { + match f(state, x) { + None => LoopState::Break(Try::from_ok(acc)), + Some(x) => LoopState::from_try(fold(acc, x)), + } + }).into_try() + } +} + +/// An iterator that maps each element to an iterator, and yields the elements +/// of the produced iterators. +/// +/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flat_map`]: trait.Iterator.html#method.flat_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct FlatMap { + pub(super) inner: FlattenCompat, ::IntoIter> +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for FlatMap + where ::IntoIter: Clone +{ + fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } } +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for FlatMap + where U::IntoIter: fmt::Debug +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FlatMap").field("inner", &self.inner).finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for FlatMap + where F: FnMut(I::Item) -> U, +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { self.inner.next() } + + #[inline] + fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_fold(init, fold) + } + + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.fold(init, fold) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for FlatMap + where F: FnMut(I::Item) -> U, + U: IntoIterator, + U::IntoIter: DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option { self.inner.next_back() } + + #[inline] + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_rfold(init, fold) + } + + #[inline] + fn rfold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.rfold(init, fold) + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for FlatMap + where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {} + +/// An iterator that flattens one level of nesting in an iterator of things +/// that can be turned into iterators. +/// +/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flatten`]: trait.Iterator.html#method.flatten +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "iterator_flatten", since = "1.29.0")] +pub struct Flatten +where I::Item: IntoIterator { + pub(super) inner: FlattenCompat::IntoIter>, +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl fmt::Debug for Flatten + where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug, + I::Item: IntoIterator, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Flatten").field("inner", &self.inner).finish() + } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl Clone for Flatten + where I: Iterator + Clone, U: Iterator + Clone, + I::Item: IntoIterator, +{ + fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl Iterator for Flatten + where I: Iterator, U: Iterator, + I::Item: IntoIterator +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { self.inner.next() } + + #[inline] + fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_fold(init, fold) + } + + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.fold(init, fold) + } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl DoubleEndedIterator for Flatten + where I: DoubleEndedIterator, U: DoubleEndedIterator, + I::Item: IntoIterator +{ + #[inline] + fn next_back(&mut self) -> Option { self.inner.next_back() } + + #[inline] + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_rfold(init, fold) + } + + #[inline] + fn rfold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.rfold(init, fold) + } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl FusedIterator for Flatten + where I: FusedIterator, U: Iterator, + I::Item: IntoIterator {} + +/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. +pub(super) fn flatten_compat(iter: I) -> FlattenCompat { + FlattenCompat { iter, frontiter: None, backiter: None } +} + +/// Real logic of both `Flatten` and `FlatMap` which simply delegate to +/// this type. +#[derive(Clone, Debug)] +pub(super) struct FlattenCompat { + iter: I, + frontiter: Option, + backiter: Option, +} + +impl Iterator for FlattenCompat + where I: Iterator, U: Iterator, + I::Item: IntoIterator +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { + loop { + if let Some(ref mut inner) = self.frontiter { + if let elt@Some(_) = inner.next() { return elt } + } + match self.iter.next() { + None => return self.backiter.as_mut().and_then(|it| it.next()), + Some(inner) => self.frontiter = Some(inner.into_iter()), + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let lo = flo.saturating_add(blo); + match (self.iter.size_hint(), fhi, bhi) { + ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), + _ => (lo, None) + } + } + + #[inline] + fn try_fold(&mut self, mut init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if let Some(ref mut front) = self.frontiter { + init = front.try_fold(init, &mut fold)?; + } + self.frontiter = None; + + { + let frontiter = &mut self.frontiter; + init = self.iter.try_fold(init, |acc, x| { + let mut mid = x.into_iter(); + let r = mid.try_fold(acc, &mut fold); + *frontiter = Some(mid); + r + })?; + } + self.frontiter = None; + + if let Some(ref mut back) = self.backiter { + init = back.try_fold(init, &mut fold)?; + } + self.backiter = None; + + Try::from_ok(init) + } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.frontiter.into_iter() + .chain(self.iter.map(IntoIterator::into_iter)) + .chain(self.backiter) + .fold(init, |acc, iter| iter.fold(acc, &mut fold)) + } +} + +impl DoubleEndedIterator for FlattenCompat + where I: DoubleEndedIterator, U: DoubleEndedIterator, + I::Item: IntoIterator +{ + #[inline] + fn next_back(&mut self) -> Option { + loop { + if let Some(ref mut inner) = self.backiter { + if let elt@Some(_) = inner.next_back() { return elt } + } + match self.iter.next_back() { + None => return self.frontiter.as_mut().and_then(|it| it.next_back()), + next => self.backiter = next.map(IntoIterator::into_iter), + } + } + } + + #[inline] + fn try_rfold(&mut self, mut init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if let Some(ref mut back) = self.backiter { + init = back.try_rfold(init, &mut fold)?; + } + self.backiter = None; + + { + let backiter = &mut self.backiter; + init = self.iter.try_rfold(init, |acc, x| { + let mut mid = x.into_iter(); + let r = mid.try_rfold(acc, &mut fold); + *backiter = Some(mid); + r + })?; + } + self.backiter = None; + + if let Some(ref mut front) = self.frontiter { + init = front.try_rfold(init, &mut fold)?; + } + self.frontiter = None; + + Try::from_ok(init) + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.frontiter.into_iter() + .chain(self.iter.map(IntoIterator::into_iter)) + .chain(self.backiter) + .rfold(init, |acc, iter| iter.rfold(acc, &mut fold)) + } +} + +/// An iterator that yields `None` forever after the underlying iterator +/// yields `None` once. +/// +/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`fuse`]: trait.Iterator.html#method.fuse +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Fuse { + pub(super) iter: I, + pub(super) done: bool +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Fuse where I: Iterator {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Fuse where I: Iterator { + type Item = ::Item; + + #[inline] + default fn next(&mut self) -> Option<::Item> { + if self.done { + None + } else { + let next = self.iter.next(); + self.done = next.is_none(); + next + } + } + + #[inline] + default fn nth(&mut self, n: usize) -> Option { + if self.done { + None + } else { + let nth = self.iter.nth(n); + self.done = nth.is_none(); + nth + } + } + + #[inline] + default fn last(self) -> Option { + if self.done { + None + } else { + self.iter.last() + } + } + + #[inline] + default fn count(self) -> usize { + if self.done { + 0 + } else { + self.iter.count() + } + } + + #[inline] + default fn size_hint(&self) -> (usize, Option) { + if self.done { + (0, Some(0)) + } else { + self.iter.size_hint() + } + } + + #[inline] + default fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if self.done { + Try::from_ok(init) + } else { + let acc = self.iter.try_fold(init, fold)?; + self.done = true; + Try::from_ok(acc) + } + } + + #[inline] + default fn fold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + if self.done { + init + } else { + self.iter.fold(init, fold) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { + #[inline] + default fn next_back(&mut self) -> Option<::Item> { + if self.done { + None + } else { + let next = self.iter.next_back(); + self.done = next.is_none(); + next + } + } + + #[inline] + default fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if self.done { + Try::from_ok(init) + } else { + let acc = self.iter.try_rfold(init, fold)?; + self.done = true; + Try::from_ok(acc) + } + } + + #[inline] + default fn rfold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + if self.done { + init + } else { + self.iter.rfold(init, fold) + } + } +} + +unsafe impl TrustedRandomAccess for Fuse + where I: TrustedRandomAccess, +{ + unsafe fn get_unchecked(&mut self, i: usize) -> I::Item { + self.iter.get_unchecked(i) + } + + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl Iterator for Fuse where I: FusedIterator { + #[inline] + fn next(&mut self) -> Option<::Item> { + self.iter.next() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.iter.nth(n) + } + + #[inline] + fn last(self) -> Option { + self.iter.last() + } + + #[inline] + fn count(self) -> usize { + self.iter.count() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.iter.try_fold(init, fold) + } + + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.iter.fold(init, fold) + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl DoubleEndedIterator for Fuse + where I: DoubleEndedIterator + FusedIterator +{ + #[inline] + fn next_back(&mut self) -> Option<::Item> { + self.iter.next_back() + } + + #[inline] + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.iter.try_rfold(init, fold) + } + + #[inline] + fn rfold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.iter.rfold(init, fold) + } +} + + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Fuse where I: ExactSizeIterator { + fn len(&self) -> usize { + self.iter.len() + } + + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +/// An iterator that calls a function with a reference to each element before +/// yielding it. +/// +/// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`inspect`]: trait.Iterator.html#method.inspect +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Inspect { + pub(super) iter: I, + pub(super) f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Inspect { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Inspect") + .field("iter", &self.iter) + .finish() + } +} + +impl Inspect where F: FnMut(&I::Item) { + #[inline] + fn do_inspect(&mut self, elt: Option) -> Option { + if let Some(ref a) = elt { + (self.f)(a); + } + + elt + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Inspect where F: FnMut(&I::Item) { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + let next = self.iter.next(); + self.do_inspect(next) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + + #[inline] + fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let f = &mut self.f; + self.iter.try_fold(init, move |acc, item| { f(&item); fold(acc, item) }) + } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter.fold(init, move |acc, item| { f(&item); fold(acc, item) }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Inspect + where F: FnMut(&I::Item), +{ + #[inline] + fn next_back(&mut self) -> Option { + let next = self.iter.next_back(); + self.do_inspect(next) + } + + #[inline] + fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + let f = &mut self.f; + self.iter.try_rfold(init, move |acc, item| { f(&item); fold(acc, item) }) + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter.rfold(init, move |acc, item| { f(&item); fold(acc, item) }) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Inspect + where F: FnMut(&I::Item) +{ + fn len(&self) -> usize { + self.iter.len() + } + + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Inspect + where F: FnMut(&I::Item) {} diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 974906b682d21..bc8760934d2ed 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -306,12 +306,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use cmp; -use fmt; -use iter_private::TrustedRandomAccess; use ops::Try; -use usize; -use intrinsics; #[stable(feature = "rust1", since = "1.0.0")] pub use self::iterator::Iterator; @@ -343,10 +338,28 @@ pub use self::traits::FusedIterator; #[unstable(feature = "trusted_len", issue = "37572")] pub use self::traits::TrustedLen; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::adapters::{Rev, Cycle, Chain, Zip, Map, Filter, FilterMap, Enumerate}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::adapters::{Peekable, SkipWhile, TakeWhile, Skip, Take, Scan, FlatMap}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::adapters::{Fuse, Inspect}; +#[stable(feature = "iter_cloned", since = "1.1.0")] +pub use self::adapters::Cloned; +#[stable(feature = "iterator_step_by", since = "1.28.0")] +pub use self::adapters::StepBy; +#[stable(feature = "iterator_flatten", since = "1.29.0")] +pub use self::adapters::Flatten; +#[unstable(feature = "iter_copied", issue = "57127")] +pub use self::adapters::Copied; + +use self::adapters::{flatten_compat, ChainState, ZipImpl}; + mod iterator; mod range; mod sources; mod traits; +mod adapters; /// Used to make try_fold closures more like normal loops #[derive(PartialEq)] @@ -397,2767 +410,3 @@ impl LoopState { } } } - -/// A double-ended iterator with the direction inverted. -/// -/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`rev`]: trait.Iterator.html#method.rev -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Rev { - iter: T -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Rev where I: DoubleEndedIterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { self.iter.next_back() } - #[inline] - fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } - - #[inline] - fn nth(&mut self, n: usize) -> Option<::Item> { self.iter.nth_back(n) } - - fn try_fold(&mut self, init: B, f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - self.iter.try_rfold(init, f) - } - - fn fold(self, init: Acc, f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - self.iter.rfold(init, f) - } - - #[inline] - fn find

(&mut self, predicate: P) -> Option - where P: FnMut(&Self::Item) -> bool - { - self.iter.rfind(predicate) - } - - #[inline] - fn rposition

(&mut self, predicate: P) -> Option where - P: FnMut(Self::Item) -> bool - { - self.iter.position(predicate) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Rev where I: DoubleEndedIterator { - #[inline] - fn next_back(&mut self) -> Option<::Item> { self.iter.next() } - - #[inline] - fn nth_back(&mut self, n: usize) -> Option<::Item> { self.iter.nth(n) } - - fn try_rfold(&mut self, init: B, f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - self.iter.try_fold(init, f) - } - - fn rfold(self, init: Acc, f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - self.iter.fold(init, f) - } - - fn rfind

(&mut self, predicate: P) -> Option - where P: FnMut(&Self::Item) -> bool - { - self.iter.find(predicate) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Rev - where I: ExactSizeIterator + DoubleEndedIterator -{ - fn len(&self) -> usize { - self.iter.len() - } - - fn is_empty(&self) -> bool { - self.iter.is_empty() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Rev - where I: FusedIterator + DoubleEndedIterator {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Rev - where I: TrustedLen + DoubleEndedIterator {} - -/// An iterator that copies the elements of an underlying iterator. -/// -/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`copied`]: trait.Iterator.html#method.copied -/// [`Iterator`]: trait.Iterator.html -#[unstable(feature = "iter_copied", issue = "57127")] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[derive(Clone, Debug)] -pub struct Copied { - it: I, -} - -#[unstable(feature = "iter_copied", issue = "57127")] -impl<'a, I, T: 'a> Iterator for Copied - where I: Iterator, T: Copy -{ - type Item = T; - - fn next(&mut self) -> Option { - self.it.next().copied() - } - - fn size_hint(&self) -> (usize, Option) { - self.it.size_hint() - } - - fn try_fold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - self.it.try_fold(init, move |acc, &elt| f(acc, elt)) - } - - fn fold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - self.it.fold(init, move |acc, &elt| f(acc, elt)) - } -} - -#[unstable(feature = "iter_copied", issue = "57127")] -impl<'a, I, T: 'a> DoubleEndedIterator for Copied - where I: DoubleEndedIterator, T: Copy -{ - fn next_back(&mut self) -> Option { - self.it.next_back().copied() - } - - fn try_rfold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - self.it.try_rfold(init, move |acc, &elt| f(acc, elt)) - } - - fn rfold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - self.it.rfold(init, move |acc, &elt| f(acc, elt)) - } -} - -#[unstable(feature = "iter_copied", issue = "57127")] -impl<'a, I, T: 'a> ExactSizeIterator for Copied - where I: ExactSizeIterator, T: Copy -{ - fn len(&self) -> usize { - self.it.len() - } - - fn is_empty(&self) -> bool { - self.it.is_empty() - } -} - -#[unstable(feature = "iter_copied", issue = "57127")] -impl<'a, I, T: 'a> FusedIterator for Copied - where I: FusedIterator, T: Copy -{} - -#[doc(hidden)] -unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Copied - where I: TrustedRandomAccess, T: Copy -{ - unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { - *self.it.get_unchecked(i) - } - - #[inline] - fn may_have_side_effect() -> bool { - I::may_have_side_effect() - } -} - -#[unstable(feature = "iter_copied", issue = "57127")] -unsafe impl<'a, I, T: 'a> TrustedLen for Copied - where I: TrustedLen, - T: Copy -{} - -/// An iterator that clones the elements of an underlying iterator. -/// -/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`cloned`]: trait.Iterator.html#method.cloned -/// [`Iterator`]: trait.Iterator.html -#[stable(feature = "iter_cloned", since = "1.1.0")] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[derive(Clone, Debug)] -pub struct Cloned { - it: I, -} - -#[stable(feature = "iter_cloned", since = "1.1.0")] -impl<'a, I, T: 'a> Iterator for Cloned - where I: Iterator, T: Clone -{ - type Item = T; - - fn next(&mut self) -> Option { - self.it.next().cloned() - } - - fn size_hint(&self) -> (usize, Option) { - self.it.size_hint() - } - - fn try_fold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - self.it.try_fold(init, move |acc, elt| f(acc, elt.clone())) - } - - fn fold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - self.it.fold(init, move |acc, elt| f(acc, elt.clone())) - } -} - -#[stable(feature = "iter_cloned", since = "1.1.0")] -impl<'a, I, T: 'a> DoubleEndedIterator for Cloned - where I: DoubleEndedIterator, T: Clone -{ - fn next_back(&mut self) -> Option { - self.it.next_back().cloned() - } - - fn try_rfold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - self.it.try_rfold(init, move |acc, elt| f(acc, elt.clone())) - } - - fn rfold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - self.it.rfold(init, move |acc, elt| f(acc, elt.clone())) - } -} - -#[stable(feature = "iter_cloned", since = "1.1.0")] -impl<'a, I, T: 'a> ExactSizeIterator for Cloned - where I: ExactSizeIterator, T: Clone -{ - fn len(&self) -> usize { - self.it.len() - } - - fn is_empty(&self) -> bool { - self.it.is_empty() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl<'a, I, T: 'a> FusedIterator for Cloned - where I: FusedIterator, T: Clone -{} - -#[doc(hidden)] -unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned - where I: TrustedRandomAccess, T: Clone -{ - default unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { - self.it.get_unchecked(i).clone() - } - - #[inline] - default fn may_have_side_effect() -> bool { true } -} - -#[doc(hidden)] -unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned - where I: TrustedRandomAccess, T: Copy -{ - unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { - *self.it.get_unchecked(i) - } - - #[inline] - fn may_have_side_effect() -> bool { - I::may_have_side_effect() - } -} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, I, T: 'a> TrustedLen for Cloned - where I: TrustedLen, - T: Clone -{} - -/// An iterator that repeats endlessly. -/// -/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`cycle`]: trait.Iterator.html#method.cycle -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Cycle { - orig: I, - iter: I, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Cycle where I: Clone + Iterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { - match self.iter.next() { - None => { self.iter = self.orig.clone(); self.iter.next() } - y => y - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - // the cycle iterator is either empty or infinite - match self.orig.size_hint() { - sz @ (0, Some(0)) => sz, - (0, _) => (0, None), - _ => (usize::MAX, None) - } - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Cycle where I: Clone + Iterator {} - -/// An iterator for stepping iterators by a custom amount. -/// -/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See -/// its documentation for more. -/// -/// [`step_by`]: trait.Iterator.html#method.step_by -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "iterator_step_by", since = "1.28.0")] -#[derive(Clone, Debug)] -pub struct StepBy { - iter: I, - step: usize, - first_take: bool, -} - -#[stable(feature = "iterator_step_by", since = "1.28.0")] -impl Iterator for StepBy where I: Iterator { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - if self.first_take { - self.first_take = false; - self.iter.next() - } else { - self.iter.nth(self.step) - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let inner_hint = self.iter.size_hint(); - - if self.first_take { - let f = |n| if n == 0 { 0 } else { 1 + (n-1)/(self.step+1) }; - (f(inner_hint.0), inner_hint.1.map(f)) - } else { - let f = |n| n / (self.step+1); - (f(inner_hint.0), inner_hint.1.map(f)) - } - } - - #[inline] - fn nth(&mut self, mut n: usize) -> Option { - if self.first_take { - self.first_take = false; - let first = self.iter.next(); - if n == 0 { - return first; - } - n -= 1; - } - // n and self.step are indices, we need to add 1 to get the amount of elements - // When calling `.nth`, we need to subtract 1 again to convert back to an index - // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1` - let mut step = self.step + 1; - // n + 1 could overflow - // thus, if n is usize::MAX, instead of adding one, we call .nth(step) - if n == usize::MAX { - self.iter.nth(step - 1); - } else { - n += 1; - } - - // overflow handling - loop { - let mul = n.checked_mul(step); - if unsafe { intrinsics::likely(mul.is_some()) } { - return self.iter.nth(mul.unwrap() - 1); - } - let div_n = usize::MAX / n; - let div_step = usize::MAX / step; - let nth_n = div_n * n; - let nth_step = div_step * step; - let nth = if nth_n > nth_step { - step -= div_n; - nth_n - } else { - n -= div_step; - nth_step - }; - self.iter.nth(nth - 1); - } - } -} - -// StepBy can only make the iterator shorter, so the len will still fit. -#[stable(feature = "iterator_step_by", since = "1.28.0")] -impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} - -/// An iterator that strings two iterators together. -/// -/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`chain`]: trait.Iterator.html#method.chain -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Chain { - a: A, - b: B, - state: ChainState, -} - -// The iterator protocol specifies that iteration ends with the return value -// `None` from `.next()` (or `.next_back()`) and it is unspecified what -// further calls return. The chain adaptor must account for this since it uses -// two subiterators. -// -// It uses three states: -// -// - Both: `a` and `b` are remaining -// - Front: `a` remaining -// - Back: `b` remaining -// -// The fourth state (neither iterator is remaining) only occurs after Chain has -// returned None once, so we don't need to store this state. -#[derive(Clone, Debug)] -enum ChainState { - // both front and back iterator are remaining - Both, - // only front is remaining - Front, - // only back is remaining - Back, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Chain where - A: Iterator, - B: Iterator -{ - type Item = A::Item; - - #[inline] - fn next(&mut self) -> Option { - match self.state { - ChainState::Both => match self.a.next() { - elt @ Some(..) => elt, - None => { - self.state = ChainState::Back; - self.b.next() - } - }, - ChainState::Front => self.a.next(), - ChainState::Back => self.b.next(), - } - } - - #[inline] - #[rustc_inherit_overflow_checks] - fn count(self) -> usize { - match self.state { - ChainState::Both => self.a.count() + self.b.count(), - ChainState::Front => self.a.count(), - ChainState::Back => self.b.count(), - } - } - - fn try_fold(&mut self, init: Acc, mut f: F) -> R where - Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Front => { - accum = self.a.try_fold(accum, &mut f)?; - if let ChainState::Both = self.state { - self.state = ChainState::Back; - } - } - _ => { } - } - if let ChainState::Back = self.state { - accum = self.b.try_fold(accum, &mut f)?; - } - Try::from_ok(accum) - } - - fn fold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Front => { - accum = self.a.fold(accum, &mut f); - } - _ => { } - } - match self.state { - ChainState::Both | ChainState::Back => { - accum = self.b.fold(accum, &mut f); - } - _ => { } - } - accum - } - - #[inline] - fn nth(&mut self, mut n: usize) -> Option { - match self.state { - ChainState::Both | ChainState::Front => { - for x in self.a.by_ref() { - if n == 0 { - return Some(x) - } - n -= 1; - } - if let ChainState::Both = self.state { - self.state = ChainState::Back; - } - } - ChainState::Back => {} - } - if let ChainState::Back = self.state { - self.b.nth(n) - } else { - None - } - } - - #[inline] - fn find

(&mut self, mut predicate: P) -> Option where - P: FnMut(&Self::Item) -> bool, - { - match self.state { - ChainState::Both => match self.a.find(&mut predicate) { - None => { - self.state = ChainState::Back; - self.b.find(predicate) - } - v => v - }, - ChainState::Front => self.a.find(predicate), - ChainState::Back => self.b.find(predicate), - } - } - - #[inline] - fn last(self) -> Option { - match self.state { - ChainState::Both => { - // Must exhaust a before b. - let a_last = self.a.last(); - let b_last = self.b.last(); - b_last.or(a_last) - }, - ChainState::Front => self.a.last(), - ChainState::Back => self.b.last() - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); - - let lower = a_lower.saturating_add(b_lower); - - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => x.checked_add(y), - _ => None - }; - - (lower, upper) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Chain where - A: DoubleEndedIterator, - B: DoubleEndedIterator, -{ - #[inline] - fn next_back(&mut self) -> Option { - match self.state { - ChainState::Both => match self.b.next_back() { - elt @ Some(..) => elt, - None => { - self.state = ChainState::Front; - self.a.next_back() - } - }, - ChainState::Front => self.a.next_back(), - ChainState::Back => self.b.next_back(), - } - } - - fn try_rfold(&mut self, init: Acc, mut f: F) -> R where - Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Back => { - accum = self.b.try_rfold(accum, &mut f)?; - if let ChainState::Both = self.state { - self.state = ChainState::Front; - } - } - _ => { } - } - if let ChainState::Front = self.state { - accum = self.a.try_rfold(accum, &mut f)?; - } - Try::from_ok(accum) - } - - fn rfold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Back => { - accum = self.b.rfold(accum, &mut f); - } - _ => { } - } - match self.state { - ChainState::Both | ChainState::Front => { - accum = self.a.rfold(accum, &mut f); - } - _ => { } - } - accum - } - -} - -// Note: *both* must be fused to handle double-ended iterators. -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Chain - where A: FusedIterator, - B: FusedIterator, -{} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Chain - where A: TrustedLen, B: TrustedLen, -{} - -/// An iterator that iterates two other iterators simultaneously. -/// -/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`zip`]: trait.Iterator.html#method.zip -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Zip { - a: A, - b: B, - // index and len are only used by the specialized version of zip - index: usize, - len: usize, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where A: Iterator, B: Iterator -{ - type Item = (A::Item, B::Item); - - #[inline] - fn next(&mut self) -> Option { - ZipImpl::next(self) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - ZipImpl::size_hint(self) - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - ZipImpl::nth(self, n) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Zip where - A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator, -{ - #[inline] - fn next_back(&mut self) -> Option<(A::Item, B::Item)> { - ZipImpl::next_back(self) - } -} - -// Zip specialization trait -#[doc(hidden)] -trait ZipImpl { - type Item; - fn new(a: A, b: B) -> Self; - fn next(&mut self) -> Option; - fn size_hint(&self) -> (usize, Option); - fn nth(&mut self, n: usize) -> Option; - fn super_nth(&mut self, mut n: usize) -> Option { - while let Some(x) = self.next() { - if n == 0 { return Some(x) } - n -= 1; - } - None - } - fn next_back(&mut self) -> Option - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator; -} - -// General Zip impl -#[doc(hidden)] -impl ZipImpl for Zip - where A: Iterator, B: Iterator -{ - type Item = (A::Item, B::Item); - default fn new(a: A, b: B) -> Self { - Zip { - a, - b, - index: 0, // unused - len: 0, // unused - } - } - - #[inline] - default fn next(&mut self) -> Option<(A::Item, B::Item)> { - self.a.next().and_then(|x| { - self.b.next().and_then(|y| { - Some((x, y)) - }) - }) - } - - #[inline] - default fn nth(&mut self, n: usize) -> Option { - self.super_nth(n) - } - - #[inline] - default fn next_back(&mut self) -> Option<(A::Item, B::Item)> - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator - { - let a_sz = self.a.len(); - let b_sz = self.b.len(); - if a_sz != b_sz { - // Adjust a, b to equal length - if a_sz > b_sz { - for _ in 0..a_sz - b_sz { self.a.next_back(); } - } else { - for _ in 0..b_sz - a_sz { self.b.next_back(); } - } - } - match (self.a.next_back(), self.b.next_back()) { - (Some(x), Some(y)) => Some((x, y)), - (None, None) => None, - _ => unreachable!(), - } - } - - #[inline] - default fn size_hint(&self) -> (usize, Option) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); - - let lower = cmp::min(a_lower, b_lower); - - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => Some(cmp::min(x,y)), - (Some(x), None) => Some(x), - (None, Some(y)) => Some(y), - (None, None) => None - }; - - (lower, upper) - } -} - -#[doc(hidden)] -impl ZipImpl for Zip - where A: TrustedRandomAccess, B: TrustedRandomAccess -{ - fn new(a: A, b: B) -> Self { - let len = cmp::min(a.len(), b.len()); - Zip { - a, - b, - index: 0, - len, - } - } - - #[inline] - fn next(&mut self) -> Option<(A::Item, B::Item)> { - if self.index < self.len { - let i = self.index; - self.index += 1; - unsafe { - Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) - } - } else if A::may_have_side_effect() && self.index < self.a.len() { - // match the base implementation's potential side effects - unsafe { - self.a.get_unchecked(self.index); - } - self.index += 1; - None - } else { - None - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let len = self.len - self.index; - (len, Some(len)) - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - let delta = cmp::min(n, self.len - self.index); - let end = self.index + delta; - while self.index < end { - let i = self.index; - self.index += 1; - if A::may_have_side_effect() { - unsafe { self.a.get_unchecked(i); } - } - if B::may_have_side_effect() { - unsafe { self.b.get_unchecked(i); } - } - } - - self.super_nth(n - delta) - } - - #[inline] - fn next_back(&mut self) -> Option<(A::Item, B::Item)> - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator - { - // Adjust a, b to equal length - if A::may_have_side_effect() { - let sz = self.a.len(); - if sz > self.len { - for _ in 0..sz - cmp::max(self.len, self.index) { - self.a.next_back(); - } - } - } - if B::may_have_side_effect() { - let sz = self.b.len(); - if sz > self.len { - for _ in 0..sz - self.len { - self.b.next_back(); - } - } - } - if self.index < self.len { - self.len -= 1; - let i = self.len; - unsafe { - Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) - } - } else { - None - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Zip - where A: ExactSizeIterator, B: ExactSizeIterator {} - -#[doc(hidden)] -unsafe impl TrustedRandomAccess for Zip - where A: TrustedRandomAccess, - B: TrustedRandomAccess, -{ - unsafe fn get_unchecked(&mut self, i: usize) -> (A::Item, B::Item) { - (self.a.get_unchecked(i), self.b.get_unchecked(i)) - } - - fn may_have_side_effect() -> bool { - A::may_have_side_effect() || B::may_have_side_effect() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Zip - where A: FusedIterator, B: FusedIterator, {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Zip - where A: TrustedLen, B: TrustedLen, -{} - -/// An iterator that maps the values of `iter` with `f`. -/// -/// This `struct` is created by the [`map`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`map`]: trait.Iterator.html#method.map -/// [`Iterator`]: trait.Iterator.html -/// -/// # Notes about side effects -/// -/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that -/// you can also [`map`] backwards: -/// -/// ```rust -/// let v: Vec = vec![1, 2, 3].into_iter().map(|x| x + 1).rev().collect(); -/// -/// assert_eq!(v, [4, 3, 2]); -/// ``` -/// -/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html -/// -/// But if your closure has state, iterating backwards may act in a way you do -/// not expect. Let's go through an example. First, in the forward direction: -/// -/// ```rust -/// let mut c = 0; -/// -/// for pair in vec!['a', 'b', 'c'].into_iter() -/// .map(|letter| { c += 1; (letter, c) }) { -/// println!("{:?}", pair); -/// } -/// ``` -/// -/// This will print "('a', 1), ('b', 2), ('c', 3)". -/// -/// Now consider this twist where we add a call to `rev`. This version will -/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed, -/// but the values of the counter still go in order. This is because `map()` is -/// still being called lazily on each item, but we are popping items off the -/// back of the vector now, instead of shifting them from the front. -/// -/// ```rust -/// let mut c = 0; -/// -/// for pair in vec!['a', 'b', 'c'].into_iter() -/// .map(|letter| { c += 1; (letter, c) }) -/// .rev() { -/// println!("{:?}", pair); -/// } -/// ``` -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Map { - iter: I, - f: F, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Map { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Map") - .field("iter", &self.iter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Map where F: FnMut(I::Item) -> B { - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().map(&mut self.f) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - - fn try_fold(&mut self, init: Acc, mut g: G) -> R where - Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try - { - let f = &mut self.f; - self.iter.try_fold(init, move |acc, elt| g(acc, f(elt))) - } - - fn fold(self, init: Acc, mut g: G) -> Acc - where G: FnMut(Acc, Self::Item) -> Acc, - { - let mut f = self.f; - self.iter.fold(init, move |acc, elt| g(acc, f(elt))) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Map where - F: FnMut(I::Item) -> B, -{ - #[inline] - fn next_back(&mut self) -> Option { - self.iter.next_back().map(&mut self.f) - } - - fn try_rfold(&mut self, init: Acc, mut g: G) -> R where - Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try - { - let f = &mut self.f; - self.iter.try_rfold(init, move |acc, elt| g(acc, f(elt))) - } - - fn rfold(self, init: Acc, mut g: G) -> Acc - where G: FnMut(Acc, Self::Item) -> Acc, - { - let mut f = self.f; - self.iter.rfold(init, move |acc, elt| g(acc, f(elt))) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Map - where F: FnMut(I::Item) -> B -{ - fn len(&self) -> usize { - self.iter.len() - } - - fn is_empty(&self) -> bool { - self.iter.is_empty() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Map - where F: FnMut(I::Item) -> B {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Map - where I: TrustedLen, - F: FnMut(I::Item) -> B {} - -#[doc(hidden)] -unsafe impl TrustedRandomAccess for Map - where I: TrustedRandomAccess, - F: FnMut(I::Item) -> B, -{ - unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { - (self.f)(self.iter.get_unchecked(i)) - } - #[inline] - fn may_have_side_effect() -> bool { true } -} - -/// An iterator that filters the elements of `iter` with `predicate`. -/// -/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`filter`]: trait.Iterator.html#method.filter -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Filter { - iter: I, - predicate: P, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Filter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Filter") - .field("iter", &self.iter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Filter where P: FnMut(&I::Item) -> bool { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - for x in &mut self.iter { - if (self.predicate)(&x) { - return Some(x); - } - } - None - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } - - // this special case allows the compiler to make `.filter(_).count()` - // branchless. Barring perfect branch prediction (which is unattainable in - // the general case), this will be much faster in >90% of cases (containing - // virtually all real workloads) and only a tiny bit slower in the rest. - // - // Having this specialization thus allows us to write `.filter(p).count()` - // where we would otherwise write `.map(|x| p(x) as usize).sum()`, which is - // less readable and also less backwards-compatible to Rust before 1.10. - // - // Using the branchless version will also simplify the LLVM byte code, thus - // leaving more budget for LLVM optimizations. - #[inline] - fn count(mut self) -> usize { - let mut count = 0; - for x in &mut self.iter { - count += (self.predicate)(&x) as usize; - } - count - } - - #[inline] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let predicate = &mut self.predicate; - self.iter.try_fold(init, move |acc, item| if predicate(&item) { - fold(acc, item) - } else { - Try::from_ok(acc) - }) - } - - #[inline] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut predicate = self.predicate; - self.iter.fold(init, move |acc, item| if predicate(&item) { - fold(acc, item) - } else { - acc - }) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Filter - where P: FnMut(&I::Item) -> bool, -{ - #[inline] - fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if (self.predicate)(&x) { - return Some(x); - } - } - None - } - - #[inline] - fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let predicate = &mut self.predicate; - self.iter.try_rfold(init, move |acc, item| if predicate(&item) { - fold(acc, item) - } else { - Try::from_ok(acc) - }) - } - - #[inline] - fn rfold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut predicate = self.predicate; - self.iter.rfold(init, move |acc, item| if predicate(&item) { - fold(acc, item) - } else { - acc - }) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Filter - where P: FnMut(&I::Item) -> bool {} - -/// An iterator that uses `f` to both filter and map elements from `iter`. -/// -/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`filter_map`]: trait.Iterator.html#method.filter_map -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct FilterMap { - iter: I, - f: F, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for FilterMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("FilterMap") - .field("iter", &self.iter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for FilterMap - where F: FnMut(I::Item) -> Option, -{ - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - for x in self.iter.by_ref() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } - - #[inline] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let f = &mut self.f; - self.iter.try_fold(init, move |acc, item| match f(item) { - Some(x) => fold(acc, x), - None => Try::from_ok(acc), - }) - } - - #[inline] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut f = self.f; - self.iter.fold(init, move |acc, item| match f(item) { - Some(x) => fold(acc, x), - None => acc, - }) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for FilterMap - where F: FnMut(I::Item) -> Option, -{ - #[inline] - fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None - } - - #[inline] - fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let f = &mut self.f; - self.iter.try_rfold(init, move |acc, item| match f(item) { - Some(x) => fold(acc, x), - None => Try::from_ok(acc), - }) - } - - #[inline] - fn rfold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut f = self.f; - self.iter.rfold(init, move |acc, item| match f(item) { - Some(x) => fold(acc, x), - None => acc, - }) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for FilterMap - where F: FnMut(I::Item) -> Option {} - -/// An iterator that yields the current count and the element during iteration. -/// -/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`enumerate`]: trait.Iterator.html#method.enumerate -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Enumerate { - iter: I, - count: usize, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Enumerate where I: Iterator { - type Item = (usize, ::Item); - - /// # Overflow Behavior - /// - /// The method does no guarding against overflows, so enumerating more than - /// `usize::MAX` elements either produces the wrong result or panics. If - /// debug assertions are enabled, a panic is guaranteed. - /// - /// # Panics - /// - /// Might panic if the index of the element overflows a `usize`. - #[inline] - #[rustc_inherit_overflow_checks] - fn next(&mut self) -> Option<(usize, ::Item)> { - self.iter.next().map(|a| { - let ret = (self.count, a); - // Possible undefined overflow. - self.count += 1; - ret - }) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - - #[inline] - #[rustc_inherit_overflow_checks] - fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { - self.iter.nth(n).map(|a| { - let i = self.count + n; - self.count = i + 1; - (i, a) - }) - } - - #[inline] - fn count(self) -> usize { - self.iter.count() - } - - #[inline] - #[rustc_inherit_overflow_checks] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let count = &mut self.count; - self.iter.try_fold(init, move |acc, item| { - let acc = fold(acc, (*count, item)); - *count += 1; - acc - }) - } - - #[inline] - #[rustc_inherit_overflow_checks] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut count = self.count; - self.iter.fold(init, move |acc, item| { - let acc = fold(acc, (count, item)); - count += 1; - acc - }) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Enumerate where - I: ExactSizeIterator + DoubleEndedIterator -{ - #[inline] - fn next_back(&mut self) -> Option<(usize, ::Item)> { - self.iter.next_back().map(|a| { - let len = self.iter.len(); - // Can safely add, `ExactSizeIterator` promises that the number of - // elements fits into a `usize`. - (self.count + len, a) - }) - } - - #[inline] - fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - // Can safely add and subtract the count, as `ExactSizeIterator` promises - // that the number of elements fits into a `usize`. - let mut count = self.count + self.iter.len(); - self.iter.try_rfold(init, move |acc, item| { - count -= 1; - fold(acc, (count, item)) - }) - } - - #[inline] - fn rfold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - // Can safely add and subtract the count, as `ExactSizeIterator` promises - // that the number of elements fits into a `usize`. - let mut count = self.count + self.iter.len(); - self.iter.rfold(init, move |acc, item| { - count -= 1; - fold(acc, (count, item)) - }) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Enumerate where I: ExactSizeIterator { - fn len(&self) -> usize { - self.iter.len() - } - - fn is_empty(&self) -> bool { - self.iter.is_empty() - } -} - -#[doc(hidden)] -unsafe impl TrustedRandomAccess for Enumerate - where I: TrustedRandomAccess -{ - unsafe fn get_unchecked(&mut self, i: usize) -> (usize, I::Item) { - (self.count + i, self.iter.get_unchecked(i)) - } - - fn may_have_side_effect() -> bool { - I::may_have_side_effect() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Enumerate where I: FusedIterator {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Enumerate - where I: TrustedLen, -{} - - -/// An iterator with a `peek()` that returns an optional reference to the next -/// element. -/// -/// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`peekable`]: trait.Iterator.html#method.peekable -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Peekable { - iter: I, - /// Remember a peeked value, even if it was None. - peeked: Option>, -} - -// Peekable must remember if a None has been seen in the `.peek()` method. -// It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the -// underlying iterator at most once. This does not by itself make the iterator -// fused. -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Peekable { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - match self.peeked.take() { - Some(v) => v, - None => self.iter.next(), - } - } - - #[inline] - #[rustc_inherit_overflow_checks] - fn count(mut self) -> usize { - match self.peeked.take() { - Some(None) => 0, - Some(Some(_)) => 1 + self.iter.count(), - None => self.iter.count(), - } - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - match self.peeked.take() { - Some(None) => None, - Some(v @ Some(_)) if n == 0 => v, - Some(Some(_)) => self.iter.nth(n - 1), - None => self.iter.nth(n), - } - } - - #[inline] - fn last(mut self) -> Option { - let peek_opt = match self.peeked.take() { - Some(None) => return None, - Some(v) => v, - None => None, - }; - self.iter.last().or(peek_opt) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let peek_len = match self.peeked { - Some(None) => return (0, Some(0)), - Some(Some(_)) => 1, - None => 0, - }; - let (lo, hi) = self.iter.size_hint(); - let lo = lo.saturating_add(peek_len); - let hi = hi.and_then(|x| x.checked_add(peek_len)); - (lo, hi) - } - - #[inline] - fn try_fold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try - { - let acc = match self.peeked.take() { - Some(None) => return Try::from_ok(init), - Some(Some(v)) => f(init, v)?, - None => init, - }; - self.iter.try_fold(acc, f) - } - - #[inline] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let acc = match self.peeked { - Some(None) => return init, - Some(Some(v)) => fold(init, v), - None => init, - }; - self.iter.fold(acc, fold) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Peekable {} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Peekable {} - -impl Peekable { - /// Returns a reference to the next() value without advancing the iterator. - /// - /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`. - /// But if the iteration is over, `None` is returned. - /// - /// [`next`]: trait.Iterator.html#tymethod.next - /// - /// Because `peek()` returns a reference, and many iterators iterate over - /// references, there can be a possibly confusing situation where the - /// return value is a double reference. You can see this effect in the - /// examples below. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let xs = [1, 2, 3]; - /// - /// let mut iter = xs.iter().peekable(); - /// - /// // peek() lets us see into the future - /// assert_eq!(iter.peek(), Some(&&1)); - /// assert_eq!(iter.next(), Some(&1)); - /// - /// assert_eq!(iter.next(), Some(&2)); - /// - /// // The iterator does not advance even if we `peek` multiple times - /// assert_eq!(iter.peek(), Some(&&3)); - /// assert_eq!(iter.peek(), Some(&&3)); - /// - /// assert_eq!(iter.next(), Some(&3)); - /// - /// // After the iterator is finished, so is `peek()` - /// assert_eq!(iter.peek(), None); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn peek(&mut self) -> Option<&I::Item> { - let iter = &mut self.iter; - self.peeked.get_or_insert_with(|| iter.next()).as_ref() - } -} - -/// An iterator that rejects elements while `predicate` is true. -/// -/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`skip_while`]: trait.Iterator.html#method.skip_while -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct SkipWhile { - iter: I, - flag: bool, - predicate: P, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for SkipWhile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("SkipWhile") - .field("iter", &self.iter) - .field("flag", &self.flag) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for SkipWhile - where P: FnMut(&I::Item) -> bool -{ - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - let flag = &mut self.flag; - let pred = &mut self.predicate; - self.iter.find(move |x| { - if *flag || !pred(x) { - *flag = true; - true - } else { - false - } - }) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } - - #[inline] - fn try_fold(&mut self, mut init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if !self.flag { - match self.next() { - Some(v) => init = fold(init, v)?, - None => return Try::from_ok(init), - } - } - self.iter.try_fold(init, fold) - } - - #[inline] - fn fold(mut self, mut init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - if !self.flag { - match self.next() { - Some(v) => init = fold(init, v), - None => return init, - } - } - self.iter.fold(init, fold) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for SkipWhile - where I: FusedIterator, P: FnMut(&I::Item) -> bool {} - -/// An iterator that only accepts elements while `predicate` is true. -/// -/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`take_while`]: trait.Iterator.html#method.take_while -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct TakeWhile { - iter: I, - flag: bool, - predicate: P, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for TakeWhile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("TakeWhile") - .field("iter", &self.iter) - .field("flag", &self.flag) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for TakeWhile - where P: FnMut(&I::Item) -> bool -{ - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - if self.flag { - None - } else { - self.iter.next().and_then(|x| { - if (self.predicate)(&x) { - Some(x) - } else { - self.flag = true; - None - } - }) - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - if self.flag { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } - } - - #[inline] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if self.flag { - Try::from_ok(init) - } else { - let flag = &mut self.flag; - let p = &mut self.predicate; - self.iter.try_fold(init, move |acc, x|{ - if p(&x) { - LoopState::from_try(fold(acc, x)) - } else { - *flag = true; - LoopState::Break(Try::from_ok(acc)) - } - }).into_try() - } - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for TakeWhile - where I: FusedIterator, P: FnMut(&I::Item) -> bool {} - -/// An iterator that skips over `n` elements of `iter`. -/// -/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`skip`]: trait.Iterator.html#method.skip -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Skip { - iter: I, - n: usize -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Skip where I: Iterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option { - if self.n == 0 { - self.iter.next() - } else { - let old_n = self.n; - self.n = 0; - self.iter.nth(old_n) - } - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - // Can't just add n + self.n due to overflow. - if self.n == 0 { - self.iter.nth(n) - } else { - let to_skip = self.n; - self.n = 0; - // nth(n) skips n+1 - if self.iter.nth(to_skip-1).is_none() { - return None; - } - self.iter.nth(n) - } - } - - #[inline] - fn count(self) -> usize { - self.iter.count().saturating_sub(self.n) - } - - #[inline] - fn last(mut self) -> Option { - if self.n == 0 { - self.iter.last() - } else { - let next = self.next(); - if next.is_some() { - // recurse. n should be 0. - self.last().or(next) - } else { - None - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (lower, upper) = self.iter.size_hint(); - - let lower = lower.saturating_sub(self.n); - let upper = upper.map(|x| x.saturating_sub(self.n)); - - (lower, upper) - } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let n = self.n; - self.n = 0; - if n > 0 { - // nth(n) skips n+1 - if self.iter.nth(n - 1).is_none() { - return Try::from_ok(init); - } - } - self.iter.try_fold(init, fold) - } - - #[inline] - fn fold(mut self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - if self.n > 0 { - // nth(n) skips n+1 - if self.iter.nth(self.n - 1).is_none() { - return init; - } - } - self.iter.fold(init, fold) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Skip where I: ExactSizeIterator {} - -#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")] -impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSizeIterator { - fn next_back(&mut self) -> Option { - if self.len() > 0 { - self.iter.next_back() - } else { - None - } - } - - fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let mut n = self.len(); - if n == 0 { - Try::from_ok(init) - } else { - self.iter.try_rfold(init, move |acc, x| { - n -= 1; - let r = fold(acc, x); - if n == 0 { LoopState::Break(r) } - else { LoopState::from_try(r) } - }).into_try() - } - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Skip where I: FusedIterator {} - -/// An iterator that only iterates over the first `n` iterations of `iter`. -/// -/// This `struct` is created by the [`take`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`take`]: trait.Iterator.html#method.take -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Take { - iter: I, - n: usize -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Take where I: Iterator{ - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { - if self.n != 0 { - self.n -= 1; - self.iter.next() - } else { - None - } - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - if self.n > n { - self.n -= n + 1; - self.iter.nth(n) - } else { - if self.n > 0 { - self.iter.nth(self.n - 1); - self.n = 0; - } - None - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - if self.n == 0 { - return (0, Some(0)); - } - - let (lower, upper) = self.iter.size_hint(); - - let lower = cmp::min(lower, self.n); - - let upper = match upper { - Some(x) if x < self.n => Some(x), - _ => Some(self.n) - }; - - (lower, upper) - } - - #[inline] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if self.n == 0 { - Try::from_ok(init) - } else { - let n = &mut self.n; - self.iter.try_fold(init, move |acc, x| { - *n -= 1; - let r = fold(acc, x); - if *n == 0 { LoopState::Break(r) } - else { LoopState::from_try(r) } - }).into_try() - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Take where I: ExactSizeIterator {} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Take where I: FusedIterator {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Take {} - -/// An iterator to maintain state while iterating another iterator. -/// -/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`scan`]: trait.Iterator.html#method.scan -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Scan { - iter: I, - f: F, - state: St, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Scan { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Scan") - .field("iter", &self.iter) - .field("state", &self.state) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Scan where - I: Iterator, - F: FnMut(&mut St, I::Item) -> Option, -{ - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().and_then(|a| (self.f)(&mut self.state, a)) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the scan function - } - - #[inline] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let state = &mut self.state; - let f = &mut self.f; - self.iter.try_fold(init, move |acc, x| { - match f(state, x) { - None => LoopState::Break(Try::from_ok(acc)), - Some(x) => LoopState::from_try(fold(acc, x)), - } - }).into_try() - } -} - -/// An iterator that maps each element to an iterator, and yields the elements -/// of the produced iterators. -/// -/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`flat_map`]: trait.Iterator.html#method.flat_map -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct FlatMap { - inner: FlattenCompat, ::IntoIter> -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Clone for FlatMap - where ::IntoIter: Clone -{ - fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } } -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for FlatMap - where U::IntoIter: fmt::Debug -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("FlatMap").field("inner", &self.inner).finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for FlatMap - where F: FnMut(I::Item) -> U, -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { self.inner.next() } - - #[inline] - fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.fold(init, fold) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for FlatMap - where F: FnMut(I::Item) -> U, - U: IntoIterator, - U::IntoIter: DoubleEndedIterator -{ - #[inline] - fn next_back(&mut self) -> Option { self.inner.next_back() } - - #[inline] - fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.rfold(init, fold) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for FlatMap - where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {} - -/// An iterator that flattens one level of nesting in an iterator of things -/// that can be turned into iterators. -/// -/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`flatten`]: trait.Iterator.html#method.flatten -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "iterator_flatten", since = "1.29.0")] -pub struct Flatten -where I::Item: IntoIterator { - inner: FlattenCompat::IntoIter>, -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl fmt::Debug for Flatten - where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug, - I::Item: IntoIterator, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Flatten").field("inner", &self.inner).finish() - } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl Clone for Flatten - where I: Iterator + Clone, U: Iterator + Clone, - I::Item: IntoIterator, -{ - fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl Iterator for Flatten - where I: Iterator, U: Iterator, - I::Item: IntoIterator -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { self.inner.next() } - - #[inline] - fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.fold(init, fold) - } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl DoubleEndedIterator for Flatten - where I: DoubleEndedIterator, U: DoubleEndedIterator, - I::Item: IntoIterator -{ - #[inline] - fn next_back(&mut self) -> Option { self.inner.next_back() } - - #[inline] - fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.rfold(init, fold) - } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl FusedIterator for Flatten - where I: FusedIterator, U: Iterator, - I::Item: IntoIterator {} - -/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. -fn flatten_compat(iter: I) -> FlattenCompat { - FlattenCompat { iter, frontiter: None, backiter: None } -} - -/// Real logic of both `Flatten` and `FlatMap` which simply delegate to -/// this type. -#[derive(Clone, Debug)] -struct FlattenCompat { - iter: I, - frontiter: Option, - backiter: Option, -} - -impl Iterator for FlattenCompat - where I: Iterator, U: Iterator, - I::Item: IntoIterator -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { - loop { - if let Some(ref mut inner) = self.frontiter { - if let elt@Some(_) = inner.next() { return elt } - } - match self.iter.next() { - None => return self.backiter.as_mut().and_then(|it| it.next()), - Some(inner) => self.frontiter = Some(inner.into_iter()), - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); - let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); - let lo = flo.saturating_add(blo); - match (self.iter.size_hint(), fhi, bhi) { - ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), - _ => (lo, None) - } - } - - #[inline] - fn try_fold(&mut self, mut init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if let Some(ref mut front) = self.frontiter { - init = front.try_fold(init, &mut fold)?; - } - self.frontiter = None; - - { - let frontiter = &mut self.frontiter; - init = self.iter.try_fold(init, |acc, x| { - let mut mid = x.into_iter(); - let r = mid.try_fold(acc, &mut fold); - *frontiter = Some(mid); - r - })?; - } - self.frontiter = None; - - if let Some(ref mut back) = self.backiter { - init = back.try_fold(init, &mut fold)?; - } - self.backiter = None; - - Try::from_ok(init) - } - - #[inline] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.frontiter.into_iter() - .chain(self.iter.map(IntoIterator::into_iter)) - .chain(self.backiter) - .fold(init, |acc, iter| iter.fold(acc, &mut fold)) - } -} - -impl DoubleEndedIterator for FlattenCompat - where I: DoubleEndedIterator, U: DoubleEndedIterator, - I::Item: IntoIterator -{ - #[inline] - fn next_back(&mut self) -> Option { - loop { - if let Some(ref mut inner) = self.backiter { - if let elt@Some(_) = inner.next_back() { return elt } - } - match self.iter.next_back() { - None => return self.frontiter.as_mut().and_then(|it| it.next_back()), - next => self.backiter = next.map(IntoIterator::into_iter), - } - } - } - - #[inline] - fn try_rfold(&mut self, mut init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if let Some(ref mut back) = self.backiter { - init = back.try_rfold(init, &mut fold)?; - } - self.backiter = None; - - { - let backiter = &mut self.backiter; - init = self.iter.try_rfold(init, |acc, x| { - let mut mid = x.into_iter(); - let r = mid.try_rfold(acc, &mut fold); - *backiter = Some(mid); - r - })?; - } - self.backiter = None; - - if let Some(ref mut front) = self.frontiter { - init = front.try_rfold(init, &mut fold)?; - } - self.frontiter = None; - - Try::from_ok(init) - } - - #[inline] - fn rfold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.frontiter.into_iter() - .chain(self.iter.map(IntoIterator::into_iter)) - .chain(self.backiter) - .rfold(init, |acc, iter| iter.rfold(acc, &mut fold)) - } -} - -/// An iterator that yields `None` forever after the underlying iterator -/// yields `None` once. -/// -/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`fuse`]: trait.Iterator.html#method.fuse -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Fuse { - iter: I, - done: bool -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Fuse where I: Iterator {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Fuse where I: Iterator { - type Item = ::Item; - - #[inline] - default fn next(&mut self) -> Option<::Item> { - if self.done { - None - } else { - let next = self.iter.next(); - self.done = next.is_none(); - next - } - } - - #[inline] - default fn nth(&mut self, n: usize) -> Option { - if self.done { - None - } else { - let nth = self.iter.nth(n); - self.done = nth.is_none(); - nth - } - } - - #[inline] - default fn last(self) -> Option { - if self.done { - None - } else { - self.iter.last() - } - } - - #[inline] - default fn count(self) -> usize { - if self.done { - 0 - } else { - self.iter.count() - } - } - - #[inline] - default fn size_hint(&self) -> (usize, Option) { - if self.done { - (0, Some(0)) - } else { - self.iter.size_hint() - } - } - - #[inline] - default fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if self.done { - Try::from_ok(init) - } else { - let acc = self.iter.try_fold(init, fold)?; - self.done = true; - Try::from_ok(acc) - } - } - - #[inline] - default fn fold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - if self.done { - init - } else { - self.iter.fold(init, fold) - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { - #[inline] - default fn next_back(&mut self) -> Option<::Item> { - if self.done { - None - } else { - let next = self.iter.next_back(); - self.done = next.is_none(); - next - } - } - - #[inline] - default fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if self.done { - Try::from_ok(init) - } else { - let acc = self.iter.try_rfold(init, fold)?; - self.done = true; - Try::from_ok(acc) - } - } - - #[inline] - default fn rfold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - if self.done { - init - } else { - self.iter.rfold(init, fold) - } - } -} - -unsafe impl TrustedRandomAccess for Fuse - where I: TrustedRandomAccess, -{ - unsafe fn get_unchecked(&mut self, i: usize) -> I::Item { - self.iter.get_unchecked(i) - } - - fn may_have_side_effect() -> bool { - I::may_have_side_effect() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl Iterator for Fuse where I: FusedIterator { - #[inline] - fn next(&mut self) -> Option<::Item> { - self.iter.next() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - self.iter.nth(n) - } - - #[inline] - fn last(self) -> Option { - self.iter.last() - } - - #[inline] - fn count(self) -> usize { - self.iter.count() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.iter.try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.iter.fold(init, fold) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl DoubleEndedIterator for Fuse - where I: DoubleEndedIterator + FusedIterator -{ - #[inline] - fn next_back(&mut self) -> Option<::Item> { - self.iter.next_back() - } - - #[inline] - fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.iter.try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.iter.rfold(init, fold) - } -} - - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Fuse where I: ExactSizeIterator { - fn len(&self) -> usize { - self.iter.len() - } - - fn is_empty(&self) -> bool { - self.iter.is_empty() - } -} - -/// An iterator that calls a function with a reference to each element before -/// yielding it. -/// -/// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`inspect`]: trait.Iterator.html#method.inspect -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Inspect { - iter: I, - f: F, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Inspect { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Inspect") - .field("iter", &self.iter) - .finish() - } -} - -impl Inspect where F: FnMut(&I::Item) { - #[inline] - fn do_inspect(&mut self, elt: Option) -> Option { - if let Some(ref a) = elt { - (self.f)(a); - } - - elt - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Inspect where F: FnMut(&I::Item) { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - let next = self.iter.next(); - self.do_inspect(next) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - - #[inline] - fn try_fold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let f = &mut self.f; - self.iter.try_fold(init, move |acc, item| { f(&item); fold(acc, item) }) - } - - #[inline] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut f = self.f; - self.iter.fold(init, move |acc, item| { f(&item); fold(acc, item) }) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Inspect - where F: FnMut(&I::Item), -{ - #[inline] - fn next_back(&mut self) -> Option { - let next = self.iter.next_back(); - self.do_inspect(next) - } - - #[inline] - fn try_rfold(&mut self, init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - let f = &mut self.f; - self.iter.try_rfold(init, move |acc, item| { f(&item); fold(acc, item) }) - } - - #[inline] - fn rfold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - let mut f = self.f; - self.iter.rfold(init, move |acc, item| { f(&item); fold(acc, item) }) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Inspect - where F: FnMut(&I::Item) -{ - fn len(&self) -> usize { - self.iter.len() - } - - fn is_empty(&self) -> bool { - self.iter.is_empty() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Inspect - where F: FnMut(&I::Item) {} From c40450ce65d11e771a32feaa8a1df9dbea480486 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:24:57 -0500 Subject: [PATCH 0258/1064] Move core::iter iterator.rs to traits module --- src/libcore/iter/mod.rs | 3 +-- src/libcore/iter/{ => traits}/iterator.rs | 12 ++++++------ src/libcore/iter/{traits.rs => traits/mod.rs} | 4 ++++ 3 files changed, 11 insertions(+), 8 deletions(-) rename src/libcore/iter/{ => traits}/iterator.rs (99%) rename src/libcore/iter/{traits.rs => traits/mod.rs} (99%) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index bc8760934d2ed..6dc7469998c02 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -309,7 +309,7 @@ use ops::Try; #[stable(feature = "rust1", since = "1.0.0")] -pub use self::iterator::Iterator; +pub use self::traits::Iterator; #[unstable(feature = "step_trait", reason = "likely to be replaced by finer-grained traits", @@ -355,7 +355,6 @@ pub use self::adapters::Copied; use self::adapters::{flatten_compat, ChainState, ZipImpl}; -mod iterator; mod range; mod sources; mod traits; diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/traits/iterator.rs similarity index 99% rename from src/libcore/iter/iterator.rs rename to src/libcore/iter/traits/iterator.rs index ac21586c0b8a9..0ce817d02a52c 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1,12 +1,12 @@ use cmp::Ordering; use ops::Try; -use super::LoopState; -use super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse}; -use super::{Flatten, FlatMap, flatten_compat}; -use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; -use super::{Zip, Sum, Product}; -use super::{ChainState, FromIterator, ZipImpl}; +use super::super::LoopState; +use super::super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse}; +use super::super::{Flatten, FlatMap, flatten_compat}; +use super::super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; +use super::super::{Zip, Sum, Product}; +use super::super::{ChainState, FromIterator, ZipImpl}; fn _assert_is_object_safe(_: &dyn Iterator) {} diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits/mod.rs similarity index 99% rename from src/libcore/iter/traits.rs rename to src/libcore/iter/traits/mod.rs index e8c6cd8b79c72..742540681b473 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits/mod.rs @@ -3,6 +3,10 @@ use num::Wrapping; use super::LoopState; +mod iterator; + +pub use self::iterator::Iterator; + /// Conversion from an `Iterator`. /// /// By implementing `FromIterator` for a type, you define how it will be From 34d5624255737db8478dab62d9dc3940495062e6 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:27:22 -0500 Subject: [PATCH 0259/1064] Move DoubleEndedIterator to own module --- src/libcore/iter/traits/double_ended.rs | 297 +++++++++++++++++++++++ src/libcore/iter/traits/mod.rs | 301 +----------------------- 2 files changed, 300 insertions(+), 298 deletions(-) create mode 100644 src/libcore/iter/traits/double_ended.rs diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs new file mode 100644 index 0000000000000..2976afc0b4f81 --- /dev/null +++ b/src/libcore/iter/traits/double_ended.rs @@ -0,0 +1,297 @@ +use ops::Try; +use iter::LoopState; + +/// An iterator able to yield elements from both ends. +/// +/// Something that implements `DoubleEndedIterator` has one extra capability +/// over something that implements [`Iterator`]: the ability to also take +/// `Item`s from the back, as well as the front. +/// +/// It is important to note that both back and forth work on the same range, +/// and do not cross: iteration is over when they meet in the middle. +/// +/// In a similar fashion to the [`Iterator`] protocol, once a +/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again +/// may or may not ever return `Some` again. `next()` and `next_back()` are +/// interchangeable for this purpose. +/// +/// [`Iterator`]: trait.Iterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let numbers = vec![1, 2, 3, 4, 5, 6]; +/// +/// let mut iter = numbers.iter(); +/// +/// assert_eq!(Some(&1), iter.next()); +/// assert_eq!(Some(&6), iter.next_back()); +/// assert_eq!(Some(&5), iter.next_back()); +/// assert_eq!(Some(&2), iter.next()); +/// assert_eq!(Some(&3), iter.next()); +/// assert_eq!(Some(&4), iter.next()); +/// assert_eq!(None, iter.next()); +/// assert_eq!(None, iter.next_back()); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait DoubleEndedIterator: Iterator { + /// Removes and returns an element from the end of the iterator. + /// + /// Returns `None` when there are no more elements. + /// + /// The [trait-level] docs contain more details. + /// + /// [trait-level]: trait.DoubleEndedIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let numbers = vec![1, 2, 3, 4, 5, 6]; + /// + /// let mut iter = numbers.iter(); + /// + /// assert_eq!(Some(&1), iter.next()); + /// assert_eq!(Some(&6), iter.next_back()); + /// assert_eq!(Some(&5), iter.next_back()); + /// assert_eq!(Some(&2), iter.next()); + /// assert_eq!(Some(&3), iter.next()); + /// assert_eq!(Some(&4), iter.next()); + /// assert_eq!(None, iter.next()); + /// assert_eq!(None, iter.next_back()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn next_back(&mut self) -> Option; + + /// Returns the `n`th element from the end of the iterator. + /// + /// This is essentially the reversed version of [`nth`]. Although like most indexing + /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro + /// the end, `nth_back(1)` the second, and so on. + /// + /// Note that all elements between the end and the returned element will be + /// consumed, including the returned element. This also means that calling + /// `nth_back(0)` multiple times on the same iterator will return different + /// elements. + /// + /// `nth_back()` will return [`None`] if `n` is greater than or equal to the length of the + /// iterator. + /// + /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`nth`]: ../../std/iter/trait.Iterator.html#method.nth + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iter_nth_back)] + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().nth_back(2), Some(&1)); + /// ``` + /// + /// Calling `nth_back()` multiple times doesn't rewind the iterator: + /// + /// ``` + /// #![feature(iter_nth_back)] + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.nth_back(1), Some(&2)); + /// assert_eq!(iter.nth_back(1), None); + /// ``` + /// + /// Returning `None` if there are less than `n + 1` elements: + /// + /// ``` + /// #![feature(iter_nth_back)] + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().nth_back(10), None); + /// ``` + #[inline] + #[unstable(feature = "iter_nth_back", issue = "56995")] + fn nth_back(&mut self, mut n: usize) -> Option { + for x in self.rev() { + if n == 0 { return Some(x) } + n -= 1; + } + None + } + + /// This is the reverse version of [`try_fold()`]: it takes elements + /// starting from the back of the iterator. + /// + /// [`try_fold()`]: trait.Iterator.html#method.try_fold + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = ["1", "2", "3"]; + /// let sum = a.iter() + /// .map(|&s| s.parse::()) + /// .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y))); + /// assert_eq!(sum, Ok(6)); + /// ``` + /// + /// Short-circuiting: + /// + /// ``` + /// let a = ["1", "rust", "3"]; + /// let mut it = a.iter(); + /// let sum = it + /// .by_ref() + /// .map(|&s| s.parse::()) + /// .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y))); + /// assert!(sum.is_err()); + /// + /// // Because it short-circuited, the remaining elements are still + /// // available through the iterator. + /// assert_eq!(it.next_back(), Some(&"1")); + /// ``` + #[inline] + #[stable(feature = "iterator_try_fold", since = "1.27.0")] + fn try_rfold(&mut self, init: B, mut f: F) -> R + where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try + { + let mut accum = init; + while let Some(x) = self.next_back() { + accum = f(accum, x)?; + } + Try::from_ok(accum) + } + + /// An iterator method that reduces the iterator's elements to a single, + /// final value, starting from the back. + /// + /// This is the reverse version of [`fold()`]: it takes elements starting from + /// the back of the iterator. + /// + /// `rfold()` takes two arguments: an initial value, and a closure with two + /// arguments: an 'accumulator', and an element. The closure returns the value that + /// the accumulator should have for the next iteration. + /// + /// The initial value is the value the accumulator will have on the first + /// call. + /// + /// After applying this closure to every element of the iterator, `rfold()` + /// returns the accumulator. + /// + /// This operation is sometimes called 'reduce' or 'inject'. + /// + /// Folding is useful whenever you have a collection of something, and want + /// to produce a single value from it. + /// + /// [`fold()`]: trait.Iterator.html#method.fold + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// // the sum of all of the elements of a + /// let sum = a.iter() + /// .rfold(0, |acc, &x| acc + x); + /// + /// assert_eq!(sum, 6); + /// ``` + /// + /// This example builds a string, starting with an initial value + /// and continuing with each element from the back until the front: + /// + /// ``` + /// let numbers = [1, 2, 3, 4, 5]; + /// + /// let zero = "0".to_string(); + /// + /// let result = numbers.iter().rfold(zero, |acc, &x| { + /// format!("({} + {})", x, acc) + /// }); + /// + /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))"); + /// ``` + #[inline] + #[stable(feature = "iter_rfold", since = "1.27.0")] + fn rfold(mut self, accum: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + self.try_rfold(accum, move |acc, x| Ok::(f(acc, x))).unwrap() + } + + /// Searches for an element of an iterator from the back that satisfies a predicate. + /// + /// `rfind()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, starting at the end, and if any + /// of them return `true`, then `rfind()` returns [`Some(element)`]. If they all return + /// `false`, it returns [`None`]. + /// + /// `rfind()` is short-circuiting; in other words, it will stop processing + /// as soon as the closure returns `true`. + /// + /// Because `rfind()` takes a reference, and many iterators iterate over + /// references, this leads to a possibly confusing situation where the + /// argument is a double reference. You can see this effect in the + /// examples below, with `&&x`. + /// + /// [`Some(element)`]: ../../std/option/enum.Option.html#variant.Some + /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2)); + /// + /// assert_eq!(a.iter().rfind(|&&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.rfind(|&&x| x == 2), Some(&2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next_back(), Some(&1)); + /// ``` + #[inline] + #[stable(feature = "iter_rfind", since = "1.27.0")] + fn rfind

(&mut self, mut predicate: P) -> Option + where + Self: Sized, + P: FnMut(&Self::Item) -> bool + { + self.try_rfold((), move |(), x| { + if predicate(&x) { LoopState::Break(x) } + else { LoopState::Continue(()) } + }).break_value() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { + fn next_back(&mut self) -> Option { + (**self).next_back() + } + fn nth_back(&mut self, n: usize) -> Option { + (**self).nth_back(n) + } +} diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index 742540681b473..d0a10d27db8c4 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -1,11 +1,11 @@ -use ops::{Mul, Add, Try}; +use ops::{Mul, Add}; use num::Wrapping; -use super::LoopState; - mod iterator; +mod double_ended; pub use self::iterator::Iterator; +pub use self::double_ended::DoubleEndedIterator; /// Conversion from an `Iterator`. /// @@ -357,301 +357,6 @@ impl Extend<()> for () { } } -/// An iterator able to yield elements from both ends. -/// -/// Something that implements `DoubleEndedIterator` has one extra capability -/// over something that implements [`Iterator`]: the ability to also take -/// `Item`s from the back, as well as the front. -/// -/// It is important to note that both back and forth work on the same range, -/// and do not cross: iteration is over when they meet in the middle. -/// -/// In a similar fashion to the [`Iterator`] protocol, once a -/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again -/// may or may not ever return `Some` again. `next()` and `next_back()` are -/// interchangeable for this purpose. -/// -/// [`Iterator`]: trait.Iterator.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// let numbers = vec![1, 2, 3, 4, 5, 6]; -/// -/// let mut iter = numbers.iter(); -/// -/// assert_eq!(Some(&1), iter.next()); -/// assert_eq!(Some(&6), iter.next_back()); -/// assert_eq!(Some(&5), iter.next_back()); -/// assert_eq!(Some(&2), iter.next()); -/// assert_eq!(Some(&3), iter.next()); -/// assert_eq!(Some(&4), iter.next()); -/// assert_eq!(None, iter.next()); -/// assert_eq!(None, iter.next_back()); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait DoubleEndedIterator: Iterator { - /// Removes and returns an element from the end of the iterator. - /// - /// Returns `None` when there are no more elements. - /// - /// The [trait-level] docs contain more details. - /// - /// [trait-level]: trait.DoubleEndedIterator.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let numbers = vec![1, 2, 3, 4, 5, 6]; - /// - /// let mut iter = numbers.iter(); - /// - /// assert_eq!(Some(&1), iter.next()); - /// assert_eq!(Some(&6), iter.next_back()); - /// assert_eq!(Some(&5), iter.next_back()); - /// assert_eq!(Some(&2), iter.next()); - /// assert_eq!(Some(&3), iter.next()); - /// assert_eq!(Some(&4), iter.next()); - /// assert_eq!(None, iter.next()); - /// assert_eq!(None, iter.next_back()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn next_back(&mut self) -> Option; - - /// Returns the `n`th element from the end of the iterator. - /// - /// This is essentially the reversed version of [`nth`]. Although like most indexing - /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro - /// the end, `nth_back(1)` the second, and so on. - /// - /// Note that all elements between the end and the returned element will be - /// consumed, including the returned element. This also means that calling - /// `nth_back(0)` multiple times on the same iterator will return different - /// elements. - /// - /// `nth_back()` will return [`None`] if `n` is greater than or equal to the length of the - /// iterator. - /// - /// [`None`]: ../../std/option/enum.Option.html#variant.None - /// [`nth`]: ../../std/iter/trait.Iterator.html#method.nth - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// #![feature(iter_nth_back)] - /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().nth_back(2), Some(&1)); - /// ``` - /// - /// Calling `nth_back()` multiple times doesn't rewind the iterator: - /// - /// ``` - /// #![feature(iter_nth_back)] - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert_eq!(iter.nth_back(1), Some(&2)); - /// assert_eq!(iter.nth_back(1), None); - /// ``` - /// - /// Returning `None` if there are less than `n + 1` elements: - /// - /// ``` - /// #![feature(iter_nth_back)] - /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().nth_back(10), None); - /// ``` - #[inline] - #[unstable(feature = "iter_nth_back", issue = "56995")] - fn nth_back(&mut self, mut n: usize) -> Option { - for x in self.rev() { - if n == 0 { return Some(x) } - n -= 1; - } - None - } - - /// This is the reverse version of [`try_fold()`]: it takes elements - /// starting from the back of the iterator. - /// - /// [`try_fold()`]: trait.Iterator.html#method.try_fold - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = ["1", "2", "3"]; - /// let sum = a.iter() - /// .map(|&s| s.parse::()) - /// .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y))); - /// assert_eq!(sum, Ok(6)); - /// ``` - /// - /// Short-circuiting: - /// - /// ``` - /// let a = ["1", "rust", "3"]; - /// let mut it = a.iter(); - /// let sum = it - /// .by_ref() - /// .map(|&s| s.parse::()) - /// .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y))); - /// assert!(sum.is_err()); - /// - /// // Because it short-circuited, the remaining elements are still - /// // available through the iterator. - /// assert_eq!(it.next_back(), Some(&"1")); - /// ``` - #[inline] - #[stable(feature = "iterator_try_fold", since = "1.27.0")] - fn try_rfold(&mut self, init: B, mut f: F) -> R - where - Self: Sized, - F: FnMut(B, Self::Item) -> R, - R: Try - { - let mut accum = init; - while let Some(x) = self.next_back() { - accum = f(accum, x)?; - } - Try::from_ok(accum) - } - - /// An iterator method that reduces the iterator's elements to a single, - /// final value, starting from the back. - /// - /// This is the reverse version of [`fold()`]: it takes elements starting from - /// the back of the iterator. - /// - /// `rfold()` takes two arguments: an initial value, and a closure with two - /// arguments: an 'accumulator', and an element. The closure returns the value that - /// the accumulator should have for the next iteration. - /// - /// The initial value is the value the accumulator will have on the first - /// call. - /// - /// After applying this closure to every element of the iterator, `rfold()` - /// returns the accumulator. - /// - /// This operation is sometimes called 'reduce' or 'inject'. - /// - /// Folding is useful whenever you have a collection of something, and want - /// to produce a single value from it. - /// - /// [`fold()`]: trait.Iterator.html#method.fold - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// // the sum of all of the elements of a - /// let sum = a.iter() - /// .rfold(0, |acc, &x| acc + x); - /// - /// assert_eq!(sum, 6); - /// ``` - /// - /// This example builds a string, starting with an initial value - /// and continuing with each element from the back until the front: - /// - /// ``` - /// let numbers = [1, 2, 3, 4, 5]; - /// - /// let zero = "0".to_string(); - /// - /// let result = numbers.iter().rfold(zero, |acc, &x| { - /// format!("({} + {})", x, acc) - /// }); - /// - /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))"); - /// ``` - #[inline] - #[stable(feature = "iter_rfold", since = "1.27.0")] - fn rfold(mut self, accum: B, mut f: F) -> B - where - Self: Sized, - F: FnMut(B, Self::Item) -> B, - { - self.try_rfold(accum, move |acc, x| Ok::(f(acc, x))).unwrap() - } - - /// Searches for an element of an iterator from the back that satisfies a predicate. - /// - /// `rfind()` takes a closure that returns `true` or `false`. It applies - /// this closure to each element of the iterator, starting at the end, and if any - /// of them return `true`, then `rfind()` returns [`Some(element)`]. If they all return - /// `false`, it returns [`None`]. - /// - /// `rfind()` is short-circuiting; in other words, it will stop processing - /// as soon as the closure returns `true`. - /// - /// Because `rfind()` takes a reference, and many iterators iterate over - /// references, this leads to a possibly confusing situation where the - /// argument is a double reference. You can see this effect in the - /// examples below, with `&&x`. - /// - /// [`Some(element)`]: ../../std/option/enum.Option.html#variant.Some - /// [`None`]: ../../std/option/enum.Option.html#variant.None - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2)); - /// - /// assert_eq!(a.iter().rfind(|&&x| x == 5), None); - /// ``` - /// - /// Stopping at the first `true`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert_eq!(iter.rfind(|&&x| x == 2), Some(&2)); - /// - /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next_back(), Some(&1)); - /// ``` - #[inline] - #[stable(feature = "iter_rfind", since = "1.27.0")] - fn rfind

(&mut self, mut predicate: P) -> Option - where - Self: Sized, - P: FnMut(&Self::Item) -> bool - { - self.try_rfold((), move |(), x| { - if predicate(&x) { LoopState::Break(x) } - else { LoopState::Continue(()) } - }).break_value() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { - fn next_back(&mut self) -> Option { - (**self).next_back() - } - fn nth_back(&mut self, n: usize) -> Option { - (**self).nth_back(n) - } -} - /// An iterator that knows its exact length. /// /// Many [`Iterator`]s don't know how many times they will iterate, but some do. From 6a2845954a94a639bf3beb1b9f2ab615b839f8d9 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:28:27 -0500 Subject: [PATCH 0260/1064] Move ExactSizeIterator to own module --- src/libcore/iter/traits/exact_size.rs | 143 +++++++++++++++++++++++++ src/libcore/iter/traits/mod.rs | 145 +------------------------- 2 files changed, 145 insertions(+), 143 deletions(-) create mode 100644 src/libcore/iter/traits/exact_size.rs diff --git a/src/libcore/iter/traits/exact_size.rs b/src/libcore/iter/traits/exact_size.rs new file mode 100644 index 0000000000000..3bfba29e21960 --- /dev/null +++ b/src/libcore/iter/traits/exact_size.rs @@ -0,0 +1,143 @@ +/// An iterator that knows its exact length. +/// +/// Many [`Iterator`]s don't know how many times they will iterate, but some do. +/// If an iterator knows how many times it can iterate, providing access to +/// that information can be useful. For example, if you want to iterate +/// backwards, a good start is to know where the end is. +/// +/// When implementing an `ExactSizeIterator`, you must also implement +/// [`Iterator`]. When doing so, the implementation of [`size_hint`] *must* +/// return the exact size of the iterator. +/// +/// [`Iterator`]: trait.Iterator.html +/// [`size_hint`]: trait.Iterator.html#method.size_hint +/// +/// The [`len`] method has a default implementation, so you usually shouldn't +/// implement it. However, you may be able to provide a more performant +/// implementation than the default, so overriding it in this case makes sense. +/// +/// [`len`]: #method.len +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // a finite range knows exactly how many times it will iterate +/// let five = 0..5; +/// +/// assert_eq!(5, five.len()); +/// ``` +/// +/// In the [module level docs][moddocs], we implemented an [`Iterator`], +/// `Counter`. Let's implement `ExactSizeIterator` for it as well: +/// +/// [moddocs]: index.html +/// +/// ``` +/// # struct Counter { +/// # count: usize, +/// # } +/// # impl Counter { +/// # fn new() -> Counter { +/// # Counter { count: 0 } +/// # } +/// # } +/// # impl Iterator for Counter { +/// # type Item = usize; +/// # fn next(&mut self) -> Option { +/// # self.count += 1; +/// # if self.count < 6 { +/// # Some(self.count) +/// # } else { +/// # None +/// # } +/// # } +/// # } +/// impl ExactSizeIterator for Counter { +/// // We can easily calculate the remaining number of iterations. +/// fn len(&self) -> usize { +/// 5 - self.count +/// } +/// } +/// +/// // And now we can use it! +/// +/// let counter = Counter::new(); +/// +/// assert_eq!(5, counter.len()); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ExactSizeIterator: Iterator { + /// Returns the exact number of times the iterator will iterate. + /// + /// This method has a default implementation, so you usually should not + /// implement it directly. However, if you can provide a more efficient + /// implementation, you can do so. See the [trait-level] docs for an + /// example. + /// + /// This function has the same safety guarantees as the [`size_hint`] + /// function. + /// + /// [trait-level]: trait.ExactSizeIterator.html + /// [`size_hint`]: trait.Iterator.html#method.size_hint + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // a finite range knows exactly how many times it will iterate + /// let five = 0..5; + /// + /// assert_eq!(5, five.len()); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn len(&self) -> usize { + let (lower, upper) = self.size_hint(); + // Note: This assertion is overly defensive, but it checks the invariant + // guaranteed by the trait. If this trait were rust-internal, + // we could use debug_assert!; assert_eq! will check all Rust user + // implementations too. + assert_eq!(upper, Some(lower)); + lower + } + + /// Returns whether the iterator is empty. + /// + /// This method has a default implementation using `self.len()`, so you + /// don't need to implement it yourself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(exact_size_is_empty)] + /// + /// let mut one_element = std::iter::once(0); + /// assert!(!one_element.is_empty()); + /// + /// assert_eq!(one_element.next(), Some(0)); + /// assert!(one_element.is_empty()); + /// + /// assert_eq!(one_element.next(), None); + /// ``` + #[inline] + #[unstable(feature = "exact_size_is_empty", issue = "35428")] + fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for &mut I { + fn len(&self) -> usize { + (**self).len() + } + fn is_empty(&self) -> bool { + (**self).is_empty() + } +} + diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index d0a10d27db8c4..5df3b0f69a563 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -3,9 +3,11 @@ use num::Wrapping; mod iterator; mod double_ended; +mod exact_size; pub use self::iterator::Iterator; pub use self::double_ended::DoubleEndedIterator; +pub use self::exact_size::ExactSizeIterator; /// Conversion from an `Iterator`. /// @@ -357,149 +359,6 @@ impl Extend<()> for () { } } -/// An iterator that knows its exact length. -/// -/// Many [`Iterator`]s don't know how many times they will iterate, but some do. -/// If an iterator knows how many times it can iterate, providing access to -/// that information can be useful. For example, if you want to iterate -/// backwards, a good start is to know where the end is. -/// -/// When implementing an `ExactSizeIterator`, you must also implement -/// [`Iterator`]. When doing so, the implementation of [`size_hint`] *must* -/// return the exact size of the iterator. -/// -/// [`Iterator`]: trait.Iterator.html -/// [`size_hint`]: trait.Iterator.html#method.size_hint -/// -/// The [`len`] method has a default implementation, so you usually shouldn't -/// implement it. However, you may be able to provide a more performant -/// implementation than the default, so overriding it in this case makes sense. -/// -/// [`len`]: #method.len -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// // a finite range knows exactly how many times it will iterate -/// let five = 0..5; -/// -/// assert_eq!(5, five.len()); -/// ``` -/// -/// In the [module level docs][moddocs], we implemented an [`Iterator`], -/// `Counter`. Let's implement `ExactSizeIterator` for it as well: -/// -/// [moddocs]: index.html -/// -/// ``` -/// # struct Counter { -/// # count: usize, -/// # } -/// # impl Counter { -/// # fn new() -> Counter { -/// # Counter { count: 0 } -/// # } -/// # } -/// # impl Iterator for Counter { -/// # type Item = usize; -/// # fn next(&mut self) -> Option { -/// # self.count += 1; -/// # if self.count < 6 { -/// # Some(self.count) -/// # } else { -/// # None -/// # } -/// # } -/// # } -/// impl ExactSizeIterator for Counter { -/// // We can easily calculate the remaining number of iterations. -/// fn len(&self) -> usize { -/// 5 - self.count -/// } -/// } -/// -/// // And now we can use it! -/// -/// let counter = Counter::new(); -/// -/// assert_eq!(5, counter.len()); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait ExactSizeIterator: Iterator { - /// Returns the exact number of times the iterator will iterate. - /// - /// This method has a default implementation, so you usually should not - /// implement it directly. However, if you can provide a more efficient - /// implementation, you can do so. See the [trait-level] docs for an - /// example. - /// - /// This function has the same safety guarantees as the [`size_hint`] - /// function. - /// - /// [trait-level]: trait.ExactSizeIterator.html - /// [`size_hint`]: trait.Iterator.html#method.size_hint - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// // a finite range knows exactly how many times it will iterate - /// let five = 0..5; - /// - /// assert_eq!(5, five.len()); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn len(&self) -> usize { - let (lower, upper) = self.size_hint(); - // Note: This assertion is overly defensive, but it checks the invariant - // guaranteed by the trait. If this trait were rust-internal, - // we could use debug_assert!; assert_eq! will check all Rust user - // implementations too. - assert_eq!(upper, Some(lower)); - lower - } - - /// Returns whether the iterator is empty. - /// - /// This method has a default implementation using `self.len()`, so you - /// don't need to implement it yourself. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// #![feature(exact_size_is_empty)] - /// - /// let mut one_element = std::iter::once(0); - /// assert!(!one_element.is_empty()); - /// - /// assert_eq!(one_element.next(), Some(0)); - /// assert!(one_element.is_empty()); - /// - /// assert_eq!(one_element.next(), None); - /// ``` - #[inline] - #[unstable(feature = "exact_size_is_empty", issue = "35428")] - fn is_empty(&self) -> bool { - self.len() == 0 - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for &mut I { - fn len(&self) -> usize { - (**self).len() - } - fn is_empty(&self) -> bool { - (**self).is_empty() - } -} - /// Trait to represent types that can be created by summing up an iterator. /// /// This trait is used to implement the [`sum`] method on iterators. Types which From 3ba9733d718768edd1d5a8f26d1f2940b0aea327 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:29:39 -0500 Subject: [PATCH 0261/1064] Move FromIterator, IntoIterator, Extend into own module --- src/libcore/iter/traits/collect.rs | 349 ++++++++++++++++++++++++++++ src/libcore/iter/traits/mod.rs | 352 +---------------------------- 2 files changed, 351 insertions(+), 350 deletions(-) create mode 100644 src/libcore/iter/traits/collect.rs diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs new file mode 100644 index 0000000000000..5204f6a642509 --- /dev/null +++ b/src/libcore/iter/traits/collect.rs @@ -0,0 +1,349 @@ +/// Conversion from an `Iterator`. +/// +/// By implementing `FromIterator` for a type, you define how it will be +/// created from an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// `FromIterator`'s [`from_iter`] is rarely called explicitly, and is instead +/// used through [`Iterator`]'s [`collect`] method. See [`collect`]'s +/// documentation for more examples. +/// +/// [`from_iter`]: #tymethod.from_iter +/// [`Iterator`]: trait.Iterator.html +/// [`collect`]: trait.Iterator.html#method.collect +/// +/// See also: [`IntoIterator`]. +/// +/// [`IntoIterator`]: trait.IntoIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v = Vec::from_iter(five_fives); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Using [`collect`] to implicitly use `FromIterator`: +/// +/// ``` +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v: Vec = five_fives.collect(); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Implementing `FromIterator` for your type: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement FromIterator +/// impl FromIterator for MyCollection { +/// fn from_iter>(iter: I) -> Self { +/// let mut c = MyCollection::new(); +/// +/// for i in iter { +/// c.add(i); +/// } +/// +/// c +/// } +/// } +/// +/// // Now we can make a new iterator... +/// let iter = (0..5).into_iter(); +/// +/// // ... and make a MyCollection out of it +/// let c = MyCollection::from_iter(iter); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// +/// // collect works too! +/// +/// let iter = (0..5).into_iter(); +/// let c: MyCollection = iter.collect(); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented( + message="a collection of type `{Self}` cannot be built from an iterator \ + over elements of type `{A}`", + label="a collection of type `{Self}` cannot be built from `std::iter::Iterator`", +)] +pub trait FromIterator: Sized { + /// Creates a value from an iterator. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: index.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::iter::FromIterator; + /// + /// let five_fives = std::iter::repeat(5).take(5); + /// + /// let v = Vec::from_iter(five_fives); + /// + /// assert_eq!(v, vec![5, 5, 5, 5, 5]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn from_iter>(iter: T) -> Self; +} + +/// Conversion into an `Iterator`. +/// +/// By implementing `IntoIterator` for a type, you define how it will be +/// converted to an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// One benefit of implementing `IntoIterator` is that your type will [work +/// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). +/// +/// See also: [`FromIterator`]. +/// +/// [`FromIterator`]: trait.FromIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let v = vec![1, 2, 3]; +/// let mut iter = v.into_iter(); +/// +/// assert_eq!(Some(1), iter.next()); +/// assert_eq!(Some(2), iter.next()); +/// assert_eq!(Some(3), iter.next()); +/// assert_eq!(None, iter.next()); +/// ``` +/// Implementing `IntoIterator` for your type: +/// +/// ``` +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement IntoIterator +/// impl IntoIterator for MyCollection { +/// type Item = i32; +/// type IntoIter = ::std::vec::IntoIter; +/// +/// fn into_iter(self) -> Self::IntoIter { +/// self.0.into_iter() +/// } +/// } +/// +/// // Now we can make a new collection... +/// let mut c = MyCollection::new(); +/// +/// // ... add some stuff to it ... +/// c.add(0); +/// c.add(1); +/// c.add(2); +/// +/// // ... and then turn it into an Iterator: +/// for (i, n) in c.into_iter().enumerate() { +/// assert_eq!(i as i32, n); +/// } +/// ``` +/// +/// It is common to use `IntoIterator` as a trait bound. This allows +/// the input collection type to change, so long as it is still an +/// iterator. Additional bounds can be specified by restricting on +/// `Item`: +/// +/// ```rust +/// fn collect_as_strings(collection: T) -> Vec +/// where T: IntoIterator, +/// T::Item : std::fmt::Debug, +/// { +/// collection +/// .into_iter() +/// .map(|item| format!("{:?}", item)) +/// .collect() +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoIterator { + /// The type of the elements being iterated over. + #[stable(feature = "rust1", since = "1.0.0")] + type Item; + + /// Which kind of iterator are we turning this into? + #[stable(feature = "rust1", since = "1.0.0")] + type IntoIter: Iterator; + + /// Creates an iterator from a value. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: index.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let v = vec![1, 2, 3]; + /// let mut iter = v.into_iter(); + /// + /// assert_eq!(Some(1), iter.next()); + /// assert_eq!(Some(2), iter.next()); + /// assert_eq!(Some(3), iter.next()); + /// assert_eq!(None, iter.next()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_iter(self) -> Self::IntoIter; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +/// Extend a collection with the contents of an iterator. +/// +/// Iterators produce a series of values, and collections can also be thought +/// of as a series of values. The `Extend` trait bridges this gap, allowing you +/// to extend a collection by including the contents of that iterator. When +/// extending a collection with an already existing key, that entry is updated +/// or, in the case of collections that permit multiple entries with equal +/// keys, that entry is inserted. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // You can extend a String with some chars: +/// let mut message = String::from("The first three letters are: "); +/// +/// message.extend(&['a', 'b', 'c']); +/// +/// assert_eq!("abc", &message[29..32]); +/// ``` +/// +/// Implementing `Extend`: +/// +/// ``` +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // since MyCollection has a list of i32s, we implement Extend for i32 +/// impl Extend for MyCollection { +/// +/// // This is a bit simpler with the concrete type signature: we can call +/// // extend on anything which can be turned into an Iterator which gives +/// // us i32s. Because we need i32s to put into MyCollection. +/// fn extend>(&mut self, iter: T) { +/// +/// // The implementation is very straightforward: loop through the +/// // iterator, and add() each element to ourselves. +/// for elem in iter { +/// self.add(elem); +/// } +/// } +/// } +/// +/// let mut c = MyCollection::new(); +/// +/// c.add(5); +/// c.add(6); +/// c.add(7); +/// +/// // let's extend our collection with three more numbers +/// c.extend(vec![1, 2, 3]); +/// +/// // we've added these elements onto the end +/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c)); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Extend { + /// Extends a collection with the contents of an iterator. + /// + /// As this is the only method for this trait, the [trait-level] docs + /// contain more details. + /// + /// [trait-level]: trait.Extend.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // You can extend a String with some chars: + /// let mut message = String::from("abc"); + /// + /// message.extend(['d', 'e', 'f'].iter()); + /// + /// assert_eq!("abcdef", &message); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn extend>(&mut self, iter: T); +} + +#[stable(feature = "extend_for_unit", since = "1.28.0")] +impl Extend<()> for () { + fn extend>(&mut self, iter: T) { + iter.into_iter().for_each(drop) + } +} diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index 5df3b0f69a563..093799d7bce20 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -4,360 +4,12 @@ use num::Wrapping; mod iterator; mod double_ended; mod exact_size; +mod collect; pub use self::iterator::Iterator; pub use self::double_ended::DoubleEndedIterator; pub use self::exact_size::ExactSizeIterator; - -/// Conversion from an `Iterator`. -/// -/// By implementing `FromIterator` for a type, you define how it will be -/// created from an iterator. This is common for types which describe a -/// collection of some kind. -/// -/// `FromIterator`'s [`from_iter`] is rarely called explicitly, and is instead -/// used through [`Iterator`]'s [`collect`] method. See [`collect`]'s -/// documentation for more examples. -/// -/// [`from_iter`]: #tymethod.from_iter -/// [`Iterator`]: trait.Iterator.html -/// [`collect`]: trait.Iterator.html#method.collect -/// -/// See also: [`IntoIterator`]. -/// -/// [`IntoIterator`]: trait.IntoIterator.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// use std::iter::FromIterator; -/// -/// let five_fives = std::iter::repeat(5).take(5); -/// -/// let v = Vec::from_iter(five_fives); -/// -/// assert_eq!(v, vec![5, 5, 5, 5, 5]); -/// ``` -/// -/// Using [`collect`] to implicitly use `FromIterator`: -/// -/// ``` -/// let five_fives = std::iter::repeat(5).take(5); -/// -/// let v: Vec = five_fives.collect(); -/// -/// assert_eq!(v, vec![5, 5, 5, 5, 5]); -/// ``` -/// -/// Implementing `FromIterator` for your type: -/// -/// ``` -/// use std::iter::FromIterator; -/// -/// // A sample collection, that's just a wrapper over Vec -/// #[derive(Debug)] -/// struct MyCollection(Vec); -/// -/// // Let's give it some methods so we can create one and add things -/// // to it. -/// impl MyCollection { -/// fn new() -> MyCollection { -/// MyCollection(Vec::new()) -/// } -/// -/// fn add(&mut self, elem: i32) { -/// self.0.push(elem); -/// } -/// } -/// -/// // and we'll implement FromIterator -/// impl FromIterator for MyCollection { -/// fn from_iter>(iter: I) -> Self { -/// let mut c = MyCollection::new(); -/// -/// for i in iter { -/// c.add(i); -/// } -/// -/// c -/// } -/// } -/// -/// // Now we can make a new iterator... -/// let iter = (0..5).into_iter(); -/// -/// // ... and make a MyCollection out of it -/// let c = MyCollection::from_iter(iter); -/// -/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); -/// -/// // collect works too! -/// -/// let iter = (0..5).into_iter(); -/// let c: MyCollection = iter.collect(); -/// -/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented( - message="a collection of type `{Self}` cannot be built from an iterator \ - over elements of type `{A}`", - label="a collection of type `{Self}` cannot be built from `std::iter::Iterator`", -)] -pub trait FromIterator: Sized { - /// Creates a value from an iterator. - /// - /// See the [module-level documentation] for more. - /// - /// [module-level documentation]: index.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::iter::FromIterator; - /// - /// let five_fives = std::iter::repeat(5).take(5); - /// - /// let v = Vec::from_iter(five_fives); - /// - /// assert_eq!(v, vec![5, 5, 5, 5, 5]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter>(iter: T) -> Self; -} - -/// Conversion into an `Iterator`. -/// -/// By implementing `IntoIterator` for a type, you define how it will be -/// converted to an iterator. This is common for types which describe a -/// collection of some kind. -/// -/// One benefit of implementing `IntoIterator` is that your type will [work -/// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). -/// -/// See also: [`FromIterator`]. -/// -/// [`FromIterator`]: trait.FromIterator.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// let v = vec![1, 2, 3]; -/// let mut iter = v.into_iter(); -/// -/// assert_eq!(Some(1), iter.next()); -/// assert_eq!(Some(2), iter.next()); -/// assert_eq!(Some(3), iter.next()); -/// assert_eq!(None, iter.next()); -/// ``` -/// Implementing `IntoIterator` for your type: -/// -/// ``` -/// // A sample collection, that's just a wrapper over Vec -/// #[derive(Debug)] -/// struct MyCollection(Vec); -/// -/// // Let's give it some methods so we can create one and add things -/// // to it. -/// impl MyCollection { -/// fn new() -> MyCollection { -/// MyCollection(Vec::new()) -/// } -/// -/// fn add(&mut self, elem: i32) { -/// self.0.push(elem); -/// } -/// } -/// -/// // and we'll implement IntoIterator -/// impl IntoIterator for MyCollection { -/// type Item = i32; -/// type IntoIter = ::std::vec::IntoIter; -/// -/// fn into_iter(self) -> Self::IntoIter { -/// self.0.into_iter() -/// } -/// } -/// -/// // Now we can make a new collection... -/// let mut c = MyCollection::new(); -/// -/// // ... add some stuff to it ... -/// c.add(0); -/// c.add(1); -/// c.add(2); -/// -/// // ... and then turn it into an Iterator: -/// for (i, n) in c.into_iter().enumerate() { -/// assert_eq!(i as i32, n); -/// } -/// ``` -/// -/// It is common to use `IntoIterator` as a trait bound. This allows -/// the input collection type to change, so long as it is still an -/// iterator. Additional bounds can be specified by restricting on -/// `Item`: -/// -/// ```rust -/// fn collect_as_strings(collection: T) -> Vec -/// where T: IntoIterator, -/// T::Item : std::fmt::Debug, -/// { -/// collection -/// .into_iter() -/// .map(|item| format!("{:?}", item)) -/// .collect() -/// } -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait IntoIterator { - /// The type of the elements being iterated over. - #[stable(feature = "rust1", since = "1.0.0")] - type Item; - - /// Which kind of iterator are we turning this into? - #[stable(feature = "rust1", since = "1.0.0")] - type IntoIter: Iterator; - - /// Creates an iterator from a value. - /// - /// See the [module-level documentation] for more. - /// - /// [module-level documentation]: index.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let v = vec![1, 2, 3]; - /// let mut iter = v.into_iter(); - /// - /// assert_eq!(Some(1), iter.next()); - /// assert_eq!(Some(2), iter.next()); - /// assert_eq!(Some(3), iter.next()); - /// assert_eq!(None, iter.next()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn into_iter(self) -> Self::IntoIter; -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for I { - type Item = I::Item; - type IntoIter = I; - - fn into_iter(self) -> I { - self - } -} - -/// Extend a collection with the contents of an iterator. -/// -/// Iterators produce a series of values, and collections can also be thought -/// of as a series of values. The `Extend` trait bridges this gap, allowing you -/// to extend a collection by including the contents of that iterator. When -/// extending a collection with an already existing key, that entry is updated -/// or, in the case of collections that permit multiple entries with equal -/// keys, that entry is inserted. -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// // You can extend a String with some chars: -/// let mut message = String::from("The first three letters are: "); -/// -/// message.extend(&['a', 'b', 'c']); -/// -/// assert_eq!("abc", &message[29..32]); -/// ``` -/// -/// Implementing `Extend`: -/// -/// ``` -/// // A sample collection, that's just a wrapper over Vec -/// #[derive(Debug)] -/// struct MyCollection(Vec); -/// -/// // Let's give it some methods so we can create one and add things -/// // to it. -/// impl MyCollection { -/// fn new() -> MyCollection { -/// MyCollection(Vec::new()) -/// } -/// -/// fn add(&mut self, elem: i32) { -/// self.0.push(elem); -/// } -/// } -/// -/// // since MyCollection has a list of i32s, we implement Extend for i32 -/// impl Extend for MyCollection { -/// -/// // This is a bit simpler with the concrete type signature: we can call -/// // extend on anything which can be turned into an Iterator which gives -/// // us i32s. Because we need i32s to put into MyCollection. -/// fn extend>(&mut self, iter: T) { -/// -/// // The implementation is very straightforward: loop through the -/// // iterator, and add() each element to ourselves. -/// for elem in iter { -/// self.add(elem); -/// } -/// } -/// } -/// -/// let mut c = MyCollection::new(); -/// -/// c.add(5); -/// c.add(6); -/// c.add(7); -/// -/// // let's extend our collection with three more numbers -/// c.extend(vec![1, 2, 3]); -/// -/// // we've added these elements onto the end -/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c)); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait Extend { - /// Extends a collection with the contents of an iterator. - /// - /// As this is the only method for this trait, the [trait-level] docs - /// contain more details. - /// - /// [trait-level]: trait.Extend.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// // You can extend a String with some chars: - /// let mut message = String::from("abc"); - /// - /// message.extend(['d', 'e', 'f'].iter()); - /// - /// assert_eq!("abcdef", &message); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn extend>(&mut self, iter: T); -} - -#[stable(feature = "extend_for_unit", since = "1.28.0")] -impl Extend<()> for () { - fn extend>(&mut self, iter: T) { - iter.into_iter().for_each(drop) - } -} +pub use self::collect::{FromIterator, IntoIterator, Extend}; /// Trait to represent types that can be created by summing up an iterator. /// From 4a036142a0da3cbae374f824a332bc43d4cecd09 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:33:12 -0500 Subject: [PATCH 0262/1064] Move Sum, Product to own module --- src/libcore/iter/traits/accum.rs | 225 ++++++++++++++++++++++++++++++ src/libcore/iter/traits/mod.rs | 228 +------------------------------ 2 files changed, 227 insertions(+), 226 deletions(-) create mode 100644 src/libcore/iter/traits/accum.rs diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs new file mode 100644 index 0000000000000..dfe1d2a1006d7 --- /dev/null +++ b/src/libcore/iter/traits/accum.rs @@ -0,0 +1,225 @@ +use ops::{Mul, Add}; +use num::Wrapping; + +/// Trait to represent types that can be created by summing up an iterator. +/// +/// This trait is used to implement the [`sum`] method on iterators. Types which +/// implement the trait can be generated by the [`sum`] method. Like +/// [`FromIterator`] this trait should rarely be called directly and instead +/// interacted with through [`Iterator::sum`]. +/// +/// [`sum`]: ../../std/iter/trait.Sum.html#tymethod.sum +/// [`FromIterator`]: ../../std/iter/trait.FromIterator.html +/// [`Iterator::sum`]: ../../std/iter/trait.Iterator.html#method.sum +#[stable(feature = "iter_arith_traits", since = "1.12.0")] +pub trait Sum: Sized { + /// Method which takes an iterator and generates `Self` from the elements by + /// "summing up" the items. + #[stable(feature = "iter_arith_traits", since = "1.12.0")] + fn sum>(iter: I) -> Self; +} + +/// Trait to represent types that can be created by multiplying elements of an +/// iterator. +/// +/// This trait is used to implement the [`product`] method on iterators. Types +/// which implement the trait can be generated by the [`product`] method. Like +/// [`FromIterator`] this trait should rarely be called directly and instead +/// interacted with through [`Iterator::product`]. +/// +/// [`product`]: ../../std/iter/trait.Product.html#tymethod.product +/// [`FromIterator`]: ../../std/iter/trait.FromIterator.html +/// [`Iterator::product`]: ../../std/iter/trait.Iterator.html#method.product +#[stable(feature = "iter_arith_traits", since = "1.12.0")] +pub trait Product: Sized { + /// Method which takes an iterator and generates `Self` from the elements by + /// multiplying the items. + #[stable(feature = "iter_arith_traits", since = "1.12.0")] + fn product>(iter: I) -> Self; +} + +// N.B., explicitly use Add and Mul here to inherit overflow checks +macro_rules! integer_sum_product { + (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($( + #[$attr] + impl Sum for $a { + fn sum>(iter: I) -> $a { + iter.fold($zero, Add::add) + } + } + + #[$attr] + impl Product for $a { + fn product>(iter: I) -> $a { + iter.fold($one, Mul::mul) + } + } + + #[$attr] + impl<'a> Sum<&'a $a> for $a { + fn sum>(iter: I) -> $a { + iter.fold($zero, Add::add) + } + } + + #[$attr] + impl<'a> Product<&'a $a> for $a { + fn product>(iter: I) -> $a { + iter.fold($one, Mul::mul) + } + } + )*); + ($($a:ty)*) => ( + integer_sum_product!(@impls 0, 1, + #[stable(feature = "iter_arith_traits", since = "1.12.0")], + $($a)+); + integer_sum_product!(@impls Wrapping(0), Wrapping(1), + #[stable(feature = "wrapping_iter_arith", since = "1.14.0")], + $(Wrapping<$a>)+); + ); +} + +macro_rules! float_sum_product { + ($($a:ident)*) => ($( + #[stable(feature = "iter_arith_traits", since = "1.12.0")] + impl Sum for $a { + fn sum>(iter: I) -> $a { + iter.fold(0.0, |a, b| a + b) + } + } + + #[stable(feature = "iter_arith_traits", since = "1.12.0")] + impl Product for $a { + fn product>(iter: I) -> $a { + iter.fold(1.0, |a, b| a * b) + } + } + + #[stable(feature = "iter_arith_traits", since = "1.12.0")] + impl<'a> Sum<&'a $a> for $a { + fn sum>(iter: I) -> $a { + iter.fold(0.0, |a, b| a + *b) + } + } + + #[stable(feature = "iter_arith_traits", since = "1.12.0")] + impl<'a> Product<&'a $a> for $a { + fn product>(iter: I) -> $a { + iter.fold(1.0, |a, b| a * *b) + } + } + )*) +} + +integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } +float_sum_product! { f32 f64 } + +/// An iterator adapter that produces output as long as the underlying +/// iterator produces `Result::Ok` values. +/// +/// If an error is encountered, the iterator stops and the error is +/// stored. The error may be recovered later via `reconstruct`. +struct ResultShunt { + iter: I, + error: Option, +} + +impl ResultShunt + where I: Iterator> +{ + /// Process the given iterator as if it yielded a `T` instead of a + /// `Result`. Any errors will stop the inner iterator and + /// the overall result will be an error. + pub fn process(iter: I, mut f: F) -> Result + where F: FnMut(&mut Self) -> U + { + let mut shunt = ResultShunt::new(iter); + let value = f(shunt.by_ref()); + shunt.reconstruct(value) + } + + fn new(iter: I) -> Self { + ResultShunt { + iter, + error: None, + } + } + + /// Consume the adapter and rebuild a `Result` value. This should + /// *always* be called, otherwise any potential error would be + /// lost. + fn reconstruct(self, val: U) -> Result { + match self.error { + None => Ok(val), + Some(e) => Err(e), + } + } +} + +impl Iterator for ResultShunt + where I: Iterator> +{ + type Item = T; + + fn next(&mut self) -> Option { + match self.iter.next() { + Some(Ok(v)) => Some(v), + Some(Err(e)) => { + self.error = Some(e); + None + } + None => None, + } + } + + fn size_hint(&self) -> (usize, Option) { + if self.error.is_some() { + (0, Some(0)) + } else { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } + } +} + +#[stable(feature = "iter_arith_traits_result", since="1.16.0")] +impl Sum> for Result + where T: Sum, +{ + /// Takes each element in the `Iterator`: if it is an `Err`, no further + /// elements are taken, and the `Err` is returned. Should no `Err` occur, + /// the sum of all elements is returned. + /// + /// # Examples + /// + /// This sums up every integer in a vector, rejecting the sum if a negative + /// element is encountered: + /// + /// ``` + /// let v = vec![1, 2]; + /// let res: Result = v.iter().map(|&x: &i32| + /// if x < 0 { Err("Negative element found") } + /// else { Ok(x) } + /// ).sum(); + /// assert_eq!(res, Ok(3)); + /// ``` + fn sum(iter: I) -> Result + where I: Iterator>, + { + ResultShunt::process(iter, |i| i.sum()) + } +} + +#[stable(feature = "iter_arith_traits_result", since="1.16.0")] +impl Product> for Result + where T: Product, +{ + /// Takes each element in the `Iterator`: if it is an `Err`, no further + /// elements are taken, and the `Err` is returned. Should no `Err` occur, + /// the product of all elements is returned. + fn product(iter: I) -> Result + where I: Iterator>, + { + ResultShunt::process(iter, |i| i.product()) + } +} diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index 093799d7bce20..25637ef9f4ede 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -1,238 +1,14 @@ -use ops::{Mul, Add}; -use num::Wrapping; - mod iterator; mod double_ended; mod exact_size; mod collect; +mod accum; pub use self::iterator::Iterator; pub use self::double_ended::DoubleEndedIterator; pub use self::exact_size::ExactSizeIterator; pub use self::collect::{FromIterator, IntoIterator, Extend}; - -/// Trait to represent types that can be created by summing up an iterator. -/// -/// This trait is used to implement the [`sum`] method on iterators. Types which -/// implement the trait can be generated by the [`sum`] method. Like -/// [`FromIterator`] this trait should rarely be called directly and instead -/// interacted with through [`Iterator::sum`]. -/// -/// [`sum`]: ../../std/iter/trait.Sum.html#tymethod.sum -/// [`FromIterator`]: ../../std/iter/trait.FromIterator.html -/// [`Iterator::sum`]: ../../std/iter/trait.Iterator.html#method.sum -#[stable(feature = "iter_arith_traits", since = "1.12.0")] -pub trait Sum: Sized { - /// Method which takes an iterator and generates `Self` from the elements by - /// "summing up" the items. - #[stable(feature = "iter_arith_traits", since = "1.12.0")] - fn sum>(iter: I) -> Self; -} - -/// Trait to represent types that can be created by multiplying elements of an -/// iterator. -/// -/// This trait is used to implement the [`product`] method on iterators. Types -/// which implement the trait can be generated by the [`product`] method. Like -/// [`FromIterator`] this trait should rarely be called directly and instead -/// interacted with through [`Iterator::product`]. -/// -/// [`product`]: ../../std/iter/trait.Product.html#tymethod.product -/// [`FromIterator`]: ../../std/iter/trait.FromIterator.html -/// [`Iterator::product`]: ../../std/iter/trait.Iterator.html#method.product -#[stable(feature = "iter_arith_traits", since = "1.12.0")] -pub trait Product: Sized { - /// Method which takes an iterator and generates `Self` from the elements by - /// multiplying the items. - #[stable(feature = "iter_arith_traits", since = "1.12.0")] - fn product>(iter: I) -> Self; -} - -// N.B., explicitly use Add and Mul here to inherit overflow checks -macro_rules! integer_sum_product { - (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($( - #[$attr] - impl Sum for $a { - fn sum>(iter: I) -> $a { - iter.fold($zero, Add::add) - } - } - - #[$attr] - impl Product for $a { - fn product>(iter: I) -> $a { - iter.fold($one, Mul::mul) - } - } - - #[$attr] - impl<'a> Sum<&'a $a> for $a { - fn sum>(iter: I) -> $a { - iter.fold($zero, Add::add) - } - } - - #[$attr] - impl<'a> Product<&'a $a> for $a { - fn product>(iter: I) -> $a { - iter.fold($one, Mul::mul) - } - } - )*); - ($($a:ty)*) => ( - integer_sum_product!(@impls 0, 1, - #[stable(feature = "iter_arith_traits", since = "1.12.0")], - $($a)+); - integer_sum_product!(@impls Wrapping(0), Wrapping(1), - #[stable(feature = "wrapping_iter_arith", since = "1.14.0")], - $(Wrapping<$a>)+); - ); -} - -macro_rules! float_sum_product { - ($($a:ident)*) => ($( - #[stable(feature = "iter_arith_traits", since = "1.12.0")] - impl Sum for $a { - fn sum>(iter: I) -> $a { - iter.fold(0.0, |a, b| a + b) - } - } - - #[stable(feature = "iter_arith_traits", since = "1.12.0")] - impl Product for $a { - fn product>(iter: I) -> $a { - iter.fold(1.0, |a, b| a * b) - } - } - - #[stable(feature = "iter_arith_traits", since = "1.12.0")] - impl<'a> Sum<&'a $a> for $a { - fn sum>(iter: I) -> $a { - iter.fold(0.0, |a, b| a + *b) - } - } - - #[stable(feature = "iter_arith_traits", since = "1.12.0")] - impl<'a> Product<&'a $a> for $a { - fn product>(iter: I) -> $a { - iter.fold(1.0, |a, b| a * *b) - } - } - )*) -} - -integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } -float_sum_product! { f32 f64 } - -/// An iterator adapter that produces output as long as the underlying -/// iterator produces `Result::Ok` values. -/// -/// If an error is encountered, the iterator stops and the error is -/// stored. The error may be recovered later via `reconstruct`. -struct ResultShunt { - iter: I, - error: Option, -} - -impl ResultShunt - where I: Iterator> -{ - /// Process the given iterator as if it yielded a `T` instead of a - /// `Result`. Any errors will stop the inner iterator and - /// the overall result will be an error. - pub fn process(iter: I, mut f: F) -> Result - where F: FnMut(&mut Self) -> U - { - let mut shunt = ResultShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - ResultShunt { - iter, - error: None, - } - } - - /// Consume the adapter and rebuild a `Result` value. This should - /// *always* be called, otherwise any potential error would be - /// lost. - fn reconstruct(self, val: U) -> Result { - match self.error { - None => Ok(val), - Some(e) => Err(e), - } - } -} - -impl Iterator for ResultShunt - where I: Iterator> -{ - type Item = T; - - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Ok(v)) => Some(v), - Some(Err(e)) => { - self.error = Some(e); - None - } - None => None, - } - } - - fn size_hint(&self) -> (usize, Option) { - if self.error.is_some() { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } - } -} - -#[stable(feature = "iter_arith_traits_result", since="1.16.0")] -impl Sum> for Result - where T: Sum, -{ - /// Takes each element in the `Iterator`: if it is an `Err`, no further - /// elements are taken, and the `Err` is returned. Should no `Err` occur, - /// the sum of all elements is returned. - /// - /// # Examples - /// - /// This sums up every integer in a vector, rejecting the sum if a negative - /// element is encountered: - /// - /// ``` - /// let v = vec![1, 2]; - /// let res: Result = v.iter().map(|&x: &i32| - /// if x < 0 { Err("Negative element found") } - /// else { Ok(x) } - /// ).sum(); - /// assert_eq!(res, Ok(3)); - /// ``` - fn sum(iter: I) -> Result - where I: Iterator>, - { - ResultShunt::process(iter, |i| i.sum()) - } -} - -#[stable(feature = "iter_arith_traits_result", since="1.16.0")] -impl Product> for Result - where T: Product, -{ - /// Takes each element in the `Iterator`: if it is an `Err`, no further - /// elements are taken, and the `Err` is returned. Should no `Err` occur, - /// the product of all elements is returned. - fn product(iter: I) -> Result - where I: Iterator>, - { - ResultShunt::process(iter, |i| i.product()) - } -} +pub use self::accum::{Sum, Product}; /// An iterator that always continues to yield `None` when exhausted. /// From 9228f3c6b2017993b0b829d60ecc51279e51ccb9 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 17:33:53 -0500 Subject: [PATCH 0263/1064] Move FusedIterator, TrustedLen to own module --- src/libcore/iter/traits/marker.rs | 44 +++++++++++++++++++++++++++++ src/libcore/iter/traits/mod.rs | 47 ++----------------------------- 2 files changed, 46 insertions(+), 45 deletions(-) create mode 100644 src/libcore/iter/traits/marker.rs diff --git a/src/libcore/iter/traits/marker.rs b/src/libcore/iter/traits/marker.rs new file mode 100644 index 0000000000000..602619bce5a96 --- /dev/null +++ b/src/libcore/iter/traits/marker.rs @@ -0,0 +1,44 @@ +/// An iterator that always continues to yield `None` when exhausted. +/// +/// Calling next on a fused iterator that has returned `None` once is guaranteed +/// to return [`None`] again. This trait should be implemented by all iterators +/// that behave this way because it allows optimizing [`Iterator::fuse`]. +/// +/// Note: In general, you should not use `FusedIterator` in generic bounds if +/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`] +/// on the iterator. If the iterator is already fused, the additional [`Fuse`] +/// wrapper will be a no-op with no performance penalty. +/// +/// [`None`]: ../../std/option/enum.Option.html#variant.None +/// [`Iterator::fuse`]: ../../std/iter/trait.Iterator.html#method.fuse +/// [`Fuse`]: ../../std/iter/struct.Fuse.html +#[stable(feature = "fused", since = "1.26.0")] +pub trait FusedIterator: Iterator {} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for &mut I {} + +/// An iterator that reports an accurate length using size_hint. +/// +/// The iterator reports a size hint where it is either exact +/// (lower bound is equal to upper bound), or the upper bound is [`None`]. +/// The upper bound must only be [`None`] if the actual iterator length is +/// larger than [`usize::MAX`]. In that case, the lower bound must be +/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`. +/// +/// The iterator must produce exactly the number of elements it reported +/// or diverge before reaching the end. +/// +/// # Safety +/// +/// This trait must only be implemented when the contract is upheld. +/// Consumers of this trait must inspect [`.size_hint`]’s upper bound. +/// +/// [`None`]: ../../std/option/enum.Option.html#variant.None +/// [`usize::MAX`]: ../../std/usize/constant.MAX.html +/// [`.size_hint`]: ../../std/iter/trait.Iterator.html#method.size_hint +#[unstable(feature = "trusted_len", issue = "37572")] +pub unsafe trait TrustedLen : Iterator {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for &mut I {} diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index 25637ef9f4ede..000b9fad70b94 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -3,54 +3,11 @@ mod double_ended; mod exact_size; mod collect; mod accum; +mod marker; pub use self::iterator::Iterator; pub use self::double_ended::DoubleEndedIterator; pub use self::exact_size::ExactSizeIterator; pub use self::collect::{FromIterator, IntoIterator, Extend}; pub use self::accum::{Sum, Product}; - -/// An iterator that always continues to yield `None` when exhausted. -/// -/// Calling next on a fused iterator that has returned `None` once is guaranteed -/// to return [`None`] again. This trait should be implemented by all iterators -/// that behave this way because it allows optimizing [`Iterator::fuse`]. -/// -/// Note: In general, you should not use `FusedIterator` in generic bounds if -/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`] -/// on the iterator. If the iterator is already fused, the additional [`Fuse`] -/// wrapper will be a no-op with no performance penalty. -/// -/// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [`Iterator::fuse`]: ../../std/iter/trait.Iterator.html#method.fuse -/// [`Fuse`]: ../../std/iter/struct.Fuse.html -#[stable(feature = "fused", since = "1.26.0")] -pub trait FusedIterator: Iterator {} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for &mut I {} - -/// An iterator that reports an accurate length using size_hint. -/// -/// The iterator reports a size hint where it is either exact -/// (lower bound is equal to upper bound), or the upper bound is [`None`]. -/// The upper bound must only be [`None`] if the actual iterator length is -/// larger than [`usize::MAX`]. In that case, the lower bound must be -/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`. -/// -/// The iterator must produce exactly the number of elements it reported -/// or diverge before reaching the end. -/// -/// # Safety -/// -/// This trait must only be implemented when the contract is upheld. -/// Consumers of this trait must inspect [`.size_hint`]’s upper bound. -/// -/// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [`usize::MAX`]: ../../std/usize/constant.MAX.html -/// [`.size_hint`]: ../../std/iter/trait.Iterator.html#method.size_hint -#[unstable(feature = "trusted_len", issue = "37572")] -pub unsafe trait TrustedLen : Iterator {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for &mut I {} +pub use self::marker::{FusedIterator, TrustedLen}; From 3c44e1f08553af4309d16ab098522e57a057fabc Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 19:27:24 -0500 Subject: [PATCH 0264/1064] Move Zip and ZipImpl to own module --- src/libcore/iter/adapters/mod.rs | 263 +------------------------------ src/libcore/iter/adapters/zip.rs | 261 ++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 258 deletions(-) create mode 100644 src/libcore/iter/adapters/zip.rs diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index abeb13180c335..b0faded887130 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -7,6 +7,11 @@ use intrinsics; use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; use super::LoopState; +mod zip; + +pub use self::zip::Zip; +pub(super) use self::zip::ZipImpl; + /// A double-ended iterator with the direction inverted. /// /// This `struct` is created by the [`rev`] method on [`Iterator`]. See its @@ -703,264 +708,6 @@ unsafe impl TrustedLen for Chain where A: TrustedLen, B: TrustedLen, {} -/// An iterator that iterates two other iterators simultaneously. -/// -/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`zip`]: trait.Iterator.html#method.zip -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Zip { - a: A, - b: B, - // index and len are only used by the specialized version of zip - index: usize, - len: usize, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where A: Iterator, B: Iterator -{ - type Item = (A::Item, B::Item); - - #[inline] - fn next(&mut self) -> Option { - ZipImpl::next(self) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - ZipImpl::size_hint(self) - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - ZipImpl::nth(self, n) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Zip where - A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator, -{ - #[inline] - fn next_back(&mut self) -> Option<(A::Item, B::Item)> { - ZipImpl::next_back(self) - } -} - -// Zip specialization trait -#[doc(hidden)] -pub(super) trait ZipImpl { - type Item; - fn new(a: A, b: B) -> Self; - fn next(&mut self) -> Option; - fn size_hint(&self) -> (usize, Option); - fn nth(&mut self, n: usize) -> Option; - fn super_nth(&mut self, mut n: usize) -> Option { - while let Some(x) = self.next() { - if n == 0 { return Some(x) } - n -= 1; - } - None - } - fn next_back(&mut self) -> Option - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator; -} - -// General Zip impl -#[doc(hidden)] -impl ZipImpl for Zip - where A: Iterator, B: Iterator -{ - type Item = (A::Item, B::Item); - default fn new(a: A, b: B) -> Self { - Zip { - a, - b, - index: 0, // unused - len: 0, // unused - } - } - - #[inline] - default fn next(&mut self) -> Option<(A::Item, B::Item)> { - self.a.next().and_then(|x| { - self.b.next().and_then(|y| { - Some((x, y)) - }) - }) - } - - #[inline] - default fn nth(&mut self, n: usize) -> Option { - self.super_nth(n) - } - - #[inline] - default fn next_back(&mut self) -> Option<(A::Item, B::Item)> - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator - { - let a_sz = self.a.len(); - let b_sz = self.b.len(); - if a_sz != b_sz { - // Adjust a, b to equal length - if a_sz > b_sz { - for _ in 0..a_sz - b_sz { self.a.next_back(); } - } else { - for _ in 0..b_sz - a_sz { self.b.next_back(); } - } - } - match (self.a.next_back(), self.b.next_back()) { - (Some(x), Some(y)) => Some((x, y)), - (None, None) => None, - _ => unreachable!(), - } - } - - #[inline] - default fn size_hint(&self) -> (usize, Option) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); - - let lower = cmp::min(a_lower, b_lower); - - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => Some(cmp::min(x,y)), - (Some(x), None) => Some(x), - (None, Some(y)) => Some(y), - (None, None) => None - }; - - (lower, upper) - } -} - -#[doc(hidden)] -impl ZipImpl for Zip - where A: TrustedRandomAccess, B: TrustedRandomAccess -{ - fn new(a: A, b: B) -> Self { - let len = cmp::min(a.len(), b.len()); - Zip { - a, - b, - index: 0, - len, - } - } - - #[inline] - fn next(&mut self) -> Option<(A::Item, B::Item)> { - if self.index < self.len { - let i = self.index; - self.index += 1; - unsafe { - Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) - } - } else if A::may_have_side_effect() && self.index < self.a.len() { - // match the base implementation's potential side effects - unsafe { - self.a.get_unchecked(self.index); - } - self.index += 1; - None - } else { - None - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let len = self.len - self.index; - (len, Some(len)) - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - let delta = cmp::min(n, self.len - self.index); - let end = self.index + delta; - while self.index < end { - let i = self.index; - self.index += 1; - if A::may_have_side_effect() { - unsafe { self.a.get_unchecked(i); } - } - if B::may_have_side_effect() { - unsafe { self.b.get_unchecked(i); } - } - } - - self.super_nth(n - delta) - } - - #[inline] - fn next_back(&mut self) -> Option<(A::Item, B::Item)> - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator - { - // Adjust a, b to equal length - if A::may_have_side_effect() { - let sz = self.a.len(); - if sz > self.len { - for _ in 0..sz - cmp::max(self.len, self.index) { - self.a.next_back(); - } - } - } - if B::may_have_side_effect() { - let sz = self.b.len(); - if sz > self.len { - for _ in 0..sz - self.len { - self.b.next_back(); - } - } - } - if self.index < self.len { - self.len -= 1; - let i = self.len; - unsafe { - Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) - } - } else { - None - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Zip - where A: ExactSizeIterator, B: ExactSizeIterator {} - -#[doc(hidden)] -unsafe impl TrustedRandomAccess for Zip - where A: TrustedRandomAccess, - B: TrustedRandomAccess, -{ - unsafe fn get_unchecked(&mut self, i: usize) -> (A::Item, B::Item) { - (self.a.get_unchecked(i), self.b.get_unchecked(i)) - } - - fn may_have_side_effect() -> bool { - A::may_have_side_effect() || B::may_have_side_effect() - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Zip - where A: FusedIterator, B: FusedIterator, {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Zip - where A: TrustedLen, B: TrustedLen, -{} - /// An iterator that maps the values of `iter` with `f`. /// /// This `struct` is created by the [`map`] method on [`Iterator`]. See its diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs new file mode 100644 index 0000000000000..d2937f5d3e147 --- /dev/null +++ b/src/libcore/iter/adapters/zip.rs @@ -0,0 +1,261 @@ +use cmp; +use iter_private::TrustedRandomAccess; +use super::super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; + +/// An iterator that iterates two other iterators simultaneously. +/// +/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`zip`]: trait.Iterator.html#method.zip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Zip { + a: A, + b: B, + // index and len are only used by the specialized version of zip + index: usize, + len: usize, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Zip where A: Iterator, B: Iterator +{ + type Item = (A::Item, B::Item); + + #[inline] + fn next(&mut self) -> Option { + ZipImpl::next(self) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + ZipImpl::size_hint(self) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + ZipImpl::nth(self, n) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Zip where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, +{ + #[inline] + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { + ZipImpl::next_back(self) + } +} + +// Zip specialization trait +#[doc(hidden)] +pub(in super::super) trait ZipImpl { + type Item; + fn new(a: A, b: B) -> Self; + fn next(&mut self) -> Option; + fn size_hint(&self) -> (usize, Option); + fn nth(&mut self, n: usize) -> Option; + fn super_nth(&mut self, mut n: usize) -> Option { + while let Some(x) = self.next() { + if n == 0 { return Some(x) } + n -= 1; + } + None + } + fn next_back(&mut self) -> Option + where A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator; +} + +// General Zip impl +#[doc(hidden)] +impl ZipImpl for Zip + where A: Iterator, B: Iterator +{ + type Item = (A::Item, B::Item); + default fn new(a: A, b: B) -> Self { + Zip { + a, + b, + index: 0, // unused + len: 0, // unused + } + } + + #[inline] + default fn next(&mut self) -> Option<(A::Item, B::Item)> { + self.a.next().and_then(|x| { + self.b.next().and_then(|y| { + Some((x, y)) + }) + }) + } + + #[inline] + default fn nth(&mut self, n: usize) -> Option { + self.super_nth(n) + } + + #[inline] + default fn next_back(&mut self) -> Option<(A::Item, B::Item)> + where A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator + { + let a_sz = self.a.len(); + let b_sz = self.b.len(); + if a_sz != b_sz { + // Adjust a, b to equal length + if a_sz > b_sz { + for _ in 0..a_sz - b_sz { self.a.next_back(); } + } else { + for _ in 0..b_sz - a_sz { self.b.next_back(); } + } + } + match (self.a.next_back(), self.b.next_back()) { + (Some(x), Some(y)) => Some((x, y)), + (None, None) => None, + _ => unreachable!(), + } + } + + #[inline] + default fn size_hint(&self) -> (usize, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = cmp::min(a_lower, b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None + }; + + (lower, upper) + } +} + +#[doc(hidden)] +impl ZipImpl for Zip + where A: TrustedRandomAccess, B: TrustedRandomAccess +{ + fn new(a: A, b: B) -> Self { + let len = cmp::min(a.len(), b.len()); + Zip { + a, + b, + index: 0, + len, + } + } + + #[inline] + fn next(&mut self) -> Option<(A::Item, B::Item)> { + if self.index < self.len { + let i = self.index; + self.index += 1; + unsafe { + Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) + } + } else if A::may_have_side_effect() && self.index < self.a.len() { + // match the base implementation's potential side effects + unsafe { + self.a.get_unchecked(self.index); + } + self.index += 1; + None + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len - self.index; + (len, Some(len)) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + let delta = cmp::min(n, self.len - self.index); + let end = self.index + delta; + while self.index < end { + let i = self.index; + self.index += 1; + if A::may_have_side_effect() { + unsafe { self.a.get_unchecked(i); } + } + if B::may_have_side_effect() { + unsafe { self.b.get_unchecked(i); } + } + } + + self.super_nth(n - delta) + } + + #[inline] + fn next_back(&mut self) -> Option<(A::Item, B::Item)> + where A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator + { + // Adjust a, b to equal length + if A::may_have_side_effect() { + let sz = self.a.len(); + if sz > self.len { + for _ in 0..sz - cmp::max(self.len, self.index) { + self.a.next_back(); + } + } + } + if B::may_have_side_effect() { + let sz = self.b.len(); + if sz > self.len { + for _ in 0..sz - self.len { + self.b.next_back(); + } + } + } + if self.index < self.len { + self.len -= 1; + let i = self.len; + unsafe { + Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) + } + } else { + None + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Zip + where A: ExactSizeIterator, B: ExactSizeIterator {} + +#[doc(hidden)] +unsafe impl TrustedRandomAccess for Zip + where A: TrustedRandomAccess, + B: TrustedRandomAccess, +{ + unsafe fn get_unchecked(&mut self, i: usize) -> (A::Item, B::Item) { + (self.a.get_unchecked(i), self.b.get_unchecked(i)) + } + + fn may_have_side_effect() -> bool { + A::may_have_side_effect() || B::may_have_side_effect() + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Zip + where A: FusedIterator, B: FusedIterator, {} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Zip + where A: TrustedLen, B: TrustedLen, +{} From 520e8b001ef7c49dcf1ad8f1f7817f2b16ad709b Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Wed, 19 Dec 2018 16:33:53 -0500 Subject: [PATCH 0265/1064] Move TrustedRandomAccess into Zip module --- src/libcore/iter/adapters/mod.rs | 2 +- src/libcore/iter/adapters/zip.rs | 18 +++++++++++++++++- src/libcore/iter/mod.rs | 1 + src/libcore/lib.rs | 1 - src/libcore/slice/mod.rs | 1 - src/libcore/str/mod.rs | 3 +-- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index b0faded887130..f2bedf390e3bc 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1,6 +1,5 @@ use cmp; use fmt; -use iter_private::TrustedRandomAccess; use ops::Try; use usize; use intrinsics; @@ -11,6 +10,7 @@ mod zip; pub use self::zip::Zip; pub(super) use self::zip::ZipImpl; +pub(crate) use self::zip::TrustedRandomAccess; /// A double-ended iterator with the direction inverted. /// diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs index d2937f5d3e147..6a0a7d8b12cdf 100644 --- a/src/libcore/iter/adapters/zip.rs +++ b/src/libcore/iter/adapters/zip.rs @@ -1,5 +1,4 @@ use cmp; -use iter_private::TrustedRandomAccess; use super::super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; /// An iterator that iterates two other iterators simultaneously. @@ -259,3 +258,20 @@ impl FusedIterator for Zip unsafe impl TrustedLen for Zip where A: TrustedLen, B: TrustedLen, {} + +/// An iterator whose items are random-accessible efficiently +/// +/// # Safety +/// +/// The iterator's .len() and size_hint() must be exact. +/// `.len()` must be cheap to call. +/// +/// .get_unchecked() must return distinct mutable references for distinct +/// indices (if applicable), and must return a valid reference if index is in +/// 0..self.len(). +pub(crate) unsafe trait TrustedRandomAccess : ExactSizeIterator { + unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item; + /// Returns `true` if getting an iterator element may have + /// side effects. Remember to take inner iterators into account. + fn may_have_side_effect() -> bool; +} diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 6dc7469998c02..1f390d7e0a925 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -354,6 +354,7 @@ pub use self::adapters::Flatten; pub use self::adapters::Copied; use self::adapters::{flatten_compat, ChainState, ZipImpl}; +pub(crate) use self::adapters::TrustedRandomAccess; mod range; mod sources; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index df32cfa337313..c8cd72371e748 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -219,7 +219,6 @@ pub mod task; pub mod alloc; // note: does not need to be public -mod iter_private; mod tuple; mod unit; diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 9f9515e6d9b7c..d062da0c247ad 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -34,7 +34,6 @@ use result::Result::{Ok, Err}; use ptr; use mem; use marker::{Copy, Send, Sync, Sized, self}; -use iter_private::TrustedRandomAccess; #[unstable(feature = "slice_internals", issue = "0", reason = "exposed from core to be reused in std; use the memchr crate")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 1ee8b7735c17d..ac92018563654 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -9,8 +9,7 @@ use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; use char; use fmt; -use iter::{Map, Cloned, FusedIterator, TrustedLen, Filter}; -use iter_private::TrustedRandomAccess; +use iter::{Map, Cloned, FusedIterator, TrustedLen, TrustedRandomAccess, Filter}; use slice::{self, SliceIndex, Split as SliceSplit}; use mem; From ebfd08312522b85a5b4085aa0a2bf6fb9b9873d7 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 19:28:40 -0500 Subject: [PATCH 0266/1064] Move Chain and ChainState to own module --- src/libcore/iter/adapters/chain.rs | 255 +++++++++++++++++++++++++++++ src/libcore/iter/adapters/mod.rs | 254 +--------------------------- 2 files changed, 258 insertions(+), 251 deletions(-) create mode 100644 src/libcore/iter/adapters/chain.rs diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs new file mode 100644 index 0000000000000..5defb857d50d0 --- /dev/null +++ b/src/libcore/iter/adapters/chain.rs @@ -0,0 +1,255 @@ +use ops::Try; +use usize; +use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen}; + +/// An iterator that strings two iterators together. +/// +/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`chain`]: trait.Iterator.html#method.chain +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Chain { + pub(in super::super) a: A, + pub(in super::super) b: B, + pub(in super::super) state: ChainState, +} + +// The iterator protocol specifies that iteration ends with the return value +// `None` from `.next()` (or `.next_back()`) and it is unspecified what +// further calls return. The chain adaptor must account for this since it uses +// two subiterators. +// +// It uses three states: +// +// - Both: `a` and `b` are remaining +// - Front: `a` remaining +// - Back: `b` remaining +// +// The fourth state (neither iterator is remaining) only occurs after Chain has +// returned None once, so we don't need to store this state. +#[derive(Clone, Debug)] +pub(in super::super) enum ChainState { + // both front and back iterator are remaining + Both, + // only front is remaining + Front, + // only back is remaining + Back, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Chain where + A: Iterator, + B: Iterator +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + match self.state { + ChainState::Both => match self.a.next() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Back; + self.b.next() + } + }, + ChainState::Front => self.a.next(), + ChainState::Back => self.b.next(), + } + } + + #[inline] + #[rustc_inherit_overflow_checks] + fn count(self) -> usize { + match self.state { + ChainState::Both => self.a.count() + self.b.count(), + ChainState::Front => self.a.count(), + ChainState::Back => self.b.count(), + } + } + + fn try_fold(&mut self, init: Acc, mut f: F) -> R where + Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Front => { + accum = self.a.try_fold(accum, &mut f)?; + if let ChainState::Both = self.state { + self.state = ChainState::Back; + } + } + _ => { } + } + if let ChainState::Back = self.state { + accum = self.b.try_fold(accum, &mut f)?; + } + Try::from_ok(accum) + } + + fn fold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Front => { + accum = self.a.fold(accum, &mut f); + } + _ => { } + } + match self.state { + ChainState::Both | ChainState::Back => { + accum = self.b.fold(accum, &mut f); + } + _ => { } + } + accum + } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option { + match self.state { + ChainState::Both | ChainState::Front => { + for x in self.a.by_ref() { + if n == 0 { + return Some(x) + } + n -= 1; + } + if let ChainState::Both = self.state { + self.state = ChainState::Back; + } + } + ChainState::Back => {} + } + if let ChainState::Back = self.state { + self.b.nth(n) + } else { + None + } + } + + #[inline] + fn find

(&mut self, mut predicate: P) -> Option where + P: FnMut(&Self::Item) -> bool, + { + match self.state { + ChainState::Both => match self.a.find(&mut predicate) { + None => { + self.state = ChainState::Back; + self.b.find(predicate) + } + v => v + }, + ChainState::Front => self.a.find(predicate), + ChainState::Back => self.b.find(predicate), + } + } + + #[inline] + fn last(self) -> Option { + match self.state { + ChainState::Both => { + // Must exhaust a before b. + let a_last = self.a.last(); + let b_last = self.b.last(); + b_last.or(a_last) + }, + ChainState::Front => self.a.last(), + ChainState::Back => self.b.last() + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = a_lower.saturating_add(b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Chain where + A: DoubleEndedIterator, + B: DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option { + match self.state { + ChainState::Both => match self.b.next_back() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Front; + self.a.next_back() + } + }, + ChainState::Front => self.a.next_back(), + ChainState::Back => self.b.next_back(), + } + } + + fn try_rfold(&mut self, init: Acc, mut f: F) -> R where + Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Back => { + accum = self.b.try_rfold(accum, &mut f)?; + if let ChainState::Both = self.state { + self.state = ChainState::Front; + } + } + _ => { } + } + if let ChainState::Front = self.state { + accum = self.a.try_rfold(accum, &mut f)?; + } + Try::from_ok(accum) + } + + fn rfold(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + match self.state { + ChainState::Both | ChainState::Back => { + accum = self.b.rfold(accum, &mut f); + } + _ => { } + } + match self.state { + ChainState::Both | ChainState::Front => { + accum = self.a.rfold(accum, &mut f); + } + _ => { } + } + accum + } + +} + +// Note: *both* must be fused to handle double-ended iterators. +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for Chain + where A: FusedIterator, + B: FusedIterator, +{} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Chain + where A: TrustedLen, B: TrustedLen, +{} + diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index f2bedf390e3bc..67c7c7a0566d6 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -6,9 +6,12 @@ use intrinsics; use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; use super::LoopState; +mod chain; mod zip; +pub use self::chain::Chain; pub use self::zip::Zip; +pub(super) use self::chain::ChainState; pub(super) use self::zip::ZipImpl; pub(crate) use self::zip::TrustedRandomAccess; @@ -457,257 +460,6 @@ impl Iterator for StepBy where I: Iterator { #[stable(feature = "iterator_step_by", since = "1.28.0")] impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} -/// An iterator that strings two iterators together. -/// -/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`chain`]: trait.Iterator.html#method.chain -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Chain { - pub(super) a: A, - pub(super) b: B, - pub(super) state: ChainState, -} - -// The iterator protocol specifies that iteration ends with the return value -// `None` from `.next()` (or `.next_back()`) and it is unspecified what -// further calls return. The chain adaptor must account for this since it uses -// two subiterators. -// -// It uses three states: -// -// - Both: `a` and `b` are remaining -// - Front: `a` remaining -// - Back: `b` remaining -// -// The fourth state (neither iterator is remaining) only occurs after Chain has -// returned None once, so we don't need to store this state. -#[derive(Clone, Debug)] -pub(super) enum ChainState { - // both front and back iterator are remaining - Both, - // only front is remaining - Front, - // only back is remaining - Back, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Chain where - A: Iterator, - B: Iterator -{ - type Item = A::Item; - - #[inline] - fn next(&mut self) -> Option { - match self.state { - ChainState::Both => match self.a.next() { - elt @ Some(..) => elt, - None => { - self.state = ChainState::Back; - self.b.next() - } - }, - ChainState::Front => self.a.next(), - ChainState::Back => self.b.next(), - } - } - - #[inline] - #[rustc_inherit_overflow_checks] - fn count(self) -> usize { - match self.state { - ChainState::Both => self.a.count() + self.b.count(), - ChainState::Front => self.a.count(), - ChainState::Back => self.b.count(), - } - } - - fn try_fold(&mut self, init: Acc, mut f: F) -> R where - Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Front => { - accum = self.a.try_fold(accum, &mut f)?; - if let ChainState::Both = self.state { - self.state = ChainState::Back; - } - } - _ => { } - } - if let ChainState::Back = self.state { - accum = self.b.try_fold(accum, &mut f)?; - } - Try::from_ok(accum) - } - - fn fold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Front => { - accum = self.a.fold(accum, &mut f); - } - _ => { } - } - match self.state { - ChainState::Both | ChainState::Back => { - accum = self.b.fold(accum, &mut f); - } - _ => { } - } - accum - } - - #[inline] - fn nth(&mut self, mut n: usize) -> Option { - match self.state { - ChainState::Both | ChainState::Front => { - for x in self.a.by_ref() { - if n == 0 { - return Some(x) - } - n -= 1; - } - if let ChainState::Both = self.state { - self.state = ChainState::Back; - } - } - ChainState::Back => {} - } - if let ChainState::Back = self.state { - self.b.nth(n) - } else { - None - } - } - - #[inline] - fn find

(&mut self, mut predicate: P) -> Option where - P: FnMut(&Self::Item) -> bool, - { - match self.state { - ChainState::Both => match self.a.find(&mut predicate) { - None => { - self.state = ChainState::Back; - self.b.find(predicate) - } - v => v - }, - ChainState::Front => self.a.find(predicate), - ChainState::Back => self.b.find(predicate), - } - } - - #[inline] - fn last(self) -> Option { - match self.state { - ChainState::Both => { - // Must exhaust a before b. - let a_last = self.a.last(); - let b_last = self.b.last(); - b_last.or(a_last) - }, - ChainState::Front => self.a.last(), - ChainState::Back => self.b.last() - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); - - let lower = a_lower.saturating_add(b_lower); - - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => x.checked_add(y), - _ => None - }; - - (lower, upper) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Chain where - A: DoubleEndedIterator, - B: DoubleEndedIterator, -{ - #[inline] - fn next_back(&mut self) -> Option { - match self.state { - ChainState::Both => match self.b.next_back() { - elt @ Some(..) => elt, - None => { - self.state = ChainState::Front; - self.a.next_back() - } - }, - ChainState::Front => self.a.next_back(), - ChainState::Back => self.b.next_back(), - } - } - - fn try_rfold(&mut self, init: Acc, mut f: F) -> R where - Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Back => { - accum = self.b.try_rfold(accum, &mut f)?; - if let ChainState::Both = self.state { - self.state = ChainState::Front; - } - } - _ => { } - } - if let ChainState::Front = self.state { - accum = self.a.try_rfold(accum, &mut f)?; - } - Try::from_ok(accum) - } - - fn rfold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, - { - let mut accum = init; - match self.state { - ChainState::Both | ChainState::Back => { - accum = self.b.rfold(accum, &mut f); - } - _ => { } - } - match self.state { - ChainState::Both | ChainState::Front => { - accum = self.a.rfold(accum, &mut f); - } - _ => { } - } - accum - } - -} - -// Note: *both* must be fused to handle double-ended iterators. -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Chain - where A: FusedIterator, - B: FusedIterator, -{} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Chain - where A: TrustedLen, B: TrustedLen, -{} - /// An iterator that maps the values of `iter` with `f`. /// /// This `struct` is created by the [`map`] method on [`Iterator`]. See its From fb974df28157f205f81d59ab3fc9cb96d78bf590 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 20:24:52 -0500 Subject: [PATCH 0267/1064] Move Flatten and FlatMap to own module --- src/libcore/iter/adapters/flatten.rs | 318 +++++++++++++++++++++++++++ src/libcore/iter/adapters/mod.rs | 316 +------------------------- 2 files changed, 321 insertions(+), 313 deletions(-) create mode 100644 src/libcore/iter/adapters/flatten.rs diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs new file mode 100644 index 0000000000000..b88e91fad3b0a --- /dev/null +++ b/src/libcore/iter/adapters/flatten.rs @@ -0,0 +1,318 @@ +use fmt; +use ops::Try; +use super::super::{Iterator, DoubleEndedIterator, FusedIterator}; +use super::Map; + +/// An iterator that maps each element to an iterator, and yields the elements +/// of the produced iterators. +/// +/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flat_map`]: trait.Iterator.html#method.flat_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct FlatMap { + pub(in super::super) inner: FlattenCompat, ::IntoIter> +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for FlatMap + where ::IntoIter: Clone +{ + fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } } +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for FlatMap + where U::IntoIter: fmt::Debug +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FlatMap").field("inner", &self.inner).finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for FlatMap + where F: FnMut(I::Item) -> U, +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { self.inner.next() } + + #[inline] + fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_fold(init, fold) + } + + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.fold(init, fold) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for FlatMap + where F: FnMut(I::Item) -> U, + U: IntoIterator, + U::IntoIter: DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option { self.inner.next_back() } + + #[inline] + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_rfold(init, fold) + } + + #[inline] + fn rfold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.rfold(init, fold) + } +} + +#[stable(feature = "fused", since = "1.26.0")] +impl FusedIterator for FlatMap + where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {} + +/// An iterator that flattens one level of nesting in an iterator of things +/// that can be turned into iterators. +/// +/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flatten`]: trait.Iterator.html#method.flatten +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[stable(feature = "iterator_flatten", since = "1.29.0")] +pub struct Flatten +where I::Item: IntoIterator { + pub(in super::super) inner: FlattenCompat::IntoIter>, +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl fmt::Debug for Flatten + where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug, + I::Item: IntoIterator, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Flatten").field("inner", &self.inner).finish() + } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl Clone for Flatten + where I: Iterator + Clone, U: Iterator + Clone, + I::Item: IntoIterator, +{ + fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl Iterator for Flatten + where I: Iterator, U: Iterator, + I::Item: IntoIterator +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { self.inner.next() } + + #[inline] + fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_fold(init, fold) + } + + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.fold(init, fold) + } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl DoubleEndedIterator for Flatten + where I: DoubleEndedIterator, U: DoubleEndedIterator, + I::Item: IntoIterator +{ + #[inline] + fn next_back(&mut self) -> Option { self.inner.next_back() } + + #[inline] + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + self.inner.try_rfold(init, fold) + } + + #[inline] + fn rfold(self, init: Acc, fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.rfold(init, fold) + } +} + +#[stable(feature = "iterator_flatten", since = "1.29.0")] +impl FusedIterator for Flatten + where I: FusedIterator, U: Iterator, + I::Item: IntoIterator {} + +/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. +pub(in super::super) fn flatten_compat(iter: I) -> FlattenCompat { + FlattenCompat { iter, frontiter: None, backiter: None } +} + +/// Real logic of both `Flatten` and `FlatMap` which simply delegate to +/// this type. +#[derive(Clone, Debug)] +pub(in super::super) struct FlattenCompat { + iter: I, + frontiter: Option, + backiter: Option, +} + +impl Iterator for FlattenCompat + where I: Iterator, U: Iterator, + I::Item: IntoIterator +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { + loop { + if let Some(ref mut inner) = self.frontiter { + if let elt@Some(_) = inner.next() { return elt } + } + match self.iter.next() { + None => return self.backiter.as_mut().and_then(|it| it.next()), + Some(inner) => self.frontiter = Some(inner.into_iter()), + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let lo = flo.saturating_add(blo); + match (self.iter.size_hint(), fhi, bhi) { + ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), + _ => (lo, None) + } + } + + #[inline] + fn try_fold(&mut self, mut init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if let Some(ref mut front) = self.frontiter { + init = front.try_fold(init, &mut fold)?; + } + self.frontiter = None; + + { + let frontiter = &mut self.frontiter; + init = self.iter.try_fold(init, |acc, x| { + let mut mid = x.into_iter(); + let r = mid.try_fold(acc, &mut fold); + *frontiter = Some(mid); + r + })?; + } + self.frontiter = None; + + if let Some(ref mut back) = self.backiter { + init = back.try_fold(init, &mut fold)?; + } + self.backiter = None; + + Try::from_ok(init) + } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.frontiter.into_iter() + .chain(self.iter.map(IntoIterator::into_iter)) + .chain(self.backiter) + .fold(init, |acc, iter| iter.fold(acc, &mut fold)) + } +} + +impl DoubleEndedIterator for FlattenCompat + where I: DoubleEndedIterator, U: DoubleEndedIterator, + I::Item: IntoIterator +{ + #[inline] + fn next_back(&mut self) -> Option { + loop { + if let Some(ref mut inner) = self.backiter { + if let elt@Some(_) = inner.next_back() { return elt } + } + match self.iter.next_back() { + None => return self.frontiter.as_mut().and_then(|it| it.next_back()), + next => self.backiter = next.map(IntoIterator::into_iter), + } + } + } + + #[inline] + fn try_rfold(&mut self, mut init: Acc, mut fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if let Some(ref mut back) = self.backiter { + init = back.try_rfold(init, &mut fold)?; + } + self.backiter = None; + + { + let backiter = &mut self.backiter; + init = self.iter.try_rfold(init, |acc, x| { + let mut mid = x.into_iter(); + let r = mid.try_rfold(acc, &mut fold); + *backiter = Some(mid); + r + })?; + } + self.backiter = None; + + if let Some(ref mut front) = self.frontiter { + init = front.try_rfold(init, &mut fold)?; + } + self.frontiter = None; + + Try::from_ok(init) + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.frontiter.into_iter() + .chain(self.iter.map(IntoIterator::into_iter)) + .chain(self.backiter) + .rfold(init, |acc, iter| iter.rfold(acc, &mut fold)) + } +} + diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 67c7c7a0566d6..a3e0696d21531 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -7,11 +7,14 @@ use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, Tru use super::LoopState; mod chain; +mod flatten; mod zip; pub use self::chain::Chain; +pub use self::flatten::{FlatMap, Flatten}; pub use self::zip::Zip; pub(super) use self::chain::ChainState; +pub(super) use self::flatten::{FlattenCompat, flatten_compat}; pub(super) use self::zip::ZipImpl; pub(crate) use self::zip::TrustedRandomAccess; @@ -1620,319 +1623,6 @@ impl Iterator for Scan where } } -/// An iterator that maps each element to an iterator, and yields the elements -/// of the produced iterators. -/// -/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`flat_map`]: trait.Iterator.html#method.flat_map -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct FlatMap { - pub(super) inner: FlattenCompat, ::IntoIter> -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Clone for FlatMap - where ::IntoIter: Clone -{ - fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } } -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for FlatMap - where U::IntoIter: fmt::Debug -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("FlatMap").field("inner", &self.inner).finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for FlatMap - where F: FnMut(I::Item) -> U, -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { self.inner.next() } - - #[inline] - fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.fold(init, fold) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for FlatMap - where F: FnMut(I::Item) -> U, - U: IntoIterator, - U::IntoIter: DoubleEndedIterator -{ - #[inline] - fn next_back(&mut self) -> Option { self.inner.next_back() } - - #[inline] - fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.rfold(init, fold) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for FlatMap - where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {} - -/// An iterator that flattens one level of nesting in an iterator of things -/// that can be turned into iterators. -/// -/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`flatten`]: trait.Iterator.html#method.flatten -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "iterator_flatten", since = "1.29.0")] -pub struct Flatten -where I::Item: IntoIterator { - pub(super) inner: FlattenCompat::IntoIter>, -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl fmt::Debug for Flatten - where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug, - I::Item: IntoIterator, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Flatten").field("inner", &self.inner).finish() - } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl Clone for Flatten - where I: Iterator + Clone, U: Iterator + Clone, - I::Item: IntoIterator, -{ - fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl Iterator for Flatten - where I: Iterator, U: Iterator, - I::Item: IntoIterator -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { self.inner.next() } - - #[inline] - fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.fold(init, fold) - } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl DoubleEndedIterator for Flatten - where I: DoubleEndedIterator, U: DoubleEndedIterator, - I::Item: IntoIterator -{ - #[inline] - fn next_back(&mut self) -> Option { self.inner.next_back() } - - #[inline] - fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - self.inner.try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.inner.rfold(init, fold) - } -} - -#[stable(feature = "iterator_flatten", since = "1.29.0")] -impl FusedIterator for Flatten - where I: FusedIterator, U: Iterator, - I::Item: IntoIterator {} - -/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. -pub(super) fn flatten_compat(iter: I) -> FlattenCompat { - FlattenCompat { iter, frontiter: None, backiter: None } -} - -/// Real logic of both `Flatten` and `FlatMap` which simply delegate to -/// this type. -#[derive(Clone, Debug)] -pub(super) struct FlattenCompat { - iter: I, - frontiter: Option, - backiter: Option, -} - -impl Iterator for FlattenCompat - where I: Iterator, U: Iterator, - I::Item: IntoIterator -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { - loop { - if let Some(ref mut inner) = self.frontiter { - if let elt@Some(_) = inner.next() { return elt } - } - match self.iter.next() { - None => return self.backiter.as_mut().and_then(|it| it.next()), - Some(inner) => self.frontiter = Some(inner.into_iter()), - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); - let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); - let lo = flo.saturating_add(blo); - match (self.iter.size_hint(), fhi, bhi) { - ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), - _ => (lo, None) - } - } - - #[inline] - fn try_fold(&mut self, mut init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if let Some(ref mut front) = self.frontiter { - init = front.try_fold(init, &mut fold)?; - } - self.frontiter = None; - - { - let frontiter = &mut self.frontiter; - init = self.iter.try_fold(init, |acc, x| { - let mut mid = x.into_iter(); - let r = mid.try_fold(acc, &mut fold); - *frontiter = Some(mid); - r - })?; - } - self.frontiter = None; - - if let Some(ref mut back) = self.backiter { - init = back.try_fold(init, &mut fold)?; - } - self.backiter = None; - - Try::from_ok(init) - } - - #[inline] - fn fold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.frontiter.into_iter() - .chain(self.iter.map(IntoIterator::into_iter)) - .chain(self.backiter) - .fold(init, |acc, iter| iter.fold(acc, &mut fold)) - } -} - -impl DoubleEndedIterator for FlattenCompat - where I: DoubleEndedIterator, U: DoubleEndedIterator, - I::Item: IntoIterator -{ - #[inline] - fn next_back(&mut self) -> Option { - loop { - if let Some(ref mut inner) = self.backiter { - if let elt@Some(_) = inner.next_back() { return elt } - } - match self.iter.next_back() { - None => return self.frontiter.as_mut().and_then(|it| it.next_back()), - next => self.backiter = next.map(IntoIterator::into_iter), - } - } - } - - #[inline] - fn try_rfold(&mut self, mut init: Acc, mut fold: Fold) -> R where - Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try - { - if let Some(ref mut back) = self.backiter { - init = back.try_rfold(init, &mut fold)?; - } - self.backiter = None; - - { - let backiter = &mut self.backiter; - init = self.iter.try_rfold(init, |acc, x| { - let mut mid = x.into_iter(); - let r = mid.try_rfold(acc, &mut fold); - *backiter = Some(mid); - r - })?; - } - self.backiter = None; - - if let Some(ref mut front) = self.frontiter { - init = front.try_rfold(init, &mut fold)?; - } - self.frontiter = None; - - Try::from_ok(init) - } - - #[inline] - fn rfold(self, init: Acc, mut fold: Fold) -> Acc - where Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.frontiter.into_iter() - .chain(self.iter.map(IntoIterator::into_iter)) - .chain(self.backiter) - .rfold(init, |acc, iter| iter.rfold(acc, &mut fold)) - } -} - /// An iterator that yields `None` forever after the underlying iterator /// yields `None` once. /// From 7e4177311adbeb7a1fa64c1f4e1f6610cf96973d Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 19:31:00 -0500 Subject: [PATCH 0268/1064] Don't expose ChainState to Iterator --- src/libcore/iter/adapters/chain.rs | 13 +++++++++---- src/libcore/iter/adapters/mod.rs | 1 - src/libcore/iter/mod.rs | 2 +- src/libcore/iter/traits/iterator.rs | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs index 5defb857d50d0..573b096fb463e 100644 --- a/src/libcore/iter/adapters/chain.rs +++ b/src/libcore/iter/adapters/chain.rs @@ -13,9 +13,14 @@ use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen}; #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chain { - pub(in super::super) a: A, - pub(in super::super) b: B, - pub(in super::super) state: ChainState, + a: A, + b: B, + state: ChainState, +} +impl Chain { + pub(in super::super) fn new(a: A, b: B) -> Chain { + Chain { a, b, state: ChainState::Both } + } } // The iterator protocol specifies that iteration ends with the return value @@ -32,7 +37,7 @@ pub struct Chain { // The fourth state (neither iterator is remaining) only occurs after Chain has // returned None once, so we don't need to store this state. #[derive(Clone, Debug)] -pub(in super::super) enum ChainState { +enum ChainState { // both front and back iterator are remaining Both, // only front is remaining diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index a3e0696d21531..355f86f31ce09 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -13,7 +13,6 @@ mod zip; pub use self::chain::Chain; pub use self::flatten::{FlatMap, Flatten}; pub use self::zip::Zip; -pub(super) use self::chain::ChainState; pub(super) use self::flatten::{FlattenCompat, flatten_compat}; pub(super) use self::zip::ZipImpl; pub(crate) use self::zip::TrustedRandomAccess; diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 1f390d7e0a925..209cf6d9451da 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -353,7 +353,7 @@ pub use self::adapters::Flatten; #[unstable(feature = "iter_copied", issue = "57127")] pub use self::adapters::Copied; -use self::adapters::{flatten_compat, ChainState, ZipImpl}; +use self::adapters::{flatten_compat, ZipImpl}; pub(crate) use self::adapters::TrustedRandomAccess; mod range; diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 0ce817d02a52c..bb4549dc9031f 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -6,7 +6,7 @@ use super::super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, F use super::super::{Flatten, FlatMap, flatten_compat}; use super::super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; use super::super::{Zip, Sum, Product}; -use super::super::{ChainState, FromIterator, ZipImpl}; +use super::super::{FromIterator, ZipImpl}; fn _assert_is_object_safe(_: &dyn Iterator) {} @@ -425,7 +425,7 @@ pub trait Iterator { fn chain(self, other: U) -> Chain where Self: Sized, U: IntoIterator, { - Chain{a: self, b: other.into_iter(), state: ChainState::Both} + Chain::new(self, other.into_iter()) } /// 'Zips up' two iterators into a single iterator of pairs. From 53b400c30cfb73fc622186086e7315c751f5cb91 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 20:35:23 -0500 Subject: [PATCH 0269/1064] Don't expose FlattenCompat to Iterator --- src/libcore/iter/adapters/flatten.rs | 28 ++++++++++++++++++++-------- src/libcore/iter/adapters/mod.rs | 1 - src/libcore/iter/mod.rs | 2 +- src/libcore/iter/traits/iterator.rs | 6 +++--- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs index b88e91fad3b0a..40f6865d38bcf 100644 --- a/src/libcore/iter/adapters/flatten.rs +++ b/src/libcore/iter/adapters/flatten.rs @@ -14,7 +14,12 @@ use super::Map; #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct FlatMap { - pub(in super::super) inner: FlattenCompat, ::IntoIter> + inner: FlattenCompat, ::IntoIter> +} +impl U> FlatMap { + pub(in super::super) fn new(iter: I, f: F) -> FlatMap { + FlatMap { inner: FlattenCompat::new(iter.map(f)) } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -100,7 +105,13 @@ impl FusedIterator for FlatMap #[stable(feature = "iterator_flatten", since = "1.29.0")] pub struct Flatten where I::Item: IntoIterator { - pub(in super::super) inner: FlattenCompat::IntoIter>, + inner: FlattenCompat::IntoIter>, +} +impl Flatten +where I::Item: IntoIterator { + pub(in super::super) fn new(iter: I) -> Flatten { + Flatten { inner: FlattenCompat::new(iter) } + } } #[stable(feature = "iterator_flatten", since = "1.29.0")] @@ -177,19 +188,20 @@ impl FusedIterator for Flatten where I: FusedIterator, U: Iterator, I::Item: IntoIterator {} -/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. -pub(in super::super) fn flatten_compat(iter: I) -> FlattenCompat { - FlattenCompat { iter, frontiter: None, backiter: None } -} - /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. #[derive(Clone, Debug)] -pub(in super::super) struct FlattenCompat { +struct FlattenCompat { iter: I, frontiter: Option, backiter: Option, } +impl FlattenCompat { + /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. + fn new(iter: I) -> FlattenCompat { + FlattenCompat { iter, frontiter: None, backiter: None } + } +} impl Iterator for FlattenCompat where I: Iterator, U: Iterator, diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 355f86f31ce09..869329a007f61 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -13,7 +13,6 @@ mod zip; pub use self::chain::Chain; pub use self::flatten::{FlatMap, Flatten}; pub use self::zip::Zip; -pub(super) use self::flatten::{FlattenCompat, flatten_compat}; pub(super) use self::zip::ZipImpl; pub(crate) use self::zip::TrustedRandomAccess; diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 209cf6d9451da..024b9ff9c4f82 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -353,7 +353,7 @@ pub use self::adapters::Flatten; #[unstable(feature = "iter_copied", issue = "57127")] pub use self::adapters::Copied; -use self::adapters::{flatten_compat, ZipImpl}; +use self::adapters::ZipImpl; pub(crate) use self::adapters::TrustedRandomAccess; mod range; diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index bb4549dc9031f..2a3079838b035 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -3,7 +3,7 @@ use ops::Try; use super::super::LoopState; use super::super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse}; -use super::super::{Flatten, FlatMap, flatten_compat}; +use super::super::{Flatten, FlatMap}; use super::super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; use super::super::{Zip, Sum, Product}; use super::super::{FromIterator, ZipImpl}; @@ -1098,7 +1098,7 @@ pub trait Iterator { fn flat_map(self, f: F) -> FlatMap where Self: Sized, U: IntoIterator, F: FnMut(Self::Item) -> U, { - FlatMap { inner: flatten_compat(self.map(f)) } + FlatMap::new(self, f) } /// Creates an iterator that flattens nested structure. @@ -1166,7 +1166,7 @@ pub trait Iterator { #[stable(feature = "iterator_flatten", since = "1.29.0")] fn flatten(self) -> Flatten where Self: Sized, Self::Item: IntoIterator { - Flatten { inner: flatten_compat(self) } + Flatten::new(self) } /// Creates an iterator which ends after the first [`None`]. From 52b36e28d8e7dab1897c450f5c658885117d887d Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 21:10:53 -0500 Subject: [PATCH 0270/1064] Move super_nth out of ZipImpl --- src/libcore/iter/adapters/zip.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs index 6a0a7d8b12cdf..a27af53f39c9d 100644 --- a/src/libcore/iter/adapters/zip.rs +++ b/src/libcore/iter/adapters/zip.rs @@ -18,6 +18,15 @@ pub struct Zip { index: usize, len: usize, } +impl Zip { + fn super_nth(&mut self, mut n: usize) -> Option<(A::Item, B::Item)> { + while let Some(x) = Iterator::next(self) { + if n == 0 { return Some(x) } + n -= 1; + } + None + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Zip where A: Iterator, B: Iterator @@ -59,13 +68,6 @@ pub(in super::super) trait ZipImpl { fn next(&mut self) -> Option; fn size_hint(&self) -> (usize, Option); fn nth(&mut self, n: usize) -> Option; - fn super_nth(&mut self, mut n: usize) -> Option { - while let Some(x) = self.next() { - if n == 0 { return Some(x) } - n -= 1; - } - None - } fn next_back(&mut self) -> Option where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator; From 5971ccc08d8bfadeb0614c4555ffd32c51066cdc Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 21:19:24 -0500 Subject: [PATCH 0271/1064] Don't expose ZipImpl to Iterator --- src/libcore/iter/adapters/mod.rs | 1 - src/libcore/iter/adapters/zip.rs | 5 ++++- src/libcore/iter/mod.rs | 1 - src/libcore/iter/traits/iterator.rs | 3 +-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 869329a007f61..1368775c6bfae 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -13,7 +13,6 @@ mod zip; pub use self::chain::Chain; pub use self::flatten::{FlatMap, Flatten}; pub use self::zip::Zip; -pub(super) use self::zip::ZipImpl; pub(crate) use self::zip::TrustedRandomAccess; /// A double-ended iterator with the direction inverted. diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs index a27af53f39c9d..3548d0e282602 100644 --- a/src/libcore/iter/adapters/zip.rs +++ b/src/libcore/iter/adapters/zip.rs @@ -19,6 +19,9 @@ pub struct Zip { len: usize, } impl Zip { + pub(in super::super) fn new(a: A, b: B) -> Zip { + ZipImpl::new(a, b) + } fn super_nth(&mut self, mut n: usize) -> Option<(A::Item, B::Item)> { while let Some(x) = Iterator::next(self) { if n == 0 { return Some(x) } @@ -62,7 +65,7 @@ impl DoubleEndedIterator for Zip where // Zip specialization trait #[doc(hidden)] -pub(in super::super) trait ZipImpl { +trait ZipImpl { type Item; fn new(a: A, b: B) -> Self; fn next(&mut self) -> Option; diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 024b9ff9c4f82..b6bb5f01b2d29 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -353,7 +353,6 @@ pub use self::adapters::Flatten; #[unstable(feature = "iter_copied", issue = "57127")] pub use self::adapters::Copied; -use self::adapters::ZipImpl; pub(crate) use self::adapters::TrustedRandomAccess; mod range; diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 2a3079838b035..62029b169525e 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -5,8 +5,7 @@ use super::super::LoopState; use super::super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse}; use super::super::{Flatten, FlatMap}; use super::super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; -use super::super::{Zip, Sum, Product}; -use super::super::{FromIterator, ZipImpl}; +use super::super::{Zip, Sum, Product, FromIterator}; fn _assert_is_object_safe(_: &dyn Iterator) {} From 4c28b2c4b171be143d2a5ca7c0c389e9d3d7f26a Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 21:28:06 -0500 Subject: [PATCH 0272/1064] Move nontrivial constructors to inherent methods --- src/libcore/iter/adapters/mod.rs | 70 ++++++++++++++++++++++------- src/libcore/iter/traits/iterator.rs | 15 +++---- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 1368775c6bfae..8bd064021e6c7 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -339,8 +339,13 @@ unsafe impl<'a, I, T: 'a> TrustedLen for Cloned #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Cycle { - pub(super) orig: I, - pub(super) iter: I, + orig: I, + iter: I, +} +impl Cycle { + pub(super) fn new(iter: I) -> Cycle { + Cycle { orig: iter.clone(), iter } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -380,9 +385,15 @@ impl FusedIterator for Cycle where I: Clone + Iterator {} #[stable(feature = "iterator_step_by", since = "1.28.0")] #[derive(Clone, Debug)] pub struct StepBy { - pub(super) iter: I, - pub(super) step: usize, - pub(super) first_take: bool, + iter: I, + step: usize, + first_take: bool, +} +impl StepBy { + pub(super) fn new(iter: I, step: usize) -> StepBy { + assert!(step != 0); + StepBy { iter, step: step - 1, first_take: true } + } } #[stable(feature = "iterator_step_by", since = "1.28.0")] @@ -867,8 +878,13 @@ impl FusedIterator for FilterMap #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Enumerate { - pub(super) iter: I, - pub(super) count: usize, + iter: I, + count: usize, +} +impl Enumerate { + pub(super) fn new(iter: I) -> Enumerate { + Enumerate { iter, count: 0 } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1028,9 +1044,14 @@ unsafe impl TrustedLen for Enumerate #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Peekable { - pub(super) iter: I, + iter: I, /// Remember a peeked value, even if it was None. - pub(super) peeked: Option>, + peeked: Option>, +} +impl Peekable { + pub(super) fn new(iter: I) -> Peekable { + Peekable { iter, peeked: None } + } } // Peekable must remember if a None has been seen in the `.peek()` method. @@ -1180,9 +1201,14 @@ impl Peekable { #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct SkipWhile { - pub(super) iter: I, - pub(super) flag: bool, - pub(super) predicate: P, + iter: I, + flag: bool, + predicate: P, +} +impl SkipWhile { + pub(super) fn new(iter: I, predicate: P) -> SkipWhile { + SkipWhile { iter, flag: false, predicate } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -1263,9 +1289,14 @@ impl FusedIterator for SkipWhile #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct TakeWhile { - pub(super) iter: I, - pub(super) flag: bool, - pub(super) predicate: P, + iter: I, + flag: bool, + predicate: P, +} +impl TakeWhile { + pub(super) fn new(iter: I, predicate: P) -> TakeWhile { + TakeWhile { iter, flag: false, predicate } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -1632,8 +1663,13 @@ impl Iterator for Scan where #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Fuse { - pub(super) iter: I, - pub(super) done: bool + iter: I, + done: bool +} +impl Fuse { + pub(super) fn new(iter: I) -> Fuse { + Fuse { iter, done: false } + } } #[stable(feature = "fused", since = "1.26.0")] diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 62029b169525e..44e29fd813a9d 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -366,8 +366,7 @@ pub trait Iterator { #[inline] #[stable(feature = "iterator_step_by", since = "1.28.0")] fn step_by(self, step: usize) -> StepBy where Self: Sized { - assert!(step != 0); - StepBy{iter: self, step: step - 1, first_take: true} + StepBy::new(self, step) } /// Takes two iterators and creates a new iterator over both in sequence. @@ -771,7 +770,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn enumerate(self) -> Enumerate where Self: Sized { - Enumerate { iter: self, count: 0 } + Enumerate::new(self) } /// Creates an iterator which can use `peek` to look at the next element of @@ -817,7 +816,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn peekable(self) -> Peekable where Self: Sized { - Peekable{iter: self, peeked: None} + Peekable::new(self) } /// Creates an iterator that [`skip`]s elements based on a predicate. @@ -880,7 +879,7 @@ pub trait Iterator { fn skip_while

(self, predicate: P) -> SkipWhile where Self: Sized, P: FnMut(&Self::Item) -> bool, { - SkipWhile { iter: self, flag: false, predicate } + SkipWhile::new(self, predicate) } /// Creates an iterator that yields elements based on a predicate. @@ -960,7 +959,7 @@ pub trait Iterator { fn take_while

(self, predicate: P) -> TakeWhile where Self: Sized, P: FnMut(&Self::Item) -> bool, { - TakeWhile { iter: self, flag: false, predicate } + TakeWhile::new(self, predicate) } /// Creates an iterator that skips the first `n` elements. @@ -1225,7 +1224,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn fuse(self) -> Fuse where Self: Sized { - Fuse{iter: self, done: false} + Fuse::new(self) } /// Do something with each element of an iterator, passing the value on. @@ -2310,7 +2309,7 @@ pub trait Iterator { #[stable(feature = "rust1", since = "1.0.0")] #[inline] fn cycle(self) -> Cycle where Self: Sized + Clone { - Cycle{orig: self.clone(), iter: self} + Cycle::new(self) } /// Sums the elements of an iterator. From 02bda7a0617fd0d0d3ac11dffb17ffba8c0f0601 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Mon, 17 Dec 2018 21:39:07 -0500 Subject: [PATCH 0273/1064] Move trivial constructors to inherent methods --- src/libcore/iter/adapters/mod.rs | 82 +++++++++++++++++++++++------ src/libcore/iter/traits/iterator.rs | 20 +++---- 2 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 8bd064021e6c7..f8d6bedeace25 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -26,7 +26,12 @@ pub(crate) use self::zip::TrustedRandomAccess; #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Rev { - pub(super) iter: T + iter: T +} +impl Rev { + pub(super) fn new(iter: T) -> Rev { + Rev { iter } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -127,7 +132,12 @@ unsafe impl TrustedLen for Rev #[must_use = "iterators are lazy and do nothing unless consumed"] #[derive(Clone, Debug)] pub struct Copied { - pub(super) it: I, + it: I, +} +impl Copied { + pub(super) fn new(it: I) -> Copied { + Copied { it } + } } #[unstable(feature = "iter_copied", issue = "57127")] @@ -227,7 +237,12 @@ unsafe impl<'a, I, T: 'a> TrustedLen for Copied #[must_use = "iterators are lazy and do nothing unless consumed"] #[derive(Clone, Debug)] pub struct Cloned { - pub(super) it: I, + it: I, +} +impl Cloned { + pub(super) fn new(it: I) -> Cloned { + Cloned { it } + } } #[stable(feature = "iter_cloned", since = "1.1.0")] @@ -525,8 +540,13 @@ impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Map { - pub(super) iter: I, - pub(super) f: F, + iter: I, + f: F, +} +impl Map { + pub(super) fn new(iter: I, f: F) -> Map { + Map { iter, f } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -636,8 +656,13 @@ unsafe impl TrustedRandomAccess for Map #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Filter { - pub(super) iter: I, - pub(super) predicate: P, + iter: I, + predicate: P, +} +impl Filter { + pub(super) fn new(iter: I, predicate: P) -> Filter { + Filter { iter, predicate } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -768,8 +793,13 @@ impl FusedIterator for Filter #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct FilterMap { - pub(super) iter: I, - pub(super) f: F, + iter: I, + f: F, +} +impl FilterMap { + pub(super) fn new(iter: I, f: F) -> FilterMap { + FilterMap { iter, f } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -1377,8 +1407,13 @@ impl FusedIterator for TakeWhile #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Skip { - pub(super) iter: I, - pub(super) n: usize + iter: I, + n: usize +} +impl Skip { + pub(super) fn new(iter: I, n: usize) -> Skip { + Skip { iter, n } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1518,6 +1553,11 @@ pub struct Take { pub(super) iter: I, pub(super) n: usize } +impl Take { + pub(super) fn new(iter: I, n: usize) -> Take { + Take { iter, n } + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Take where I: Iterator{ @@ -1603,9 +1643,14 @@ unsafe impl TrustedLen for Take {} #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Scan { - pub(super) iter: I, - pub(super) f: F, - pub(super) state: St, + iter: I, + f: F, + state: St, +} +impl Scan { + pub(super) fn new(iter: I, state: St, f: F) -> Scan { + Scan { iter, state, f } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -1893,8 +1938,13 @@ impl ExactSizeIterator for Fuse where I: ExactSizeIterator { #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Inspect { - pub(super) iter: I, - pub(super) f: F, + iter: I, + f: F, +} +impl Inspect { + pub(super) fn new(iter: I, f: F) -> Inspect { + Inspect { iter, f } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 44e29fd813a9d..9dfa83f473baf 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -558,7 +558,7 @@ pub trait Iterator { fn map(self, f: F) -> Map where Self: Sized, F: FnMut(Self::Item) -> B, { - Map { iter: self, f } + Map::new(self, f) } /// Calls a closure on each element of an iterator. @@ -669,7 +669,7 @@ pub trait Iterator { fn filter

(self, predicate: P) -> Filter where Self: Sized, P: FnMut(&Self::Item) -> bool, { - Filter {iter: self, predicate } + Filter::new(self, predicate) } /// Creates an iterator that both filters and maps. @@ -726,7 +726,7 @@ pub trait Iterator { fn filter_map(self, f: F) -> FilterMap where Self: Sized, F: FnMut(Self::Item) -> Option, { - FilterMap { iter: self, f } + FilterMap::new(self, f) } /// Creates an iterator which gives the current iteration count as well as @@ -981,7 +981,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn skip(self, n: usize) -> Skip where Self: Sized { - Skip { iter: self, n } + Skip::new(self, n) } /// Creates an iterator that yields its first `n` elements. @@ -1013,7 +1013,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take(self, n: usize) -> Take where Self: Sized, { - Take { iter: self, n } + Take::new(self, n) } /// An iterator adaptor similar to [`fold`] that holds internal state and @@ -1058,7 +1058,7 @@ pub trait Iterator { fn scan(self, initial_state: St, f: F) -> Scan where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option, { - Scan { iter: self, f, state: initial_state } + Scan::new(self, initial_state, f) } /// Creates an iterator that works like map, but flattens nested structure. @@ -1307,7 +1307,7 @@ pub trait Iterator { fn inspect(self, f: F) -> Inspect where Self: Sized, F: FnMut(&Self::Item), { - Inspect { iter: self, f } + Inspect::new(self, f) } /// Borrows an iterator, rather than consuming it. @@ -2181,7 +2181,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn rev(self) -> Rev where Self: Sized + DoubleEndedIterator { - Rev{iter: self} + Rev::new(self) } /// Converts an iterator of pairs into a pair of containers. @@ -2249,7 +2249,7 @@ pub trait Iterator { fn copied<'a, T: 'a>(self) -> Copied where Self: Sized + Iterator, T: Copy { - Copied { it: self } + Copied::new(self) } /// Creates an iterator which [`clone`]s all of its elements. @@ -2278,7 +2278,7 @@ pub trait Iterator { fn cloned<'a, T: 'a>(self) -> Cloned where Self: Sized + Iterator, T: Clone { - Cloned { it: self } + Cloned::new(self) } /// Repeats an iterator endlessly. From 0c54d2d12ee21f53657e76bf7d2ace9445520ff5 Mon Sep 17 00:00:00 2001 From: Johnathan Van Why Date: Tue, 22 Jan 2019 15:02:57 -0800 Subject: [PATCH 0274/1064] Mention that core::intrinsics::transmute is available at core::mem::transmute. In #[no_std] environments, std::mem::transmute is unavailable. Searching for transmute in libcore only pulls up core::intrinsics::transmute, which is behind the (unstable) core_intrinsics feature flag. Users wishing to use transmute in #[no_std] environments typically should use core::mem::transmute instead, as it is stable. This documentation makes core::mem::transmute discoverable. --- src/libcore/intrinsics.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index db19baf7a2c64..74c0eae939cb4 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -729,6 +729,10 @@ extern "rust-intrinsic" { /// cause [undefined behavior][ub] with this function. `transmute` should be /// the absolute last resort. /// + /// `transmute` is re-exported by [core::mem](../mem/index.html) as + /// `core::mem::transmute`, which may be used without the `core_intrinsics` + /// feature flag. + /// /// The [nomicon](../../nomicon/transmutes.html) has additional /// documentation. /// From e4fedf4be4c0cf735787bc81ff5ea0d7086fe6cd Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 22 Jan 2019 19:54:30 -0500 Subject: [PATCH 0275/1064] Don't try to clean predicates involving ReErased There's nothing to render when we have a bound involving ReErased (either a type or region outliving it), so we don't attempt to generate a clean WherePredicate Fixes #57806 --- src/librustdoc/clean/auto_trait.rs | 4 +++ src/librustdoc/clean/mod.rs | 48 ++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 27ca205720d6a..b99181c0d4f9e 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -574,6 +574,10 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let mut ty_to_fn: FxHashMap, Option)> = Default::default(); for (orig_p, p) in clean_where_predicates { + if p.is_none() { + continue; + } + let p = p.unwrap(); match p { WherePredicate::BoundPredicate { ty, mut bounds } => { // Writing a projection trait bound of the form diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6eea95b61c990..a7ce0520b6d3d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1271,7 +1271,10 @@ impl Clean> for ty::RegionKind { ty::RePlaceholder(..) | ty::ReEmpty | ty::ReClosureBound(_) | - ty::ReErased => None + ty::ReErased => { + debug!("Cannot clean region {:?}", self); + None + } } } } @@ -1310,16 +1313,16 @@ impl Clean for hir::WherePredicate { } } -impl<'a> Clean for ty::Predicate<'a> { - fn clean(&self, cx: &DocContext) -> WherePredicate { +impl<'a> Clean> for ty::Predicate<'a> { + fn clean(&self, cx: &DocContext) -> Option { use rustc::ty::Predicate; match *self { - Predicate::Trait(ref pred) => pred.clean(cx), - Predicate::Subtype(ref pred) => pred.clean(cx), + Predicate::Trait(ref pred) => Some(pred.clean(cx)), + Predicate::Subtype(ref pred) => Some(pred.clean(cx)), Predicate::RegionOutlives(ref pred) => pred.clean(cx), Predicate::TypeOutlives(ref pred) => pred.clean(cx), - Predicate::Projection(ref pred) => pred.clean(cx), + Predicate::Projection(ref pred) => Some(pred.clean(cx)), Predicate::WellFormed(..) | Predicate::ObjectSafe(..) | @@ -1345,24 +1348,39 @@ impl<'tcx> Clean for ty::SubtypePredicate<'tcx> { } } -impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &DocContext) -> WherePredicate { +impl<'tcx> Clean> for + ty::OutlivesPredicate,ty::Region<'tcx>> { + + fn clean(&self, cx: &DocContext) -> Option { let ty::OutlivesPredicate(ref a, ref b) = *self; - WherePredicate::RegionPredicate { + + match (a, b) { + (ty::ReEmpty, ty::ReEmpty) => { + return None; + }, + _ => {} + } + + Some(WherePredicate::RegionPredicate { lifetime: a.clean(cx).expect("failed to clean lifetime"), bounds: vec![GenericBound::Outlives(b.clean(cx).expect("failed to clean bounds"))] - } + }) } } -impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &DocContext) -> WherePredicate { +impl<'tcx> Clean> for ty::OutlivesPredicate, ty::Region<'tcx>> { + fn clean(&self, cx: &DocContext) -> Option { let ty::OutlivesPredicate(ref ty, ref lt) = *self; - WherePredicate::BoundPredicate { + match lt { + ty::ReEmpty => return None, + _ => {} + } + + Some(WherePredicate::BoundPredicate { ty: ty.clean(cx), bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))] - } + }) } } @@ -1579,7 +1597,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, }).collect::>(); let mut where_predicates = preds.predicates.iter() - .map(|(p, _)| p.clean(cx)) + .flat_map(|(p, _)| p.clean(cx)) .collect::>(); // Type parameters and have a Sized bound by default unless removed with From 55dea0edecc71a88ca11adb0629c0434e5d0f14b Mon Sep 17 00:00:00 2001 From: Alex Berghage Date: Sun, 6 Jan 2019 11:53:47 -0700 Subject: [PATCH 0276/1064] Simplify units in Duration/Instant math on Windows Right now we do unit conversions between PerfCounter measurements and nanoseconds for every add/sub we do between Durations and Instants on Windows machines. This leads to goofy behavior, like this snippet failing: ``` let now = Instant::now(); let offset = Duration::from_millis(5); assert_eq!((now + offset) - now, (now - now) + offset); ``` with precision problems like this: ``` thread 'main' panicked at 'assertion failed: `(left == right)` left: `4.999914ms`, right: `5ms`', src\main.rs:6:5 ``` To fix it, this changeset does the unit conversion once, when we measure the clock, and all the subsequent math in u64 nanoseconds. It also adds an exact associativity test to the `sys/time.rs` test suite to make sure we don't regress on this in the future. --- src/libstd/sys/windows/time.rs | 120 +++++++++++++++++++++------------ src/libstd/time.rs | 9 +++ 2 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index 8e8e9195cf471..b0cdd0a7f3b2c 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -1,10 +1,7 @@ use cmp::Ordering; use fmt; use mem; -use sync::Once; use sys::c; -use sys::cvt; -use sys_common::mul_div_u64; use time::Duration; use convert::TryInto; use core::hash::{Hash, Hasher}; @@ -14,7 +11,7 @@ const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / 100; #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] pub struct Instant { - t: c::LARGE_INTEGER, + t: u64, } #[derive(Copy, Clone)] @@ -33,11 +30,12 @@ pub const UNIX_EPOCH: SystemTime = SystemTime { impl Instant { pub fn now() -> Instant { - let mut t = Instant { t: 0 }; - cvt(unsafe { - c::QueryPerformanceCounter(&mut t.t) - }).unwrap(); - t + // High precision timing on windows operates in "Performance Counter" + // units, as returned by the WINAPI QueryPerformanceCounter function. + // These relate to seconds by a factor of QueryPerformanceFrequency. + // In order to keep unit conversions out of normal interval math, we + // measure in QPC units and immediately convert to nanoseconds. + perf_counter::PerformanceCounterInstant::now().into() } pub fn actually_monotonic() -> bool { @@ -49,43 +47,36 @@ impl Instant { } pub fn sub_instant(&self, other: &Instant) -> Duration { - // Values which are +- 1 need to be considered as basically the same - // units in time due to various measurement oddities, according to - // Windows [1] - // - // [1]: - // https://msdn.microsoft.com/en-us/library/windows/desktop - // /dn553408%28v=vs.85%29.aspx#guidance - if other.t > self.t && other.t - self.t == 1 { + // On windows there's a threshold below which we consider two timestamps + // equivalent due to measurement error. For more details + doc link, + // check the docs on epsilon_nanos. + let epsilon_ns = + perf_counter::PerformanceCounterInstant::epsilon_nanos() as u64; + if other.t > self.t && other.t - self.t <= epsilon_ns { return Duration::new(0, 0) } - let diff = (self.t as u64).checked_sub(other.t as u64) - .expect("specified instant was later than \ - self"); - let nanos = mul_div_u64(diff, NANOS_PER_SEC, frequency() as u64); - Duration::new(nanos / NANOS_PER_SEC, (nanos % NANOS_PER_SEC) as u32) + let diff = (self.t).checked_sub(other.t) + .expect("specified instant was later than self"); + Duration::new(diff / NANOS_PER_SEC, (diff % NANOS_PER_SEC) as u32) } pub fn checked_add_duration(&self, other: &Duration) -> Option { - let freq = frequency() as u64; - let t = other.as_secs() - .checked_mul(freq)? - .checked_add(mul_div_u64(other.subsec_nanos() as u64, freq, NANOS_PER_SEC))? + let sum = other.as_secs() + .checked_mul(NANOS_PER_SEC)? + .checked_add(other.subsec_nanos() as u64)? .checked_add(self.t as u64)?; Some(Instant { - t: t as c::LARGE_INTEGER, + t: sum, }) } pub fn checked_sub_duration(&self, other: &Duration) -> Option { - let freq = frequency() as u64; - let t = other.as_secs().checked_mul(freq).and_then(|i| { - (self.t as u64).checked_sub(i) - }).and_then(|i| { - i.checked_sub(mul_div_u64(other.subsec_nanos() as u64, freq, NANOS_PER_SEC)) - })?; + let other_ns = other.as_secs() + .checked_mul(NANOS_PER_SEC)? + .checked_add(other.subsec_nanos() as u64)?; + let difference = self.t.checked_sub(other_ns)?; Some(Instant { - t: t as c::LARGE_INTEGER, + t: difference, }) } } @@ -186,14 +177,59 @@ fn intervals2dur(intervals: u64) -> Duration { ((intervals % INTERVALS_PER_SEC) * 100) as u32) } -fn frequency() -> c::LARGE_INTEGER { - static mut FREQUENCY: c::LARGE_INTEGER = 0; - static ONCE: Once = Once::new(); +mod perf_counter { + use super::{NANOS_PER_SEC}; + use sync::Once; + use sys_common::mul_div_u64; + use sys::c; + use sys::cvt; + + pub struct PerformanceCounterInstant { + ts: c::LARGE_INTEGER + } + impl PerformanceCounterInstant { + pub fn now() -> Self { + Self { + ts: query() + } + } - unsafe { - ONCE.call_once(|| { - cvt(c::QueryPerformanceFrequency(&mut FREQUENCY)).unwrap(); - }); - FREQUENCY + // Per microsoft docs, the margin of error for cross-thread time comparisons + // using QueryPerformanceCounter is 1 "tick" -- defined as 1/frequency(). + // Reference: https://docs.microsoft.com/en-us/windows/desktop/SysInfo + // /acquiring-high-resolution-time-stamps + pub fn epsilon_nanos() -> u32 { + let epsilon = NANOS_PER_SEC / (frequency() as u64); + // As noted elsewhere, subsecond nanos always fit in a u32 + epsilon as u32 + } + } + impl From for super::Instant { + fn from(other: PerformanceCounterInstant) -> Self { + let freq = frequency() as u64; + Self { + t: mul_div_u64(other.ts as u64, NANOS_PER_SEC, freq) + } + } + } + + fn frequency() -> c::LARGE_INTEGER { + static mut FREQUENCY: c::LARGE_INTEGER = 0; + static ONCE: Once = Once::new(); + + unsafe { + ONCE.call_once(|| { + cvt(c::QueryPerformanceFrequency(&mut FREQUENCY)).unwrap(); + }); + FREQUENCY + } + } + + fn query() -> c::LARGE_INTEGER { + let mut qpc_value: c::LARGE_INTEGER = 0; + cvt(unsafe { + c::QueryPerformanceCounter(&mut qpc_value) + }).unwrap(); + qpc_value } } diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 507ea395c6c6c..23924559fcc24 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -610,6 +610,15 @@ mod tests { assert_eq!(a + year, a.checked_add(year).unwrap()); } + #[test] + fn instant_math_is_associative() { + let now = Instant::now(); + let offset = Duration::from_millis(5); + // Changing the order of instant math shouldn't change the results, + // especially when the expression reduces to X + identity. + assert_eq!((now + offset) - now, (now - now) + offset); + } + #[test] #[should_panic] fn instant_duration_panic() { From 0f566ec5751aebaf2261c267f1ff172ec43ab2e0 Mon Sep 17 00:00:00 2001 From: Alex Berghage Date: Sun, 20 Jan 2019 18:05:09 -0700 Subject: [PATCH 0277/1064] Move Instant backing type to Duration Per review comments, this commit switches out the backing type for Instant on windows to a Duration. Tests all pass, and the code's a lot simpler (plus it should be portable now, with the exception of the QueryPerformanceWhatever functions). --- src/libstd/sys/windows/time.rs | 36 +++++++++++++--------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index b0cdd0a7f3b2c..113affb737edd 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -11,7 +11,7 @@ const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / 100; #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] pub struct Instant { - t: u64, + t: Duration, } #[derive(Copy, Clone)] @@ -49,34 +49,25 @@ impl Instant { pub fn sub_instant(&self, other: &Instant) -> Duration { // On windows there's a threshold below which we consider two timestamps // equivalent due to measurement error. For more details + doc link, - // check the docs on epsilon_nanos. - let epsilon_ns = - perf_counter::PerformanceCounterInstant::epsilon_nanos() as u64; - if other.t > self.t && other.t - self.t <= epsilon_ns { + // check the docs on epsilon. + let epsilon = + perf_counter::PerformanceCounterInstant::epsilon(); + if other.t > self.t && other.t - self.t <= epsilon { return Duration::new(0, 0) } - let diff = (self.t).checked_sub(other.t) - .expect("specified instant was later than self"); - Duration::new(diff / NANOS_PER_SEC, (diff % NANOS_PER_SEC) as u32) + self.t.checked_sub(other.t) + .expect("specified instant was later than self") } pub fn checked_add_duration(&self, other: &Duration) -> Option { - let sum = other.as_secs() - .checked_mul(NANOS_PER_SEC)? - .checked_add(other.subsec_nanos() as u64)? - .checked_add(self.t as u64)?; Some(Instant { - t: sum, + t: self.t.checked_add(*other)? }) } pub fn checked_sub_duration(&self, other: &Duration) -> Option { - let other_ns = other.as_secs() - .checked_mul(NANOS_PER_SEC)? - .checked_add(other.subsec_nanos() as u64)?; - let difference = self.t.checked_sub(other_ns)?; Some(Instant { - t: difference, + t: self.t.checked_sub(*other)? }) } } @@ -183,6 +174,7 @@ mod perf_counter { use sys_common::mul_div_u64; use sys::c; use sys::cvt; + use time::Duration; pub struct PerformanceCounterInstant { ts: c::LARGE_INTEGER @@ -198,17 +190,17 @@ mod perf_counter { // using QueryPerformanceCounter is 1 "tick" -- defined as 1/frequency(). // Reference: https://docs.microsoft.com/en-us/windows/desktop/SysInfo // /acquiring-high-resolution-time-stamps - pub fn epsilon_nanos() -> u32 { + pub fn epsilon() -> Duration { let epsilon = NANOS_PER_SEC / (frequency() as u64); - // As noted elsewhere, subsecond nanos always fit in a u32 - epsilon as u32 + Duration::from_nanos(epsilon) } } impl From for super::Instant { fn from(other: PerformanceCounterInstant) -> Self { let freq = frequency() as u64; + let instant_nsec = mul_div_u64(other.ts as u64, NANOS_PER_SEC, freq); Self { - t: mul_div_u64(other.ts as u64, NANOS_PER_SEC, freq) + t: Duration::from_nanos(instant_nsec) } } } From 41be93c2f694b6b8c493b255d2e77c0703135b14 Mon Sep 17 00:00:00 2001 From: Alex Berghage Date: Tue, 22 Jan 2019 19:31:55 -0700 Subject: [PATCH 0278/1064] Rebase and fix new instantiation fn --- src/libstd/sys/windows/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index 113affb737edd..fe3766f25c85f 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -43,7 +43,7 @@ impl Instant { } pub const fn zero() -> Instant { - Instant { t: 0 } + Instant { t: Duration::from_secs(0) } } pub fn sub_instant(&self, other: &Instant) -> Duration { From 8af02faab8434d63b6eedb7b5e8f47d0ff0b5e6c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 22 Jan 2019 22:51:33 -0500 Subject: [PATCH 0279/1064] reposition markdown hyperlink reference --- src/libcore/num/dec2flt/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 8bde41fefd5b1..c137986e684a5 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -129,8 +129,6 @@ macro_rules! from_str_float_impl { /// /// # Grammar /// - /// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation - /// /// All strings that adhere to the following [EBNF] grammar /// will result in an [`Ok`] being returned: /// @@ -144,6 +142,8 @@ macro_rules! from_str_float_impl { /// Digit ::= [0-9] /// ``` /// + /// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation + /// /// # Known bugs /// /// In some situations, some strings that should create a valid float From 91f328fb557cb4e4623bf50188168c2c1d9cc390 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 23 Jan 2019 11:21:24 +0100 Subject: [PATCH 0280/1064] make sure to accept all android licenses --- src/ci/docker/scripts/android-sdk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/android-sdk.sh b/src/ci/docker/scripts/android-sdk.sh index e06c57fbab90c..179f63fc830a6 100644 --- a/src/ci/docker/scripts/android-sdk.sh +++ b/src/ci/docker/scripts/android-sdk.sh @@ -20,7 +20,7 @@ download_sysimage() { # The output from sdkmanager is so noisy that it will occupy all of the 4 MB # log extremely quickly. Thus we must silence all output. yes | sdkmanager --licenses > /dev/null - sdkmanager platform-tools emulator \ + yes | sdkmanager platform-tools emulator \ "platforms;android-$api" \ "system-images;android-$api;default;$abi" > /dev/null } From 22f794b00fa8d84c9e827f8c8af762ee60074a8a Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 23 Jan 2019 02:35:13 +0100 Subject: [PATCH 0281/1064] Suggest removing leading left angle brackets. This commit adds errors and accompanying suggestions as below: ``` bar::<<<<::Output>(); ^^^ help: remove extra angle brackets ``` --- src/libsyntax/parse/parser.rs | 209 +++++++++++++++++++++++++- src/test/ui/issues/issue-57819.fixed | 47 ++++++ src/test/ui/issues/issue-57819.rs | 47 ++++++ src/test/ui/issues/issue-57819.stderr | 44 ++++++ 4 files changed, 339 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/issues/issue-57819.fixed create mode 100644 src/test/ui/issues/issue-57819.rs create mode 100644 src/test/ui/issues/issue-57819.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 439eec5b0c48d..6ad07a8e2f1d2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -242,6 +242,12 @@ pub struct Parser<'a> { desugar_doc_comments: bool, /// Whether we should configure out of line modules as we parse. pub cfg_mods: bool, + /// This field is used to keep track of how many left angle brackets we have seen. This is + /// required in order to detect extra leading left angle brackets (`<` characters) and error + /// appropriately. + /// + /// See the comments in the `parse_path_segment` function for more details. + crate unmatched_angle_bracket_count: u32, } @@ -563,6 +569,7 @@ impl<'a> Parser<'a> { }, desugar_doc_comments, cfg_mods: true, + unmatched_angle_bracket_count: 0, }; let tok = parser.next_tok(); @@ -1027,7 +1034,7 @@ impl<'a> Parser<'a> { /// starting token. fn eat_lt(&mut self) -> bool { self.expected_tokens.push(TokenType::Token(token::Lt)); - match self.token { + let ate = match self.token { token::Lt => { self.bump(); true @@ -1038,7 +1045,15 @@ impl<'a> Parser<'a> { true } _ => false, + }; + + if ate { + // See doc comment for `unmatched_angle_bracket_count`. + self.unmatched_angle_bracket_count += 1; + debug!("eat_lt: (increment) count={:?}", self.unmatched_angle_bracket_count); } + + ate } fn expect_lt(&mut self) -> PResult<'a, ()> { @@ -1054,24 +1069,35 @@ impl<'a> Parser<'a> { /// signal an error. fn expect_gt(&mut self) -> PResult<'a, ()> { self.expected_tokens.push(TokenType::Token(token::Gt)); - match self.token { + let ate = match self.token { token::Gt => { self.bump(); - Ok(()) + Some(()) } token::BinOp(token::Shr) => { let span = self.span.with_lo(self.span.lo() + BytePos(1)); - Ok(self.bump_with(token::Gt, span)) + Some(self.bump_with(token::Gt, span)) } token::BinOpEq(token::Shr) => { let span = self.span.with_lo(self.span.lo() + BytePos(1)); - Ok(self.bump_with(token::Ge, span)) + Some(self.bump_with(token::Ge, span)) } token::Ge => { let span = self.span.with_lo(self.span.lo() + BytePos(1)); - Ok(self.bump_with(token::Eq, span)) + Some(self.bump_with(token::Eq, span)) } - _ => self.unexpected() + _ => None, + }; + + match ate { + Some(x) => { + // See doc comment for `unmatched_angle_bracket_count`. + self.unmatched_angle_bracket_count -= 1; + debug!("expect_gt: (decrement) count={:?}", self.unmatched_angle_bracket_count); + + Ok(x) + }, + None => self.unexpected(), } } @@ -2079,7 +2105,11 @@ impl<'a> Parser<'a> { path_span = self.span.to(self.span); } + // See doc comment for `unmatched_angle_bracket_count`. self.expect(&token::Gt)?; + self.unmatched_angle_bracket_count -= 1; + debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count); + self.expect(&token::ModSep)?; let qself = QSelf { ty, path_span, position: path.segments.len() }; @@ -2182,9 +2212,15 @@ impl<'a> Parser<'a> { } let lo = self.span; + // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If + // it isn't, then we reset the unmatched angle bracket count as we're about to start + // parsing a new path. + if style == PathStyle::Expr { self.unmatched_angle_bracket_count = 0; } + let args = if self.eat_lt() { // `<'a, T, A = U>` - let (args, bindings) = self.parse_generic_args()?; + let (args, bindings) = + self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?; self.expect_gt()?; let span = lo.to(self.prev_span); AngleBracketedArgs { args, bindings, span }.into() @@ -5319,6 +5355,163 @@ impl<'a> Parser<'a> { } } + /// Parse generic args (within a path segment) with recovery for extra leading angle brackets. + /// For the purposes of understanding the parsing logic of generic arguments, this function + /// can be thought of being the same as just calling `self.parse_generic_args()` if the source + /// had the correct amount of leading angle brackets. + /// + /// ```ignore (diagnostics) + /// bar::<<<::Output>(); + /// ^^ help: remove extra angle brackets + /// ``` + fn parse_generic_args_with_leaning_angle_bracket_recovery( + &mut self, + style: PathStyle, + lo: Span, + ) -> PResult<'a, (Vec, Vec)> { + // We need to detect whether there are extra leading left angle brackets and produce an + // appropriate error and suggestion. This cannot be implemented by looking ahead at + // upcoming tokens for a matching `>` character - if there are unmatched `<` tokens + // then there won't be matching `>` tokens to find. + // + // To explain how this detection works, consider the following example: + // + // ```ignore (diagnostics) + // bar::<<<::Output>(); + // ^^ help: remove extra angle brackets + // ``` + // + // Parsing of the left angle brackets starts in this function. We start by parsing the + // `<` token (incrementing the counter of unmatched angle brackets on `Parser` via + // `eat_lt`): + // + // *Upcoming tokens:* `<<<::Output>;` + // *Unmatched count:* 1 + // *`parse_path_segment` calls deep:* 0 + // + // This has the effect of recursing as this function is called if a `<` character + // is found within the expected generic arguments: + // + // *Upcoming tokens:* `<<::Output>;` + // *Unmatched count:* 2 + // *`parse_path_segment` calls deep:* 1 + // + // Eventually we will have recursed until having consumed all of the `<` tokens and + // this will be reflected in the count: + // + // *Upcoming tokens:* `T as Foo>::Output>;` + // *Unmatched count:* 4 + // `parse_path_segment` calls deep:* 3 + // + // The parser will continue until reaching the first `>` - this will decrement the + // unmatched angle bracket count and return to the parent invocation of this function + // having succeeded in parsing: + // + // *Upcoming tokens:* `::Output>;` + // *Unmatched count:* 3 + // *`parse_path_segment` calls deep:* 2 + // + // This will continue until the next `>` character which will also return successfully + // to the parent invocation of this function and decrement the count: + // + // *Upcoming tokens:* `;` + // *Unmatched count:* 2 + // *`parse_path_segment` calls deep:* 1 + // + // At this point, this function will expect to find another matching `>` character but + // won't be able to and will return an error. This will continue all the way up the + // call stack until the first invocation: + // + // *Upcoming tokens:* `;` + // *Unmatched count:* 2 + // *`parse_path_segment` calls deep:* 0 + // + // In doing this, we have managed to work out how many unmatched leading left angle + // brackets there are, but we cannot recover as the unmatched angle brackets have + // already been consumed. To remedy this, whenever `parse_generic_args` is invoked, we + // make a snapshot of the current parser state and invoke it on that and inspect + // the result: + // + // - If success (ie. when it found a matching `>` character) then the snapshot state + // is kept (this is required to propagate the count upwards). + // + // - If error and in was in a recursive call, then the snapshot state is kept (this is + // required to propagate the count upwards). + // + // - If error and this was the first invocation (before any recursion had taken place) + // then we choose not to keep the snapshot state - that way we haven't actually + // consumed any of the `<` characters, but can still inspect the count from the + // snapshot to know how many `<` characters to remove. Using this information, we can + // emit an error and consume the extra `<` characters before attempting to parse + // the generic arguments again (this time hopefullt successfully as the unmatched `<` + // characters are gone). + // + // In practice, the recursion of this function is indirect and there will be other + // locations that consume some `<` characters - as long as we update the count when + // this happens, it isn't an issue. + let mut snapshot = self.clone(); + debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)"); + match snapshot.parse_generic_args() { + Ok(value) => { + debug!( + "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot success) \ + snapshot.count={:?}", + snapshot.unmatched_angle_bracket_count, + ); + mem::replace(self, snapshot); + Ok(value) + }, + Err(mut e) => { + debug!( + "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \ + snapshot.count={:?}", + snapshot.unmatched_angle_bracket_count, + ); + if style == PathStyle::Expr && snapshot.unmatched_angle_bracket_count > 0 { + // Cancel error from being unable to find `>`. We know the error + // must have been this due to a non-zero unmatched angle bracket + // count. + e.cancel(); + + // Eat the unmatched angle brackets. + for _ in 0..snapshot.unmatched_angle_bracket_count { + self.eat_lt(); + } + + // Make a span over ${unmatched angle bracket count} characters. + let span = lo.with_hi( + lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count) + ); + let plural = snapshot.unmatched_angle_bracket_count > 1; + self.diagnostic() + .struct_span_err( + span, + &format!( + "unmatched angle bracket{}", + if plural { "s" } else { "" } + ), + ) + .span_suggestion_with_applicability( + span, + &format!( + "remove extra angle bracket{}", + if plural { "s" } else { "" } + ), + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + + // Try again without unmatched angle bracket characters. + self.parse_generic_args() + } else { + mem::replace(self, snapshot); + Err(e) + } + }, + } + } + /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, /// possibly including trailing comma. fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { diff --git a/src/test/ui/issues/issue-57819.fixed b/src/test/ui/issues/issue-57819.fixed new file mode 100644 index 0000000000000..3fab21db2d06e --- /dev/null +++ b/src/test/ui/issues/issue-57819.fixed @@ -0,0 +1,47 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<<>(); +// ^^ help: remove extra angle brackets +// ``` + +trait Foo { + type Output; +} + +fn foo() { + // More complex cases with more than one correct leading `<` character: + + bar::<::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<::Output>(); +} + +fn bar() {} + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); +} diff --git a/src/test/ui/issues/issue-57819.rs b/src/test/ui/issues/issue-57819.rs new file mode 100644 index 0000000000000..5cafbf439be2d --- /dev/null +++ b/src/test/ui/issues/issue-57819.rs @@ -0,0 +1,47 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<<>(); +// ^^ help: remove extra angle brackets +// ``` + +trait Foo { + type Output; +} + +fn foo() { + // More complex cases with more than one correct leading `<` character: + + bar::<<<<::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<<::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<<::Output>(); + //~^ ERROR unmatched angle bracket + + bar::<::Output>(); +} + +fn bar() {} + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::<<<<>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<<<>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<<>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::<>(); + //~^ ERROR unmatched angle bracket + + let _ = vec![1, 2, 3].into_iter().collect::>(); +} diff --git a/src/test/ui/issues/issue-57819.stderr b/src/test/ui/issues/issue-57819.stderr new file mode 100644 index 0000000000000..493e9835b1ca9 --- /dev/null +++ b/src/test/ui/issues/issue-57819.stderr @@ -0,0 +1,44 @@ +error: unmatched angle brackets + --> $DIR/issue-57819.rs:19:10 + | +LL | bar::<<<<::Output>(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:22:10 + | +LL | bar::<<<::Output>(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-57819.rs:25:10 + | +LL | bar::<<::Output>(); + | ^ help: remove extra angle bracket + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:34:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<<<>(); + | ^^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:37:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<<>(); + | ^^^ help: remove extra angle brackets + +error: unmatched angle brackets + --> $DIR/issue-57819.rs:40:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<<>(); + | ^^ help: remove extra angle brackets + +error: unmatched angle bracket + --> $DIR/issue-57819.rs:43:48 + | +LL | let _ = vec![1, 2, 3].into_iter().collect::<>(); + | ^ help: remove extra angle bracket + +error: aborting due to 7 previous errors + From d4ee556126edb0d22b8774a4d85a842c443adf60 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 23 Jan 2019 11:34:02 +0100 Subject: [PATCH 0282/1064] Follow naming scheme for "frame" methods --- src/librustc_mir/interpret/eval_context.rs | 8 ++++---- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/step.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b2db0fea3d09a..132b753eb9a62 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -282,12 +282,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } } - pub fn monomorphize_in_frame + Subst<'tcx>>( + pub(super) fn monomorphize + Subst<'tcx>>( &self, t: T, ) -> EvalResult<'tcx, T> { match self.stack.last() { - Some(frame) => Ok(self.monomorphize(t, frame.instance.substs)), + Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)), None => if t.needs_subst() { err!(TooGeneric).into() } else { @@ -296,7 +296,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } } - pub fn monomorphize + Subst<'tcx>>( + fn monomorphize_with_substs + Subst<'tcx>>( &self, t: T, substs: &'tcx Substs<'tcx> @@ -315,7 +315,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc let cell = &frame.local_layouts[local]; if cell.get().is_none() { let local_ty = frame.mir.local_decls[local].ty; - let local_ty = self.monomorphize(local_ty, frame.instance.substs); + let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); let layout = self.layout_of(local_ty)?; cell.set(Some(layout)); } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 8995d091aaab6..8741571342f83 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -508,7 +508,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> Constant(ref constant) => { let layout = from_known_layout(layout, || { - let ty = self.monomorphize_in_frame(mir_op.ty(self.mir(), *self.tcx))?; + let ty = self.monomorphize(mir_op.ty(self.mir(), *self.tcx))?; self.layout_of(ty) })?; let op = self.const_value_to_op(*constant.literal)?; diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index f1b4e6a5055b6..25f3e4c1f771d 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -248,7 +248,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } NullaryOp(mir::NullOp::SizeOf, ty) => { - let ty = self.monomorphize_in_frame(ty)?; + let ty = self.monomorphize(ty)?; let layout = self.layout_of(ty)?; assert!(!layout.is_unsized(), "SizeOf nullary MIR operator called for unsized type"); @@ -260,7 +260,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } Cast(kind, ref operand, cast_ty) => { - debug_assert_eq!(self.monomorphize_in_frame(cast_ty)?, dest.layout.ty); + debug_assert_eq!(self.monomorphize(cast_ty)?, dest.layout.ty); let src = self.eval_operand(operand, None)?; self.cast(src, kind, dest)?; } From 5d6faf7b4af94d0da681e9873539f9f13279290d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 23 Jan 2019 11:34:58 +0100 Subject: [PATCH 0283/1064] Remove unused feature gates --- src/test/ui/existential_types/auxiliary/cross_crate_ice.rs | 1 - src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs index c6fba2c33a81f..af2d209826e19 100644 --- a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs @@ -1,6 +1,5 @@ // Crate that exports an existential type. Used for testing cross-crate. -#![feature(const_fn)] #![crate_type="rlib"] #![feature(existential_type)] diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs index c23fa6b5dea01..39ec5394febe4 100644 --- a/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs @@ -1,6 +1,5 @@ // Crate that exports an existential type. Used for testing cross-crate. -#![feature(const_fn)] #![crate_type="rlib"] #![feature(existential_type)] From 0cf97042d1317630e619b13a1b416f3b7794fb2a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 23 Jan 2019 12:05:00 +0100 Subject: [PATCH 0284/1064] Fix invalid background color --- src/librustdoc/html/static/themes/dark.css | 4 ---- src/librustdoc/html/static/themes/light.css | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 2cd1a8580890c..61392f1ce0f31 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -419,10 +419,6 @@ kbd { color: #ccc; } -.impl-items code { - background-color: rgba(0, 0, 0, 0); -} - #sidebar-toggle { background-color: #565656; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 4cf35f64d19a4..de6d847a30c77 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -414,10 +414,6 @@ kbd { color: #999; } -.impl-items code { - background-color: rgba(0, 0, 0, 0); -} - #sidebar-toggle { background-color: #F1F1F1; } From 645b7c2c36a3d71de69af51a29a0d4d832b95cbd Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 23 Jan 2019 11:54:23 +0100 Subject: [PATCH 0285/1064] ignore images line ending on older git versions On Ubuntu 16.04 git 2.7.4 tries to fix the line ending of .png and .ico files, and obviously it ruins them. This commit adds an attribute to those files to properly mark them as binary. --- .gitattributes | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitattributes b/.gitattributes index b223c8ac5fb84..f0b1c67bd0fdd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,3 +9,7 @@ src/etc/installer/gfx/* binary *.woff binary src/vendor/** -text Cargo.lock -merge linguist-generated=false + +# Older git versions try to fix line endings on images, this prevents it. +*.png binary +*.ico binary From 8db59d49f3364c26f424518d99631ca008b9b4f5 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 23 Jan 2019 18:40:40 +0530 Subject: [PATCH 0286/1064] Add os::fortanix_sgx::ffi module --- src/libstd/os/fortanix_sgx/mod.rs | 2 +- src/libstd/sys/sgx/ext/ffi.rs | 109 ++++++++++++++++++++++++++++++ src/libstd/sys/sgx/ext/mod.rs | 1 + 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/libstd/sys/sgx/ext/ffi.rs diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs index 47c7b5dcbe64a..810965fc1b85a 100644 --- a/src/libstd/os/fortanix_sgx/mod.rs +++ b/src/libstd/os/fortanix_sgx/mod.rs @@ -56,4 +56,4 @@ pub mod mem { pub use sys::abi::mem::*; } -pub use sys::ext::{io, arch}; +pub use sys::ext::{io, arch, ffi}; diff --git a/src/libstd/sys/sgx/ext/ffi.rs b/src/libstd/sys/sgx/ext/ffi.rs new file mode 100644 index 0000000000000..7b0ffea49ae7c --- /dev/null +++ b/src/libstd/sys/sgx/ext/ffi.rs @@ -0,0 +1,109 @@ +//! SGX-specific extension to the primitives in the `std::ffi` module + +#![unstable(feature = "sgx_platform", issue = "56975")] + +use ffi::{OsStr, OsString}; +use mem; +use sys::os_str::Buf; +use sys_common::{FromInner, IntoInner, AsInner}; + +/// SGX-specific extensions to [`OsString`]. +/// +/// [`OsString`]: ../../../../std/ffi/struct.OsString.html +#[unstable(feature = "sgx_platform", issue = "56975")] +pub trait OsStringExt { + /// Creates an [`OsString`] from a byte vector. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsString; + /// use std::os::unix::ffi::OsStringExt; + /// + /// let bytes = b"foo".to_vec(); + /// let os_string = OsString::from_vec(bytes); + /// assert_eq!(os_string.to_str(), Some("foo")); + /// ``` + /// + /// [`OsString`]: ../../../ffi/struct.OsString.html + #[unstable(feature = "sgx_platform", issue = "56975")] + fn from_vec(vec: Vec) -> Self; + + /// Yields the underlying byte vector of this [`OsString`]. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsString; + /// use std::os::unix::ffi::OsStringExt; + /// + /// let mut os_string = OsString::new(); + /// os_string.push("foo"); + /// let bytes = os_string.into_vec(); + /// assert_eq!(bytes, b"foo"); + /// ``` + /// + /// [`OsString`]: ../../../ffi/struct.OsString.html + #[unstable(feature = "sgx_platform", issue = "56975")] + fn into_vec(self) -> Vec; +} + +#[unstable(feature = "sgx_platform", issue = "56975")] +impl OsStringExt for OsString { + fn from_vec(vec: Vec) -> OsString { + FromInner::from_inner(Buf { inner: vec }) + } + fn into_vec(self) -> Vec { + self.into_inner().inner + } +} + +/// SGX-specific extensions to [`OsStr`]. +/// +/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html +#[unstable(feature = "sgx_platform", issue = "56975")] +pub trait OsStrExt { + #[unstable(feature = "sgx_platform", issue = "56975")] + /// Creates an [`OsStr`] from a byte slice. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// use std::os::unix::ffi::OsStrExt; + /// + /// let bytes = b"foo"; + /// let os_str = OsStr::from_bytes(bytes); + /// assert_eq!(os_str.to_str(), Some("foo")); + /// ``` + /// + /// [`OsStr`]: ../../../ffi/struct.OsStr.html + fn from_bytes(slice: &[u8]) -> &Self; + + /// Gets the underlying byte view of the [`OsStr`] slice. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// use std::os::unix::ffi::OsStrExt; + /// + /// let mut os_str = OsStr::new("foo"); + /// let bytes = os_str.as_bytes(); + /// assert_eq!(bytes, b"foo"); + /// ``` + /// + /// [`OsStr`]: ../../../ffi/struct.OsStr.html + #[unstable(feature = "sgx_platform", issue = "56975")] + fn as_bytes(&self) -> &[u8]; +} + +#[unstable(feature = "sgx_platform", issue = "56975")] +impl OsStrExt for OsStr { + fn from_bytes(slice: &[u8]) -> &OsStr { + unsafe { mem::transmute(slice) } + } + fn as_bytes(&self) -> &[u8] { + &self.as_inner().inner + } +} diff --git a/src/libstd/sys/sgx/ext/mod.rs b/src/libstd/sys/sgx/ext/mod.rs index 5489f6f56946e..51b2659da83e3 100644 --- a/src/libstd/sys/sgx/ext/mod.rs +++ b/src/libstd/sys/sgx/ext/mod.rs @@ -2,3 +2,4 @@ pub mod arch; pub mod io; +pub mod ffi; From 0db2587a1c0f6492d595cd86b036789161adab31 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Wed, 23 Jan 2019 15:05:39 +0100 Subject: [PATCH 0287/1064] Don't export table by default in wasm --- src/librustc_codegen_ssa/back/linker.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 06d4f940436da..ad61f8f01d8d4 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -911,9 +911,6 @@ impl<'a> WasmLd<'a> { // For now we just never have an entry symbol cmd.arg("--no-entry"); - // Make the default table accessible - cmd.arg("--export-table"); - // Rust code should never have warnings, and warnings are often // indicative of bugs, let's prevent them. cmd.arg("--fatal-warnings"); From b2dfd9680d9d59ce5dcc16118da1f3384ceb19ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 22 Dec 2018 18:59:03 +0100 Subject: [PATCH 0288/1064] Fix race condition when emitting stored diagnostics --- src/librustc/dep_graph/graph.rs | 84 ++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index a9e80ddf4ba2a..63857d6c9189a 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -1,4 +1,4 @@ -use errors::DiagnosticBuilder; +use errors::{Diagnostic, DiagnosticBuilder}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -9,6 +9,7 @@ use std::hash::Hash; use std::collections::hash_map::Entry; use ty::{self, TyCtxt}; use util::common::{ProfileQueriesMsg, profq_msg}; +use parking_lot::{Mutex, Condvar}; use ich::{StableHashingContext, StableHashingContextProvider, Fingerprint}; @@ -60,6 +61,12 @@ struct DepGraphData { colors: DepNodeColorMap, + /// A set of loaded diagnostics which has been emitted. + emitted_diagnostics: Mutex>, + + /// Used to wait for diagnostics to be emitted. + emitted_diagnostics_cond_var: Condvar, + /// When we load, there may be `.o` files, cached mir, or other such /// things available to us. If we find that they are not dirty, we /// load the path to the file storing those work-products here into @@ -83,6 +90,8 @@ impl DepGraph { previous_work_products: prev_work_products, dep_node_debug: Default::default(), current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)), + emitted_diagnostics: Default::default(), + emitted_diagnostics_cond_var: Condvar::new(), previous: prev_graph, colors: DepNodeColorMap::new(prev_graph_node_count), loaded_from_cache: Default::default(), @@ -718,28 +727,18 @@ impl DepGraph { }; // ... emitting any stored diagnostic ... - if did_allocation { - // Only the thread which did the allocation emits the error messages - - // FIXME: Ensure that these are printed before returning for all threads. - // Currently threads where did_allocation = false can continue on - // and emit other diagnostics before these diagnostics are emitted. - // Such diagnostics should be emitted after these. - // See https://github.com/rust-lang/rust/issues/48685 - let diagnostics = tcx.queries.on_disk_cache - .load_diagnostics(tcx, prev_dep_node_index); - if diagnostics.len() > 0 { - let handle = tcx.sess.diagnostic(); + let diagnostics = tcx.queries.on_disk_cache + .load_diagnostics(tcx, prev_dep_node_index); - // Promote the previous diagnostics to the current session. - tcx.queries.on_disk_cache - .store_diagnostics(dep_node_index, diagnostics.clone().into()); - - for diagnostic in diagnostics { - DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit(); - } - } + if unlikely!(diagnostics.len() > 0) { + self.emit_diagnostics( + tcx, + data, + dep_node_index, + did_allocation, + diagnostics + ); } // ... and finally storing a "Green" entry in the color map. @@ -755,6 +754,49 @@ impl DepGraph { Some(dep_node_index) } + /// Atomically emits some loaded diagnotics assuming that this only gets called with + /// did_allocation set to true on one thread + #[cold] + #[inline(never)] + fn emit_diagnostics<'tcx>( + &self, + tcx: TyCtxt<'_, 'tcx, 'tcx>, + data: &DepGraphData, + dep_node_index: DepNodeIndex, + did_allocation: bool, + diagnostics: Vec, + ) { + if did_allocation || !cfg!(parallel_queries) { + // Only the thread which did the allocation emits the error messages + let handle = tcx.sess.diagnostic(); + + // Promote the previous diagnostics to the current session. + tcx.queries.on_disk_cache + .store_diagnostics(dep_node_index, diagnostics.clone().into()); + + for diagnostic in diagnostics { + DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit(); + } + + #[cfg(parallel_queries)] + { + // Mark the diagnostics and emitted and wake up waiters + data.emitted_diagnostics.lock().insert(dep_node_index); + data.emitted_diagnostics_cond_var.notify_all(); + } + } else { + // The other threads will wait for the diagnostics to be emitted + + let mut emitted_diagnostics = data.emitted_diagnostics.lock(); + loop { + if emitted_diagnostics.contains(&dep_node_index) { + break; + } + data.emitted_diagnostics_cond_var.wait(&mut emitted_diagnostics); + } + } + } + // Returns true if the given node has been marked as green during the // current compilation session. Used in various assertions pub fn is_green(&self, dep_node: &DepNode) -> bool { From 8ab12f6cc06033f483d085b37b766d681dcc61ca Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 23 Jan 2019 21:39:15 +0100 Subject: [PATCH 0289/1064] Optimize snapshot usage. This commit implements a suggestion from @estebank that optimizes the use of snapshots. Instead of creating a snapshot for each recursion in `parse_path_segment` and then replacing `self` with them until the first invocation where if leading angle brackets are detected, `self` is not replaced and instead the snapshot is used to inform how parsing should continue. Now, a snapshot is created in the first invocation that acts as a backup of the parser state before any generic arguments are parsed (and therefore, before recursion starts). This backup replaces `self` if after all parsing of generic arguments has concluded we can determine that there are leading angle brackets. Parsing can then proceed from the backup state making use of the now known number of unmatched leading angle brackets to recover. --- src/libsyntax/parse/parser.rs | 125 ++++++++++++++++------------------ 1 file changed, 57 insertions(+), 68 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6ad07a8e2f1d2..d03a346c3d55b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5428,87 +5428,76 @@ impl<'a> Parser<'a> { // // In doing this, we have managed to work out how many unmatched leading left angle // brackets there are, but we cannot recover as the unmatched angle brackets have - // already been consumed. To remedy this, whenever `parse_generic_args` is invoked, we - // make a snapshot of the current parser state and invoke it on that and inspect - // the result: - // - // - If success (ie. when it found a matching `>` character) then the snapshot state - // is kept (this is required to propagate the count upwards). - // - // - If error and in was in a recursive call, then the snapshot state is kept (this is - // required to propagate the count upwards). - // - // - If error and this was the first invocation (before any recursion had taken place) - // then we choose not to keep the snapshot state - that way we haven't actually - // consumed any of the `<` characters, but can still inspect the count from the - // snapshot to know how many `<` characters to remove. Using this information, we can - // emit an error and consume the extra `<` characters before attempting to parse - // the generic arguments again (this time hopefullt successfully as the unmatched `<` - // characters are gone). + // already been consumed. To remedy this, we keep a snapshot of the parser state + // before we do the above. We can then inspect whether we ended up with a parsing error + // and unmatched left angle brackets and if so, restore the parser state before we + // consumed any `<` characters to emit an error and consume the erroneous tokens to + // recover by attempting to parse again. // // In practice, the recursion of this function is indirect and there will be other // locations that consume some `<` characters - as long as we update the count when // this happens, it isn't an issue. - let mut snapshot = self.clone(); + + let is_first_invocation = style == PathStyle::Expr; + // Take a snapshot before attempting to parse - we can restore this later. + let snapshot = if is_first_invocation { + Some(self.clone()) + } else { + None + }; + debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)"); - match snapshot.parse_generic_args() { - Ok(value) => { - debug!( - "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot success) \ - snapshot.count={:?}", - snapshot.unmatched_angle_bracket_count, - ); - mem::replace(self, snapshot); - Ok(value) - }, - Err(mut e) => { + match self.parse_generic_args() { + Ok(value) => Ok(value), + Err(ref mut e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => { + // Cancel error from being unable to find `>`. We know the error + // must have been this due to a non-zero unmatched angle bracket + // count. + e.cancel(); + + // Swap `self` with our backup of the parser state before attempting to parse + // generic arguments. + let snapshot = mem::replace(self, snapshot.unwrap()); + debug!( "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \ snapshot.count={:?}", snapshot.unmatched_angle_bracket_count, ); - if style == PathStyle::Expr && snapshot.unmatched_angle_bracket_count > 0 { - // Cancel error from being unable to find `>`. We know the error - // must have been this due to a non-zero unmatched angle bracket - // count. - e.cancel(); - - // Eat the unmatched angle brackets. - for _ in 0..snapshot.unmatched_angle_bracket_count { - self.eat_lt(); - } - // Make a span over ${unmatched angle bracket count} characters. - let span = lo.with_hi( - lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count) - ); - let plural = snapshot.unmatched_angle_bracket_count > 1; - self.diagnostic() - .struct_span_err( - span, - &format!( - "unmatched angle bracket{}", - if plural { "s" } else { "" } - ), - ) - .span_suggestion_with_applicability( - span, - &format!( - "remove extra angle bracket{}", - if plural { "s" } else { "" } - ), - String::new(), - Applicability::MachineApplicable, - ) - .emit(); - - // Try again without unmatched angle bracket characters. - self.parse_generic_args() - } else { - mem::replace(self, snapshot); - Err(e) + // Eat the unmatched angle brackets. + for _ in 0..snapshot.unmatched_angle_bracket_count { + self.eat_lt(); } + + // Make a span over ${unmatched angle bracket count} characters. + let span = lo.with_hi( + lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count) + ); + let plural = snapshot.unmatched_angle_bracket_count > 1; + self.diagnostic() + .struct_span_err( + span, + &format!( + "unmatched angle bracket{}", + if plural { "s" } else { "" } + ), + ) + .span_suggestion_with_applicability( + span, + &format!( + "remove extra angle bracket{}", + if plural { "s" } else { "" } + ), + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + + // Try again without unmatched angle bracket characters. + self.parse_generic_args() }, + Err(e) => Err(e), } } From fc0c8839f7a4b5a4f8ee4c9c8177fb0ecfb0e5de Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 23 Jan 2019 16:32:59 -0500 Subject: [PATCH 0290/1064] Don't ICE when logging unusual types MonoItemExt#to_string is used for both debug logging and LLVM symbol name generation. When debugging, we want to print out any type we encounter, even if it's something weird like GeneratorWitness. However, during codegen, we still want to error if we encounter an unexpected type when generating a name. To resolve this issue, this commit introduces a new 'debug' parameter to the relevant methods. When set to 'true', it allows any type to be printed - when set to 'false', it 'bug!'s when encountering an unexpected type. This prevents an ICE when enabling debug logging (via RUST_LOG) while running rustc on generator-related code. --- src/librustc_codegen_llvm/type_of.rs | 2 +- src/librustc_codegen_ssa/mono_item.rs | 8 +-- src/librustc_mir/monomorphize/collector.rs | 4 +- src/librustc_mir/monomorphize/item.rs | 56 ++++++++++++------- src/librustc_mir/monomorphize/partitioning.rs | 4 +- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 97128c2d2a2ce..afaeb352cd992 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -55,7 +55,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::Str => { let mut name = String::with_capacity(32); let printer = DefPathBasedNames::new(cx.tcx, true, true); - printer.push_type_name(layout.ty, &mut name); + printer.push_type_name(layout.ty, &mut name, false); if let (&ty::Adt(def, _), &layout::Variants::Single { index }) = (&layout.ty.sty, &layout.variants) { diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 21e0044759a5a..8488ab2ae862f 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -13,7 +13,7 @@ pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt; pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { fn define>(&self, cx: &'a Bx::CodegenCx) { debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx()), + self.to_string(cx.tcx(), true), self.to_raw_string(), cx.codegen_unit().name()); @@ -45,7 +45,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } debug!("END IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx()), + self.to_string(cx.tcx(), true), self.to_raw_string(), cx.codegen_unit().name()); } @@ -57,7 +57,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { visibility: Visibility ) { debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx()), + self.to_string(cx.tcx(), true), self.to_raw_string(), cx.codegen_unit().name()); @@ -76,7 +76,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } debug!("END PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx()), + self.to_string(cx.tcx(), true), self.to_raw_string(), cx.codegen_unit().name()); } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index eb49547e9bf52..bc63f8b6ac854 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -355,7 +355,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // We've been here already, no need to search again. return; } - debug!("BEGIN collect_items_rec({})", starting_point.to_string(tcx)); + debug!("BEGIN collect_items_rec({})", starting_point.to_string(tcx, true)); let mut neighbors = Vec::new(); let recursion_depth_reset; @@ -409,7 +409,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, recursion_depths.insert(def_id, depth); } - debug!("END collect_items_rec({})", starting_point.to_string(tcx)); + debug!("END collect_items_rec({})", starting_point.to_string(tcx, true)); } fn record_accesses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index c831cbd98299c..431cc0d52b4c8 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -159,14 +159,14 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { tcx.substitute_normalize_and_test_predicates((def_id, &substs)) } - fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String { + fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, debug: bool) -> String { return match *self.as_mono_item() { MonoItem::Fn(instance) => { - to_string_internal(tcx, "fn ", instance) + to_string_internal(tcx, "fn ", instance, debug) }, MonoItem::Static(def_id) => { let instance = Instance::new(def_id, tcx.intern_substs(&[])); - to_string_internal(tcx, "static ", instance) + to_string_internal(tcx, "static ", instance, debug) }, MonoItem::GlobalAsm(..) => { "global_asm".to_string() @@ -175,12 +175,13 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, prefix: &str, - instance: Instance<'tcx>) + instance: Instance<'tcx>, + debug: bool) -> String { let mut result = String::with_capacity(32); result.push_str(prefix); let printer = DefPathBasedNames::new(tcx, false, false); - printer.push_instance_as_string(instance, &mut result); + printer.push_instance_as_string(instance, &mut result, debug); result } } @@ -238,7 +239,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } } - pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) { + // Pushes the type name of the specified type to the provided string. + // If 'debug' is true, printing normally unprintable types is allowed + // (e.g. ty::GeneratorWitness). This parameter should only be set when + // this method is being used for logging purposes (e.g. with debug! or info!) + // When being used for codegen purposes, 'debug' should be set to 'false' + // in order to catch unexpected types that should never end up in a type name + pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { match t.sty { ty::Bool => output.push_str("bool"), ty::Char => output.push_str("char"), @@ -260,12 +267,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { ty::Float(ast::FloatTy::F64) => output.push_str("f64"), ty::Adt(adt_def, substs) => { self.push_def_path(adt_def.did, output); - self.push_type_params(substs, iter::empty(), output); + self.push_type_params(substs, iter::empty(), output, debug); }, ty::Tuple(component_types) => { output.push('('); for &component_type in component_types { - self.push_type_name(component_type, output); + self.push_type_name(component_type, output, debug); output.push_str(", "); } if !component_types.is_empty() { @@ -281,7 +288,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { hir::MutMutable => output.push_str("mut "), } - self.push_type_name(inner_type, output); + self.push_type_name(inner_type, output, debug); }, ty::Ref(_, inner_type, mutbl) => { output.push('&'); @@ -289,17 +296,17 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push_str("mut "); } - self.push_type_name(inner_type, output); + self.push_type_name(inner_type, output, debug); }, ty::Array(inner_type, len) => { output.push('['); - self.push_type_name(inner_type, output); + self.push_type_name(inner_type, output, debug); write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap(); output.push(']'); }, ty::Slice(inner_type) => { output.push('['); - self.push_type_name(inner_type, output); + self.push_type_name(inner_type, output, debug); output.push(']'); }, ty::Dynamic(ref trait_data, ..) => { @@ -309,6 +316,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { principal.skip_binder().substs, trait_data.projection_bounds(), output, + debug ); } else { output.push_str("dyn '_"); @@ -338,7 +346,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { if !sig.inputs().is_empty() { for ¶meter_type in sig.inputs() { - self.push_type_name(parameter_type, output); + self.push_type_name(parameter_type, output, debug); output.push_str(", "); } output.pop(); @@ -357,7 +365,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { if !sig.output().is_unit() { output.push_str(" -> "); - self.push_type_name(sig.output(), output); + self.push_type_name(sig.output(), output, debug); } }, ty::Generator(def_id, GeneratorSubsts { ref substs }, _) | @@ -365,7 +373,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { self.push_def_path(def_id, output); let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); let substs = substs.truncate_to(self.tcx, generics); - self.push_type_params(substs, iter::empty(), output); + self.push_type_params(substs, iter::empty(), output, debug); } ty::Error | ty::Bound(..) | @@ -376,8 +384,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { ty::Param(_) | ty::GeneratorWitness(_) | ty::Opaque(..) => { - bug!("DefPathBasedNames: Trying to create type name for \ + if debug { + output.push_str(&format!("`{:?}`", t)); + } else { + bug!("DefPathBasedNames: Trying to create type name for \ unexpected type: {:?}", t); + } } } } @@ -412,7 +424,8 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { fn push_type_params(&self, substs: &Substs<'tcx>, projections: I, - output: &mut String) + output: &mut String, + debug: bool) where I: Iterator> { let mut projections = projections.peekable(); @@ -423,7 +436,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push('<'); for type_parameter in substs.types() { - self.push_type_name(type_parameter, output); + self.push_type_name(type_parameter, output, debug); output.push_str(", "); } @@ -432,7 +445,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str(); output.push_str(name); output.push_str("="); - self.push_type_name(projection.ty, output); + self.push_type_name(projection.ty, output, debug); output.push_str(", "); } @@ -444,8 +457,9 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { pub fn push_instance_as_string(&self, instance: Instance<'tcx>, - output: &mut String) { + output: &mut String, + debug: bool) { self.push_def_path(instance.def_id(), output); - self.push_type_params(instance.substs, iter::empty(), output); + self.push_type_params(instance.substs, iter::empty(), output, debug); } } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index c3613fbf04c1b..569e4c828f601 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -879,7 +879,7 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .unwrap_or(""); debug!(" - {} [{:?}] [{}]", - mono_item.to_string(tcx), + mono_item.to_string(tcx, true), linkage, symbol_hash); } @@ -971,7 +971,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( let mut item_keys: Vec<_> = items .iter() .map(|i| { - let mut output = i.to_string(tcx); + let mut output = i.to_string(tcx, false); output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); From 31cd65f7120e209f7b29b205393156763409547a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 23 Jan 2019 17:39:26 -0500 Subject: [PATCH 0291/1064] Fix std::future::from_generator documentation This function takes a generator and wraps it in a future, not vice-versa. --- src/libstd/future.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/future.rs b/src/libstd/future.rs index a7b9895177fe5..22900c3067b11 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -11,7 +11,7 @@ use core::ops::{Drop, Generator, GeneratorState}; #[doc(inline)] pub use core::future::*; -/// Wrap a future in a generator. +/// Wrap a generator in a future. /// /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`). From f14d007ee4f4b69cdb3880db49608b432bea8352 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 23 Jan 2019 16:42:23 +0100 Subject: [PATCH 0292/1064] Add suggestion for incorrect field syntax. This commit adds a suggestion when a `=` character is used when specifying the value of a field in a struct constructor incorrectly instead of a `:` character. --- src/libsyntax/parse/parser.rs | 18 ++++++++++++- src/test/ui/issues/issue-57684.fixed | 37 +++++++++++++++++++++++++++ src/test/ui/issues/issue-57684.rs | 37 +++++++++++++++++++++++++++ src/test/ui/issues/issue-57684.stderr | 18 +++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-57684.fixed create mode 100644 src/test/ui/issues/issue-57684.rs create mode 100644 src/test/ui/issues/issue-57684.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 09ea099525326..b9c602550e333 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2263,8 +2263,24 @@ impl<'a> Parser<'a> { let lo = self.span; // Check if a colon exists one ahead. This means we're parsing a fieldname. - let (fieldname, expr, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) { + let (fieldname, expr, is_shorthand) = if self.look_ahead(1, |t| { + t == &token::Colon || t == &token::Eq + }) { let fieldname = self.parse_field_name()?; + + // Check for an equals token. This means the source incorrectly attempts to + // initialize a field with an eq rather than a colon. + if self.token == token::Eq { + self.diagnostic() + .struct_span_err(self.span, "expected `:`, found `=`") + .span_suggestion_with_applicability( + fieldname.span.shrink_to_hi().to(self.span), + "replace equals symbol with a colon", + ":".to_string(), + Applicability::MachineApplicable, + ) + .emit(); + } self.bump(); // `:` (fieldname, self.parse_expr()?, false) } else { diff --git a/src/test/ui/issues/issue-57684.fixed b/src/test/ui/issues/issue-57684.fixed new file mode 100644 index 0000000000000..4a432206d51e1 --- /dev/null +++ b/src/test/ui/issues/issue-57684.fixed @@ -0,0 +1,37 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted when a `=` character is used to initialize +// a struct field when a `:` is expected. +// +// ``` +// error: struct fields are initialized with a colon +// --> $DIR/issue-57684.rs:12:20 +// | +// LL | let _ = X { f1 = 5 }; +// | ^ help: replace equals symbol with a colon: `:` +// ``` + +struct X { + f1: i32, +} + +struct Y { + f1: i32, + f2: i32, + f3: i32, +} + +fn main() { + let _ = X { f1: 5 }; + //~^ ERROR expected `:`, found `=` + + let f3 = 3; + let _ = Y { + f1: 5, + //~^ ERROR expected `:`, found `=` + f2: 4, + f3, + }; +} diff --git a/src/test/ui/issues/issue-57684.rs b/src/test/ui/issues/issue-57684.rs new file mode 100644 index 0000000000000..7a62785e32f1c --- /dev/null +++ b/src/test/ui/issues/issue-57684.rs @@ -0,0 +1,37 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted when a `=` character is used to initialize +// a struct field when a `:` is expected. +// +// ``` +// error: struct fields are initialized with a colon +// --> $DIR/issue-57684.rs:12:20 +// | +// LL | let _ = X { f1 = 5 }; +// | ^ help: replace equals symbol with a colon: `:` +// ``` + +struct X { + f1: i32, +} + +struct Y { + f1: i32, + f2: i32, + f3: i32, +} + +fn main() { + let _ = X { f1 = 5 }; + //~^ ERROR expected `:`, found `=` + + let f3 = 3; + let _ = Y { + f1 = 5, + //~^ ERROR expected `:`, found `=` + f2: 4, + f3, + }; +} diff --git a/src/test/ui/issues/issue-57684.stderr b/src/test/ui/issues/issue-57684.stderr new file mode 100644 index 0000000000000..514bbffde6b1e --- /dev/null +++ b/src/test/ui/issues/issue-57684.stderr @@ -0,0 +1,18 @@ +error: expected `:`, found `=` + --> $DIR/issue-57684.rs:27:20 + | +LL | let _ = X { f1 = 5 }; + | -^ + | | + | help: replace equals symbol with a colon: `:` + +error: expected `:`, found `=` + --> $DIR/issue-57684.rs:32:12 + | +LL | f1 = 5, + | -^ + | | + | help: replace equals symbol with a colon: `:` + +error: aborting due to 2 previous errors + From 14ce5364de3bf7d2da59fbe52360459c0f2c6ada Mon Sep 17 00:00:00 2001 From: Alex Berghage Date: Wed, 23 Jan 2019 21:36:38 -0700 Subject: [PATCH 0293/1064] Add a comment on the meaning of Instant t: Duration --- src/libstd/sys/windows/time.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index fe3766f25c85f..8a8159af2f1a6 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -11,6 +11,8 @@ const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / 100; #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] pub struct Instant { + // This duration is relative to an arbitrary microsecond epoch + // from the winapi QueryPerformanceCounter function. t: Duration, } From b12aa4fb6e86be9c031cfc4e52ab934ba49897eb Mon Sep 17 00:00:00 2001 From: Jewoo Lee Date: Thu, 24 Jan 2019 13:38:46 +0900 Subject: [PATCH 0294/1064] Stabilize no_panic_pow --- src/libcore/num/mod.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 41caa1788fbb8..423b800d5852f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -847,13 +847,12 @@ overflow occurred. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64)); assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn checked_pow(self, mut exp: u32) -> Option { let mut base = self; @@ -966,7 +965,6 @@ saturating at the numeric bounds instead of overflowing. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "use std::", stringify!($SelfT), "; assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64); @@ -974,7 +972,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT), "::MIN);", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn saturating_pow(self, exp: u32) -> Self { match self.checked_pow(exp) { @@ -1297,13 +1295,12 @@ wrapping around at the boundary of the type. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81); assert_eq!(3i8.wrapping_pow(5), -13); assert_eq!(3i8.wrapping_pow(6), -39);", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn wrapping_pow(self, mut exp: u32) -> Self { let mut base = self; @@ -1669,12 +1666,11 @@ whether an overflow happened. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false)); assert_eq!(3i8.overflowing_pow(5), (-13, true));", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { let mut base = self; @@ -2789,11 +2785,10 @@ overflow occurred. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32)); assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn checked_pow(self, mut exp: u32) -> Option { let mut base = self; @@ -2893,14 +2888,13 @@ saturating at the numeric bounds instead of overflowing. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "use std::", stringify!($SelfT), "; assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64); assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn saturating_pow(self, exp: u32) -> Self { match self.checked_pow(exp) { @@ -3178,11 +3172,10 @@ wrapping around at the boundary of the type. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243); assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn wrapping_pow(self, mut exp: u32) -> Self { let mut base = self; @@ -3497,11 +3490,10 @@ whether an overflow happened. Basic usage: ``` -#![feature(no_panic_pow)] ", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false)); assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, " ```"), - #[unstable(feature = "no_panic_pow", issue = "48320")] + #[stable(feature = "no_panic_pow", since = "1.34.0")] #[inline] pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { let mut base = self; From 48cb04fbca1d398c170b713b3fe7e681a8e39a4f Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 16 Jan 2019 14:59:52 +0100 Subject: [PATCH 0295/1064] Enable Clang-based tests on x86_64-gnu-debug builder. --- src/ci/docker/x86_64-gnu-debug/Dockerfile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index bdde7ad7fe854..241c25aaa050b 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -7,6 +7,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ ca-certificates \ python2.7 \ + python2.7-dev \ git \ cmake \ sudo \ @@ -16,9 +17,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 + ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-debug \ + --enable-lld \ + --enable-lldb \ --enable-optimize -ENV SCRIPT python2.7 ../x.py build +ENV SCRIPT \ + python2.7 ../x.py build && \ + python2.7 ../x.py test src/test/run-make-fulldeps --test-args clang From db97c48ad6e7f36468b152e9b08efc6f2f7da691 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 1 Jun 2018 16:40:33 -0600 Subject: [PATCH 0296/1064] Remove quote_*! macros and associated APIs --- src/bootstrap/builder.rs | 3 - src/bootstrap/mk/Makefile.in | 1 - src/bootstrap/test.rs | 20 - .../src/language-features/plugin.md | 3 +- src/librustc/lib.rs | 1 - src/librustc_borrowck/lib.rs | 1 - src/librustc_codegen_llvm/lib.rs | 1 - src/librustc_codegen_ssa/lib.rs | 1 - src/librustc_codegen_utils/lib.rs | 1 - src/librustc_driver/driver.rs | 2 +- src/librustc_driver/lib.rs | 1 - src/librustc_lint/lib.rs | 1 - src/librustc_metadata/lib.rs | 1 - src/librustc_typeck/lib.rs | 1 - src/libsyntax/ext/quote.rs | 893 ------------------ src/libsyntax/feature_gate.rs | 2 +- src/libsyntax/lib.rs | 1 - src/libsyntax/parse/mod.rs | 39 +- src/libsyntax/parse/parser.rs | 3 - src/libsyntax/util/parser_testing.rs | 2 +- src/libsyntax_ext/lib.rs | 22 +- src/test/run-fail-fulldeps/qquote.rs | 35 - .../auxiliary/issue-16723.rs | 29 - .../auxiliary/macro_crate_test.rs | 227 +---- .../auxiliary/plugin_with_plugin_lib.rs | 13 - .../auxiliary/procedural_mbe_matching.rs | 82 -- .../syntax_extension_with_dll_deps_2.rs | 27 - src/test/run-pass-fulldeps/issue-16723.rs | 19 - src/test/run-pass-fulldeps/issue-16992.rs | 15 - .../issue-18763-quote-token-tree.rs | 22 - .../macro-crate-does-hygiene-work.rs | 16 - .../macro-crate-multi-decorator-literals.rs | 50 - .../macro-crate-multi-decorator.rs | 4 +- src/test/run-pass-fulldeps/macro-crate.rs | 46 - .../mbe_matching_test_macro.rs | 11 - .../plugin-lib-ok-in-plugin.rs | 16 - .../plugin-plus-extern-crate.rs | 17 - src/test/run-pass-fulldeps/qquote.rs | 92 -- src/test/run-pass-fulldeps/quote-tokens.rs | 45 - .../quote-unused-sp-no-warning.rs | 15 - .../syntax-extension-with-dll-deps.rs | 10 - .../ui-fulldeps/auxiliary/macro_crate_test.rs | 149 --- src/test/ui-fulldeps/gated-plugin.rs | 4 +- src/test/ui-fulldeps/gated-plugin.stderr | 2 +- src/test/ui-fulldeps/gated-quote.rs | 57 -- src/test/ui-fulldeps/gated-quote.stderr | 80 -- src/test/ui-fulldeps/issue-48941.rs | 16 - src/test/ui-fulldeps/issue-48941.stderr | 14 - .../ui-fulldeps/macro-crate-doesnt-resolve.rs | 8 - .../macro-crate-doesnt-resolve.stderr | 9 - .../macro-crate-unexported-macro.rs | 9 - .../macro-crate-unexported-macro.stderr | 8 - .../ui-fulldeps/plugin-as-extern-crate.rs | 6 +- .../ui-fulldeps/plugin-as-extern-crate.stderr | 2 +- .../ui-fulldeps/plugin-plus-extern-crate.rs | 17 - .../plugin-plus-extern-crate.stderr | 14 - src/test/ui-fulldeps/qquote.rs | 27 - src/test/ui-fulldeps/qquote.stderr | 9 - src/test/ui/quote-with-interpolated.rs | 14 - src/test/ui/quote-with-interpolated.stderr | 40 - 60 files changed, 57 insertions(+), 2219 deletions(-) delete mode 100644 src/libsyntax/ext/quote.rs delete mode 100644 src/test/run-fail-fulldeps/qquote.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/issue-16723.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/plugin_with_plugin_lib.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_2.rs delete mode 100644 src/test/run-pass-fulldeps/issue-16723.rs delete mode 100644 src/test/run-pass-fulldeps/issue-16992.rs delete mode 100644 src/test/run-pass-fulldeps/issue-18763-quote-token-tree.rs delete mode 100644 src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs delete mode 100644 src/test/run-pass-fulldeps/macro-crate-multi-decorator-literals.rs delete mode 100644 src/test/run-pass-fulldeps/macro-crate.rs delete mode 100644 src/test/run-pass-fulldeps/mbe_matching_test_macro.rs delete mode 100644 src/test/run-pass-fulldeps/plugin-lib-ok-in-plugin.rs delete mode 100644 src/test/run-pass-fulldeps/plugin-plus-extern-crate.rs delete mode 100644 src/test/run-pass-fulldeps/qquote.rs delete mode 100644 src/test/run-pass-fulldeps/quote-tokens.rs delete mode 100644 src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs delete mode 100644 src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs delete mode 100644 src/test/ui-fulldeps/auxiliary/macro_crate_test.rs delete mode 100644 src/test/ui-fulldeps/gated-quote.rs delete mode 100644 src/test/ui-fulldeps/gated-quote.stderr delete mode 100644 src/test/ui-fulldeps/issue-48941.rs delete mode 100644 src/test/ui-fulldeps/issue-48941.stderr delete mode 100644 src/test/ui-fulldeps/macro-crate-doesnt-resolve.rs delete mode 100644 src/test/ui-fulldeps/macro-crate-doesnt-resolve.stderr delete mode 100644 src/test/ui-fulldeps/macro-crate-unexported-macro.rs delete mode 100644 src/test/ui-fulldeps/macro-crate-unexported-macro.stderr delete mode 100644 src/test/ui-fulldeps/plugin-plus-extern-crate.rs delete mode 100644 src/test/ui-fulldeps/plugin-plus-extern-crate.stderr delete mode 100644 src/test/ui-fulldeps/qquote.rs delete mode 100644 src/test/ui-fulldeps/qquote.stderr delete mode 100644 src/test/ui/quote-with-interpolated.rs delete mode 100644 src/test/ui/quote-with-interpolated.stderr diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 31adab64f609d..c3dc9458839e4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -378,14 +378,11 @@ impl<'a> Builder<'a> { test::Debuginfo, test::UiFullDeps, test::RunPassFullDeps, - test::RunFailFullDeps, test::Rustdoc, test::Pretty, test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty, - test::RunPassFullDepsPretty, - test::RunFailFullDepsPretty, test::Crate, test::CrateLibrustc, test::CrateRustdoc, diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 8ff1456f0f47c..1c27cf3909b1a 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -53,7 +53,6 @@ check-aux: src/test/run-fail/pretty \ src/test/run-pass-valgrind/pretty \ src/test/run-pass-fulldeps/pretty \ - src/test/run-fail-fulldeps/pretty \ $(AUX_ARGS) \ $(BOOTSTRAP_ARGS) check-bootstrap: diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2edc78ebaa94f..216649808e2a4 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -848,12 +848,6 @@ host_test!(RunPassFullDeps { suite: "run-pass-fulldeps" }); -host_test!(RunFailFullDeps { - path: "src/test/run-fail-fulldeps", - mode: "run-fail", - suite: "run-fail-fulldeps" -}); - host_test!(Rustdoc { path: "src/test/rustdoc", mode: "rustdoc", @@ -888,20 +882,6 @@ test!(RunPassValgrindPretty { default: false, host: true }); -test!(RunPassFullDepsPretty { - path: "src/test/run-pass-fulldeps/pretty", - mode: "pretty", - suite: "run-pass-fulldeps", - default: false, - host: true -}); -test!(RunFailFullDepsPretty { - path: "src/test/run-fail-fulldeps/pretty", - mode: "pretty", - suite: "run-fail-fulldeps", - default: false, - host: true -}); default_test!(RunMake { path: "src/test/run-make", diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 03ea392c86307..cab350381d2bd 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -52,6 +52,7 @@ that implements Roman numeral integer literals. #![feature(plugin_registrar, rustc_private)] extern crate syntax; +extern crate syntax_pos; extern crate rustc; extern crate rustc_plugin; @@ -59,7 +60,7 @@ use syntax::parse::token; use syntax::tokenstream::TokenTree; use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; use syntax::ext::build::AstBuilder; // A trait for expr_usize. -use syntax::ext::quote::rt::Span; +use syntax_pos::Span; use rustc_plugin::Registry; fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index fba9b8527677c..7ecec0b9a69ac 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -41,7 +41,6 @@ #![feature(nll)] #![feature(non_exhaustive)] #![feature(proc_macro_internals)] -#![feature(quote)] #![feature(optin_builtin_traits)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 14e0381dad1a4..8bdc4e1d5c1ea 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -5,7 +5,6 @@ #![allow(non_camel_case_types)] #![feature(nll)] -#![feature(quote)] #![recursion_limit="256"] diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 272f34b0b3f16..a88b1a8f52e96 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -17,7 +17,6 @@ #![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] -#![feature(quote)] #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index d47bd23766f69..1accbeb2aa822 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -12,7 +12,6 @@ #![feature(nll)] #![allow(unused_attributes)] #![allow(dead_code)] -#![feature(quote)] #![recursion_limit="256"] diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 5f61852178d0f..1f590d46ed8c6 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -11,7 +11,6 @@ #![feature(custom_attribute)] #![feature(nll)] #![allow(unused_attributes)] -#![feature(quote)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d23d8b829c0c0..142d60c8d00b2 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -916,7 +916,7 @@ where crate_loader, &resolver_arenas, ); - syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features_untracked().quote); + syntax_ext::register_builtins(&mut resolver, syntax_exts); // Expand all macros sess.profiler(|p| p.start_activity(ProfileCategory::Expansion)); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index c8a5bbe8315b3..abcdf175ada99 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -11,7 +11,6 @@ #![feature(box_syntax)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] -#![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![feature(set_stdio)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 71c859d8dbea7..d3d17184a0181 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -17,7 +17,6 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(nll)] -#![feature(quote)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index d38562c93f804..1a6614212407d 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -7,7 +7,6 @@ #![feature(nll)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] -#![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![feature(crate_visibility_modifier)] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 6c1c49bda4ce5..5149f460baca0 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -66,7 +66,6 @@ This API is completely unstable and subject to change. #![feature(crate_visibility_modifier)] #![feature(exhaustive_patterns)] #![feature(nll)] -#![feature(quote)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs deleted file mode 100644 index df3b49cf6ed73..0000000000000 --- a/src/libsyntax/ext/quote.rs +++ /dev/null @@ -1,893 +0,0 @@ -use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Stmt, Ty}; -use source_map::respan; -use syntax_pos::{Span, DUMMY_SP}; -use ext::base::ExtCtxt; -use ext::base; -use ext::build::AstBuilder; -use parse::parser::{Parser, PathStyle}; -use parse::token; -use ptr::P; -use tokenstream::{DelimSpan, TokenStream, TokenTree}; - -/// Quasiquoting works via token trees. -/// -/// This is registered as a set of expression syntax extension called quote! -/// that lifts its argument token-tree to an AST representing the -/// construction of the same token tree, with `token::SubstNt` interpreted -/// as antiquotes (splices). - -pub mod rt { - use ast; - use source_map::Spanned; - use ext::base::ExtCtxt; - use parse::{self, classify}; - use parse::token::{self, Token}; - use ptr::P; - use symbol::Symbol; - use ThinVec; - - use tokenstream::{DelimSpan, TokenTree, TokenStream}; - - pub use parse::new_parser_from_tts; - pub use syntax_pos::{BytePos, Span, DUMMY_SP, FileName}; - pub use source_map::{dummy_spanned}; - - pub trait ToTokens { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec; - } - - impl ToTokens for TokenTree { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![self.clone()] - } - } - - impl ToTokens for Vec { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - self.iter().flat_map(|t| t.to_tokens(cx)).collect() - } - } - - impl ToTokens for Spanned { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - // FIXME: use the span? - self.node.to_tokens(cx) - } - } - - impl ToTokens for Option { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - match *self { - Some(ref t) => t.to_tokens(cx), - None => Vec::new(), - } - } - } - - impl ToTokens for ast::Ident { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![TokenTree::Token(self.span, Token::from_ast_ident(*self))] - } - } - - impl ToTokens for ast::Path { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtPath(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Ty { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtTy(P(self.clone())); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Block { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtBlock(P(self.clone())); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Generics { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtGenerics(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::WhereClause { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtWhereClause(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for P { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtItem(self.clone()); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::ImplItem { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtImplItem(self.clone()); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for P { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtImplItem((**self).clone()); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::TraitItem { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtTraitItem(self.clone()); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Stmt { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtStmt(self.clone()); - let mut tts = vec![TokenTree::Token(self.span, Token::interpolated(nt))]; - - // Some statements require a trailing semicolon. - if classify::stmt_ends_with_semi(&self.node) { - tts.push(TokenTree::Token(self.span, token::Semi)); - } - - tts - } - } - - impl ToTokens for P { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtExpr(self.clone()); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for P { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtPat(self.clone()); - vec![TokenTree::Token(self.span, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Arm { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtArm(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Arg { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtArg(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for P { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtBlock(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Lifetime { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![TokenTree::Token(self.ident.span, token::Lifetime(self.ident))] - } - } - - macro_rules! impl_to_tokens_slice { - ($t: ty, $sep: expr) => { - impl ToTokens for [$t] { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - let mut v = vec![]; - for (i, x) in self.iter().enumerate() { - if i > 0 { - v.extend_from_slice(&$sep); - } - v.extend(x.to_tokens(cx)); - } - v - } - } - }; - } - - impl_to_tokens_slice! { ast::Ty, [TokenTree::Token(DUMMY_SP, token::Comma)] } - impl_to_tokens_slice! { P, [] } - impl_to_tokens_slice! { ast::Arg, [TokenTree::Token(DUMMY_SP, token::Comma)] } - - impl ToTokens for ast::MetaItem { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let nt = token::NtMeta(self.clone()); - vec![TokenTree::Token(DUMMY_SP, Token::interpolated(nt))] - } - } - - impl ToTokens for ast::Attribute { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let mut r = vec![]; - // FIXME: The spans could be better - r.push(TokenTree::Token(self.span, token::Pound)); - if self.style == ast::AttrStyle::Inner { - r.push(TokenTree::Token(self.span, token::Not)); - } - let mut inner = Vec::new(); - for (i, segment) in self.path.segments.iter().enumerate() { - if i > 0 { - inner.push(TokenTree::Token(self.span, token::Colon).into()); - } - inner.push(TokenTree::Token( - self.span, token::Token::from_ast_ident(segment.ident) - ).into()); - } - self.tokens.clone().append_to_tree_and_joint_vec(&mut inner); - - let delim_span = DelimSpan::from_single(self.span); - r.push(TokenTree::Delimited( - delim_span, token::Bracket, TokenStream::new(inner).into() - )); - r - } - } - - impl ToTokens for str { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - let lit = ast::LitKind::Str(Symbol::intern(self), ast::StrStyle::Cooked); - dummy_spanned(lit).to_tokens(cx) - } - } - - impl ToTokens for () { - fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![ - TokenTree::Delimited(DelimSpan::dummy(), token::Paren, TokenStream::empty().into()) - ] - } - } - - impl ToTokens for ast::Lit { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - // FIXME: This is wrong - P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Lit(self.clone()), - span: DUMMY_SP, - attrs: ThinVec::new(), - }).to_tokens(cx) - } - } - - impl ToTokens for bool { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - dummy_spanned(ast::LitKind::Bool(*self)).to_tokens(cx) - } - } - - impl ToTokens for char { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - dummy_spanned(ast::LitKind::Char(*self)).to_tokens(cx) - } - } - - macro_rules! impl_to_tokens_int { - (signed, $t:ty, $tag:expr) => ( - impl ToTokens for $t { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - let val = if *self < 0 { - -self - } else { - *self - }; - let lit = ast::LitKind::Int(val as u128, ast::LitIntType::Signed($tag)); - let lit = P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Lit(dummy_spanned(lit)), - span: DUMMY_SP, - attrs: ThinVec::new(), - }); - if *self >= 0 { - return lit.to_tokens(cx); - } - P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Unary(ast::UnOp::Neg, lit), - span: DUMMY_SP, - attrs: ThinVec::new(), - }).to_tokens(cx) - } - } - ); - (unsigned, $t:ty, $tag:expr) => ( - impl ToTokens for $t { - fn to_tokens(&self, cx: &ExtCtxt) -> Vec { - let lit = ast::LitKind::Int(*self as u128, ast::LitIntType::Unsigned($tag)); - dummy_spanned(lit).to_tokens(cx) - } - } - ); - } - - impl_to_tokens_int! { signed, isize, ast::IntTy::Isize } - impl_to_tokens_int! { signed, i8, ast::IntTy::I8 } - impl_to_tokens_int! { signed, i16, ast::IntTy::I16 } - impl_to_tokens_int! { signed, i32, ast::IntTy::I32 } - impl_to_tokens_int! { signed, i64, ast::IntTy::I64 } - - impl_to_tokens_int! { unsigned, usize, ast::UintTy::Usize } - impl_to_tokens_int! { unsigned, u8, ast::UintTy::U8 } - impl_to_tokens_int! { unsigned, u16, ast::UintTy::U16 } - impl_to_tokens_int! { unsigned, u32, ast::UintTy::U32 } - impl_to_tokens_int! { unsigned, u64, ast::UintTy::U64 } - - pub trait ExtParseUtils { - fn parse_item(&self, s: String) -> P; - fn parse_expr(&self, s: String) -> P; - fn parse_stmt(&self, s: String) -> ast::Stmt; - fn parse_tts(&self, s: String) -> Vec; - } - - impl<'a> ExtParseUtils for ExtCtxt<'a> { - fn parse_item(&self, s: String) -> P { - panictry!(parse::parse_item_from_source_str( - FileName::quote_expansion_source_code(&s), - s, - self.parse_sess())).expect("parse error") - } - - fn parse_stmt(&self, s: String) -> ast::Stmt { - panictry!(parse::parse_stmt_from_source_str( - FileName::quote_expansion_source_code(&s), - s, - self.parse_sess())).expect("parse error") - } - - fn parse_expr(&self, s: String) -> P { - panictry!(parse::parse_expr_from_source_str( - FileName::quote_expansion_source_code(&s), - s, - self.parse_sess())) - } - - fn parse_tts(&self, s: String) -> Vec { - let source_name = FileName::quote_expansion_source_code(&s); - parse::parse_stream_from_source_str(source_name, s, self.parse_sess(), None) - .into_trees().collect() - } - } -} - -// Replaces `Token::OpenDelim .. Token::CloseDelim` with `TokenTree::Delimited(..)`. -pub fn unflatten(tts: Vec) -> Vec { - let mut results = Vec::new(); - let mut result = Vec::new(); - let mut open_span = DUMMY_SP; - for tree in tts { - match tree { - TokenTree::Token(span, token::OpenDelim(..)) => { - open_span = span; - results.push(::std::mem::replace(&mut result, Vec::new())); - } - TokenTree::Token(span, token::CloseDelim(delim)) => { - let delim_span = DelimSpan::from_pair(open_span, span); - let tree = TokenTree::Delimited( - delim_span, - delim, - result.into_iter().map(TokenStream::from).collect::().into(), - ); - result = results.pop().unwrap(); - result.push(tree); - } - tree => result.push(tree), - } - } - result -} - -// These panicking parsing functions are used by the quote_*!() syntax extensions, -// but shouldn't be used otherwise. -pub fn parse_expr_panic(parser: &mut Parser) -> P { - panictry!(parser.parse_expr()) -} - -pub fn parse_item_panic(parser: &mut Parser) -> Option> { - panictry!(parser.parse_item()) -} - -pub fn parse_pat_panic(parser: &mut Parser) -> P { - panictry!(parser.parse_pat(None)) -} - -pub fn parse_arm_panic(parser: &mut Parser) -> Arm { - panictry!(parser.parse_arm()) -} - -pub fn parse_ty_panic(parser: &mut Parser) -> P { - panictry!(parser.parse_ty()) -} - -pub fn parse_stmt_panic(parser: &mut Parser) -> Option { - panictry!(parser.parse_stmt()) -} - -pub fn parse_attribute_panic(parser: &mut Parser, permit_inner: bool) -> ast::Attribute { - panictry!(parser.parse_attribute(permit_inner)) -} - -pub fn parse_arg_panic(parser: &mut Parser) -> Arg { - panictry!(parser.parse_arg()) -} - -pub fn parse_block_panic(parser: &mut Parser) -> P { - panictry!(parser.parse_block()) -} - -pub fn parse_meta_item_panic(parser: &mut Parser) -> ast::MetaItem { - panictry!(parser.parse_meta_item()) -} - -pub fn parse_path_panic(parser: &mut Parser, mode: PathStyle) -> ast::Path { - panictry!(parser.parse_path(mode)) -} - -pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let (cx_expr, expr) = expand_tts(cx, sp, tts); - let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_expr_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_item_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_pat_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_arm(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_arm_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_ty(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_ty_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_stmt(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_stmt_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_attr(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_attribute_panic", - vec![cx.expr_bool(sp, true)], tts); - - base::MacEager::expr(expanded) -} - -pub fn expand_quote_arg(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_arg_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_block(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_block_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_meta_item(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let expanded = expand_parse_call(cx, sp, "parse_meta_item_panic", vec![], tts); - base::MacEager::expr(expanded) -} - -pub fn expand_quote_path(cx: &mut ExtCtxt, - sp: Span, - tts: &[TokenTree]) - -> Box { - let mode = mk_parser_path(cx, sp, &["PathStyle", "Type"]); - let expanded = expand_parse_call(cx, sp, "parse_path_panic", vec![mode], tts); - base::MacEager::expr(expanded) -} - -fn ids_ext(strs: Vec) -> Vec { - strs.iter().map(|s| ast::Ident::from_str(s)).collect() -} - -fn id_ext(s: &str) -> ast::Ident { - ast::Ident::from_str(s) -} - -// Lift an ident to the expr that evaluates to that ident. -fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P { - let e_str = cx.expr_str(sp, ident.name); - cx.expr_method_call(sp, - cx.expr_ident(sp, id_ext("ext_cx")), - id_ext("ident_of"), - vec![e_str]) -} - -// Lift a name to the expr that evaluates to that name -fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P { - let e_str = cx.expr_str(sp, ident.name); - cx.expr_method_call(sp, - cx.expr_ident(sp, id_ext("ext_cx")), - id_ext("name_of"), - vec![e_str]) -} - -fn mk_tt_path(cx: &ExtCtxt, sp: Span, name: &str) -> P { - let idents = vec![id_ext("syntax"), id_ext("tokenstream"), id_ext("TokenTree"), id_ext(name)]; - cx.expr_path(cx.path_global(sp, idents)) -} - -fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> P { - let idents = vec![id_ext("syntax"), id_ext("parse"), id_ext("token"), id_ext(name)]; - cx.expr_path(cx.path_global(sp, idents)) -} - -fn mk_parser_path(cx: &ExtCtxt, sp: Span, names: &[&str]) -> P { - let mut idents = vec![id_ext("syntax"), id_ext("parse"), id_ext("parser")]; - idents.extend(names.iter().cloned().map(id_ext)); - cx.expr_path(cx.path_global(sp, idents)) -} - -fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOpToken) -> P { - let name = match bop { - token::Plus => "Plus", - token::Minus => "Minus", - token::Star => "Star", - token::Slash => "Slash", - token::Percent => "Percent", - token::Caret => "Caret", - token::And => "And", - token::Or => "Or", - token::Shl => "Shl", - token::Shr => "Shr" - }; - mk_token_path(cx, sp, name) -} - -fn mk_delim(cx: &ExtCtxt, sp: Span, delim: token::DelimToken) -> P { - let name = match delim { - token::Paren => "Paren", - token::Bracket => "Bracket", - token::Brace => "Brace", - token::NoDelim => "NoDelim", - }; - mk_token_path(cx, sp, name) -} - -#[allow(non_upper_case_globals)] -fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { - macro_rules! mk_lit { - ($name: expr, $suffix: expr, $content: expr $(, $count: expr)*) => {{ - let name = mk_name(cx, sp, ast::Ident::with_empty_ctxt($content)); - let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![ - name $(, cx.expr_u16(sp, $count))* - ]); - let suffix = match $suffix { - Some(name) => cx.expr_some(sp, mk_name(cx, sp, ast::Ident::with_empty_ctxt(name))), - None => cx.expr_none(sp) - }; - cx.expr_call(sp, mk_token_path(cx, sp, "Literal"), vec![inner, suffix]) - }} - } - - let name = match *tok { - token::BinOp(binop) => { - return cx.expr_call(sp, mk_token_path(cx, sp, "BinOp"), vec![mk_binop(cx, sp, binop)]); - } - token::BinOpEq(binop) => { - return cx.expr_call(sp, mk_token_path(cx, sp, "BinOpEq"), - vec![mk_binop(cx, sp, binop)]); - } - - token::OpenDelim(delim) => { - return cx.expr_call(sp, mk_token_path(cx, sp, "OpenDelim"), - vec![mk_delim(cx, sp, delim)]); - } - token::CloseDelim(delim) => { - return cx.expr_call(sp, mk_token_path(cx, sp, "CloseDelim"), - vec![mk_delim(cx, sp, delim)]); - } - - token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), - token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), - token::Literal(token::Err(_i), _suf) => return cx.expr(sp, ast::ExprKind::Err), - token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), - token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), - token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), - token::Literal(token::StrRaw(i, n), suf) => return mk_lit!("StrRaw", suf, i, n), - token::Literal(token::ByteStr(i), suf) => return mk_lit!("ByteStr", suf, i), - token::Literal(token::ByteStrRaw(i, n), suf) => return mk_lit!("ByteStrRaw", suf, i, n), - - token::Ident(ident, is_raw) => { - return cx.expr_call(sp, - mk_token_path(cx, sp, "Ident"), - vec![mk_ident(cx, sp, ident), cx.expr_bool(sp, is_raw)]); - } - - token::Lifetime(ident) => { - return cx.expr_call(sp, - mk_token_path(cx, sp, "Lifetime"), - vec![mk_ident(cx, sp, ident)]); - } - - token::DocComment(ident) => { - return cx.expr_call(sp, - mk_token_path(cx, sp, "DocComment"), - vec![mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident))]); - } - - token::Interpolated(_) => { - cx.span_err(sp, "quote! with interpolated token"); - // Use dummy name. - "Interpolated" - } - - token::Eq => "Eq", - token::Lt => "Lt", - token::Le => "Le", - token::EqEq => "EqEq", - token::Ne => "Ne", - token::Ge => "Ge", - token::Gt => "Gt", - token::AndAnd => "AndAnd", - token::OrOr => "OrOr", - token::Not => "Not", - token::Tilde => "Tilde", - token::At => "At", - token::Dot => "Dot", - token::DotDot => "DotDot", - token::DotDotDot => "DotDotDot", - token::DotDotEq => "DotDotEq", - token::Comma => "Comma", - token::Semi => "Semi", - token::Colon => "Colon", - token::ModSep => "ModSep", - token::RArrow => "RArrow", - token::LArrow => "LArrow", - token::FatArrow => "FatArrow", - token::Pound => "Pound", - token::Dollar => "Dollar", - token::Question => "Question", - token::SingleQuote => "SingleQuote", - token::Eof => "Eof", - - token::Whitespace | token::Comment | token::Shebang(_) => { - panic!("unhandled token in quote!"); - } - }; - mk_token_path(cx, sp, name) -} - -fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, quoted: bool) -> Vec { - match *tt { - TokenTree::Token(sp, token::Ident(ident, _)) if quoted => { - // tt.extend($ident.to_tokens(ext_cx)) - - let e_to_toks = - cx.expr_method_call(sp, - cx.expr_ident(sp, ident), - id_ext("to_tokens"), - vec![cx.expr_ident(sp, id_ext("ext_cx"))]); - let e_to_toks = - cx.expr_method_call(sp, e_to_toks, id_ext("into_iter"), vec![]); - - let e_push = - cx.expr_method_call(sp, - cx.expr_ident(sp, id_ext("tt")), - id_ext("extend"), - vec![e_to_toks]); - - vec![cx.stmt_expr(e_push)] - } - TokenTree::Token(sp, ref tok) => { - let e_sp = cx.expr_ident(sp, id_ext("_sp")); - let e_tok = cx.expr_call(sp, - mk_tt_path(cx, sp, "Token"), - vec![e_sp, expr_mk_token(cx, sp, tok)]); - let e_push = - cx.expr_method_call(sp, - cx.expr_ident(sp, id_ext("tt")), - id_ext("push"), - vec![e_tok]); - vec![cx.stmt_expr(e_push)] - }, - TokenTree::Delimited(span, delim, ref tts) => { - let mut stmts = statements_mk_tt(cx, &TokenTree::open_tt(span.open, delim), false); - stmts.extend(statements_mk_tts(cx, tts.clone())); - stmts.extend(statements_mk_tt(cx, &TokenTree::close_tt(span.close, delim), false)); - stmts - } - } -} - -fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[TokenTree]) - -> (P, Vec) { - let mut p = cx.new_parser_from_tts(tts); - - let cx_expr = panictry!(p.parse_expr()); - if !p.eat(&token::Comma) { - let _ = p.diagnostic().fatal("expected token `,`"); - } - - let tts = panictry!(p.parse_all_token_trees()); - p.abort_if_errors(); - - (cx_expr, tts) -} - -fn mk_stmts_let(cx: &ExtCtxt, sp: Span) -> Vec { - // We also bind a single value, sp, to ext_cx.call_site() - // - // This causes every span in a token-tree quote to be attributed to the - // call site of the extension using the quote. We can't really do much - // better since the source of the quote may well be in a library that - // was not even parsed by this compilation run, that the user has no - // source code for (eg. in libsyntax, which they're just _using_). - // - // The old quasiquoter had an elaborate mechanism for denoting input - // file locations from which quotes originated; unfortunately this - // relied on feeding the source string of the quote back into the - // compiler (which we don't really want to do) and, in any case, only - // pushed the problem a very small step further back: an error - // resulting from a parse of the resulting quote is still attributed to - // the site the string literal occurred, which was in a source file - // _other_ than the one the user has control over. For example, an - // error in a quote from the protocol compiler, invoked in user code - // using macro_rules! for example, will be attributed to the macro_rules.rs - // file in libsyntax, which the user might not even have source to (unless - // they happen to have a compiler on hand). Over all, the phase distinction - // just makes quotes "hard to attribute". Possibly this could be fixed - // by recreating some of the original qq machinery in the tt regime - // (pushing fake SourceFiles onto the parser to account for original sites - // of quotes, for example) but at this point it seems not likely to be - // worth the hassle. - - let e_sp = cx.expr_method_call(sp, - cx.expr_ident(sp, id_ext("ext_cx")), - id_ext("call_site"), - Vec::new()); - - let stmt_let_sp = cx.stmt_let(sp, false, - id_ext("_sp"), - e_sp); - - let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp)); - - vec![stmt_let_sp, stmt_let_tt] -} - -fn statements_mk_tts(cx: &ExtCtxt, tts: TokenStream) -> Vec { - let mut ss = Vec::new(); - let mut quoted = false; - for tt in tts.into_trees() { - quoted = match tt { - TokenTree::Token(_, token::Dollar) if !quoted => true, - _ => { - ss.extend(statements_mk_tt(cx, &tt, quoted)); - false - } - } - } - ss -} - -fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) -> (P, P) { - let (cx_expr, tts) = parse_arguments_to_quote(cx, tts); - - let mut vector = mk_stmts_let(cx, sp); - vector.extend(statements_mk_tts(cx, tts.iter().cloned().collect())); - vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt")))); - let block = cx.expr_block(cx.block(sp, vector)); - let unflatten = vec![id_ext("syntax"), id_ext("ext"), id_ext("quote"), id_ext("unflatten")]; - - (cx_expr, cx.expr_call_global(sp, unflatten, vec![block])) -} - -fn expand_wrapper(cx: &ExtCtxt, - sp: Span, - cx_expr: P, - expr: P, - imports: &[&[&str]]) -> P { - // Explicitly borrow to avoid moving from the invoker (#16992) - let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr)); - let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow); - - let mut stmts = imports.iter().map(|path| { - // make item: `use ...;` - let path = path.iter().map(|s| s.to_string()).collect(); - let use_item = cx.item_use_glob( - sp, - respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited), - ids_ext(path), - ); - cx.stmt_item(sp, use_item) - }).chain(Some(stmt_let_ext_cx)).collect::>(); - stmts.push(cx.stmt_expr(expr)); - - cx.expr_block(cx.block(sp, stmts)) -} - -fn expand_parse_call(cx: &ExtCtxt, - sp: Span, - parse_method: &str, - arg_exprs: Vec> , - tts: &[TokenTree]) -> P { - let (cx_expr, tts_expr) = expand_tts(cx, sp, tts); - - let parse_sess_call = || cx.expr_method_call( - sp, cx.expr_ident(sp, id_ext("ext_cx")), - id_ext("parse_sess"), Vec::new()); - - let new_parser_call = - cx.expr_call(sp, - cx.expr_ident(sp, id_ext("new_parser_from_tts")), - vec![parse_sess_call(), tts_expr]); - - let path = vec![id_ext("syntax"), id_ext("ext"), id_ext("quote"), id_ext(parse_method)]; - let mut args = vec![cx.expr_mut_addr_of(sp, new_parser_call)]; - args.extend(arg_exprs); - let expr = cx.expr_call_global(sp, path, args); - - if parse_method == "parse_attribute" { - expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"], - &["syntax", "parse", "attr"]]) - } else { - expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]) - } -} diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9b54e8f9c1f2c..9e107fee5bad3 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -124,7 +124,6 @@ declare_features! ( (active, link_llvm_intrinsics, "1.0.0", Some(29602), None), (active, linkage, "1.0.0", Some(29603), None), - (active, quote, "1.0.0", Some(29601), None), // rustc internal (active, rustc_diagnostic_macros, "1.0.0", None, None), @@ -504,6 +503,7 @@ declare_features! ( // Paths of the form: `extern::foo::bar` (removed, extern_in_paths, "1.33.0", Some(55600), None, Some("subsumed by `::foo::bar` paths")), + (removed, quote, "1.0.0", Some(29601), None, None), ); declare_features! ( diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index df22dacce1a75..b2a3ae7f9d975 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -174,7 +174,6 @@ pub mod ext { pub mod derive; pub mod expand; pub mod placeholders; - pub mod quote; pub mod source_util; pub mod tt { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 8d039692ac4dd..c7330004d6ded 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -8,7 +8,6 @@ use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; use feature_gate::UnstableFeatures; use parse::parser::Parser; -use ptr::P; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use diagnostics::plugin::ErrorMap; @@ -135,25 +134,6 @@ pub fn parse_crate_attrs_from_source_str(name: FileName, source: String, sess: & new_parser_from_source_str(sess, name, source).parse_inner_attributes() } -crate fn parse_expr_from_source_str(name: FileName, source: String, sess: &ParseSess) - -> PResult> { - new_parser_from_source_str(sess, name, source).parse_expr() -} - -/// Parses an item. -/// -/// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err` -/// when a syntax error occurred. -crate fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess) - -> PResult>> { - new_parser_from_source_str(sess, name, source).parse_item() -} - -crate fn parse_stmt_from_source_str(name: FileName, source: String, sess: &ParseSess) - -> PResult> { - new_parser_from_source_str(sess, name, source).parse_stmt() -} - pub fn parse_stream_from_source_str(name: FileName, source: String, sess: &ParseSess, override_span: Option) -> TokenStream { @@ -781,13 +761,22 @@ mod tests { use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION}; use ast::{self, Ident, PatKind}; use attr::first_attr_value_str_by_name; - use parse; + use ptr::P; use print::pprust::item_to_string; use tokenstream::{DelimSpan, TokenTree}; use util::parser_testing::string_to_stream; use util::parser_testing::{string_to_expr, string_to_item}; use with_globals; + /// Parses an item. + /// + /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err` + /// when a syntax error occurred. + fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess) + -> PResult>> { + new_parser_from_source_str(sess, name, source).parse_item() + } + // produce a syntax_pos::span fn sp(a: u32, b: u32) -> Span { Span::new(BytePos(a), BytePos(b), NO_EXPANSION) @@ -1016,9 +1005,15 @@ mod tests { #[test] fn ttdelim_span() { + fn parse_expr_from_source_str( + name: FileName, source: String, sess: &ParseSess + ) -> PResult> { + new_parser_from_source_str(sess, name, source).parse_expr() + } + with_globals(|| { let sess = ParseSess::new(FilePathMapping::empty()); - let expr = parse::parse_expr_from_source_str(PathBuf::from("foo").into(), + let expr = parse_expr_from_source_str(PathBuf::from("foo").into(), "foo!( fn main() { body } )".to_string(), &sess).unwrap(); let tts: Vec<_> = match expr.node { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 09ea099525326..624baeaf85aff 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1285,9 +1285,6 @@ impl<'a> Parser<'a> { crate fn span_bug>(&self, sp: S, m: &str) -> ! { self.sess.span_diagnostic.span_bug(sp, m) } - crate fn abort_if_errors(&self) { - self.sess.span_diagnostic.abort_if_errors(); - } fn cancel(&self, err: &mut DiagnosticBuilder) { self.sess.span_diagnostic.cancel(err) diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index e407be6c1fe80..d0b3cd865ce6e 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -25,7 +25,7 @@ fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T { let mut p = string_to_parser(&ps, s); let x = panictry!(f(&mut p)); - p.abort_if_errors(); + p.sess.span_diagnostic.abort_if_errors(); x } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 17996f2369161..5e767d237cc0e 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -11,7 +11,6 @@ #![feature(decl_macro)] #![feature(nll)] #![feature(str_escape)] -#![feature(quote)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] @@ -58,8 +57,7 @@ use syntax::ext::hygiene; use syntax::symbol::Symbol; pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, - user_exts: Vec, - enable_quotes: bool) { + user_exts: Vec) { deriving::register_builtin_derives(resolver); let mut register = |name, ext| { @@ -81,24 +79,6 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, )* } } - if enable_quotes { - use syntax::ext::quote::*; - register! { - quote_tokens: expand_quote_tokens, - quote_expr: expand_quote_expr, - quote_ty: expand_quote_ty, - quote_item: expand_quote_item, - quote_pat: expand_quote_pat, - quote_arm: expand_quote_arm, - quote_stmt: expand_quote_stmt, - quote_attr: expand_quote_attr, - quote_arg: expand_quote_arg, - quote_block: expand_quote_block, - quote_meta_item: expand_quote_meta_item, - quote_path: expand_quote_path, - } - } - use syntax::ext::source_util::*; register! { line: expand_line, diff --git a/src/test/run-fail-fulldeps/qquote.rs b/src/test/run-fail-fulldeps/qquote.rs deleted file mode 100644 index d0e0521672878..0000000000000 --- a/src/test/run-fail-fulldeps/qquote.rs +++ /dev/null @@ -1,35 +0,0 @@ -// ignore-cross-compile - -// error-pattern:expected expression, found statement (`let`) - -#![feature(quote, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; - -use syntax::ast; -use syntax::source_map; -use syntax::print::pprust; -use syntax::symbol::Symbol; -use syntax_pos::DUMMY_SP; - -fn main() { - syntax::with_globals(|| run()); -} - -fn run() { - let ps = syntax::parse::ParseSess::new(source_map::FilePathMapping::empty()); - let mut resolver = syntax::ext::base::DummyResolver; - let mut cx = syntax::ext::base::ExtCtxt::new( - &ps, - syntax::ext::expand::ExpansionConfig::default("qquote".to_string()), - &mut resolver); - let cx = &mut cx; - - println!("{}", pprust::expr_to_string(&*quote_expr!(&cx, 23))); - assert_eq!(pprust::expr_to_string(&*quote_expr!(&cx, 23)), "23"); - - let expr = quote_expr!(&cx, let x isize = 20;); - println!("{}", pprust::expr_to_string(&*expr)); - assert_eq!(pprust::expr_to_string(&*expr), "let x isize = 20;"); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-16723.rs b/src/test/run-pass-fulldeps/auxiliary/issue-16723.rs deleted file mode 100644 index 76680f5dda240..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/issue-16723.rs +++ /dev/null @@ -1,29 +0,0 @@ -// force-host - -#![feature(plugin_registrar, quote, rustc_private)] -#![crate_type = "dylib"] - -extern crate syntax; -extern crate rustc; -extern crate rustc_data_structures; -extern crate rustc_plugin; -#[macro_use] extern crate smallvec; -extern crate syntax_pos; - -use smallvec::SmallVec; -use syntax::ext::base::{ExtCtxt, MacResult, MacEager}; -use syntax::tokenstream; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("multiple_items", expand) -} - -fn expand(cx: &mut ExtCtxt, _: syntax_pos::Span, _: &[tokenstream::TokenTree]) - -> Box { - MacEager::items(smallvec![ - quote_item!(cx, struct Struct1;).unwrap(), - quote_item!(cx, struct Struct2;).unwrap() - ]) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs index e31628782dc47..a2b1d6976d0eb 100644 --- a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs +++ b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs @@ -1,209 +1,34 @@ // force-host +// no-prefer-dynamic -#![feature(plugin_registrar, quote, rustc_private)] +#![crate_type = "proc-macro"] +#![feature(rustc_private)] extern crate syntax; extern crate rustc; extern crate rustc_plugin; extern crate syntax_pos; - -use syntax::ast::{self, Item, MetaItem, ItemKind}; -use syntax::source_map::DUMMY_SP; -use syntax::ext::base::*; -use syntax::ext::quote::rt::ToTokens; -use syntax::parse::{self, token}; -use syntax::ptr::P; -use syntax::symbol::Symbol; -use syntax::tokenstream::TokenTree; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[macro_export] -macro_rules! exported_macro { () => (2) } -macro_rules! unexported_macro { () => (3) } - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("make_a_1", expand_make_a_1); - reg.register_macro("identity", expand_identity); - reg.register_syntax_extension( - Symbol::intern("rustc_into_multi_foo"), - MultiModifier(Box::new(expand_into_foo_multi))); - reg.register_syntax_extension( - Symbol::intern("rustc_duplicate"), - MultiDecorator(Box::new(expand_duplicate))); - reg.register_syntax_extension( - Symbol::intern("rustc_caller"), - MultiDecorator(Box::new(expand_caller))); -} - -fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box { - if !tts.is_empty() { - cx.span_fatal(sp, "make_a_1 takes no arguments"); - } - MacEager::expr(quote_expr!(cx, 1)) -} - -// See Issue #15750 -fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree]) -> Box { - // Parse an expression and emit it unchanged. - let mut parser = parse::new_parser_from_tts(cx.parse_sess(), tts.to_vec()); - let expr = parser.parse_expr().unwrap(); - MacEager::expr(quote_expr!(&mut *cx, $expr)) -} - -fn expand_into_foo_multi(cx: &mut ExtCtxt, - _sp: Span, - _attr: &MetaItem, - it: Annotatable) - -> Vec { - match it { - Annotatable::Item(it) => vec![ - Annotatable::Item(P(Item { - attrs: it.attrs.clone(), - ..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone() - })), - Annotatable::Item(quote_item!(cx, enum Foo3 { Bar }).unwrap()), - Annotatable::Item(quote_item!(cx, #[cfg(any())] fn foo2() {}).unwrap()), - ], - Annotatable::ImplItem(_it) => vec![ - quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| { - match i.node { - ItemKind::Impl(.., mut items) => { - Annotatable::ImplItem(P(items.pop().expect("impl method not found"))) - } - _ => unreachable!("impl parsed to something other than impl") - } - }) - ], - Annotatable::TraitItem(_it) => vec![ - quote_item!(cx, trait X { fn foo(&self) -> i32 { 0 } }).unwrap().and_then(|i| { - match i.node { - ItemKind::Trait(.., mut items) => { - Annotatable::TraitItem(P(items.pop().expect("trait method not found"))) - } - _ => unreachable!("trait parsed to something other than trait") - } - }) - ], - // covered in proc_macro/macros-in-extern.rs - Annotatable::ForeignItem(..) => unimplemented!(), - // covered in proc_macro/attr-stmt-expr.rs - Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item"), - } +extern crate proc_macro; + +use proc_macro::{TokenTree, TokenStream}; + +#[proc_macro_attribute] +pub fn rustc_duplicate(attr: TokenStream, item: TokenStream) -> TokenStream { + let mut new_name = Some(attr.into_iter().nth(0).unwrap()); + let mut encountered_idents = 0; + let input = item.to_string(); + let ret = item.into_iter().map(move |token| match token { + TokenTree::Ident(_) if encountered_idents == 1 => { + encountered_idents += 1; + new_name.take().unwrap() + } + TokenTree::Ident(_) => { + encountered_idents += 1; + token + } + _ => token + }).collect::(); + let mut input_again = input.parse::().unwrap(); + input_again.extend(ret); + input_again } - -// Create a duplicate of the annotatable, based on the MetaItem -fn expand_duplicate(cx: &mut ExtCtxt, - _sp: Span, - mi: &MetaItem, - it: &Annotatable, - push: &mut FnMut(Annotatable)) { - let copy_name = match mi.node { - ast::MetaItemKind::List(ref xs) => { - if let Some(word) = xs[0].word() { - word.ident.segments.last().unwrap().ident - } else { - cx.span_err(mi.span, "Expected word"); - return; - } - } - _ => { - cx.span_err(mi.span, "Expected list"); - return; - } - }; - - // Duplicate the item but replace its ident by the MetaItem - match it.clone() { - Annotatable::Item(it) => { - let mut new_it = (*it).clone(); - new_it.attrs.clear(); - new_it.ident = copy_name; - push(Annotatable::Item(P(new_it))); - } - Annotatable::ImplItem(it) => { - let mut new_it = (*it).clone(); - new_it.attrs.clear(); - new_it.ident = copy_name; - push(Annotatable::ImplItem(P(new_it))); - } - Annotatable::TraitItem(tt) => { - let mut new_it = (*tt).clone(); - new_it.attrs.clear(); - new_it.ident = copy_name; - push(Annotatable::TraitItem(P(new_it))); - } - // covered in proc_macro/macros-in-extern.rs - Annotatable::ForeignItem(..) => unimplemented!(), - // covered in proc_macro/attr-stmt-expr.rs - Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item") - } -} - -pub fn token_separate(ecx: &ExtCtxt, things: &[T], - token: token::Token) -> Vec { - let mut output: Vec = vec![]; - for (i, thing) in things.iter().enumerate() { - output.extend(thing.to_tokens(ecx)); - if i < things.len() - 1 { - output.push(TokenTree::Token(DUMMY_SP, token.clone())); - } - } - - output -} - -fn expand_caller(cx: &mut ExtCtxt, - sp: Span, - mi: &MetaItem, - it: &Annotatable, - push: &mut FnMut(Annotatable)) { - let (orig_fn_name, ret_type) = match *it { - Annotatable::Item(ref item) => match item.node { - ItemKind::Fn(ref decl, ..) => { - (item.ident, &decl.output) - } - _ => cx.span_fatal(item.span, "Only functions with return types can be annotated.") - }, - _ => cx.span_fatal(sp, "Only functions can be annotated.") - }; - - let (caller_name, arguments) = if let Some(list) = mi.meta_item_list() { - if list.len() < 2 { - cx.span_fatal(mi.span(), "Need a function name and at least one parameter."); - } - - let fn_name = match list[0].name() { - Some(name) => ast::Ident::with_empty_ctxt(name), - None => cx.span_fatal(list[0].span(), "First parameter must be an ident.") - }; - - (fn_name, &list[1..]) - } else { - cx.span_fatal(mi.span, "Expected list."); - }; - - let literals: Vec = arguments.iter().map(|arg| { - if let Some(lit) = arg.literal() { - lit.clone() - } else { - cx.span_fatal(arg.span(), "Expected literal."); - } - }).collect(); - - let arguments = token_separate(cx, literals.as_slice(), token::Comma); - if let ast::FunctionRetTy::Ty(ref rt) = *ret_type { - push(Annotatable::Item(quote_item!(cx, - fn $caller_name() -> $rt { - $orig_fn_name($arguments) - }).unwrap())) - } else { - push(Annotatable::Item(quote_item!(cx, - fn $caller_name() { - $orig_fn_name($arguments) - }).unwrap())) - } -} - -pub fn foo() {} diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin_with_plugin_lib.rs b/src/test/run-pass-fulldeps/auxiliary/plugin_with_plugin_lib.rs deleted file mode 100644 index 320b77e8ea8e1..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/plugin_with_plugin_lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host - -#![feature(plugin_registrar, rustc_private)] -#![deny(plugin_as_library)] // should have no effect in a plugin crate - -extern crate macro_crate_test; -extern crate rustc; -extern crate rustc_plugin; - -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(_: &mut Registry) { } diff --git a/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs b/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs deleted file mode 100644 index e2fa3744ad8fe..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs +++ /dev/null @@ -1,82 +0,0 @@ -// force-host - -#![crate_type="dylib"] -#![feature(plugin_registrar, quote, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::feature_gate::Features; -use syntax::parse::token::{NtExpr, NtPat}; -use syntax::ast::{Ident, Pat, NodeId}; -use syntax::tokenstream::{TokenTree}; -use syntax::ext::base::{ExtCtxt, MacResult, MacEager}; -use syntax::ext::build::AstBuilder; -use syntax::ext::tt::quoted; -use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; -use syntax::ext::tt::macro_parser::{Success, Failure, Error}; -use syntax::ext::tt::macro_parser::parse_failure_msg; -use syntax::ptr::P; -use syntax_pos::{Span, edition::Edition}; -use rustc_plugin::Registry; - -fn expand_mbe_matches(cx: &mut ExtCtxt, _: Span, args: &[TokenTree]) - -> Box { - - let mbe_matcher = quote_tokens!(cx, $$matched:expr, $$($$pat:pat)|+); - let mbe_matcher = quoted::parse(mbe_matcher.into_iter().collect(), - true, - cx.parse_sess, - &Features::new(), - &[], - Edition::Edition2015, - // not used... - NodeId::from_u32(0)); - let map = match TokenTree::parse(cx, &mbe_matcher, args.iter().cloned().collect()) { - Success(map) => map, - Failure(_, tok, msg) => { - panic!("expected Success, but got Failure: {} - {}", parse_failure_msg(tok), msg); - } - Error(_, s) => { - panic!("expected Success, but got Error: {}", s); - } - }; - - let matched_nt = match *map[&Ident::from_str("matched")] { - MatchedNonterminal(ref nt) => nt.clone(), - _ => unreachable!(), - }; - - let mac_expr = match (&*matched_nt, &*map[&Ident::from_str("pat")]) { - (&NtExpr(ref matched_expr), &MatchedSeq(ref pats, seq_sp)) => { - let pats: Vec> = pats.iter().map(|pat_nt| { - match *pat_nt { - MatchedNonterminal(ref nt) => match **nt { - NtPat(ref pat) => pat.clone(), - _ => unreachable!(), - }, - _ => unreachable!(), - } - }).collect(); - let span = seq_sp.entire(); - let arm = cx.arm(span, pats, cx.expr_bool(span, true)); - - quote_expr!(cx, - match $matched_expr { - $arm - _ => false - } - ) - } - _ => unreachable!() - }; - - MacEager::expr(mac_expr) -} - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("matches", expand_mbe_matches); -} diff --git a/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_2.rs b/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_2.rs deleted file mode 100644 index a356df55b3562..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_2.rs +++ /dev/null @@ -1,27 +0,0 @@ -// force-host - -#![crate_type = "dylib"] -#![feature(plugin_registrar, quote, rustc_private)] - -extern crate syntax_extension_with_dll_deps_1 as other; -extern crate syntax; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast::{Item, MetaItem}; -use syntax::ext::base::*; -use syntax::tokenstream::TokenTree; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("foo", expand_foo); -} - -fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) - -> Box { - let answer = other::the_answer(); - MacEager::expr(quote_expr!(cx, $answer)) -} diff --git a/src/test/run-pass-fulldeps/issue-16723.rs b/src/test/run-pass-fulldeps/issue-16723.rs deleted file mode 100644 index a3965f98927f9..0000000000000 --- a/src/test/run-pass-fulldeps/issue-16723.rs +++ /dev/null @@ -1,19 +0,0 @@ -// ignore-stage1 -// aux-build:issue-16723.rs -#![feature(plugin)] -#![plugin(issue_16723)] - -multiple_items!(); - -impl Struct1 { - fn foo() {} -} -impl Struct2 { - fn foo() {} -} - -fn main() { - Struct1::foo(); - Struct2::foo(); - println!("hallo"); -} diff --git a/src/test/run-pass-fulldeps/issue-16992.rs b/src/test/run-pass-fulldeps/issue-16992.rs deleted file mode 100644 index e5945b679f382..0000000000000 --- a/src/test/run-pass-fulldeps/issue-16992.rs +++ /dev/null @@ -1,15 +0,0 @@ -// ignore-cross-compile - -#![feature(quote, rustc_private)] - -extern crate syntax; - -use syntax::ext::base::ExtCtxt; - -#[allow(dead_code)] -fn foobar(cx: &mut ExtCtxt) { - quote_expr!(cx, 1); - quote_expr!(cx, 2); -} - -fn main() { } diff --git a/src/test/run-pass-fulldeps/issue-18763-quote-token-tree.rs b/src/test/run-pass-fulldeps/issue-18763-quote-token-tree.rs deleted file mode 100644 index 9fa3d3de8f22e..0000000000000 --- a/src/test/run-pass-fulldeps/issue-18763-quote-token-tree.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_imports)] -// ignore-cross-compile -#![feature(quote, rustc_private)] - -extern crate syntax; - -use syntax::ext::base::ExtCtxt; - -fn syntax_extension(cx: &ExtCtxt) { - let _toks_1 = vec![quote_tokens!(cx, /** comment */ fn foo() {})]; - let name = quote_tokens!(cx, bar); - let _toks_2 = vec![quote_item!(cx, static $name:isize = 2;)]; - let _toks_4 = quote_tokens!(cx, $name:static $name:sizeof); - let _toks_3 = vec![quote_item!(cx, - /// comment - fn foo() { let $name:isize = 3; } - )]; -} - -fn main() { -} diff --git a/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs b/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs deleted file mode 100644 index 3c251cc0f553a..0000000000000 --- a/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs +++ /dev/null @@ -1,16 +0,0 @@ -// aux-build:macro_crate_test.rs -// ignore-stage1 - -// Issue #15750: a macro that internally parses its input and then -// uses `quote_expr!` to rearrange it should be hygiene-preserving. - -#![feature(plugin)] -#![plugin(macro_crate_test)] - -fn main() { - let x = 3; - assert_eq!(3, identity!(x)); - assert_eq!(6, identity!(x+x)); - let x = 4; - assert_eq!(4, identity!(x)); -} diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator-literals.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator-literals.rs deleted file mode 100644 index eb7ab139d647f..0000000000000 --- a/src/test/run-pass-fulldeps/macro-crate-multi-decorator-literals.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![allow(plugin_as_library)] -#![allow(unused_imports)] -// aux-build:macro_crate_test.rs -// ignore-stage1 - -#![feature(plugin, rustc_attrs)] -#![plugin(macro_crate_test)] - -#[macro_use] -#[no_link] -extern crate macro_crate_test; - -// The `caller(name, args...)` attribute emits a new nullary function named -// `name` that calls the annotated function with `args`. As an example, consider -// the following: -// -// #[caller(simple, 1, "hello", 3.14)] -// fn f(num: isize, string: &'static str, float: f32) -> (isize, &'static str, float) { -// (num, string, float) -// } -// -// This results in a function named `simple` that calls `f(1, "hello", 3.14)`. -// As a result, the expression `simple()` evaluates to `(1, "helllo", 3.14)`. - -#[rustc_caller(simple, 1, "hello", 3.14)] -#[rustc_caller(simple1, 2, "bye", 6.28)] -#[rustc_caller(simple2, 3, "hi", 1.01)] -fn f(num: isize, string: &'static str, float: f32) -> (isize, &'static str, f32) { - (num, string, float) -} - -#[rustc_caller(complex, true, 10)] -#[rustc_caller(complex1, false, 15)] -#[rustc_caller(complex2, true, 20)] -fn g(emit: bool, num: i32) -> Option { - match emit { - true => Some(num), - false => None - } -} - -fn main() { - assert_eq!(simple(), (1, "hello", 3.14)); - assert_eq!(simple1(), (2, "bye", 6.28)); - assert_eq!(simple2(), (3, "hi", 1.01)); - - assert_eq!(complex(), Some(10)); - assert_eq!(complex1(), None); - assert_eq!(complex2(), Some(20)); -} diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs index ef28f233feaa1..dcac160c4c974 100644 --- a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs +++ b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs @@ -5,11 +5,9 @@ // aux-build:macro_crate_test.rs // ignore-stage1 -#![feature(plugin, rustc_attrs)] -#![plugin(macro_crate_test)] +#![feature(rustc_attrs)] #[macro_use] -#[no_link] extern crate macro_crate_test; // The duplicate macro will create a copy of the item with the given identifier. diff --git a/src/test/run-pass-fulldeps/macro-crate.rs b/src/test/run-pass-fulldeps/macro-crate.rs deleted file mode 100644 index 62838c2c0839d..0000000000000 --- a/src/test/run-pass-fulldeps/macro-crate.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![allow(plugin_as_library)] -#![allow(dead_code)] -// aux-build:macro_crate_test.rs -// ignore-stage1 - -#![feature(plugin, rustc_attrs)] -#![plugin(macro_crate_test)] - -#[macro_use] #[no_link] -extern crate macro_crate_test; - -#[rustc_into_multi_foo] -#[derive(PartialEq, Clone, Debug)] -fn foo() -> AnotherFakeTypeThatHadBetterGoAway {} - -// Check that the `#[into_multi_foo]`-generated `foo2` is configured away -fn foo2() {} - -trait Qux { - #[rustc_into_multi_foo] - fn bar(); -} - -impl Qux for i32 { - #[rustc_into_multi_foo] - fn bar() {} -} - -impl Qux for u8 {} - -pub fn main() { - assert_eq!(1, make_a_1!()); - assert_eq!(2, exported_macro!()); - - assert_eq!(Foo2::Bar2, Foo2::Bar2); - test(None::); - - let _ = Foo3::Bar; - - let x = 10i32; - assert_eq!(x.foo(), 42); - let x = 10u8; - assert_eq!(x.foo(), 0); -} - -fn test(_: Option) {} diff --git a/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs b/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs deleted file mode 100644 index c672081edf48c..0000000000000 --- a/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs +++ /dev/null @@ -1,11 +0,0 @@ -// aux-build:procedural_mbe_matching.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(procedural_mbe_matching)] - -pub fn main() { - assert_eq!(matches!(Some(123), None | Some(0)), false); - assert_eq!(matches!(Some(123), None | Some(123)), true); - assert_eq!(matches!(true, true), true); -} diff --git a/src/test/run-pass-fulldeps/plugin-lib-ok-in-plugin.rs b/src/test/run-pass-fulldeps/plugin-lib-ok-in-plugin.rs deleted file mode 100644 index e9f234f7f545e..0000000000000 --- a/src/test/run-pass-fulldeps/plugin-lib-ok-in-plugin.rs +++ /dev/null @@ -1,16 +0,0 @@ -// aux-build:macro_crate_test.rs -// aux-build:plugin_with_plugin_lib.rs -// ignore-stage1 -// ignore-cross-compile -// -// macro_crate_test will not compile on a cross-compiled target because -// libsyntax is not compiled for it. - -#![deny(plugin_as_library)] -#![feature(plugin)] -#![plugin(macro_crate_test)] -#![plugin(plugin_with_plugin_lib)] - -fn main() { - assert_eq!(1, make_a_1!()); -} diff --git a/src/test/run-pass-fulldeps/plugin-plus-extern-crate.rs b/src/test/run-pass-fulldeps/plugin-plus-extern-crate.rs deleted file mode 100644 index e45a7f59c1bdc..0000000000000 --- a/src/test/run-pass-fulldeps/plugin-plus-extern-crate.rs +++ /dev/null @@ -1,17 +0,0 @@ -// aux-build:macro_crate_test.rs -// ignore-stage1 -// ignore-cross-compile -// -// macro_crate_test will not compile on a cross-compiled target because -// libsyntax is not compiled for it. - -#![allow(plugin_as_library)] -#![feature(plugin)] -#![plugin(macro_crate_test)] - -extern crate macro_crate_test; - -fn main() { - assert_eq!(1, make_a_1!()); - macro_crate_test::foo(); -} diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs deleted file mode 100644 index 33063fc74bfb3..0000000000000 --- a/src/test/run-pass-fulldeps/qquote.rs +++ /dev/null @@ -1,92 +0,0 @@ -#![allow(unused_imports)] -// ignore-cross-compile - -#![feature(quote, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; - -use syntax::source_map::FilePathMapping; -use syntax::print::pprust::*; -use syntax::symbol::Symbol; -use syntax_pos::DUMMY_SP; - -fn main() { - syntax::with_globals(|| run()); -} - -fn run() { - let ps = syntax::parse::ParseSess::new(FilePathMapping::empty()); - let mut resolver = syntax::ext::base::DummyResolver; - let mut cx = syntax::ext::base::ExtCtxt::new( - &ps, - syntax::ext::expand::ExpansionConfig::default("qquote".to_string()), - &mut resolver); - let cx = &mut cx; - - macro_rules! check { - ($f: ident, $($e: expr),+; $expect: expr) => ({ - $(assert_eq!($f(&$e), $expect);)+ - }); - } - - let abc = quote_expr!(cx, 23); - check!(expr_to_string, abc, *quote_expr!(cx, $abc); "23"); - - let ty = quote_ty!(cx, isize); - check!(ty_to_string, ty, *quote_ty!(cx, $ty); "isize"); - - let item = quote_item!(cx, static x: $ty = 10;).unwrap(); - check!(item_to_string, item, quote_item!(cx, $item).unwrap(); "static x: isize = 10;"); - - let twenty: u16 = 20; - let stmt = quote_stmt!(cx, let x = $twenty;).unwrap(); - check!(stmt_to_string, stmt, quote_stmt!(cx, $stmt).unwrap(); "let x = 20u16;"); - - let pat = quote_pat!(cx, Some(_)); - check!(pat_to_string, pat, *quote_pat!(cx, $pat); "Some(_)"); - - let expr = quote_expr!(cx, (x, y)); - let arm = quote_arm!(cx, (ref x, ref y) => $expr,); - check!(arm_to_string, arm, quote_arm!(cx, $arm); " (ref x, ref y) => (x, y),"); - - let attr = quote_attr!(cx, #![cfg(foo = "bar")]); - check!(attribute_to_string, attr, quote_attr!(cx, $attr); r#"#![cfg(foo = "bar")]"#); - - // quote_arg! - - let arg = quote_arg!(cx, foo: i32); - check!(arg_to_string, arg, quote_arg!(cx, $arg); "foo: i32"); - - let function = quote_item!(cx, fn f($arg) { }).unwrap(); - check!(item_to_string, function; "fn f(foo: i32) { }"); - - let args = vec![arg, quote_arg!(cx, bar: u32)]; - let args = &args[..]; - let function = quote_item!(cx, fn f($args) { }).unwrap(); - check!(item_to_string, function; "fn f(foo: i32, bar: u32) { }"); - - // quote_block! - - let block = quote_block!(cx, { $stmt let y = 40u32; }); - check!(block_to_string, block, *quote_block!(cx, $block); "{ let x = 20u16; let y = 40u32; }"); - - let function = quote_item!(cx, fn f() $block).unwrap(); - check!(item_to_string, function; "fn f() { let x = 20u16; let y = 40u32; }"); - - // quote_path! - - let path = quote_path!(cx, ::syntax::ptr::P); - check!(path_to_string, path, quote_path!(cx, $path); "::syntax::ptr::P"); - - let ty = quote_ty!(cx, $path); - check!(ty_to_string, ty; "::syntax::ptr::P"); - - // quote_meta_item! - - let meta = quote_meta_item!(cx, cfg(foo = "bar")); - check!(meta_item_to_string, meta, quote_meta_item!(cx, $meta); r#"cfg(foo = "bar")"#); - - let attr = quote_attr!(cx, #![$meta]); - check!(attribute_to_string, attr; r#"#![cfg(foo = "bar")]"#); -} diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs deleted file mode 100644 index 04a4c442e0025..0000000000000 --- a/src/test/run-pass-fulldeps/quote-tokens.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_imports)] -// ignore-cross-compile -#![feature(quote, rustc_private)] - -extern crate syntax; - -use syntax::ext::base::ExtCtxt; -use syntax::ptr::P; -use syntax::parse::PResult; - -fn syntax_extension(cx: &ExtCtxt) { - let e_toks : Vec = quote_tokens!(cx, 1 + 2); - let p_toks : Vec = quote_tokens!(cx, (x, 1 .. 4, *)); - - let a: P = quote_expr!(cx, 1 + 2); - let _b: Option> = quote_item!(cx, static foo : isize = $e_toks; ); - let _c: P = quote_pat!(cx, (x, 1 .. 4, *) ); - let _d: Option = quote_stmt!(cx, let x = $a; ); - let _d: syntax::ast::Arm = quote_arm!(cx, (ref x, ref y) = (x, y) ); - let _e: P = quote_expr!(cx, match foo { $p_toks => 10 } ); - - let _f: P = quote_expr!(cx, ()); - let _g: P = quote_expr!(cx, true); - let _h: P = quote_expr!(cx, 'a'); - - let i: Option> = quote_item!(cx, #[derive(Eq)] struct Foo; ); - assert!(i.is_some()); - - let _l: P = quote_ty!(cx, &isize); - - let _n: syntax::ast::Attribute = quote_attr!(cx, #![cfg(foo, bar = "baz")]); - - let _o: Option> = quote_item!(cx, fn foo() {}); - - let stmts = vec![ - quote_stmt!(cx, let x = 1;).unwrap(), - quote_stmt!(cx, let y = 2;).unwrap(), - ]; - let expr: P = quote_expr!(cx, x + y); -} - -fn main() { -} diff --git a/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs b/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs deleted file mode 100644 index 1568bf2603986..0000000000000 --- a/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![allow(dead_code)] -// ignore-cross-compile -#![feature(quote, rustc_private)] -#![deny(unused_variables)] - -extern crate syntax; - -use syntax::ext::base::ExtCtxt; - -fn test(cx: &mut ExtCtxt) { - let foo = 10; - let _e = quote_expr!(cx, $foo); -} - -pub fn main() { } diff --git a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs deleted file mode 100644 index 7c236fd69eae6..0000000000000 --- a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs +++ /dev/null @@ -1,10 +0,0 @@ -// aux-build:syntax_extension_with_dll_deps_1.rs -// aux-build:syntax_extension_with_dll_deps_2.rs -// ignore-stage1 - -#![feature(plugin, rustc_private)] -#![plugin(syntax_extension_with_dll_deps_2)] - -fn main() { - foo!(); -} diff --git a/src/test/ui-fulldeps/auxiliary/macro_crate_test.rs b/src/test/ui-fulldeps/auxiliary/macro_crate_test.rs deleted file mode 100644 index a364aa0422deb..0000000000000 --- a/src/test/ui-fulldeps/auxiliary/macro_crate_test.rs +++ /dev/null @@ -1,149 +0,0 @@ -// force-host - -#![feature(plugin_registrar, quote, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast::{self, Item, MetaItem, ItemKind}; -use syntax::ext::base::*; -use syntax::parse; -use syntax::ptr::P; -use syntax::symbol::Symbol; -use syntax::tokenstream::TokenTree; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[macro_export] -macro_rules! exported_macro { () => (2) } -macro_rules! unexported_macro { () => (3) } - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("make_a_1", expand_make_a_1); - reg.register_macro("identity", expand_identity); - reg.register_syntax_extension( - Symbol::intern("into_multi_foo"), - MultiModifier(Box::new(expand_into_foo_multi))); - reg.register_syntax_extension( - Symbol::intern("noop_attribute"), - MultiModifier(Box::new(expand_noop_attribute))); - reg.register_syntax_extension( - Symbol::intern("duplicate"), - MultiDecorator(Box::new(expand_duplicate))); -} - -fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) - -> Box { - if !tts.is_empty() { - cx.span_fatal(sp, "make_a_1 takes no arguments"); - } - MacEager::expr(quote_expr!(cx, 1)) -} - -// See Issue #15750 -fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree]) - -> Box { - // Parse an expression and emit it unchanged. - let mut parser = parse::new_parser_from_tts(cx.parse_sess(), tts.to_vec()); - let expr = parser.parse_expr().unwrap(); - MacEager::expr(quote_expr!(&mut *cx, $expr)) -} - -fn expand_into_foo_multi(cx: &mut ExtCtxt, - _sp: Span, - _attr: &MetaItem, - it: Annotatable) -> Annotatable { - match it { - Annotatable::Item(it) => { - Annotatable::Item(P(Item { - attrs: it.attrs.clone(), - ..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone() - })) - } - Annotatable::ImplItem(_) => { - quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| { - match i.node { - ItemKind::Impl(.., mut items) => { - Annotatable::ImplItem(P(items.pop().expect("impl method not found"))) - } - _ => unreachable!("impl parsed to something other than impl") - } - }) - } - Annotatable::TraitItem(_) => { - quote_item!(cx, trait X { fn foo(&self) -> i32 { 0 } }).unwrap().and_then(|i| { - match i.node { - ItemKind::Trait(.., mut items) => { - Annotatable::TraitItem(P(items.pop().expect("trait method not found"))) - } - _ => unreachable!("trait parsed to something other than trait") - } - }) - } - // covered in proc_macro/macros-in-extern.rs - Annotatable::ForeignItem(_) => unimplemented!(), - // covered in proc_macro/attr-stmt-expr.rs - Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item") - } -} - -fn expand_noop_attribute(_cx: &mut ExtCtxt, - _sp: Span, - _attr: &MetaItem, - it: Annotatable) -> Annotatable { - it -} - -// Create a duplicate of the annotatable, based on the MetaItem -fn expand_duplicate(cx: &mut ExtCtxt, - _sp: Span, - mi: &MetaItem, - it: &Annotatable, - push: &mut FnMut(Annotatable)) -{ - let copy_name = match mi.node { - ast::MetaItemKind::List(ref xs) => { - if let Some(word) = xs[0].word() { - word.ident.segments.last().unwrap().ident - } else { - cx.span_err(mi.span, "Expected word"); - return; - } - } - _ => { - cx.span_err(mi.span, "Expected list"); - return; - } - }; - - // Duplicate the item but replace its ident by the MetaItem - match it.clone() { - Annotatable::Item(it) => { - let mut new_it = (*it).clone(); - new_it.attrs.clear(); - new_it.ident = copy_name; - push(Annotatable::Item(P(new_it))); - } - Annotatable::ImplItem(it) => { - let mut new_it = (*it).clone(); - new_it.attrs.clear(); - new_it.ident = copy_name; - push(Annotatable::ImplItem(P(new_it))); - } - Annotatable::TraitItem(tt) => { - let mut new_it = (*tt).clone(); - new_it.attrs.clear(); - new_it.ident = copy_name; - push(Annotatable::TraitItem(P(new_it))); - } - // covered in proc_macro/macros-in-extern.rs - Annotatable::ForeignItem(_) => unimplemented!(), - // covered in proc_macro/attr-stmt-expr.rs - Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item") - } -} - -pub fn foo() {} diff --git a/src/test/ui-fulldeps/gated-plugin.rs b/src/test/ui-fulldeps/gated-plugin.rs index 3a138d9af03ca..a647585e621fe 100644 --- a/src/test/ui-fulldeps/gated-plugin.rs +++ b/src/test/ui-fulldeps/gated-plugin.rs @@ -1,6 +1,6 @@ -// aux-build:macro_crate_test.rs +// aux-build:attr_plugin_test.rs -#![plugin(macro_crate_test)] +#![plugin(attr_plugin_test)] //~^ ERROR compiler plugins are experimental and possibly buggy fn main() {} diff --git a/src/test/ui-fulldeps/gated-plugin.stderr b/src/test/ui-fulldeps/gated-plugin.stderr index a72a45833d011..37c2b4432470d 100644 --- a/src/test/ui-fulldeps/gated-plugin.stderr +++ b/src/test/ui-fulldeps/gated-plugin.stderr @@ -1,7 +1,7 @@ error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597) --> $DIR/gated-plugin.rs:3:1 | -LL | #![plugin(macro_crate_test)] +LL | #![plugin(attr_plugin_test)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(plugin)] to the crate attributes to enable diff --git a/src/test/ui-fulldeps/gated-quote.rs b/src/test/ui-fulldeps/gated-quote.rs deleted file mode 100644 index 86848e3156fbd..0000000000000 --- a/src/test/ui-fulldeps/gated-quote.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Test that `quote`-related macro are gated by `quote` feature gate. - -// (To sanity-check the code, uncomment this.) -// #![feature(quote)] - -// FIXME the error message that is current emitted seems pretty bad. - -// gate-test-quote - -#![feature(rustc_private)] -#![allow(dead_code, unused_imports, unused_variables)] - -#[macro_use] -extern crate syntax; - -use syntax::ast; -use syntax::parse; - -struct ParseSess; - -impl ParseSess { - fn cfg(&self) -> ast::CrateConfig { loop { } } - fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { loop { } } - fn call_site(&self) -> () { loop { } } - fn ident_of(&self, st: &str) -> ast::Ident { loop { } } - fn name_of(&self, st: &str) -> ast::Name { loop { } } -} - -pub fn main() { - let ecx = &ParseSess; - let x = quote_tokens!(ecx, 3); - //~^ ERROR cannot find macro `quote_tokens!` in this scope - let x = quote_expr!(ecx, 3); - //~^ ERROR cannot find macro `quote_expr!` in this scope - let x = quote_ty!(ecx, 3); - //~^ ERROR cannot find macro `quote_ty!` in this scope - let x = quote_method!(ecx, 3); - //~^ ERROR cannot find macro `quote_method!` in this scope - let x = quote_item!(ecx, 3); - //~^ ERROR cannot find macro `quote_item!` in this scope - let x = quote_pat!(ecx, 3); - //~^ ERROR cannot find macro `quote_pat!` in this scope - let x = quote_arm!(ecx, 3); - //~^ ERROR cannot find macro `quote_arm!` in this scope - let x = quote_stmt!(ecx, 3); - //~^ ERROR cannot find macro `quote_stmt!` in this scope - let x = quote_attr!(ecx, 3); - //~^ ERROR cannot find macro `quote_attr!` in this scope - let x = quote_arg!(ecx, 3); - //~^ ERROR cannot find macro `quote_arg!` in this scope - let x = quote_block!(ecx, 3); - //~^ ERROR cannot find macro `quote_block!` in this scope - let x = quote_meta_item!(ecx, 3); - //~^ ERROR cannot find macro `quote_meta_item!` in this scope - let x = quote_path!(ecx, 3); - //~^ ERROR cannot find macro `quote_path!` in this scope -} diff --git a/src/test/ui-fulldeps/gated-quote.stderr b/src/test/ui-fulldeps/gated-quote.stderr deleted file mode 100644 index 897e97b7eb1ee..0000000000000 --- a/src/test/ui-fulldeps/gated-quote.stderr +++ /dev/null @@ -1,80 +0,0 @@ -error: cannot find macro `quote_path!` in this scope - --> $DIR/gated-quote.rs:55:13 - | -LL | let x = quote_path!(ecx, 3); - | ^^^^^^^^^^ - -error: cannot find macro `quote_meta_item!` in this scope - --> $DIR/gated-quote.rs:53:13 - | -LL | let x = quote_meta_item!(ecx, 3); - | ^^^^^^^^^^^^^^^ - -error: cannot find macro `quote_block!` in this scope - --> $DIR/gated-quote.rs:51:13 - | -LL | let x = quote_block!(ecx, 3); - | ^^^^^^^^^^^ - -error: cannot find macro `quote_arg!` in this scope - --> $DIR/gated-quote.rs:49:13 - | -LL | let x = quote_arg!(ecx, 3); - | ^^^^^^^^^ - -error: cannot find macro `quote_attr!` in this scope - --> $DIR/gated-quote.rs:47:13 - | -LL | let x = quote_attr!(ecx, 3); - | ^^^^^^^^^^ - -error: cannot find macro `quote_stmt!` in this scope - --> $DIR/gated-quote.rs:45:13 - | -LL | let x = quote_stmt!(ecx, 3); - | ^^^^^^^^^^ - -error: cannot find macro `quote_arm!` in this scope - --> $DIR/gated-quote.rs:43:13 - | -LL | let x = quote_arm!(ecx, 3); - | ^^^^^^^^^ - -error: cannot find macro `quote_pat!` in this scope - --> $DIR/gated-quote.rs:41:13 - | -LL | let x = quote_pat!(ecx, 3); - | ^^^^^^^^^ - -error: cannot find macro `quote_item!` in this scope - --> $DIR/gated-quote.rs:39:13 - | -LL | let x = quote_item!(ecx, 3); - | ^^^^^^^^^^ - -error: cannot find macro `quote_method!` in this scope - --> $DIR/gated-quote.rs:37:13 - | -LL | let x = quote_method!(ecx, 3); - | ^^^^^^^^^^^^ - -error: cannot find macro `quote_ty!` in this scope - --> $DIR/gated-quote.rs:35:13 - | -LL | let x = quote_ty!(ecx, 3); - | ^^^^^^^^ - -error: cannot find macro `quote_expr!` in this scope - --> $DIR/gated-quote.rs:33:13 - | -LL | let x = quote_expr!(ecx, 3); - | ^^^^^^^^^^ - -error: cannot find macro `quote_tokens!` in this scope - --> $DIR/gated-quote.rs:31:13 - | -LL | let x = quote_tokens!(ecx, 3); - | ^^^^^^^^^^^^ - -error: aborting due to 13 previous errors - diff --git a/src/test/ui-fulldeps/issue-48941.rs b/src/test/ui-fulldeps/issue-48941.rs deleted file mode 100644 index 8c4c2445670b8..0000000000000 --- a/src/test/ui-fulldeps/issue-48941.rs +++ /dev/null @@ -1,16 +0,0 @@ -// This is a regression test against an ICE that used to occur -// on malformed attributes for a custom MultiModifier. - -// aux-build:macro_crate_test.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(macro_crate_test)] - -#[noop_attribute("hi", rank = a)] //~ ERROR expected unsuffixed literal or identifier, found a -fn knight() { } - -#[noop_attribute("/user", data= = " $DIR/issue-48941.rs:10:24 - | -LL | #[noop_attribute("hi", rank = a)] //~ ERROR expected unsuffixed literal or identifier, found a - | ^^^^ - -error: expected unsuffixed literal or identifier, found = - --> $DIR/issue-48941.rs:13:27 - | -LL | #[noop_attribute("/user", data= = " $DIR/macro-crate-doesnt-resolve.rs:7:23 - | -LL | macro_crate_test::foo(); //~ ERROR cannot find function `foo` in module `macro_crate_test` - | ^^^ not found in `macro_crate_test` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui-fulldeps/macro-crate-unexported-macro.rs b/src/test/ui-fulldeps/macro-crate-unexported-macro.rs deleted file mode 100644 index 8cf0cc4e4f385..0000000000000 --- a/src/test/ui-fulldeps/macro-crate-unexported-macro.rs +++ /dev/null @@ -1,9 +0,0 @@ -// aux-build:macro_crate_test.rs - -#[macro_use] #[no_link] -extern crate macro_crate_test; - -fn main() { - unexported_macro!(); - //~^ ERROR cannot find macro `unexported_macro!` in this scope -} diff --git a/src/test/ui-fulldeps/macro-crate-unexported-macro.stderr b/src/test/ui-fulldeps/macro-crate-unexported-macro.stderr deleted file mode 100644 index 0d1b4b64fc5ee..0000000000000 --- a/src/test/ui-fulldeps/macro-crate-unexported-macro.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: cannot find macro `unexported_macro!` in this scope - --> $DIR/macro-crate-unexported-macro.rs:7:5 - | -LL | unexported_macro!(); - | ^^^^^^^^^^^^^^^^ help: you could try the macro: `exported_macro` - -error: aborting due to previous error - diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs index f192694dc7318..37ac8dfa39101 100644 --- a/src/test/ui-fulldeps/plugin-as-extern-crate.rs +++ b/src/test/ui-fulldeps/plugin-as-extern-crate.rs @@ -1,12 +1,12 @@ -// aux-build:macro_crate_test.rs +// aux-build:attr_plugin_test.rs // ignore-cross-compile // -// macro_crate_test will not compile on a cross-compiled target because +// attr_plugin_test will not compile on a cross-compiled target because // libsyntax is not compiled for it. #![deny(plugin_as_library)] #![allow(unused_extern_crates)] -extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library +extern crate attr_plugin_test; //~ ERROR compiler plugin used as an ordinary library fn main() { } diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr index f0406d5181aa1..4a5a53980eb8a 100644 --- a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr +++ b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr @@ -1,7 +1,7 @@ error: compiler plugin used as an ordinary library --> $DIR/plugin-as-extern-crate.rs:10:1 | -LL | extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library +LL | extern crate attr_plugin_test; //~ ERROR compiler plugin used as an ordinary library | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here diff --git a/src/test/ui-fulldeps/plugin-plus-extern-crate.rs b/src/test/ui-fulldeps/plugin-plus-extern-crate.rs deleted file mode 100644 index db13954f8eda9..0000000000000 --- a/src/test/ui-fulldeps/plugin-plus-extern-crate.rs +++ /dev/null @@ -1,17 +0,0 @@ -// aux-build:macro_crate_test.rs -// ignore-stage1 -// ignore-cross-compile -// -// macro_crate_test will not compile on a cross-compiled target because -// libsyntax is not compiled for it. - -#![deny(plugin_as_library)] -#![feature(plugin)] -#![plugin(macro_crate_test)] - -extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library - -fn main() { - assert_eq!(1, make_a_1!()); - macro_crate_test::foo(); -} diff --git a/src/test/ui-fulldeps/plugin-plus-extern-crate.stderr b/src/test/ui-fulldeps/plugin-plus-extern-crate.stderr deleted file mode 100644 index 284d76b613263..0000000000000 --- a/src/test/ui-fulldeps/plugin-plus-extern-crate.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: compiler plugin used as an ordinary library - --> $DIR/plugin-plus-extern-crate.rs:12:1 - | -LL | extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: lint level defined here - --> $DIR/plugin-plus-extern-crate.rs:8:9 - | -LL | #![deny(plugin_as_library)] - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui-fulldeps/qquote.rs b/src/test/ui-fulldeps/qquote.rs deleted file mode 100644 index 99e365d21ff94..0000000000000 --- a/src/test/ui-fulldeps/qquote.rs +++ /dev/null @@ -1,27 +0,0 @@ -// ignore-cross-compile - -#![feature(quote, rustc_private)] - -extern crate syntax; -extern crate syntax_pos; - -use syntax::ast; -use syntax::source_map::FilePathMapping; -use syntax::print::pprust; -use syntax::symbol::Symbol; -use syntax_pos::DUMMY_SP; - -fn main() { - let ps = syntax::parse::ParseSess::new(FilePathMapping::empty()); - let mut resolver = syntax::ext::base::DummyResolver; - let mut cx = syntax::ext::base::ExtCtxt::new( - &ps, - syntax::ext::expand::ExpansionConfig::default("qquote".to_string()), - &mut resolver); - let cx = &mut cx; - - assert_eq!(pprust::expr_to_string(&*quote_expr!(&cx, 23)), "23"); - - let expr = quote_expr!(&cx, 2 - $abcd + 7); //~ ERROR cannot find value `abcd` in this scope - assert_eq!(pprust::expr_to_string(&*expr), "2 - $abcd + 7"); -} diff --git a/src/test/ui-fulldeps/qquote.stderr b/src/test/ui-fulldeps/qquote.stderr deleted file mode 100644 index a51318b0edc98..0000000000000 --- a/src/test/ui-fulldeps/qquote.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0425]: cannot find value `abcd` in this scope - --> $DIR/qquote.rs:25:38 - | -LL | let expr = quote_expr!(&cx, 2 - $abcd + 7); //~ ERROR cannot find value `abcd` in this scope - | ^^^^ not found in this scope - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/quote-with-interpolated.rs b/src/test/ui/quote-with-interpolated.rs deleted file mode 100644 index b948226652b45..0000000000000 --- a/src/test/ui/quote-with-interpolated.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![feature(quote)] -fn main() { - macro_rules! foo { - ($bar:expr) => { - quote_expr!(cx, $bar) - //~^ ERROR quote! with interpolated token - //~| ERROR failed to resolve: maybe a missing `extern crate syntax;`? - //~| ERROR failed to resolve: maybe a missing `extern crate syntax;`? - //~| ERROR cannot find value `cx` in this scope - //~| ERROR cannot find function `new_parser_from_tts` in this scope - } - } - foo!(bar); -} diff --git a/src/test/ui/quote-with-interpolated.stderr b/src/test/ui/quote-with-interpolated.stderr deleted file mode 100644 index 96feff949bfc9..0000000000000 --- a/src/test/ui/quote-with-interpolated.stderr +++ /dev/null @@ -1,40 +0,0 @@ -error: quote! with interpolated token - --> $DIR/quote-with-interpolated.rs:5:29 - | -LL | quote_expr!(cx, $bar) - | ^^^^ -... -LL | foo!(bar); - | ---------- in this macro invocation - -error[E0433]: failed to resolve: maybe a missing `extern crate syntax;`? - --> $DIR/quote-with-interpolated.rs:5:13 - | -LL | quote_expr!(cx, $bar) - | ^^^^^^^^^^^^^^^^^^^^^ maybe a missing `extern crate syntax;`? - -error[E0433]: failed to resolve: maybe a missing `extern crate syntax;`? - --> $DIR/quote-with-interpolated.rs:5:29 - | -LL | quote_expr!(cx, $bar) - | ^^^^ maybe a missing `extern crate syntax;`? - -error[E0425]: cannot find value `cx` in this scope - --> $DIR/quote-with-interpolated.rs:5:25 - | -LL | quote_expr!(cx, $bar) - | ^^ not found in this scope -... -LL | foo!(bar); - | ---------- in this macro invocation - -error[E0425]: cannot find function `new_parser_from_tts` in this scope - --> $DIR/quote-with-interpolated.rs:5:13 - | -LL | quote_expr!(cx, $bar) - | ^^^^^^^^^^^^^^^^^^^^^ not found in this scope - -error: aborting due to 5 previous errors - -Some errors occurred: E0425, E0433. -For more information about an error, try `rustc --explain E0425`. From f38d0da89389c45067d37ba15e783c024088a09a Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 27 Oct 2018 15:29:06 +0300 Subject: [PATCH 0297/1064] Implement optimize(size) and optimize(speed) --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/hir/mod.rs | 5 +- src/librustc/ich/impls_hir.rs | 9 ++ src/librustc/session/config.rs | 2 + src/librustc/ty/query/config.rs | 6 ++ src/librustc/ty/query/mod.rs | 3 +- src/librustc/ty/query/plumbing.rs | 3 + src/librustc_codegen_llvm/attributes.rs | 44 ++++++-- src/librustc_codegen_llvm/back/lto.rs | 4 +- src/librustc_codegen_llvm/back/write.rs | 51 +++++---- src/librustc_codegen_llvm/base.rs | 4 +- src/librustc_codegen_llvm/context.rs | 5 +- src/librustc_codegen_llvm/declare.rs | 21 ++-- src/librustc_codegen_llvm/lib.rs | 17 +-- src/librustc_codegen_llvm/llvm/ffi.rs | 1 + src/librustc_codegen_llvm/llvm_util.rs | 6 +- src/librustc_codegen_ssa/back/write.rs | 3 +- src/librustc_codegen_ssa/base.rs | 37 ++++++- src/librustc_codegen_ssa/traits/backend.rs | 5 +- src/librustc_typeck/collect.rs | 115 +++++++++++++-------- src/librustc_typeck/diagnostics.rs | 1 + src/libsyntax/attr/builtin.rs | 7 ++ src/libsyntax/attr/mod.rs | 4 +- src/libsyntax/feature_gate.rs | 9 ++ src/rustllvm/RustWrapper.cpp | 2 + src/rustllvm/rustllvm.h | 1 + 26 files changed, 259 insertions(+), 107 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 4cfebaa8b5be7..05f331145afe2 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -642,6 +642,7 @@ define_dep_nodes!( <'tcx> [eval_always] CollectAndPartitionMonoItems, [] IsCodegenedItem(DefId), [] CodegenUnit(InternedString), + [] BackendOptimizationLevel(CrateNum), [] CompileCodegenUnit(InternedString), [input] OutputFilenames, [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index b58b1d359f98b..657e6e5dcde35 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -21,7 +21,7 @@ use syntax::source_map::Spanned; use rustc_target::spec::abi::Abi; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Label, Lit, StrStyle, FloatTy, IntTy, UintTy}; -use syntax::attr::InlineAttr; +use syntax::attr::{InlineAttr, OptimizeAttr}; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; @@ -2416,6 +2416,8 @@ pub struct CodegenFnAttrs { pub flags: CodegenFnAttrFlags, /// Parsed representation of the `#[inline]` attribute pub inline: InlineAttr, + /// Parsed representation of the `#[optimize]` attribute + pub optimize: OptimizeAttr, /// The `#[export_name = "..."]` attribute, indicating a custom symbol a /// function should be exported under pub export_name: Option, @@ -2476,6 +2478,7 @@ impl CodegenFnAttrs { CodegenFnAttrs { flags: CodegenFnAttrFlags::empty(), inline: InlineAttr::None, + optimize: OptimizeAttr::None, export_name: None, link_name: None, target_features: vec![], diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 159067663d42e..9022cabe7798d 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1159,6 +1159,7 @@ impl<'a> ToStableHashKey> for hir::TraitCandidate { impl_stable_hash_for!(struct hir::CodegenFnAttrs { flags, inline, + optimize, export_name, link_name, target_features, @@ -1183,6 +1184,14 @@ impl<'hir> HashStable> for attr::InlineAttr { } } +impl<'hir> HashStable> for attr::OptimizeAttr { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'hir>, + hasher: &mut StableHasher) { + mem::discriminant(self).hash_stable(hcx, hasher); + } +} + impl_stable_hash_for!(struct hir::Freevar { def, span diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index cdbef568a6005..d4bc50a6fc623 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -58,6 +58,8 @@ pub enum OptLevel { SizeMin, // -Oz } +impl_stable_hash_via_hash!(OptLevel); + /// This is what the `LtoCli` values get mapped to after resolving defaults and /// and taking other command line options into account. #[derive(Clone, Copy, PartialEq, Hash, Debug)] diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index ae41ca0cbb54f..c4757574ffe4d 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -967,6 +967,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::backend_optimization_level<'tcx> { + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "optimization level used by backend".into() + } +} + macro_rules! impl_disk_cacheable_query( ($query_name:ident, |$key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 10f35719cc80c..ec1103b0ae588 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -22,7 +22,7 @@ use mir::mono::CodegenUnit; use mir; use mir::interpret::GlobalId; use session::{CompileResult, CrateDisambiguator}; -use session::config::{EntryFnType, OutputFilenames}; +use session::config::{EntryFnType, OutputFilenames, OptLevel}; use traits::{self, Vtable}; use traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, @@ -573,6 +573,7 @@ define_queries! { <'tcx> -> (Arc, Arc>>>), [] fn is_codegened_item: IsCodegenedItem(DefId) -> bool, [] fn codegen_unit: CodegenUnit(InternedString) -> Arc>, + [] fn backend_optimization_level: BackendOptimizationLevel(CrateNum) -> OptLevel, }, Other { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 1cc9bbd22b0d6..541f5b75aa5c7 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1410,6 +1410,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::UpstreamMonomorphizationsFor => { force!(upstream_monomorphizations_for, def_id!()); } + DepKind::BackendOptimizationLevel => { + force!(backend_optimization_level, krate!()); + } } true diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 226b03c99c043..5a39e4f8b7ffa 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -5,7 +5,7 @@ use std::ffi::CString; use rustc::hir::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::session::Session; -use rustc::session::config::Sanitizer; +use rustc::session::config::{Sanitizer, OptLevel}; use rustc::ty::{self, TyCtxt, PolyFnSig}; use rustc::ty::layout::HasTyCtxt; use rustc::ty::query::Providers; @@ -20,7 +20,7 @@ use attributes; use llvm::{self, Attribute}; use llvm::AttributePlace::Function; use llvm_util; -pub use syntax::attr::{self, InlineAttr}; +pub use syntax::attr::{self, InlineAttr, OptimizeAttr}; use context::CodegenCx; use value::Value; @@ -57,13 +57,6 @@ fn unwind(val: &'ll Value, can_unwind: bool) { Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind); } -/// Tell LLVM whether it should optimize function for size. -#[inline] -#[allow(dead_code)] // possibly useful function -pub fn set_optimize_for_size(val: &'ll Value, optimize: bool) { - Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize); -} - /// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue. #[inline] pub fn naked(val: &'ll Value, is_naked: bool) { @@ -164,6 +157,39 @@ pub fn from_fn_attrs( inline(cx, llfn, codegen_fn_attrs.inline); + match codegen_fn_attrs.optimize { + OptimizeAttr::None => { + match cx.tcx.sess.opts.optimize { + OptLevel::Size => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + }, + OptLevel::SizeMin => { + llvm::Attribute::MinSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + } + OptLevel::No => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.apply_llfn(Function, llfn); + } + _ => {} + } + } + OptimizeAttr::Speed => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + } + OptimizeAttr::Size => { + llvm::Attribute::MinSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + } + } + // The `uwtable` attribute according to LLVM is: // // This attribute indicates that the ABI being targeted requires that an diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 5d5f1ceceb88c..3e51078dc6436 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -3,7 +3,7 @@ use rustc_codegen_ssa::back::symbol_export; use rustc_codegen_ssa::back::write::{ModuleConfig, CodegenContext, pre_lto_bitcode_filename}; use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinShared, ThinModule}; use rustc_codegen_ssa::traits::*; -use back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitcode, get_llvm_opt_level}; +use back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitcode, to_llvm_opt_settings}; use errors::{FatalError, Handler}; use llvm::archive_ro::ArchiveRO; use llvm::{self, True, False}; @@ -532,7 +532,7 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext, // Note that in general this shouldn't matter too much as you typically // only turn on ThinLTO when you're compiling with optimizations // otherwise. - let opt_level = config.opt_level.map(get_llvm_opt_level) + let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0) .unwrap_or(llvm::CodeGenOptLevel::None); let opt_level = match opt_level { llvm::CodeGenOptLevel::None => llvm::CodeGenOptLevel::Less, diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index c0a4f5aa44047..47637f3c5d705 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -5,8 +5,10 @@ use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, run_assembler use rustc_codegen_ssa::traits::*; use base; use consts; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::session::config::{self, OutputType, Passes, Lto}; use rustc::session::Session; +use rustc::ty::TyCtxt; use time_graph::Timeline; use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic}; use llvm_util; @@ -81,42 +83,46 @@ pub fn write_output_file( } } -pub(crate) fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel { - match optimize { - config::OptLevel::No => llvm::CodeGenOptLevel::None, - config::OptLevel::Less => llvm::CodeGenOptLevel::Less, - config::OptLevel::Default => llvm::CodeGenOptLevel::Default, - config::OptLevel::Aggressive => llvm::CodeGenOptLevel::Aggressive, - _ => llvm::CodeGenOptLevel::Default, - } -} - -pub(crate) fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize { - match optimize { - config::OptLevel::Size => llvm::CodeGenOptSizeDefault, - config::OptLevel::SizeMin => llvm::CodeGenOptSizeAggressive, - _ => llvm::CodeGenOptSizeNone, - } +pub fn create_target_machine( + tcx: TyCtxt, + find_features: bool, +) -> &'static mut llvm::TargetMachine { + target_machine_factory(tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE), find_features)() + .unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise() ) } -pub fn create_target_machine( +pub fn create_informational_target_machine( sess: &Session, find_features: bool, ) -> &'static mut llvm::TargetMachine { - target_machine_factory(sess, find_features)().unwrap_or_else(|err| { + target_machine_factory(sess, config::OptLevel::No, find_features)().unwrap_or_else(|err| { llvm_err(sess.diagnostic(), &err).raise() }) } + +pub fn to_llvm_opt_settings(cfg: config::OptLevel) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) +{ + use self::config::OptLevel::*; + match cfg { + No => (llvm::CodeGenOptLevel::None, llvm::CodeGenOptSizeNone), + Less => (llvm::CodeGenOptLevel::Less, llvm::CodeGenOptSizeNone), + Default => (llvm::CodeGenOptLevel::Default, llvm::CodeGenOptSizeNone), + Aggressive => (llvm::CodeGenOptLevel::Aggressive, llvm::CodeGenOptSizeNone), + Size => (llvm::CodeGenOptLevel::Default, llvm::CodeGenOptSizeDefault), + SizeMin => (llvm::CodeGenOptLevel::Default, llvm::CodeGenOptSizeAggressive), + } +} + // If find_features is true this won't access `sess.crate_types` by assuming // that `is_pie_binary` is false. When we discover LLVM target features // `sess.crate_types` is uninitialized so we cannot access it. -pub fn target_machine_factory(sess: &Session, find_features: bool) +pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_features: bool) -> Arc Result<&'static mut llvm::TargetMachine, String> + Send + Sync> { let reloc_model = get_reloc_model(sess); - let opt_level = get_llvm_opt_level(sess.opts.optimize); + let (opt_level, _) = to_llvm_opt_settings(optlvl); let use_softfp = sess.opts.cg.soft_float; let ffunction_sections = sess.target.target.options.function_sections; @@ -357,7 +363,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, if !config.no_prepopulate_passes { llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod); llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod); - let opt_level = config.opt_level.map(get_llvm_opt_level) + let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0) .unwrap_or(llvm::CodeGenOptLevel::None); let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal || (cgcx.lto != Lto::Fat && cgcx.opts.debugging_opts.cross_lang_lto.enabled()); @@ -689,7 +695,8 @@ pub unsafe fn with_llvm_pmb(llmod: &llvm::Module, // reasonable defaults and prepare it to actually populate the pass // manager. let builder = llvm::LLVMPassManagerBuilderCreate(); - let opt_size = config.opt_size.map(get_llvm_opt_size).unwrap_or(llvm::CodeGenOptSizeNone); + let opt_size = config.opt_size.map(|x| to_llvm_opt_settings(x).1) + .unwrap_or(llvm::CodeGenOptSizeNone); let inline_threshold = config.inline_threshold; let pgo_gen_path = config.pgo_gen.as_ref().map(|s| { diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 6a0d5fa1e1fd8..6e1ef440a3f3f 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -136,7 +136,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> { } } -pub fn compile_codegen_unit<'ll, 'tcx>(tcx: TyCtxt<'ll, 'tcx, 'tcx>, +pub fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cgu_name: InternedString) -> Stats { let start_time = Instant::now(); @@ -164,7 +164,7 @@ pub fn compile_codegen_unit<'ll, 'tcx>(tcx: TyCtxt<'ll, 'tcx, 'tcx>, let backend = LlvmCodegenBackend(()); let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... - let llvm_module = backend.new_metadata(tcx.sess, &cgu_name.as_str()); + let llvm_module = backend.new_metadata(tcx, &cgu_name.as_str()); let stats = { let cx = CodegenCx::new(tcx, cgu, &llvm_module); let mono_items = cx.codegen_unit diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 2b03e99161db8..1d7f14b02e199 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -144,16 +144,17 @@ pub fn is_pie_binary(sess: &Session) -> bool { } pub unsafe fn create_module( - sess: &Session, + tcx: TyCtxt, llcx: &'ll llvm::Context, mod_name: &str, ) -> &'ll llvm::Module { + let sess = tcx.sess; let mod_name = SmallCStr::new(mod_name); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); // Ensure the data-layout values hardcoded remain the defaults. if sess.target.target.options.is_builtin { - let tm = ::back::write::create_target_machine(sess, false); + let tm = ::back::write::create_target_machine(tcx, false); llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm); llvm::LLVMRustDisposeTargetMachine(tm); diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index aa2a0016b3e7a..166c6ab9ae9cb 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -15,7 +15,7 @@ use llvm; use llvm::AttributePlace::Function; use rustc::ty::{self, PolyFnSig}; use rustc::ty::layout::LayoutOf; -use rustc::session::config::Sanitizer; +use rustc::session::config::{Sanitizer, OptLevel}; use rustc_data_structures::small_c_str::SmallCStr; use abi::{FnType, FnTypeExt}; use attributes; @@ -65,15 +65,24 @@ fn declare_raw_fn( } } - match cx.tcx.sess.opts.cg.opt_level.as_ref().map(String::as_ref) { - Some("s") => { + // FIXME(opt): this is kinda duplicated with similar code in attributes::from_fm_attrs… + match cx.tcx.sess.opts.optimize { + OptLevel::Size => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); }, - Some("z") => { + OptLevel::SizeMin => { llvm::Attribute::MinSize.apply_llfn(Function, llfn); llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); - }, - _ => {}, + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + } + OptLevel::No => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.apply_llfn(Function, llfn); + } + _ => {} } attributes::non_lazy_bind(cx.sess(), llfn); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 272f34b0b3f16..662b84b3a910f 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -73,7 +73,7 @@ use rustc::dep_graph::DepGraph; use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; use rustc::session::{Session, CompileIncomplete}; -use rustc::session::config::{OutputFilenames, OutputType, PrintRequest}; +use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; use rustc::util::time_graph; use rustc::util::profiling::ProfileCategory; @@ -122,8 +122,8 @@ mod va_arg; pub struct LlvmCodegenBackend(()); impl ExtraBackendMethods for LlvmCodegenBackend { - fn new_metadata(&self, sess: &Session, mod_name: &str) -> ModuleLlvm { - ModuleLlvm::new(sess, mod_name) + fn new_metadata(&self, tcx: TyCtxt, mod_name: &str) -> ModuleLlvm { + ModuleLlvm::new(tcx, mod_name) } fn write_metadata<'b, 'gcx>( &self, @@ -145,10 +145,11 @@ impl ExtraBackendMethods for LlvmCodegenBackend { fn target_machine_factory( &self, sess: &Session, + optlvl: OptLevel, find_features: bool ) -> Arc Result<&'static mut llvm::TargetMachine, String> + Send + Sync> { - back::write::target_machine_factory(sess, find_features) + back::write::target_machine_factory(sess, optlvl, find_features) } fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str { llvm_util::target_cpu(sess) @@ -364,15 +365,15 @@ unsafe impl Send for ModuleLlvm { } unsafe impl Sync for ModuleLlvm { } impl ModuleLlvm { - fn new(sess: &Session, mod_name: &str) -> Self { + fn new(tcx: TyCtxt, mod_name: &str) -> Self { unsafe { - let llcx = llvm::LLVMRustContextCreate(sess.fewer_names()); - let llmod_raw = context::create_module(sess, llcx, mod_name) as *const _; + let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); + let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; ModuleLlvm { llmod_raw, llcx, - tm: create_target_machine(sess, false), + tm: create_target_machine(tcx, false), } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 11e34f600c286..fe2aed09ebca6 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -115,6 +115,7 @@ pub enum Attribute { SanitizeAddress = 21, SanitizeMemory = 22, NonLazyBind = 23, + OptimizeNone = 24, } /// LLVMIntPredicate diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index dc70ebcf943a5..e2d0e558d3b78 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -1,5 +1,5 @@ use syntax_pos::symbol::Symbol; -use back::write::create_target_machine; +use back::write::create_informational_target_machine; use llvm; use rustc::session::Session; use rustc::session::config::PrintRequest; @@ -223,7 +223,7 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { } pub fn target_features(sess: &Session) -> Vec { - let target_machine = create_target_machine(sess, true); + let target_machine = create_informational_target_machine(sess, true); target_feature_whitelist(sess) .iter() .filter_map(|&(feature, gate)| { @@ -276,7 +276,7 @@ pub fn print_passes() { pub(crate) fn print(req: PrintRequest, sess: &Session) { require_inited(); - let tm = create_target_machine(sess, true); + let tm = create_informational_target_machine(sess, true); unsafe { match req { PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm), diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 39bdc70f8322e..67d4d408babfa 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -982,6 +982,7 @@ fn start_executing_work( None }; + let ol = tcx.backend_optimization_level(LOCAL_CRATE); let cgcx = CodegenContext:: { backend: backend.clone(), crate_types: sess.crate_types.borrow().clone(), @@ -1005,7 +1006,7 @@ fn start_executing_work( regular_module_config: modules_config, metadata_module_config: metadata_config, allocator_module_config: allocator_config, - tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, false)), + tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, ol, false)), total_cgus, msvc_imps_needed: msvc_imps_needed(tcx), target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(), diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 38caacba4d069..84e55ce0f22c6 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -551,7 +551,7 @@ pub fn codegen_crate( &["crate"], Some("metadata")).as_str() .to_string(); - let metadata_llvm_module = backend.new_metadata(tcx.sess, &metadata_cgu_name); + let metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name); let metadata = time(tcx.sess, "write metadata", || { backend.write_metadata(tcx, &metadata_llvm_module) }); @@ -636,7 +636,7 @@ pub fn codegen_crate( &["crate"], Some("allocator")).as_str() .to_string(); - let modules = backend.new_metadata(tcx.sess, &llmod_id); + let modules = backend.new_metadata(tcx, &llmod_id); time(tcx.sess, "write allocator module", || { backend.codegen_allocator(tcx, &modules, kind) }); @@ -897,6 +897,39 @@ fn is_codegened_item(tcx: TyCtxt, id: DefId) -> bool { } pub fn provide_both(providers: &mut Providers) { + providers.backend_optimization_level = |tcx, cratenum| { + let for_speed = match tcx.sess.opts.optimize { + // If globally no optimisation is done, #[optimize] has no effect. + // + // This is done because if we ended up "upgrading" to `-O2` here, we’d populate the + // pass manager and it is likely that some module-wide passes (such as inliner or + // cross-function constant propagation) would ignore the `optnone` annotation we put + // on the functions, thus necessarily involving these functions into optimisations. + config::OptLevel::No => return config::OptLevel::No, + // If globally optimise-speed is already specified, just use that level. + config::OptLevel::Less => return config::OptLevel::Less, + config::OptLevel::Default => return config::OptLevel::Default, + config::OptLevel::Aggressive => return config::OptLevel::Aggressive, + // If globally optimize-for-size has been requested, use -O2 instead (if optimize(size) + // are present). + config::OptLevel::Size => config::OptLevel::Default, + config::OptLevel::SizeMin => config::OptLevel::Default, + }; + + let (defids, _) = tcx.collect_and_partition_mono_items(cratenum); + for id in &*defids { + let hir::CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id); + match optimize { + attr::OptimizeAttr::None => continue, + attr::OptimizeAttr::Size => continue, + attr::OptimizeAttr::Speed => { + return for_speed; + } + } + } + return tcx.sess.opts.optimize; + }; + providers.dllimport_foreign_items = |tcx, krate| { let module_map = tcx.foreign_modules(krate); let module_map = module_map.iter() diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 8c026059dc490..73c7614d91393 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -6,7 +6,7 @@ use super::CodegenObject; use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::EncodedMetadata; use rustc::mir::mono::Stats; -use rustc::session::Session; +use rustc::session::{Session, config}; use rustc::ty::TyCtxt; use rustc_codegen_utils::codegen_backend::CodegenBackend; use std::sync::Arc; @@ -32,7 +32,7 @@ impl<'tcx, T> Backend<'tcx> for T where } pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send { - fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module; + fn new_metadata(&self, sess: TyCtxt, mod_name: &str) -> Self::Module; fn write_metadata<'b, 'gcx>( &self, tcx: TyCtxt<'b, 'gcx, 'gcx>, @@ -50,6 +50,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se fn target_machine_factory( &self, sess: &Session, + opt_level: config::OptLevel, find_features: bool, ) -> Arc Result + Send + Sync>; fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 93f14a2ea6f64..2256dbcec002b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -36,7 +36,7 @@ use rustc_target::spec::abi; use syntax::ast; use syntax::ast::{Ident, MetaItemKind}; -use syntax::attr::{InlineAttr, list_contains_name, mark_used}; +use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used}; use syntax::source_map::Spanned; use syntax::feature_gate; use syntax::symbol::{keywords, Symbol}; @@ -2286,49 +2286,6 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; } else if attr.check_name("thread_local") { codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; - } else if attr.check_name("inline") { - codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| { - if attr.path != "inline" { - return ia; - } - let meta = match attr.meta() { - Some(meta) => meta.node, - None => return ia, - }; - match meta { - MetaItemKind::Word => { - mark_used(attr); - InlineAttr::Hint - } - MetaItemKind::List(ref items) => { - mark_used(attr); - inline_span = Some(attr.span); - if items.len() != 1 { - span_err!( - tcx.sess.diagnostic(), - attr.span, - E0534, - "expected one argument" - ); - InlineAttr::None - } else if list_contains_name(&items[..], "always") { - InlineAttr::Always - } else if list_contains_name(&items[..], "never") { - InlineAttr::Never - } else { - span_err!( - tcx.sess.diagnostic(), - items[0].span, - E0535, - "invalid argument" - ); - - InlineAttr::None - } - } - _ => ia, - } - }); } else if attr.check_name("export_name") { if let Some(s) = attr.value_str() { if s.as_str().contains("\0") { @@ -2378,6 +2335,76 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen } } + codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| { + if attr.path != "inline" { + return ia; + } + match attr.meta().map(|i| i.node) { + Some(MetaItemKind::Word) => { + mark_used(attr); + InlineAttr::Hint + } + Some(MetaItemKind::List(ref items)) => { + mark_used(attr); + inline_span = Some(attr.span); + if items.len() != 1 { + span_err!( + tcx.sess.diagnostic(), + attr.span, + E0534, + "expected one argument" + ); + InlineAttr::None + } else if list_contains_name(&items[..], "always") { + InlineAttr::Always + } else if list_contains_name(&items[..], "never") { + InlineAttr::Never + } else { + span_err!( + tcx.sess.diagnostic(), + items[0].span, + E0535, + "invalid argument" + ); + + InlineAttr::None + } + } + Some(MetaItemKind::NameValue(_)) => ia, + None => ia, + } + }); + + codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| { + if attr.path != "optimize" { + return ia; + } + let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0720, "{}", s); + match attr.meta().map(|i| i.node) { + Some(MetaItemKind::Word) => { + err(attr.span, "expected one argument"); + ia + } + Some(MetaItemKind::List(ref items)) => { + mark_used(attr); + inline_span = Some(attr.span); + if items.len() != 1 { + err(attr.span, "expected one argument"); + OptimizeAttr::None + } else if list_contains_name(&items[..], "size") { + OptimizeAttr::Size + } else if list_contains_name(&items[..], "speed") { + OptimizeAttr::Speed + } else { + err(items[0].span, "invalid argument"); + OptimizeAttr::None + } + } + Some(MetaItemKind::NameValue(_)) => ia, + None => ia, + } + }); + // If a function uses #[target_feature] it can't be inlined into general // purpose functions as they wouldn't have the right target features // enabled. For that reason we also forbid #[inline(always)] as it can't be diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index c0a8dd87ee2d5..21dcdaf4fa0e7 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4719,4 +4719,5 @@ register_diagnostics! { E0645, // trait aliases not finished E0698, // type inside generator must be known in this context E0719, // duplicate values for associated type binding + E0720, // Malformed #[optimize] attribute } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 15e480496f7a8..1a4b45e76b42d 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -63,6 +63,13 @@ pub enum InlineAttr { Never, } +#[derive(Copy, Clone, Hash, PartialEq, RustcEncodable, RustcDecodable)] +pub enum OptimizeAttr { + None, + Speed, + Size, +} + #[derive(Copy, Clone, PartialEq)] pub enum UnwindAttr { Allowed, diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index e5ce6a3f19a49..58be7c3e085c3 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -4,8 +4,8 @@ mod builtin; pub use self::builtin::{ cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation, - find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, IntType, ReprAttr, - RustcDeprecation, Stability, StabilityLevel, UnwindAttr, + find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, OptimizeAttr, + IntType, ReprAttr, RustcDeprecation, Stability, StabilityLevel, UnwindAttr, }; pub use self::IntType::*; pub use self::ReprAttr::*; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9b54e8f9c1f2c..abbcf24fca50f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -462,6 +462,9 @@ declare_features! ( // Re-Rebalance coherence (active, re_rebalance_coherence, "1.32.0", Some(55437), None), + + // #[optimize(X)] + (active, optimize_attribute, "1.34.0", Some(54882), None), ); declare_features! ( @@ -1215,6 +1218,12 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu "#[alloc_error_handler] is an unstable feature", cfg_fn!(alloc_error_handler))), + // RFC 2412 + ("optimize", Whitelisted, Gated(Stability::Unstable, + "optimize_attribute", + "#[optimize] attribute is an unstable feature", + cfg_fn!(optimize_attribute))), + // Crate level attributes ("crate_name", CrateLevel, template!(NameValueStr: "name"), Ungated), ("crate_type", CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated), diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9d3e6f93b0c11..474e771c1f011 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -188,6 +188,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { return Attribute::SanitizeMemory; case NonLazyBind: return Attribute::NonLazyBind; + case OptimizeNone: + return Attribute::OptimizeNone; } report_fatal_error("bad AttributeKind"); } diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 1ed281e8b1be1..933266b402526 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -84,6 +84,7 @@ enum LLVMRustAttribute { SanitizeAddress = 21, SanitizeMemory = 22, NonLazyBind = 23, + OptimizeNone = 24, }; typedef struct OpaqueRustString *RustStringRef; From dcf5482cdacd166268f9672f34697dd1da05ceea Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 3 Nov 2018 11:13:10 +0200 Subject: [PATCH 0298/1064] Add an idealistic test for optimize attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alas it does not currently work, because of limitations in compiletest… --- src/test/codegen/optimize-attr-1.rs | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/codegen/optimize-attr-1.rs diff --git a/src/test/codegen/optimize-attr-1.rs b/src/test/codegen/optimize-attr-1.rs new file mode 100644 index 0000000000000..b742a361da96d --- /dev/null +++ b/src/test/codegen/optimize-attr-1.rs @@ -0,0 +1,49 @@ +// revisions: NO-OPT SIZE-OPT SPEED-OPT +// [NO-OPT]compile-flags: -Copt-level=0 +// [SIZE-OPT]compile-flags: -Copt-level=s +// [SPEED-OPT]compile-flags: -Copt-level=3 + +#![feature(optimize_attribute)] +#![crate_type="rlib"] + +// NO-OPT: Function Attrs:{{.*}}optnone +// NO-OPT-NOT: {{optsize|minsize}} +// NO-OPT-NEXT: @nothing +// NO-OPT: ret i32 %1 +// +// SIZE-OPT: Function Attrs:{{.*}}optsize +// SIZE-OPT-NOT: {{minsize|optnone}} +// SIZE-OPT-NEXT: @nothing +// SIZE-OPT-NEXT: start +// SIZE-OPT-NEXT: ret i32 4 +// +// SPEED-OPT: Function Attrs: +// SPEED-OPT-NOT: {{minsize|optnone|optsize}} +// SPEED-OPT-NEXT: @nothing +// SPEED-OPT-NEXT: start +// SPEED-OPT-NEXT: ret i32 4 +#[no_mangle] +pub fn nothing() -> i32 { + 2 + 2 +} + +// CHECK: Function Attrs:{{.*}} minsize{{.*}}optsize +// CHECK-NEXT: @size +// CHECK-NEXT: start +// CHECK-NEXT: ret i32 4 +#[optimize(size)] +#[no_mangle] +pub fn size() -> i32 { + 2 + 2 +} + +// CHECK: Function Attrs: +// CHECK-NOT: {{minsize|optsize|optnone}} +// CHECK-NEXT: @speed +// CHECK-NEXT: start +// CHECK-NEXT: ret i32 4 +#[optimize(speed)] +#[no_mangle] +pub fn speed() -> i32 { + 2 + 2 +} From 4d97b2889345d69fa72233b787b30cff73232465 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 18 Nov 2018 20:51:56 +0200 Subject: [PATCH 0299/1064] Support revisions for codegen tests `compile-flags: -Copt-level` will avoid adding -O. Similarly for -g and -Cdebuglevel. --- src/librustc_codegen_llvm/attributes.rs | 6 +- src/librustc_codegen_llvm/declare.rs | 4 +- .../codegen/inline-always-works-always.rs | 21 ++++++ src/test/codegen/optimize-attr-1.rs | 59 +++++++-------- src/tools/compiletest/src/header.rs | 2 + src/tools/compiletest/src/runtest.rs | 72 +++++++++++++++---- 6 files changed, 115 insertions(+), 49 deletions(-) create mode 100644 src/test/codegen/inline-always-works-always.rs diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 5a39e4f8b7ffa..a7d4f910f7a2d 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -155,8 +155,6 @@ pub fn from_fn_attrs( let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id)) .unwrap_or_else(|| CodegenFnAttrs::new()); - inline(cx, llfn, codegen_fn_attrs.inline); - match codegen_fn_attrs.optimize { OptimizeAttr::None => { match cx.tcx.sess.opts.optimize { @@ -173,7 +171,7 @@ pub fn from_fn_attrs( OptLevel::No => { llvm::Attribute::MinSize.unapply_llfn(Function, llfn); llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); } _ => {} } @@ -190,6 +188,8 @@ pub fn from_fn_attrs( } } + inline(cx, llfn, codegen_fn_attrs.inline); + // The `uwtable` attribute according to LLVM is: // // This attribute indicates that the ABI being targeted requires that an diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 166c6ab9ae9cb..da45e0200d85f 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -65,7 +65,7 @@ fn declare_raw_fn( } } - // FIXME(opt): this is kinda duplicated with similar code in attributes::from_fm_attrs… + // FIXME(opt): this is kinda duplicated with similar code in attributes::from_fn_attrs… match cx.tcx.sess.opts.optimize { OptLevel::Size => { llvm::Attribute::MinSize.unapply_llfn(Function, llfn); @@ -80,7 +80,7 @@ fn declare_raw_fn( OptLevel::No => { llvm::Attribute::MinSize.unapply_llfn(Function, llfn); llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); } _ => {} } diff --git a/src/test/codegen/inline-always-works-always.rs b/src/test/codegen/inline-always-works-always.rs new file mode 100644 index 0000000000000..912af782a8f36 --- /dev/null +++ b/src/test/codegen/inline-always-works-always.rs @@ -0,0 +1,21 @@ +// revisions: NO-OPT SIZE-OPT SPEED-OPT +//[NO-OPT] compile-flags: -Copt-level=0 +//[SIZE-OPT] compile-flags: -Copt-level=s +//[SPEED-OPT] compile-flags: -Copt-level=3 + +#![crate_type="rlib"] + +#[no_mangle] +#[inline(always)] +pub extern "C" fn callee() -> u32 { + 4 + 4 +} + +// CHECK-LABEL: caller +// SIZE-OPT: ret i32 8 +// SPEED-OPT: ret i32 8 +// NO-OPT: ret i32 8 +#[no_mangle] +pub extern "C" fn caller() -> u32 { + callee() +} diff --git a/src/test/codegen/optimize-attr-1.rs b/src/test/codegen/optimize-attr-1.rs index b742a361da96d..376447e5b5db0 100644 --- a/src/test/codegen/optimize-attr-1.rs +++ b/src/test/codegen/optimize-attr-1.rs @@ -1,49 +1,50 @@ // revisions: NO-OPT SIZE-OPT SPEED-OPT -// [NO-OPT]compile-flags: -Copt-level=0 -// [SIZE-OPT]compile-flags: -Copt-level=s -// [SPEED-OPT]compile-flags: -Copt-level=3 +//[NO-OPT] compile-flags: -Copt-level=0 -Ccodegen-units=1 +//[SIZE-OPT] compile-flags: -Copt-level=s -Ccodegen-units=1 +//[SPEED-OPT] compile-flags: -Copt-level=3 -Ccodegen-units=1 #![feature(optimize_attribute)] #![crate_type="rlib"] -// NO-OPT: Function Attrs:{{.*}}optnone -// NO-OPT-NOT: {{optsize|minsize}} -// NO-OPT-NEXT: @nothing +// CHECK-LABEL: define i32 @nothing +// CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]] // NO-OPT: ret i32 %1 -// -// SIZE-OPT: Function Attrs:{{.*}}optsize -// SIZE-OPT-NOT: {{minsize|optnone}} -// SIZE-OPT-NEXT: @nothing -// SIZE-OPT-NEXT: start -// SIZE-OPT-NEXT: ret i32 4 -// -// SPEED-OPT: Function Attrs: -// SPEED-OPT-NOT: {{minsize|optnone|optsize}} -// SPEED-OPT-NEXT: @nothing -// SPEED-OPT-NEXT: start -// SPEED-OPT-NEXT: ret i32 4 +// SIZE-OPT: ret i32 4 +// SPEEC-OPT: ret i32 4 #[no_mangle] pub fn nothing() -> i32 { 2 + 2 } -// CHECK: Function Attrs:{{.*}} minsize{{.*}}optsize -// CHECK-NEXT: @size -// CHECK-NEXT: start -// CHECK-NEXT: ret i32 4 +// CHECK-LABEL: define i32 @size +// CHECK-SAME: [[SIZE_ATTRS:#[0-9]+]] +// NO-OPT: ret i32 %1 +// SIZE-OPT: ret i32 6 +// SPEED-OPT: ret i32 6 #[optimize(size)] #[no_mangle] pub fn size() -> i32 { - 2 + 2 + 3 + 3 } -// CHECK: Function Attrs: -// CHECK-NOT: {{minsize|optsize|optnone}} -// CHECK-NEXT: @speed -// CHECK-NEXT: start -// CHECK-NEXT: ret i32 4 +// CHECK-LABEL: define i32 @speed +// NO-OPT-SAME: [[NOTHING_ATTRS]] +// SPEED-OPT-SAME: [[NOTHING_ATTRS]] +// SIZE-OPT-SAME: [[SPEED_ATTRS:#[0-9]+]] +// NO-OPT: ret i32 %1 +// SIZE-OPT: ret i32 8 +// SPEED-OPT: ret i32 8 #[optimize(speed)] #[no_mangle] pub fn speed() -> i32 { - 2 + 2 + 4 + 4 } + +// NO-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}} +// SPEED-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}} +// SIZE-OPT-DAG: attributes [[NOTHING_ATTRS]] = {{.*}}optsize{{.*}} +// SIZE-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}} + +// SIZE-OPT: attributes [[SPEED_ATTRS]] +// SIZE-OPT-NOT: minsize +// SIZE-OPT-NOT: optsize diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 5eb1f5ec5ffda..394e408e41587 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -542,6 +542,8 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) { "#" }; + // FIXME: would be nice to allow some whitespace between comment and brace :) + // It took me like 2 days to debug why compile-flags weren’t taken into account for my test :) let comment_with_brace = comment.to_string() + "["; let rdr = BufReader::new(File::open(testfile).unwrap()); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 400c205d44b20..375dc1c128338 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -552,9 +552,10 @@ impl<'test> TestCx<'test> { .args(&["--target", &self.config.target]) .arg("-L") .arg(&aux_dir) - .args(self.split_maybe_args(&self.config.target_rustcflags)) .args(&self.props.compile_flags) .envs(self.props.exec_env.clone()); + self.maybe_add_external_args(&mut rustc, + self.split_maybe_args(&self.config.target_rustcflags)); let src = match read_from { ReadFrom::Stdin(src) => Some(src), @@ -587,6 +588,15 @@ impl<'test> TestCx<'test> { } } + fn set_revision_flags(&self, cmd: &mut Command) { + if let Some(revision) = self.revision { + // Normalize revisions to be lowercase and replace `-`s with `_`s. + // Otherwise the `--cfg` flag is not valid. + let normalized_revision = revision.to_lowercase().replace("-", "_"); + cmd.args(&["--cfg", &normalized_revision]); + } + } + fn typecheck_source(&self, src: String) -> ProcRes { let mut rustc = Command::new(&self.config.rustc_path); @@ -612,12 +622,9 @@ impl<'test> TestCx<'test> { .arg(&self.config.build_base) .arg("-L") .arg(aux_dir); - - if let Some(revision) = self.revision { - rustc.args(&["--cfg", revision]); - } - - rustc.args(self.split_maybe_args(&self.config.target_rustcflags)); + self.set_revision_flags(&mut rustc); + self.maybe_add_external_args(&mut rustc, + self.split_maybe_args(&self.config.target_rustcflags)); rustc.args(&self.props.compile_flags); self.compose_and_run_compiler(rustc, Some(src)) @@ -1119,6 +1126,35 @@ impl<'test> TestCx<'test> { Some(new_options.join(" ")) } + fn maybe_add_external_args(&self, cmd: &mut Command, args: Vec) { + // Filter out the arguments that should not be added by runtest here. + // + // Notable use-cases are: do not add our optimisation flag if + // `compile-flags: -Copt-level=x` and similar for debug-info level as well. + const OPT_FLAGS: &[&str] = &["-O", "-Copt-level=", /*-C*/"opt-level="]; + const DEBUG_FLAGS: &[&str] = &["-g", "-Cdebuginfo=", /*-C*/"debuginfo="]; + + // FIXME: ideally we would "just" check the `cmd` itself, but it does not allow inspecting + // its arguments. They need to be collected separately. For now I cannot be bothered to + // implement this the "right" way. + let have_opt_flag = self.props.compile_flags.iter().any(|arg| { + OPT_FLAGS.iter().any(|f| arg.starts_with(f)) + }); + let have_debug_flag = self.props.compile_flags.iter().any(|arg| { + DEBUG_FLAGS.iter().any(|f| arg.starts_with(f)) + }); + + for arg in args { + if OPT_FLAGS.iter().any(|f| arg.starts_with(f)) && have_opt_flag { + continue; + } + if DEBUG_FLAGS.iter().any(|f| arg.starts_with(f)) && have_debug_flag { + continue; + } + cmd.arg(arg); + } + } + fn check_debugger_output(&self, debugger_run_result: &ProcRes, check_lines: &[String]) { let num_check_lines = check_lines.len(); @@ -1707,10 +1743,7 @@ impl<'test> TestCx<'test> { rustc.arg(&format!("--target={}", target)); } - - if let Some(revision) = self.revision { - rustc.args(&["--cfg", revision]); - } + self.set_revision_flags(&mut rustc); if !is_rustdoc { if let Some(ref incremental_dir) = self.props.incremental_dir { @@ -1810,9 +1843,11 @@ impl<'test> TestCx<'test> { } if self.props.force_host { - rustc.args(self.split_maybe_args(&self.config.host_rustcflags)); + self.maybe_add_external_args(&mut rustc, + self.split_maybe_args(&self.config.host_rustcflags)); } else { - rustc.args(self.split_maybe_args(&self.config.target_rustcflags)); + self.maybe_add_external_args(&mut rustc, + self.split_maybe_args(&self.config.target_rustcflags)); if !is_rustdoc { if let Some(ref linker) = self.config.linker { rustc.arg(format!("-Clinker={}", linker)); @@ -2065,12 +2100,19 @@ impl<'test> TestCx<'test> { .arg("--input-file") .arg(irfile) .arg(&self.testpaths.file); + // It would be more appropriate to make most of the arguments configurable through + // a comment-attribute similar to `compile-flags`. For example, --check-prefixes is a very + // useful flag. + // + // For now, though… + if let Some(rev) = self.revision { + let prefixes = format!("CHECK,{}", rev); + filecheck.args(&["--check-prefixes", &prefixes]); + } self.compose_and_run(filecheck, "", None, None) } fn run_codegen_test(&self) { - assert!(self.revision.is_none(), "revisions not relevant here"); - if self.config.llvm_filecheck.is_none() { self.fatal("missing --llvm-filecheck"); } From 89e34d3e32bcb8bc52f3b9deeae7034d7f045388 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 25 Nov 2018 19:56:10 +0200 Subject: [PATCH 0300/1064] Add a feature gate test for #[optimize] --- .../ui/feature-gate-optimize_attribute.rs | 25 +++++++++++ .../ui/feature-gate-optimize_attribute.stderr | 43 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/test/ui/feature-gate-optimize_attribute.rs create mode 100644 src/test/ui/feature-gate-optimize_attribute.stderr diff --git a/src/test/ui/feature-gate-optimize_attribute.rs b/src/test/ui/feature-gate-optimize_attribute.rs new file mode 100644 index 0000000000000..4c3126f534e4f --- /dev/null +++ b/src/test/ui/feature-gate-optimize_attribute.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![crate_type="rlib"] +#![optimize(speed)] //~ ERROR #54882 + +#[optimize(size)] //~ ERROR #54882 +mod module { + +#[optimize(size)] //~ ERROR #54882 +fn size() {} + +#[optimize(speed)] //~ ERROR #54882 +fn speed() {} + +#[optimize(banana)] //~ ERROR #54882 +fn not_known() {} + +} diff --git a/src/test/ui/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gate-optimize_attribute.stderr new file mode 100644 index 0000000000000..cd790a0bb6a06 --- /dev/null +++ b/src/test/ui/feature-gate-optimize_attribute.stderr @@ -0,0 +1,43 @@ +error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) + --> $DIR/feature-gate-optimize_attribute.rs:16:1 + | +LL | #[optimize(size)] //~ ERROR #54882 + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(optimize_attribute)] to the crate attributes to enable + +error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) + --> $DIR/feature-gate-optimize_attribute.rs:19:1 + | +LL | #[optimize(speed)] //~ ERROR #54882 + | ^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(optimize_attribute)] to the crate attributes to enable + +error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) + --> $DIR/feature-gate-optimize_attribute.rs:22:1 + | +LL | #[optimize(banana)] //~ ERROR #54882 + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(optimize_attribute)] to the crate attributes to enable + +error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) + --> $DIR/feature-gate-optimize_attribute.rs:13:1 + | +LL | #[optimize(size)] //~ ERROR #54882 + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(optimize_attribute)] to the crate attributes to enable + +error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) + --> $DIR/feature-gate-optimize_attribute.rs:11:1 + | +LL | #![optimize(speed)] //~ ERROR #54882 + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(optimize_attribute)] to the crate attributes to enable + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0658`. From 5e9c8d7369ce2901d327ed2c1849417886ba7a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 2 Jan 2019 16:43:08 -0800 Subject: [PATCH 0301/1064] When using value after move, point at span of local When trying to use a value after move, instead of using a note, point at the local declaration that has a type that doesn't implement `Copy` trait. --- .../borrow_check/error_reporting.rs | 34 +++++++++++++------ src/test/ui/borrowck/borrowck-asm.mir.stderr | 10 +++--- .../borrowck/borrowck-drop-from-guard.stderr | 5 +-- .../ui/borrowck/borrowck-issue-48962.stderr | 8 ++--- ...k-move-moved-value-into-closure.mir.stderr | 5 +-- src/test/ui/borrowck/borrowck-reinit.stderr | 5 +-- src/test/ui/borrowck/issue-41962.stderr | 5 ++- ...-mutation-of-moved-out-with-mut.nll.stderr | 12 +++---- ...499-field-mutation-of-moved-out.nll.stderr | 12 +++---- ...e-27282-move-match-input-into-guard.stderr | 5 +-- src/test/ui/issues/issue-29723.stderr | 5 +-- .../ui/moves/moves-based-on-type-tuple.stderr | 4 +-- src/test/ui/nll/closure-access-spans.stderr | 16 ++++----- src/test/ui/nll/closure-move-spans.stderr | 12 +++---- src/test/ui/nll/closures-in-loops.stderr | 5 +-- ...1232-partial-init-and-erroneous-use.stderr | 8 ++--- .../issue-21232-partial-init-and-use.stderr | 34 ++++++++++--------- src/test/ui/nll/issue-51512.stderr | 4 +-- src/test/ui/nll/issue-52669.stderr | 5 +-- .../try-block/try-block-bad-lifetime.stderr | 5 +-- .../try-block-maybe-bad-lifetime.stderr | 5 +-- 21 files changed, 116 insertions(+), 88 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 233db12b03001..cbcf8c90fee41 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -198,19 +198,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let place = &self.move_data.move_paths[mpi].place; let ty = place.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx); - let note_msg = match self.describe_place_with_options( - place, - IncludingDowncast(true), - ) { - Some(name) => format!("`{}`", name), + let opt_name = self.describe_place_with_options(place, IncludingDowncast(true)); + let note_msg = match opt_name { + Some(ref name) => format!("`{}`", name), None => "value".to_owned(), }; - - err.note(&format!( - "move occurs because {} has type `{}`, \ - which does not implement the `Copy` trait", - note_msg, ty - )); + let mut note = true; + for decl in &self.mir.local_decls { + if decl.ty == ty && decl.name.map(|x| x.to_string()) == opt_name { + err.span_label( + decl.source_info.span, + format!( + "move occurs because {} has type `{}`, \ + which does not implement the `Copy` trait", + note_msg, ty, + )); + note = false; + } + } + if note { + err.note(&format!( + "move occurs because {} has type `{}`, \ + which does not implement the `Copy` trait", + note_msg, ty + )); + } } if let Some((_, mut old_err)) = self.move_error_reported diff --git a/src/test/ui/borrowck/borrowck-asm.mir.stderr b/src/test/ui/borrowck/borrowck-asm.mir.stderr index 9c47845a52830..86e4832b3873c 100644 --- a/src/test/ui/borrowck/borrowck-asm.mir.stderr +++ b/src/test/ui/borrowck/borrowck-asm.mir.stderr @@ -1,13 +1,14 @@ error[E0382]: use of moved value: `x` --> $DIR/borrowck-asm.rs:27:17 | +LL | let x = &mut 0isize; + | - move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait +LL | unsafe { LL | asm!("nop" : : "r"(x)); | - value moved here LL | } LL | let z = x; //[ast]~ ERROR use of moved value: `x` | ^ value used here after move - | - = note: move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait error[E0503]: cannot use `x` because it was mutably borrowed --> $DIR/borrowck-asm.rs:35:32 @@ -66,12 +67,13 @@ LL | let z = y; error[E0382]: use of moved value: `x` --> $DIR/borrowck-asm.rs:86:40 | +LL | let x = &mut 2; + | - move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait +LL | unsafe { LL | asm!("nop" : : "r"(x), "r"(x) ); //[ast]~ ERROR use of moved value | - ^ value used here after move | | | value moved here - | - = note: move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait error: aborting due to 7 previous errors diff --git a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr index d395b7734f9b7..07b597f480feb 100644 --- a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr +++ b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr @@ -1,13 +1,14 @@ error[E0382]: use of moved value: `my_str` --> $DIR/borrowck-drop-from-guard.rs:11:23 | +LL | let my_str = "hello".to_owned(); + | ------ move occurs because `my_str` has type `std::string::String`, which does not implement the `Copy` trait +LL | match Some(42) { LL | Some(_) if { drop(my_str); false } => {} | ------ value moved here LL | Some(_) => {} LL | None => { foo(my_str); } //~ ERROR [E0382] | ^^^^^^ value used here after move - | - = note: move occurs because `my_str` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-issue-48962.stderr b/src/test/ui/borrowck/borrowck-issue-48962.stderr index 9d53d82265eca..de4894d5b526b 100644 --- a/src/test/ui/borrowck/borrowck-issue-48962.stderr +++ b/src/test/ui/borrowck/borrowck-issue-48962.stderr @@ -1,22 +1,22 @@ error[E0382]: use of moved value: `src` --> $DIR/borrowck-issue-48962.rs:16:5 | +LL | let mut src = &mut node; + | ------- move occurs because `src` has type `&mut Node`, which does not implement the `Copy` trait LL | {src}; | --- value moved here LL | src.next = None; //~ ERROR use of moved value: `src` [E0382] | ^^^^^^^^ value used here after move - | - = note: move occurs because `src` has type `&mut Node`, which does not implement the `Copy` trait error[E0382]: use of moved value: `src` --> $DIR/borrowck-issue-48962.rs:22:5 | +LL | let mut src = &mut (22, 44); + | ------- move occurs because `src` has type `&mut (i32, i32)`, which does not implement the `Copy` trait LL | {src}; | --- value moved here LL | src.0 = 66; //~ ERROR use of moved value: `src` [E0382] | ^^^^^^^^^^ value used here after move - | - = note: move occurs because `src` has type `&mut (i32, i32)`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr index 24b9b4338a58c..0789926563ce7 100644 --- a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr +++ b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr @@ -1,6 +1,9 @@ error[E0382]: use of moved value: `t` --> $DIR/borrowck-move-moved-value-into-closure.rs:14:12 | +LL | let t: Box<_> = box 3; + | - move occurs because `t` has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | LL | call_f(move|| { *t + 1 }); | ------ - variable moved due to use in closure | | @@ -9,8 +12,6 @@ LL | call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value | ^^^^^^ - use occurs due to use in closure | | | value used here after move - | - = note: move occurs because `t` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-reinit.stderr b/src/test/ui/borrowck/borrowck-reinit.stderr index 918452726a06c..96f3981ac2fe6 100644 --- a/src/test/ui/borrowck/borrowck-reinit.stderr +++ b/src/test/ui/borrowck/borrowck-reinit.stderr @@ -11,12 +11,13 @@ LL | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast) error[E0382]: use of moved value: `x` (Mir) --> $DIR/borrowck-reinit.rs:8:16 | +LL | let mut x = Box::new(0); + | ----- move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait +... LL | drop(x); | - value moved here LL | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast) | ^ value used here after move - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index fd4d318b5ddf1..3c0071f6b3745 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -19,10 +19,13 @@ LL | if let Some(thing) = maybe { error[E0382]: use of moved value (Mir) --> $DIR/issue-41962.rs:7:21 | +LL | let maybe = Some(vec![true, true]); + | ---------------- move occurs because value has type `std::vec::Vec`, which does not implement the `Copy` trait +... LL | if let Some(thing) = maybe { | ^^^^^ value moved here, in previous iteration of loop | - = note: move occurs because value has type `std::vec::Vec`, which does not implement the `Copy` trait + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr index 7861087ad02eb..42aa038170238 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr @@ -1,32 +1,32 @@ error[E0382]: assign to part of moved value: `t` --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:23:9 | +LL | let mut t: Tuple = (S(0), 0); + | ----- move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait LL | drop(t); | - value moved here LL | t.0 = S(1); | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `u` --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:34:9 | +LL | let mut u: Tpair = Tpair(S(0), 0); + | ----- move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait LL | drop(u); | - value moved here LL | u.0 = S(1); | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `v` --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:45:9 | +LL | let mut v: Spair = Spair { x: S(0), y: 0 }; + | ----- move occurs because `v` has type `Spair`, which does not implement the `Copy` trait LL | drop(v); | - value moved here LL | v.x = S(1); | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr index d35d0058027d4..1184907f307cb 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr @@ -10,12 +10,12 @@ LL | t.0 = S(1); error[E0382]: assign to part of moved value: `t` --> $DIR/issue-54499-field-mutation-of-moved-out.rs:23:9 | +LL | let t: Tuple = (S(0), 0); + | - move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait LL | drop(t); | - value moved here LL | t.0 = S(1); | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait error[E0594]: cannot assign to `t.1`, as `t` is not declared as mutable --> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9 @@ -38,12 +38,12 @@ LL | u.0 = S(1); error[E0382]: assign to part of moved value: `u` --> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9 | +LL | let u: Tpair = Tpair(S(0), 0); + | - move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait LL | drop(u); | - value moved here LL | u.0 = S(1); | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait error[E0594]: cannot assign to `u.1`, as `u` is not declared as mutable --> $DIR/issue-54499-field-mutation-of-moved-out.rs:42:9 @@ -66,12 +66,12 @@ LL | v.x = S(1); error[E0382]: assign to part of moved value: `v` --> $DIR/issue-54499-field-mutation-of-moved-out.rs:53:9 | +LL | let v: Spair = Spair { x: S(0), y: 0 }; + | - move occurs because `v` has type `Spair`, which does not implement the `Copy` trait LL | drop(v); | - value moved here LL | v.x = S(1); | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait error[E0594]: cannot assign to `v.y`, as `v` is not declared as mutable --> $DIR/issue-54499-field-mutation-of-moved-out.rs:57:9 diff --git a/src/test/ui/issues/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/issues/issue-27282-move-match-input-into-guard.stderr index 8ea2bdb693d31..6993419326c8e 100644 --- a/src/test/ui/issues/issue-27282-move-match-input-into-guard.stderr +++ b/src/test/ui/issues/issue-27282-move-match-input-into-guard.stderr @@ -1,6 +1,9 @@ error[E0382]: use of moved value: `b` --> $DIR/issue-27282-move-match-input-into-guard.rs:18:14 | +LL | let b = &mut true; + | - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait +... LL | _ if { (|| { let bar = b; *bar = false; })(); | -- - variable moved due to use in closure | | @@ -8,8 +11,6 @@ LL | _ if { (|| { let bar = b; *bar = false; })(); LL | false } => { }, LL | &mut true => { println!("You might think we should get here"); }, | ^^^^ value used here after move - | - = note: move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29723.stderr b/src/test/ui/issues/issue-29723.stderr index de858aec881f7..7928af5d5a5cd 100644 --- a/src/test/ui/issues/issue-29723.stderr +++ b/src/test/ui/issues/issue-29723.stderr @@ -1,13 +1,14 @@ error[E0382]: use of moved value: `s` --> $DIR/issue-29723.rs:12:13 | +LL | let s = String::new(); + | - move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait +LL | let _s = match 0 { LL | 0 if { drop(s); false } => String::from("oops"), | - value moved here ... LL | s | ^ value used here after move - | - = note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/moves/moves-based-on-type-tuple.stderr b/src/test/ui/moves/moves-based-on-type-tuple.stderr index 2d2c0a15a002a..c49dbdab40210 100644 --- a/src/test/ui/moves/moves-based-on-type-tuple.stderr +++ b/src/test/ui/moves/moves-based-on-type-tuple.stderr @@ -11,12 +11,12 @@ LL | box (x, x) error[E0382]: use of moved value: `x` (Mir) --> $DIR/moves-based-on-type-tuple.rs:6:13 | +LL | fn dup(x: Box) -> Box<(Box,Box)> { + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | box (x, x) | - ^ value used here after move | | | value moved here - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/closure-access-spans.stderr b/src/test/ui/nll/closure-access-spans.stderr index efe4c15240d20..3ca0aefb592e0 100644 --- a/src/test/ui/nll/closure-access-spans.stderr +++ b/src/test/ui/nll/closure-access-spans.stderr @@ -59,50 +59,50 @@ LL | r.use_ref(); error[E0382]: borrow of moved value: `x` --> $DIR/closure-access-spans.rs:37:5 | +LL | fn closure_imm_capture_moved(mut x: String) { + | ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let r = x; | - value moved here LL | || x.len(); //~ ERROR | ^^ - borrow occurs due to use in closure | | | value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/closure-access-spans.rs:42:5 | +LL | fn closure_mut_capture_moved(mut x: String) { + | ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let r = x; | - value moved here LL | || x = String::new(); //~ ERROR | ^^ - borrow occurs due to use in closure | | | value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/closure-access-spans.rs:47:5 | +LL | fn closure_unique_capture_moved(x: &mut String) { + | - move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait LL | let r = x; | - value moved here LL | || *x = String::new(); //~ ERROR | ^^ - borrow occurs due to use in closure | | | value borrowed here after move - | - = note: move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x` --> $DIR/closure-access-spans.rs:52:5 | +LL | fn closure_move_capture_moved(x: &mut String) { + | - move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait LL | let r = x; | - value moved here LL | || x; //~ ERROR | ^^ - use occurs due to use in closure | | | value used here after move - | - = note: move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait error: aborting due to 9 previous errors diff --git a/src/test/ui/nll/closure-move-spans.stderr b/src/test/ui/nll/closure-move-spans.stderr index 3ae1912eb10bf..6750c4047601a 100644 --- a/src/test/ui/nll/closure-move-spans.stderr +++ b/src/test/ui/nll/closure-move-spans.stderr @@ -1,38 +1,38 @@ error[E0382]: use of moved value: `x` --> $DIR/closure-move-spans.rs:7:13 | +LL | fn move_after_move(x: String) { + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | || x; | -- - variable moved due to use in closure | | | value moved into closure here LL | let y = x; //~ ERROR | ^ value used here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/closure-move-spans.rs:12:13 | +LL | fn borrow_after_move(x: String) { + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | || x; | -- - variable moved due to use in closure | | | value moved into closure here LL | let y = &x; //~ ERROR | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/closure-move-spans.rs:17:13 | +LL | fn borrow_mut_after_move(mut x: String) { + | ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | || x; | -- - variable moved due to use in closure | | | value moved into closure here LL | let y = &mut x; //~ ERROR | ^^^^^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 93e095d663cc2..6c9e1639f88dd 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -1,12 +1,13 @@ error[E0382]: use of moved value: `x` --> $DIR/closures-in-loops.rs:8:9 | +LL | fn repreated_move(x: String) { + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait +LL | for i in 0..10 { LL | || x; //~ ERROR | ^^ - use occurs due to use in closure | | | value moved into closure here, in previous iteration of loop - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/closures-in-loops.rs:15:16 diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr index e29c44760a987..54c728e3d2783 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -13,12 +13,12 @@ LL | d.x = 10; error[E0382]: assign of moved value: `d` --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:43:5 | +LL | let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; + | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait LL | drop(d); | - value moved here LL | d.x = 10; | ^^^^^^^^ value assigned here after move - | - = note: move occurs because `d` has type `D`, which does not implement the `Copy` trait error[E0381]: assign to part of possibly uninitialized variable: `d` --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:49:5 @@ -35,12 +35,12 @@ LL | d.s.y = 20; error[E0382]: assign to part of moved value: `d` --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:62:5 | +LL | let mut d = D { x: 0, s: S{ y: 0, z: 0} }; + | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait LL | drop(d); | - value moved here LL | d.s.y = 20; | ^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `d` has type `D`, which does not implement the `Copy` trait error: aborting due to 6 previous errors diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr index aec7f676fcebd..23da533252cb9 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr @@ -14,21 +14,21 @@ error[E0382]: assign to part of moved value: `s` --> $DIR/issue-21232-partial-init-and-use.rs:113:5 | LL | let mut s: S = S::new(); drop(s); - | - value moved here + | ----- - value moved here + | | + | move occurs because `s` has type `S>`, which does not implement the `Copy` trait LL | s.x = 10; s.y = Box::new(20); | ^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `s` has type `S>`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `t` --> $DIR/issue-21232-partial-init-and-use.rs:120:5 | LL | let mut t: T = (0, Box::new(0)); drop(t); - | - value moved here + | ----- - value moved here + | | + | move occurs because `t` has type `(u32, std::boxed::Box)`, which does not implement the `Copy` trait LL | t.0 = 10; t.1 = Box::new(20); | ^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `t` has type `(u32, std::boxed::Box)`, which does not implement the `Copy` trait error[E0381]: assign to part of possibly uninitialized variable: `s` --> $DIR/issue-21232-partial-init-and-use.rs:127:5 @@ -46,21 +46,21 @@ error[E0382]: assign to part of moved value: `s` --> $DIR/issue-21232-partial-init-and-use.rs:141:5 | LL | let mut s: S = S::new(); drop(s); - | - value moved here + | ----- - value moved here + | | + | move occurs because `s` has type `S>`, which does not implement the `Copy` trait LL | s.x = 10; | ^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `s` has type `S>`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `t` --> $DIR/issue-21232-partial-init-and-use.rs:148:5 | LL | let mut t: T = (0, Box::new(0)); drop(t); - | - value moved here + | ----- - value moved here + | | + | move occurs because `t` has type `(u32, std::boxed::Box)`, which does not implement the `Copy` trait LL | t.0 = 10; | ^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `t` has type `(u32, std::boxed::Box)`, which does not implement the `Copy` trait error[E0381]: assign to part of possibly uninitialized variable: `s` --> $DIR/issue-21232-partial-init-and-use.rs:155:5 @@ -153,22 +153,24 @@ LL | q.r.f.0 = 10; error[E0382]: assign to part of moved value: `c` --> $DIR/issue-21232-partial-init-and-use.rs:259:13 | +LL | let mut c = (1, "".to_owned()); + | ----- move occurs because `c` has type `(i32, std::string::String)`, which does not implement the `Copy` trait +LL | match c { LL | c2 => { | -- value moved here LL | c.0 = 2; //~ ERROR assign to part of moved value | ^^^^^^^ value partially assigned here after move - | - = note: move occurs because `c` has type `(i32, std::string::String)`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `c` --> $DIR/issue-21232-partial-init-and-use.rs:269:13 | +LL | let mut c = (1, (1, "".to_owned())); + | ----- move occurs because `c` has type `(i32, (i32, std::string::String))`, which does not implement the `Copy` trait +LL | match c { LL | c2 => { | -- value moved here LL | (c.1).0 = 2; //~ ERROR assign to part of moved value | ^^^^^^^^^^^ value partially assigned here after move - | - = note: move occurs because `c` has type `(i32, (i32, std::string::String))`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `c.1` --> $DIR/issue-21232-partial-init-and-use.rs:277:13 diff --git a/src/test/ui/nll/issue-51512.stderr b/src/test/ui/nll/issue-51512.stderr index 4717935e4b9f9..a84a236ca7772 100644 --- a/src/test/ui/nll/issue-51512.stderr +++ b/src/test/ui/nll/issue-51512.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `range` --> $DIR/issue-51512.rs:7:13 | +LL | let range = 0..1; + | ----- move occurs because `range` has type `std::ops::Range`, which does not implement the `Copy` trait LL | let r = range; | ----- value moved here LL | let x = range.start; | ^^^^^^^^^^^ value used here after move - | - = note: move occurs because `range` has type `std::ops::Range`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/nll/issue-52669.stderr b/src/test/ui/nll/issue-52669.stderr index e1fb76c6bc242..f51768c3859e4 100644 --- a/src/test/ui/nll/issue-52669.stderr +++ b/src/test/ui/nll/issue-52669.stderr @@ -1,12 +1,13 @@ error[E0382]: borrow of moved value: `a.b` --> $DIR/issue-52669.rs:15:5 | +LL | fn bar(mut a: A) -> B { + | ----- move occurs because `a` has type `A`, which does not implement the `Copy` trait +LL | a.b = B; LL | foo(a); | - value moved here LL | a.b.clone() | ^^^ value borrowed here after move - | - = note: move occurs because `a` has type `A`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/try-block/try-block-bad-lifetime.stderr b/src/test/ui/try-block/try-block-bad-lifetime.stderr index 5bb0b099b977b..b1b925d694ff9 100644 --- a/src/test/ui/try-block/try-block-bad-lifetime.stderr +++ b/src/test/ui/try-block/try-block-bad-lifetime.stderr @@ -25,13 +25,14 @@ LL | ::std::mem::drop(k); //~ ERROR use of moved value: `k` error[E0382]: use of moved value: `k` --> $DIR/try-block-bad-lifetime.rs:31:26 | +LL | let k = &mut i; + | - move occurs because `k` has type `&mut i32`, which does not implement the `Copy` trait +LL | let mut j: Result<(), &mut i32> = try { LL | Err(k) ?; | - value moved here ... LL | ::std::mem::drop(k); //~ ERROR use of moved value: `k` | ^ value used here after move - | - = note: move occurs because `k` has type `&mut i32`, which does not implement the `Copy` trait error[E0506]: cannot assign to `i` because it is borrowed --> $DIR/try-block-bad-lifetime.rs:32:9 diff --git a/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr b/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr index f96c7146d18d0..dafbde6a5150b 100644 --- a/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr +++ b/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr @@ -13,13 +13,14 @@ LL | do_something_with(x); error[E0382]: borrow of moved value: `x` --> $DIR/try-block-maybe-bad-lifetime.rs:28:24 | +LL | let x = String::new(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait +... LL | ::std::mem::drop(x); | - value moved here LL | }; LL | println!("{}", x); //~ ERROR borrow of moved value: `x` | ^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0506]: cannot assign to `i` because it is borrowed --> $DIR/try-block-maybe-bad-lifetime.rs:40:9 From e0a606c6a9a7f65840afae38feaf2fe178974c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 2 Jan 2019 16:56:45 -0800 Subject: [PATCH 0302/1064] Add test for #34721 --- src/test/ui/issues/issue-34721.rs | 34 +++++++++++++++++++++++++++ src/test/ui/issues/issue-34721.stderr | 18 ++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/test/ui/issues/issue-34721.rs create mode 100644 src/test/ui/issues/issue-34721.stderr diff --git a/src/test/ui/issues/issue-34721.rs b/src/test/ui/issues/issue-34721.rs new file mode 100644 index 0000000000000..226c21446b1ed --- /dev/null +++ b/src/test/ui/issues/issue-34721.rs @@ -0,0 +1,34 @@ +#![feature(nll)] + +pub trait Foo { + fn zero(self) -> Self; +} + +impl Foo for u32 { + fn zero(self) -> u32 { 0u32 } +} + +pub mod bar { + pub use Foo; + pub fn bar(x: T) -> T { + x.zero() + } +} + +mod baz { + use bar; + use Foo; + pub fn baz(x: T) -> T { + if 0 == 1 { + bar::bar(x.zero()) + } else { + x.zero() + }; + x.zero() + //~^ ERROR use of moved value + } +} + +fn main() { + let _ = baz::baz(0u32); +} diff --git a/src/test/ui/issues/issue-34721.stderr b/src/test/ui/issues/issue-34721.stderr new file mode 100644 index 0000000000000..b4e274b1c7019 --- /dev/null +++ b/src/test/ui/issues/issue-34721.stderr @@ -0,0 +1,18 @@ +error[E0382]: use of moved value: `x` + --> $DIR/issue-34721.rs:27:9 + | +LL | pub fn baz(x: T) -> T { + | - move occurs because `x` has type `T`, which does not implement the `Copy` trait +LL | if 0 == 1 { +LL | bar::bar(x.zero()) + | - value moved here +LL | } else { +LL | x.zero() + | - value moved here +LL | }; +LL | x.zero() + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. From f6e29babc03d1554469d5f8cc49aec7dba162f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 4 Jan 2019 13:47:35 -0800 Subject: [PATCH 0303/1064] break eagerly from loop --- src/librustc_mir/borrow_check/error_reporting.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index cbcf8c90fee41..e3fc591bda847 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -214,6 +214,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { note_msg, ty, )); note = false; + break; } } if note { From 0e2d6e017592753089a9238c7fe269e45d32d459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 6 Jan 2019 15:23:30 -0800 Subject: [PATCH 0304/1064] Point at type argument suggesting adding `Copy` constraint --- src/librustc_mir/borrow_check/error_reporting.rs | 11 +++++++++++ .../ui/borrowck/two-phase-nonrecv-autoref.nll.stderr | 2 ++ src/test/ui/issues/issue-34721.stderr | 4 +++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index e3fc591bda847..d8a3cf9947024 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -217,6 +217,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { break; } } + if let ty::TyKind::Param(param_ty) = ty.sty { + let tcx = self.infcx.tcx; + let generics = tcx.generics_of(self.mir_def_id); + let def_id = generics.type_param(¶m_ty, tcx).def_id; + if let Some(sp) = tcx.hir().span_if_local(def_id) { + err.span_label( + sp, + "consider adding a `Copy` constraint to this type argument", + ); + } + } if note { err.note(&format!( "move occurs because {} has type `{}`, \ diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr index 0e99e158eda02..d026f81b7aad6 100644 --- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr +++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr @@ -10,6 +10,8 @@ LL | f(f(10)); error[E0382]: use of moved value: `*f` --> $DIR/two-phase-nonrecv-autoref.rs:69:11 | +LL | fn twice_ten_so i32>(f: Box) { + | - consider adding a `Copy` constraint to this type argument LL | f(f(10)); | - ^ value used here after move | | diff --git a/src/test/ui/issues/issue-34721.stderr b/src/test/ui/issues/issue-34721.stderr index b4e274b1c7019..2ed7b543e713c 100644 --- a/src/test/ui/issues/issue-34721.stderr +++ b/src/test/ui/issues/issue-34721.stderr @@ -2,7 +2,9 @@ error[E0382]: use of moved value: `x` --> $DIR/issue-34721.rs:27:9 | LL | pub fn baz(x: T) -> T { - | - move occurs because `x` has type `T`, which does not implement the `Copy` trait + | - - move occurs because `x` has type `T`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument LL | if 0 == 1 { LL | bar::bar(x.zero()) | - value moved here From 29e8e63c84a597886c10eef6d4f04a462238133a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 18 Jan 2019 15:47:25 -0800 Subject: [PATCH 0305/1064] review comments --- .../borrow_check/error_reporting.rs | 25 ++++++++----------- src/test/ui/borrowck/issue-41962.stderr | 5 +--- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index d8a3cf9947024..56b87feb82b2c 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -203,20 +203,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Some(ref name) => format!("`{}`", name), None => "value".to_owned(), }; - let mut note = true; - for decl in &self.mir.local_decls { - if decl.ty == ty && decl.name.map(|x| x.to_string()) == opt_name { - err.span_label( - decl.source_info.span, - format!( - "move occurs because {} has type `{}`, \ - which does not implement the `Copy` trait", - note_msg, ty, - )); - note = false; - break; - } - } if let ty::TyKind::Param(param_ty) = ty.sty { let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id); @@ -228,7 +214,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); } } - if note { + if let Place::Local(local) = place { + let decl = &self.mir.local_decls[*local]; + err.span_label( + decl.source_info.span, + format!( + "move occurs because {} has type `{}`, \ + which does not implement the `Copy` trait", + note_msg, ty, + )); + } else { err.note(&format!( "move occurs because {} has type `{}`, \ which does not implement the `Copy` trait", diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index 3c0071f6b3745..fd4d318b5ddf1 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -19,13 +19,10 @@ LL | if let Some(thing) = maybe { error[E0382]: use of moved value (Mir) --> $DIR/issue-41962.rs:7:21 | -LL | let maybe = Some(vec![true, true]); - | ---------------- move occurs because value has type `std::vec::Vec`, which does not implement the `Copy` trait -... LL | if let Some(thing) = maybe { | ^^^^^ value moved here, in previous iteration of loop | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: move occurs because value has type `std::vec::Vec`, which does not implement the `Copy` trait error: aborting due to 3 previous errors From baa0828ee35475987fd825d8eaf77e009dca2bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 24 Jan 2019 10:53:43 -0800 Subject: [PATCH 0306/1064] Fix --compare-mode=nll tests --- .../ui/binop/binop-consume-args.nll.stderr | 253 ++++++++++++++++++ .../ui/binop/binop-move-semantics.nll.stderr | 12 +- .../ui/borrowck/borrowck-asm.ast.nll.stderr | 10 +- .../borrowck-consume-unsize-vec.nll.stderr | 13 + .../borrowck-consume-upcast-box.nll.stderr | 4 +- .../borrowck-loan-in-overloaded-op.nll.stderr | 4 +- ...ve-moved-value-into-closure.ast.nll.stderr | 5 +- .../borrowck-multiple-captures.nll.stderr | 12 +- .../borrowck-overloaded-call.nll.stderr | 5 +- ...wck-overloaded-index-move-index.nll.stderr | 5 +- .../borrowck-partial-reinit-1.nll.stderr | 10 +- .../borrowck-partial-reinit-2.nll.stderr | 4 +- .../borrowck-unboxed-closures.nll.stderr | 6 +- .../borrowck-union-move-assign.nll.stderr | 4 +- .../borrowck/borrowck-union-move.nll.stderr | 24 +- .../two-phase-nonrecv-autoref.ast.nll.stderr | 2 + src/test/ui/codemap_tests/tab_3.nll.stderr | 4 +- src/test/ui/issues/issue-17385.nll.stderr | 8 +- src/test/ui/issues/issue-24357.nll.stderr | 4 +- src/test/ui/issues/issue-25700.nll.stderr | 13 + src/test/ui/issues/issue-42796.nll.stderr | 4 +- .../liveness-move-call-arg.nll.stderr | 5 +- .../liveness/liveness-move-in-loop.nll.stderr | 5 +- .../liveness-move-in-while.nll.stderr | 5 +- .../liveness-use-after-move.nll.stderr | 4 +- .../liveness-use-after-send.nll.stderr | 4 +- .../moves/move-guard-same-consts.nll.stderr | 14 + src/test/ui/moves/move-in-guard-1.nll.stderr | 14 + src/test/ui/moves/move-in-guard-2.nll.stderr | 5 +- .../moves/move-into-dead-array-2.nll.stderr | 4 +- ...s-based-on-type-access-to-field.nll.stderr | 4 +- ...ased-on-type-capture-clause-bad.nll.stderr | 4 +- ...type-distribute-copy-over-paren.nll.stderr | 8 +- .../moves-based-on-type-exprs.nll.stderr | 49 ++-- ...type-no-recursive-stack-closure.nll.stderr | 6 +- src/test/ui/no-capture-arc.nll.stderr | 5 +- src/test/ui/no-reuse-move-arc.nll.stderr | 5 +- .../once-cant-call-twice-on-heap.nll.stderr | 15 ++ src/test/ui/ref-suggestion.nll.stderr | 8 +- .../dbg-macro-move-semantics.nll.stderr | 3 +- ...nion-borrow-move-parent-sibling.nll.stderr | 12 +- src/test/ui/unop-move-semantics.nll.stderr | 6 +- .../borrow-after-move.nll.stderr | 8 +- .../ui/unsized-locals/double-move.nll.stderr | 12 +- .../use-after-move-based-on-type.nll.stderr | 4 +- ...r-move-implicity-coerced-object.nll.stderr | 5 +- ...e-after-move-self-based-on-type.nll.stderr | 4 +- .../ui/use/use-after-move-self.nll.stderr | 4 +- .../ui/walk-struct-literal-with.nll.stderr | 4 +- 49 files changed, 493 insertions(+), 139 deletions(-) create mode 100644 src/test/ui/binop/binop-consume-args.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-consume-unsize-vec.nll.stderr create mode 100644 src/test/ui/issues/issue-25700.nll.stderr create mode 100644 src/test/ui/moves/move-guard-same-consts.nll.stderr create mode 100644 src/test/ui/moves/move-in-guard-1.nll.stderr create mode 100644 src/test/ui/once-cant-call-twice-on-heap.nll.stderr diff --git a/src/test/ui/binop/binop-consume-args.nll.stderr b/src/test/ui/binop/binop-consume-args.nll.stderr new file mode 100644 index 0000000000000..59b5aba93cad4 --- /dev/null +++ b/src/test/ui/binop/binop-consume-args.nll.stderr @@ -0,0 +1,253 @@ +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:7:10 + | +LL | fn add, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs + rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:8:10 + | +LL | fn add, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs + rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:13:10 + | +LL | fn sub, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs - rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:14:10 + | +LL | fn sub, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs - rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:19:10 + | +LL | fn mul, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs * rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:20:10 + | +LL | fn mul, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs * rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:25:10 + | +LL | fn div, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs / rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:26:10 + | +LL | fn div, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs / rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:31:10 + | +LL | fn rem, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs % rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:32:10 + | +LL | fn rem, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs % rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:37:10 + | +LL | fn bitand, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs & rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:38:10 + | +LL | fn bitand, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs & rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:43:10 + | +LL | fn bitor, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs | rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:44:10 + | +LL | fn bitor, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs | rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:49:10 + | +LL | fn bitxor, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs ^ rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:50:10 + | +LL | fn bitxor, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs ^ rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:55:10 + | +LL | fn shl, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs << rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:56:10 + | +LL | fn shl, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs << rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `lhs` + --> $DIR/binop-consume-args.rs:61:10 + | +LL | fn shr, B>(lhs: A, rhs: B) { + | - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs >> rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` + | ^^^ value used here after move + +error[E0382]: use of moved value: `rhs` + --> $DIR/binop-consume-args.rs:62:10 + | +LL | fn shr, B>(lhs: A, rhs: B) { + | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | lhs >> rhs; + | --- value moved here +LL | drop(lhs); //~ ERROR use of moved value: `lhs` +LL | drop(rhs); //~ ERROR use of moved value: `rhs` + | ^^^ value used here after move + +error: aborting due to 20 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/binop/binop-move-semantics.nll.stderr b/src/test/ui/binop/binop-move-semantics.nll.stderr index 950772dc75c9e..7c84e8833a9e6 100644 --- a/src/test/ui/binop/binop-move-semantics.nll.stderr +++ b/src/test/ui/binop/binop-move-semantics.nll.stderr @@ -1,24 +1,28 @@ error[E0382]: use of moved value: `x` --> $DIR/binop-move-semantics.rs:8:5 | +LL | fn double_move>(x: T) { + | - - move occurs because `x` has type `T`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument LL | x | - value moved here LL | + LL | x; //~ ERROR: use of moved value | ^ value used here after move - | - = note: move occurs because `x` has type `T`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/binop-move-semantics.rs:14:5 | +LL | fn move_then_borrow + Clone>(x: T) { + | - - move occurs because `x` has type `T`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument LL | x | - value moved here LL | + LL | x.clone(); //~ ERROR: use of moved value | ^ value borrowed here after move - | - = note: move occurs because `x` has type `T`, which does not implement the `Copy` trait error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/binop-move-semantics.rs:21:5 diff --git a/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr b/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr index 9c47845a52830..86e4832b3873c 100644 --- a/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr +++ b/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr @@ -1,13 +1,14 @@ error[E0382]: use of moved value: `x` --> $DIR/borrowck-asm.rs:27:17 | +LL | let x = &mut 0isize; + | - move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait +LL | unsafe { LL | asm!("nop" : : "r"(x)); | - value moved here LL | } LL | let z = x; //[ast]~ ERROR use of moved value: `x` | ^ value used here after move - | - = note: move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait error[E0503]: cannot use `x` because it was mutably borrowed --> $DIR/borrowck-asm.rs:35:32 @@ -66,12 +67,13 @@ LL | let z = y; error[E0382]: use of moved value: `x` --> $DIR/borrowck-asm.rs:86:40 | +LL | let x = &mut 2; + | - move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait +LL | unsafe { LL | asm!("nop" : : "r"(x), "r"(x) ); //[ast]~ ERROR use of moved value | - ^ value used here after move | | | value moved here - | - = note: move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait error: aborting due to 7 previous errors diff --git a/src/test/ui/borrowck/borrowck-consume-unsize-vec.nll.stderr b/src/test/ui/borrowck/borrowck-consume-unsize-vec.nll.stderr new file mode 100644 index 0000000000000..ea7683a91adfe --- /dev/null +++ b/src/test/ui/borrowck/borrowck-consume-unsize-vec.nll.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `b` + --> $DIR/borrowck-consume-unsize-vec.rs:8:13 + | +LL | fn foo(b: Box<[i32;5]>) { + | - move occurs because `b` has type `std::boxed::Box<[i32; 5]>`, which does not implement the `Copy` trait +LL | consume(b); + | - value moved here +LL | consume(b); //~ ERROR use of moved value + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-consume-upcast-box.nll.stderr b/src/test/ui/borrowck/borrowck-consume-upcast-box.nll.stderr index 7357d0973dbc0..15cf359326be9 100644 --- a/src/test/ui/borrowck/borrowck-consume-upcast-box.nll.stderr +++ b/src/test/ui/borrowck/borrowck-consume-upcast-box.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `b` --> $DIR/borrowck-consume-upcast-box.rs:10:13 | +LL | fn foo(b: Box) { + | - move occurs because `b` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | consume(b); | - value moved here LL | consume(b); //~ ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `b` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.nll.stderr b/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.nll.stderr index 72d2d1fe59f66..095ae7f56b22e 100644 --- a/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.nll.stderr +++ b/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: borrow of moved value: `x` --> $DIR/borrowck-loan-in-overloaded-op.rs:21:20 | +LL | let x = Foo(box 3); + | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait LL | let _y = {x} + x.clone(); // the `{x}` forces a move to occur | - ^ value borrowed here after move | | | value moved here - | - = note: move occurs because `x` has type `Foo`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr index 24b9b4338a58c..0789926563ce7 100644 --- a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr +++ b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr @@ -1,6 +1,9 @@ error[E0382]: use of moved value: `t` --> $DIR/borrowck-move-moved-value-into-closure.rs:14:12 | +LL | let t: Box<_> = box 3; + | - move occurs because `t` has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | LL | call_f(move|| { *t + 1 }); | ------ - variable moved due to use in closure | | @@ -9,8 +12,6 @@ LL | call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value | ^^^^^^ - use occurs due to use in closure | | | value used here after move - | - = note: move occurs because `t` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr b/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr index 6f4cad2a01e48..d0065a2e7dc3d 100644 --- a/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr +++ b/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr @@ -29,6 +29,8 @@ LL | borrow(&*p2); error[E0382]: use of moved value: `x1` --> $DIR/borrowck-multiple-captures.rs:25:19 | +LL | let x1: Box<_> = box 1; + | -- move occurs because `x1` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | drop(x1); | -- value moved here ... @@ -36,12 +38,12 @@ LL | thread::spawn(move|| { | ^^^^^^ value used here after move LL | drop(x1); //~ ERROR capture of moved value: `x1` | -- use occurs due to use in closure - | - = note: move occurs because `x1` has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x2` --> $DIR/borrowck-multiple-captures.rs:25:19 | +LL | let x2: Box<_> = box 2; + | -- move occurs because `x2` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | drop(x2); | -- value moved here LL | thread::spawn(move|| { @@ -49,8 +51,6 @@ LL | thread::spawn(move|| { LL | drop(x1); //~ ERROR capture of moved value: `x1` LL | drop(x2); //~ ERROR capture of moved value: `x2` | -- use occurs due to use in closure - | - = note: move occurs because `x2` has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x` --> $DIR/borrowck-multiple-captures.rs:36:14 @@ -88,14 +88,14 @@ LL | drop(x); //~ ERROR use of moved value: `x` error[E0382]: use of moved value: `x` --> $DIR/borrowck-multiple-captures.rs:44:19 | +LL | let x: Box<_> = box 1; + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | drop(x); | - value moved here LL | thread::spawn(move|| { | ^^^^^^ value used here after move LL | drop(x); //~ ERROR capture of moved value: `x` | - use occurs due to use in closure - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to 8 previous errors diff --git a/src/test/ui/borrowck/borrowck-overloaded-call.nll.stderr b/src/test/ui/borrowck/borrowck-overloaded-call.nll.stderr index 1b4a6610ab1a4..c5a4c4e005aa7 100644 --- a/src/test/ui/borrowck/borrowck-overloaded-call.nll.stderr +++ b/src/test/ui/borrowck/borrowck-overloaded-call.nll.stderr @@ -20,12 +20,13 @@ LL | s(3); //~ ERROR cannot borrow immutable local variable `s` as mutable error[E0382]: use of moved value: `s` --> $DIR/borrowck-overloaded-call.rs:75:5 | +LL | let s = SFnOnce { + | - move occurs because `s` has type `SFnOnce`, which does not implement the `Copy` trait +... LL | s(" world".to_string()); | - value moved here LL | s(" world".to_string()); //~ ERROR use of moved value: `s` | ^ value used here after move - | - = note: move occurs because `s` has type `SFnOnce`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-move-index.nll.stderr b/src/test/ui/borrowck/borrowck-overloaded-index-move-index.nll.stderr index a19baa167de91..de60067f1a613 100644 --- a/src/test/ui/borrowck/borrowck-overloaded-index-move-index.nll.stderr +++ b/src/test/ui/borrowck/borrowck-overloaded-index-move-index.nll.stderr @@ -25,13 +25,14 @@ LL | use_mut(rs); error[E0382]: use of moved value: `s` --> $DIR/borrowck-overloaded-index-move-index.rs:53:7 | +LL | let mut s = "hello".to_string(); + | ----- move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait +... LL | println!("{}", f[s]); | - value moved here ... LL | f[s] = 10; | ^ value used here after move - | - = note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-1.nll.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-1.nll.stderr index 09a85bd7c13a9..65f2bd6cfbda9 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-1.nll.stderr +++ b/src/test/ui/borrowck/borrowck-partial-reinit-1.nll.stderr @@ -1,22 +1,24 @@ error[E0382]: assign of moved value: `t` --> $DIR/borrowck-partial-reinit-1.rs:27:5 | +LL | let mut t = Test2 { b: None }; + | ----- move occurs because `t` has type `Test2`, which does not implement the `Copy` trait +LL | let u = Test; LL | drop(t); | - value moved here LL | t.b = Some(u); | ^^^ value assigned here after move - | - = note: move occurs because `t` has type `Test2`, which does not implement the `Copy` trait error[E0382]: assign of moved value: `t` --> $DIR/borrowck-partial-reinit-1.rs:33:5 | +LL | let mut t = Test3(None); + | ----- move occurs because `t` has type `Test3`, which does not implement the `Copy` trait +LL | let u = Test; LL | drop(t); | - value moved here LL | t.0 = Some(u); | ^^^ value assigned here after move - | - = note: move occurs because `t` has type `Test3`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-2.nll.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-2.nll.stderr index 03608a1b99d24..36a871fbb12a1 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-2.nll.stderr +++ b/src/test/ui/borrowck/borrowck-partial-reinit-2.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: assign of moved value: `t` --> $DIR/borrowck-partial-reinit-2.rs:15:5 | +LL | let mut t = Test { a: 1, b: None}; + | ----- move occurs because `t` has type `Test`, which does not implement the `Copy` trait LL | let mut u = Test { a: 2, b: Some(Box::new(t))}; | - value moved here LL | t.b = Some(Box::new(u)); | ^^^ value assigned here after move - | - = note: move occurs because `t` has type `Test`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-unboxed-closures.nll.stderr b/src/test/ui/borrowck/borrowck-unboxed-closures.nll.stderr index 86baa0db96121..363a5a69a07e3 100644 --- a/src/test/ui/borrowck/borrowck-unboxed-closures.nll.stderr +++ b/src/test/ui/borrowck/borrowck-unboxed-closures.nll.stderr @@ -19,12 +19,14 @@ LL | f(1, 2); //~ ERROR cannot borrow immutable argument error[E0382]: use of moved value: `f` --> $DIR/borrowck-unboxed-closures.rs:12:5 | +LL | fn c isize>(f: F) { + | - - move occurs because `f` has type `F`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument LL | f(1, 2); | - value moved here LL | f(1, 2); //~ ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `f` has type `F`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/borrowck-union-move-assign.nll.stderr b/src/test/ui/borrowck/borrowck-union-move-assign.nll.stderr index bf0d0a45fcff7..e59fef2dc0d2f 100644 --- a/src/test/ui/borrowck/borrowck-union-move-assign.nll.stderr +++ b/src/test/ui/borrowck/borrowck-union-move-assign.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move-assign.rs:17:21 | +LL | let mut u = U { a: A }; + | ----- move occurs because `u` has type `U`, which does not implement the `Copy` trait LL | let a = u.a; | --- value moved here LL | let a = u.a; //~ ERROR use of moved value: `u.a` | ^^^ value used here after move - | - = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-union-move.nll.stderr b/src/test/ui/borrowck/borrowck-union-move.nll.stderr index fd90fc47a218d..1392a7931c30a 100644 --- a/src/test/ui/borrowck/borrowck-union-move.nll.stderr +++ b/src/test/ui/borrowck/borrowck-union-move.nll.stderr @@ -1,62 +1,62 @@ error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move.rs:26:21 | +LL | let mut u = Unn { n1: NonCopy }; + | ----- move occurs because `u` has type `Unn`, which does not implement the `Copy` trait LL | let a = u.n1; | ---- value moved here LL | let a = u.n1; //~ ERROR use of moved value: `u.n1` | ^^^^ value used here after move - | - = note: move occurs because `u` has type `Unn`, which does not implement the `Copy` trait error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move.rs:31:21 | +LL | let mut u = Unn { n1: NonCopy }; + | ----- move occurs because `u` has type `Unn`, which does not implement the `Copy` trait LL | let a = u.n1; | ---- value moved here LL | let a = u; //~ ERROR use of partially moved value: `u` | ^ value used here after move - | - = note: move occurs because `u` has type `Unn`, which does not implement the `Copy` trait error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move.rs:36:21 | +LL | let mut u = Unn { n1: NonCopy }; + | ----- move occurs because `u` has type `Unn`, which does not implement the `Copy` trait LL | let a = u.n1; | ---- value moved here LL | let a = u.n2; //~ ERROR use of moved value: `u.n2` | ^^^^ value used here after move - | - = note: move occurs because `u` has type `Unn`, which does not implement the `Copy` trait error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move.rs:63:21 | +LL | let mut u = Ucn { c: Copy }; + | ----- move occurs because `u` has type `Ucn`, which does not implement the `Copy` trait LL | let a = u.n; | --- value moved here LL | let a = u.n; //~ ERROR use of moved value: `u.n` | ^^^ value used here after move - | - = note: move occurs because `u` has type `Ucn`, which does not implement the `Copy` trait error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move.rs:68:21 | +LL | let mut u = Ucn { c: Copy }; + | ----- move occurs because `u` has type `Ucn`, which does not implement the `Copy` trait LL | let a = u.n; | --- value moved here LL | let a = u.c; //~ ERROR use of moved value: `u.c` | ^^^ value used here after move - | - = note: move occurs because `u` has type `Ucn`, which does not implement the `Copy` trait error[E0382]: use of moved value: `u` --> $DIR/borrowck-union-move.rs:83:21 | +LL | let mut u = Ucn { c: Copy }; + | ----- move occurs because `u` has type `Ucn`, which does not implement the `Copy` trait LL | let a = u.n; | --- value moved here LL | let a = u; //~ ERROR use of partially moved value: `u` | ^ value used here after move - | - = note: move occurs because `u` has type `Ucn`, which does not implement the `Copy` trait error: aborting due to 6 previous errors diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.ast.nll.stderr b/src/test/ui/borrowck/two-phase-nonrecv-autoref.ast.nll.stderr index 0e99e158eda02..d026f81b7aad6 100644 --- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.ast.nll.stderr +++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.ast.nll.stderr @@ -10,6 +10,8 @@ LL | f(f(10)); error[E0382]: use of moved value: `*f` --> $DIR/two-phase-nonrecv-autoref.rs:69:11 | +LL | fn twice_ten_so i32>(f: Box) { + | - consider adding a `Copy` constraint to this type argument LL | f(f(10)); | - ^ value used here after move | | diff --git a/src/test/ui/codemap_tests/tab_3.nll.stderr b/src/test/ui/codemap_tests/tab_3.nll.stderr index 55117ff2b1876..3b8507a067ded 100644 --- a/src/test/ui/codemap_tests/tab_3.nll.stderr +++ b/src/test/ui/codemap_tests/tab_3.nll.stderr @@ -1,13 +1,13 @@ error[E0382]: borrow of moved value: `some_vec` --> $DIR/tab_3.rs:7:20 | +LL | let some_vec = vec!["hi"]; + | -------- move occurs because `some_vec` has type `std::vec::Vec<&str>`, which does not implement the `Copy` trait LL | some_vec.into_iter(); | -------- value moved here LL | { LL | println!("{:?}", some_vec); //~ ERROR use of moved | ^^^^^^^^ value borrowed here after move - | - = note: move occurs because `some_vec` has type `std::vec::Vec<&str>`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17385.nll.stderr b/src/test/ui/issues/issue-17385.nll.stderr index 24080a3b387f2..20198f19dd5f5 100644 --- a/src/test/ui/issues/issue-17385.nll.stderr +++ b/src/test/ui/issues/issue-17385.nll.stderr @@ -1,23 +1,23 @@ error[E0382]: use of moved value: `foo` --> $DIR/issue-17385.rs:19:11 | +LL | let foo = X(1); + | --- move occurs because `foo` has type `X`, which does not implement the `Copy` trait LL | drop(foo); | --- value moved here LL | match foo { //~ ERROR use of moved value LL | X(1) => (), | ^ value used here after move - | - = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait error[E0382]: use of moved value: `e` --> $DIR/issue-17385.rs:25:11 | +LL | let e = Enum::Variant2; + | - move occurs because `e` has type `Enum`, which does not implement the `Copy` trait LL | drop(e); | - value moved here LL | match e { //~ ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-24357.nll.stderr b/src/test/ui/issues/issue-24357.nll.stderr index 06de9537af031..310535434cd08 100644 --- a/src/test/ui/issues/issue-24357.nll.stderr +++ b/src/test/ui/issues/issue-24357.nll.stderr @@ -1,6 +1,8 @@ error[E0382]: use of moved value: `x` --> $DIR/issue-24357.rs:6:12 | +LL | let x = NoCopy; + | - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait LL | let f = move || { let y = x; }; | ------- - variable moved due to use in closure | | @@ -8,8 +10,6 @@ LL | let f = move || { let y = x; }; LL | //~^ NOTE value moved (into closure) here LL | let z = x; | ^ value used here after move - | - = note: move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25700.nll.stderr b/src/test/ui/issues/issue-25700.nll.stderr new file mode 100644 index 0000000000000..ba5403cca4d06 --- /dev/null +++ b/src/test/ui/issues/issue-25700.nll.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `t` + --> $DIR/issue-25700.rs:13:10 + | +LL | let t = S::<()>(None); + | - move occurs because `t` has type `S<()>`, which does not implement the `Copy` trait +LL | drop(t); + | - value moved here +LL | drop(t); //~ ERROR use of moved value + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/issues/issue-42796.nll.stderr b/src/test/ui/issues/issue-42796.nll.stderr index 19c6a1fd557b4..23cc88bab52d5 100644 --- a/src/test/ui/issues/issue-42796.nll.stderr +++ b/src/test/ui/issues/issue-42796.nll.stderr @@ -1,13 +1,13 @@ error[E0382]: borrow of moved value: `s` --> $DIR/issue-42796.rs:18:20 | +LL | let s = "Hello!".to_owned(); + | - move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait LL | let mut s_copy = s; | - value moved here ... LL | println!("{}", s); //~ ERROR use of moved value | ^ value borrowed here after move - | - = note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/liveness/liveness-move-call-arg.nll.stderr b/src/test/ui/liveness/liveness-move-call-arg.nll.stderr index 3aa89ac8a9b71..521304d560554 100644 --- a/src/test/ui/liveness/liveness-move-call-arg.nll.stderr +++ b/src/test/ui/liveness/liveness-move-call-arg.nll.stderr @@ -1,10 +1,11 @@ error[E0382]: use of moved value: `x` --> $DIR/liveness-move-call-arg.rs:9:14 | +LL | let x: Box = box 25; + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | loop { LL | take(x); //~ ERROR use of moved value: `x` | ^ value moved here, in previous iteration of loop - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/liveness/liveness-move-in-loop.nll.stderr b/src/test/ui/liveness/liveness-move-in-loop.nll.stderr index 8a5a18f3316c7..b7e973bc9140d 100644 --- a/src/test/ui/liveness/liveness-move-in-loop.nll.stderr +++ b/src/test/ui/liveness/liveness-move-in-loop.nll.stderr @@ -1,10 +1,11 @@ error[E0382]: use of moved value: `y` --> $DIR/liveness-move-in-loop.rs:11:25 | +LL | let y: Box = box 42; + | - move occurs because `y` has type `std::boxed::Box`, which does not implement the `Copy` trait +... LL | x = y; //~ ERROR use of moved value | ^ value moved here, in previous iteration of loop - | - = note: move occurs because `y` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/liveness/liveness-move-in-while.nll.stderr b/src/test/ui/liveness/liveness-move-in-while.nll.stderr index 081983d8bf016..167dcc6b64372 100644 --- a/src/test/ui/liveness/liveness-move-in-while.nll.stderr +++ b/src/test/ui/liveness/liveness-move-in-while.nll.stderr @@ -1,12 +1,13 @@ error[E0382]: borrow of moved value: `y` --> $DIR/liveness-move-in-while.rs:7:24 | +LL | let y: Box = box 42; + | - move occurs because `y` has type `std::boxed::Box`, which does not implement the `Copy` trait +... LL | println!("{}", y); //~ ERROR use of moved value: `y` | ^ value borrowed here after move LL | while true { while true { while true { x = y; x.clone(); } } } | - value moved here, in previous iteration of loop - | - = note: move occurs because `y` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/liveness/liveness-use-after-move.nll.stderr b/src/test/ui/liveness/liveness-use-after-move.nll.stderr index 45fd43687f39b..36c25882ccd4f 100644 --- a/src/test/ui/liveness/liveness-use-after-move.nll.stderr +++ b/src/test/ui/liveness/liveness-use-after-move.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: borrow of moved value: `x` --> $DIR/liveness-use-after-move.rs:6:20 | +LL | let x: Box<_> = box 5; + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | let y = x; | - value moved here LL | println!("{}", *x); //~ ERROR use of moved value: `*x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/liveness/liveness-use-after-send.nll.stderr b/src/test/ui/liveness/liveness-use-after-send.nll.stderr index 2b55b5d59732b..d9367c871165a 100644 --- a/src/test/ui/liveness/liveness-use-after-send.nll.stderr +++ b/src/test/ui/liveness/liveness-use-after-send.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: borrow of moved value: `message` --> $DIR/liveness-use-after-send.rs:16:20 | +LL | fn test00_start(ch: Chan>, message: Box, _count: Box) { + | ------- move occurs because `message` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | send(ch, message); | ------- value moved here LL | println!("{}", message); //~ ERROR use of moved value: `message` | ^^^^^^^ value borrowed here after move - | - = note: move occurs because `message` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/moves/move-guard-same-consts.nll.stderr b/src/test/ui/moves/move-guard-same-consts.nll.stderr new file mode 100644 index 0000000000000..43f99cabcae94 --- /dev/null +++ b/src/test/ui/moves/move-guard-same-consts.nll.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-same-consts.rs:20:24 + | +LL | let x: Box<_> = box 1; + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait +... +LL | (1, 2) if take(x) => (), + | - value moved here +LL | (1, 2) if take(x) => (), //~ ERROR use of moved value: `x` + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/moves/move-in-guard-1.nll.stderr b/src/test/ui/moves/move-in-guard-1.nll.stderr new file mode 100644 index 0000000000000..41abe6fa72a57 --- /dev/null +++ b/src/test/ui/moves/move-in-guard-1.nll.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `x` + --> $DIR/move-in-guard-1.rs:10:24 + | +LL | let x: Box<_> = box 1; + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait +... +LL | (1, _) if take(x) => (), + | - value moved here +LL | (_, 2) if take(x) => (), //~ ERROR use of moved value: `x` + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/moves/move-in-guard-2.nll.stderr b/src/test/ui/moves/move-in-guard-2.nll.stderr index 2d93944384609..0b14c1620d3cf 100644 --- a/src/test/ui/moves/move-in-guard-2.nll.stderr +++ b/src/test/ui/moves/move-in-guard-2.nll.stderr @@ -1,10 +1,11 @@ error[E0382]: use of moved value: `x` --> $DIR/move-in-guard-2.rs:10:24 | +LL | let x: Box<_> = box 1; + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait +... LL | (_, 2) if take(x) => (), //~ ERROR use of moved value: `x` | ^ value moved here, in previous iteration of loop - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/moves/move-into-dead-array-2.nll.stderr b/src/test/ui/moves/move-into-dead-array-2.nll.stderr index 5b2e1bed0c7bf..20bfdc2bbac72 100644 --- a/src/test/ui/moves/move-into-dead-array-2.nll.stderr +++ b/src/test/ui/moves/move-into-dead-array-2.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `a` --> $DIR/move-into-dead-array-2.rs:14:5 | +LL | fn foo(mut a: [D; 4], i: usize) { + | ----- move occurs because `a` has type `[D; 4]`, which does not implement the `Copy` trait LL | drop(a); | - value moved here LL | a[i] = d(); //~ ERROR use of moved value: `a` | ^^^^ value used here after move - | - = note: move occurs because `a` has type `[D; 4]`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/moves/moves-based-on-type-access-to-field.nll.stderr b/src/test/ui/moves/moves-based-on-type-access-to-field.nll.stderr index 22968b329695f..6ad9a2d414c77 100644 --- a/src/test/ui/moves/moves-based-on-type-access-to-field.nll.stderr +++ b/src/test/ui/moves/moves-based-on-type-access-to-field.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-access-to-field.rs:11:12 | +LL | let x = vec!["hi".to_string()]; + | - move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait LL | consume(x.into_iter().next().unwrap()); | - value moved here LL | touch(&x[0]); //~ ERROR use of moved value: `x` | ^ value borrowed here after move - | - = note: move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/moves/moves-based-on-type-capture-clause-bad.nll.stderr b/src/test/ui/moves/moves-based-on-type-capture-clause-bad.nll.stderr index 061e871c78a73..bed0ae7275cc5 100644 --- a/src/test/ui/moves/moves-based-on-type-capture-clause-bad.nll.stderr +++ b/src/test/ui/moves/moves-based-on-type-capture-clause-bad.nll.stderr @@ -1,6 +1,8 @@ error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-capture-clause-bad.rs:8:20 | +LL | let x = "Hello world!".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | thread::spawn(move|| { | ------ value moved into closure here LL | println!("{}", x); @@ -8,8 +10,6 @@ LL | println!("{}", x); LL | }); LL | println!("{}", x); //~ ERROR use of moved value | ^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.nll.stderr b/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.nll.stderr index 10593a6078e3b..07f40274f9e31 100644 --- a/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.nll.stderr +++ b/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.nll.stderr @@ -1,24 +1,24 @@ error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-distribute-copy-over-paren.rs:11:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = Foo { f:x }; | - value moved here LL | //~^ NOTE value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-distribute-copy-over-paren.rs:20:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = Foo { f:(((x))) }; | ------- value moved here LL | //~^ NOTE value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/moves/moves-based-on-type-exprs.nll.stderr b/src/test/ui/moves/moves-based-on-type-exprs.nll.stderr index fe44803e2734b..162aec45f5f57 100644 --- a/src/test/ui/moves/moves-based-on-type-exprs.nll.stderr +++ b/src/test/ui/moves/moves-based-on-type-exprs.nll.stderr @@ -1,117 +1,122 @@ error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:12:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = Foo { f:x }; | - value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:18:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = (x, 3); | - value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:35:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait +... LL | x | - value moved here ... LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `y` --> $DIR/moves-based-on-type-exprs.rs:36:11 | +LL | let y = "ho".to_string(); + | - move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait +... LL | y | - value moved here ... LL | touch(&y); //~ ERROR use of moved value: `y` | ^^ value borrowed here after move - | - = note: move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:46:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait +... LL | true => x, | - value moved here ... LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `y` --> $DIR/moves-based-on-type-exprs.rs:47:11 | +LL | let y = "ho".to_string(); + | - move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait +... LL | false => y | - value moved here ... LL | touch(&y); //~ ERROR use of moved value: `y` | ^^ value borrowed here after move - | - = note: move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:58:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait +... LL | _ if guard(x) => 10, | - value moved here ... LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:65:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = [x]; | - value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:71:11 | +LL | let x = "hi".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = vec![x]; | - value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:77:11 | +LL | let x = vec!["hi".to_string()]; + | - move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait LL | let _y = x.into_iter().next().unwrap(); | - value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/moves-based-on-type-exprs.rs:83:11 | +LL | let x = vec!["hi".to_string()]; + | - move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait LL | let _y = [x.into_iter().next().unwrap(); 1]; | - value moved here LL | touch(&x); //~ ERROR use of moved value: `x` | ^^ value borrowed here after move - | - = note: move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait error: aborting due to 11 previous errors diff --git a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.nll.stderr b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.nll.stderr index 03a23420bbc9e..391dd67dbf60a 100644 --- a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.nll.stderr +++ b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.nll.stderr @@ -10,12 +10,14 @@ LL | (f.c)(f, true); error[E0382]: borrow of moved value: `f` --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:32:5 | +LL | fn conspirator(mut f: F) where F: FnMut(&mut R, bool) { + | - ----- move occurs because `f` has type `F`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument LL | let mut r = R {c: Box::new(f)}; | - value moved here LL | f(&mut r, false) //~ ERROR use of moved value | ^ value borrowed here after move - | - = note: move occurs because `f` has type `F`, which does not implement the `Copy` trait error: aborting due to 2 previous errors diff --git a/src/test/ui/no-capture-arc.nll.stderr b/src/test/ui/no-capture-arc.nll.stderr index a3bb56024c454..476b6f75abb46 100644 --- a/src/test/ui/no-capture-arc.nll.stderr +++ b/src/test/ui/no-capture-arc.nll.stderr @@ -1,6 +1,9 @@ error[E0382]: borrow of moved value: `arc_v` --> $DIR/no-capture-arc.rs:14:18 | +LL | let arc_v = Arc::new(v); + | ----- move occurs because `arc_v` has type `std::sync::Arc>`, which does not implement the `Copy` trait +LL | LL | thread::spawn(move|| { | ------ value moved into closure here LL | assert_eq!((*arc_v)[3], 4); @@ -8,8 +11,6 @@ LL | assert_eq!((*arc_v)[3], 4); ... LL | assert_eq!((*arc_v)[2], 3); | ^^^^^ value borrowed here after move - | - = note: move occurs because `arc_v` has type `std::sync::Arc>`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/no-reuse-move-arc.nll.stderr b/src/test/ui/no-reuse-move-arc.nll.stderr index e24edc5e8e3ca..0b14f65a77073 100644 --- a/src/test/ui/no-reuse-move-arc.nll.stderr +++ b/src/test/ui/no-reuse-move-arc.nll.stderr @@ -1,6 +1,9 @@ error[E0382]: borrow of moved value: `arc_v` --> $DIR/no-reuse-move-arc.rs:12:18 | +LL | let arc_v = Arc::new(v); + | ----- move occurs because `arc_v` has type `std::sync::Arc>`, which does not implement the `Copy` trait +LL | LL | thread::spawn(move|| { | ------ value moved into closure here LL | assert_eq!((*arc_v)[3], 4); @@ -8,8 +11,6 @@ LL | assert_eq!((*arc_v)[3], 4); ... LL | assert_eq!((*arc_v)[2], 3); //~ ERROR use of moved value: `arc_v` | ^^^^^ value borrowed here after move - | - = note: move occurs because `arc_v` has type `std::sync::Arc>`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/once-cant-call-twice-on-heap.nll.stderr b/src/test/ui/once-cant-call-twice-on-heap.nll.stderr new file mode 100644 index 0000000000000..ea53abc1b0f2d --- /dev/null +++ b/src/test/ui/once-cant-call-twice-on-heap.nll.stderr @@ -0,0 +1,15 @@ +error[E0382]: use of moved value: `blk` + --> $DIR/once-cant-call-twice-on-heap.rs:9:5 + | +LL | fn foo(blk: F) { + | - --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument +LL | blk(); + | --- value moved here +LL | blk(); //~ ERROR use of moved value + | ^^^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/ref-suggestion.nll.stderr b/src/test/ui/ref-suggestion.nll.stderr index 7c00461c900a2..bef8dcca921e6 100644 --- a/src/test/ui/ref-suggestion.nll.stderr +++ b/src/test/ui/ref-suggestion.nll.stderr @@ -1,22 +1,22 @@ error[E0382]: use of moved value: `x` --> $DIR/ref-suggestion.rs:4:5 | +LL | let x = vec![1]; + | - move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait LL | let y = x; | - value moved here LL | x; //~ ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x` --> $DIR/ref-suggestion.rs:8:5 | +LL | let x = vec![1]; + | - move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait LL | let mut y = x; | - value moved here LL | x; //~ ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x` --> $DIR/ref-suggestion.rs:16:5 diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr index 0b3f59fd7e452..5a730ad2be42c 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr @@ -1,12 +1,13 @@ error[E0382]: use of moved value: `a` --> $DIR/dbg-macro-move-semantics.rs:9:18 | +LL | let a = NoCopy(0); + | - move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait LL | let _ = dbg!(a); | ------- value moved here LL | let _ = dbg!(a); //~ ERROR use of moved value | ^ value used here after move | - = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr b/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr index 848c3d9bdb017..29d161fe150e7 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr +++ b/src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr @@ -13,12 +13,12 @@ LL | use_borrow(a); error[E0382]: use of moved value: `u` --> $DIR/union-borrow-move-parent-sibling.rs:22:13 | +LL | let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; + | - move occurs because `u` has type `U`, which does not implement the `Copy` trait LL | let a = u.x.0; | ----- value moved here LL | let b = u.y; //~ ERROR use of moved value: `u.y` | ^^^ value used here after move - | - = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0.0`) --> $DIR/union-borrow-move-parent-sibling.rs:28:13 @@ -35,12 +35,12 @@ LL | use_borrow(a); error[E0382]: use of moved value: `u` --> $DIR/union-borrow-move-parent-sibling.rs:35:13 | +LL | let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; + | - move occurs because `u` has type `U`, which does not implement the `Copy` trait LL | let a = (u.x.0).0; | --------- value moved here LL | let b = u.y; //~ ERROR use of moved value: `u.y` | ^^^ value used here after move - | - = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `*u.y`) --> $DIR/union-borrow-move-parent-sibling.rs:41:13 @@ -57,12 +57,12 @@ LL | use_borrow(a); error[E0382]: use of moved value: `u` --> $DIR/union-borrow-move-parent-sibling.rs:48:13 | +LL | let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; + | - move occurs because `u` has type `U`, which does not implement the `Copy` trait LL | let a = *u.y; | ---- value moved here LL | let b = u.x; //~ ERROR use of moved value: `u.x` | ^^^ value used here after move - | - = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait error: aborting due to 6 previous errors diff --git a/src/test/ui/unop-move-semantics.nll.stderr b/src/test/ui/unop-move-semantics.nll.stderr index 333a4734a4e5f..58953d55b1fba 100644 --- a/src/test/ui/unop-move-semantics.nll.stderr +++ b/src/test/ui/unop-move-semantics.nll.stderr @@ -1,13 +1,15 @@ error[E0382]: borrow of moved value: `x` --> $DIR/unop-move-semantics.rs:8:5 | +LL | fn move_then_borrow + Clone>(x: T) { + | - - move occurs because `x` has type `T`, which does not implement the `Copy` trait + | | + | consider adding a `Copy` constraint to this type argument LL | !x; | - value moved here LL | LL | x.clone(); //~ ERROR: use of moved value | ^ value borrowed here after move - | - = note: move occurs because `x` has type `T`, which does not implement the `Copy` trait error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/unop-move-semantics.rs:15:6 diff --git a/src/test/ui/unsized-locals/borrow-after-move.nll.stderr b/src/test/ui/unsized-locals/borrow-after-move.nll.stderr index 18cba2047356a..0e6a6f6369a15 100644 --- a/src/test/ui/unsized-locals/borrow-after-move.nll.stderr +++ b/src/test/ui/unsized-locals/borrow-after-move.nll.stderr @@ -12,13 +12,13 @@ LL | println!("{}", &x); error[E0382]: borrow of moved value: `y` --> $DIR/borrow-after-move.rs:22:24 | +LL | let y = *x; + | - move occurs because `y` has type `str`, which does not implement the `Copy` trait LL | drop_unsized(y); | - value moved here ... LL | println!("{}", &y); | ^^ value borrowed here after move - | - = note: move occurs because `y` has type `str`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/borrow-after-move.rs:30:24 @@ -34,13 +34,13 @@ LL | println!("{}", &x); error[E0382]: borrow of moved value: `y` --> $DIR/borrow-after-move.rs:32:24 | +LL | let y = *x; + | - move occurs because `y` has type `str`, which does not implement the `Copy` trait LL | y.foo(); | - value moved here ... LL | println!("{}", &y); | ^^ value borrowed here after move - | - = note: move occurs because `y` has type `str`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `x` --> $DIR/borrow-after-move.rs:39:24 diff --git a/src/test/ui/unsized-locals/double-move.nll.stderr b/src/test/ui/unsized-locals/double-move.nll.stderr index bbe6da70fb112..e40289af5ad3d 100644 --- a/src/test/ui/unsized-locals/double-move.nll.stderr +++ b/src/test/ui/unsized-locals/double-move.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `y` --> $DIR/double-move.rs:20:22 | +LL | let y = *x; + | - move occurs because `y` has type `str`, which does not implement the `Copy` trait LL | drop_unsized(y); | - value moved here LL | drop_unsized(y); //~ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `y` has type `str`, which does not implement the `Copy` trait error[E0382]: use of moved value: `x` --> $DIR/double-move.rs:26:22 @@ -21,22 +21,22 @@ LL | drop_unsized(x); //~ERROR use of moved value error[E0382]: use of moved value: `*x` --> $DIR/double-move.rs:32:18 | +LL | let x = "hello".to_owned().into_boxed_str(); + | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait LL | drop_unsized(x); | - value moved here LL | let _y = *x; //~ERROR use of moved value | ^^ value used here after move - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0382]: use of moved value: `y` --> $DIR/double-move.rs:39:9 | +LL | let y = *x; + | - move occurs because `y` has type `str`, which does not implement the `Copy` trait LL | y.foo(); | - value moved here LL | y.foo(); //~ERROR use of moved value | ^ value used here after move - | - = note: move occurs because `y` has type `str`, which does not implement the `Copy` trait error[E0382]: use of moved value: `*x` --> $DIR/double-move.rs:45:9 diff --git a/src/test/ui/use/use-after-move-based-on-type.nll.stderr b/src/test/ui/use/use-after-move-based-on-type.nll.stderr index 6f5b23b201333..8160ada9d62ea 100644 --- a/src/test/ui/use/use-after-move-based-on-type.nll.stderr +++ b/src/test/ui/use/use-after-move-based-on-type.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: borrow of moved value: `x` --> $DIR/use-after-move-based-on-type.rs:4:20 | +LL | let x = "Hello!".to_string(); + | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait LL | let _y = x; | - value moved here LL | println!("{}", x); //~ ERROR use of moved value | ^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/use/use-after-move-implicity-coerced-object.nll.stderr b/src/test/ui/use/use-after-move-implicity-coerced-object.nll.stderr index 308134774efb3..e16bca380679f 100644 --- a/src/test/ui/use/use-after-move-implicity-coerced-object.nll.stderr +++ b/src/test/ui/use/use-after-move-implicity-coerced-object.nll.stderr @@ -1,12 +1,13 @@ error[E0382]: borrow of moved value: `n` --> $DIR/use-after-move-implicity-coerced-object.rs:28:13 | +LL | let n: Box<_> = box Number { n: 42 }; + | - move occurs because `n` has type `std::boxed::Box`, which does not implement the `Copy` trait +LL | let mut l: Box<_> = box List { list: Vec::new() }; LL | l.push(n); | - value moved here LL | let x = n.to_string(); | ^ value borrowed here after move - | - = note: move occurs because `n` has type `std::boxed::Box`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/use/use-after-move-self-based-on-type.nll.stderr b/src/test/ui/use/use-after-move-self-based-on-type.nll.stderr index d7f7c3c30f6cd..4119741d805cd 100644 --- a/src/test/ui/use/use-after-move-self-based-on-type.nll.stderr +++ b/src/test/ui/use/use-after-move-self-based-on-type.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `self` --> $DIR/use-after-move-self-based-on-type.rs:12:16 | +LL | pub fn foo(self) -> isize { + | ---- move occurs because `self` has type `S`, which does not implement the `Copy` trait LL | self.bar(); | ---- value moved here LL | return self.x; //~ ERROR use of moved value: `self.x` | ^^^^^^ value used here after move - | - = note: move occurs because `self` has type `S`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/use/use-after-move-self.nll.stderr b/src/test/ui/use/use-after-move-self.nll.stderr index 3e11e94e993f5..e2ce3690cb904 100644 --- a/src/test/ui/use/use-after-move-self.nll.stderr +++ b/src/test/ui/use/use-after-move-self.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `self` --> $DIR/use-after-move-self.rs:10:16 | +LL | pub fn foo(self) -> isize { + | ---- move occurs because `self` has type `S`, which does not implement the `Copy` trait LL | self.bar(); | ---- value moved here LL | return *self.x; //~ ERROR use of moved value: `*self.x` | ^^^^^^^ value used here after move - | - = note: move occurs because `self` has type `S`, which does not implement the `Copy` trait error: aborting due to previous error diff --git a/src/test/ui/walk-struct-literal-with.nll.stderr b/src/test/ui/walk-struct-literal-with.nll.stderr index 22ad3b1e2f2e7..2263747607b9c 100644 --- a/src/test/ui/walk-struct-literal-with.nll.stderr +++ b/src/test/ui/walk-struct-literal-with.nll.stderr @@ -1,12 +1,12 @@ error[E0382]: borrow of moved value: `start` --> $DIR/walk-struct-literal-with.rs:16:20 | +LL | let start = Mine{test:"Foo".to_string(), other_val:0}; + | ----- move occurs because `start` has type `Mine`, which does not implement the `Copy` trait LL | let end = Mine{other_val:1, ..start.make_string_bar()}; | ----- value moved here LL | println!("{}", start.test); //~ ERROR use of moved value: `start.test` | ^^^^^^^^^^ value borrowed here after move - | - = note: move occurs because `start` has type `Mine`, which does not implement the `Copy` trait error: aborting due to previous error From a5d04ed8032867c4d67e0a36f3848994027e7d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 24 Jan 2019 22:25:13 +0100 Subject: [PATCH 0307/1064] submodules: update clippy from 280069dd to f1753522 Changes: ```` Rustup allow assertions_on_constants for collapsible_if and missing_test_files Improving comments. Added rustfix to the test. Improve span shortening. Added "make_return" and "blockify" convenience methods in Sugg and used them in "needless_bool". Fixed potential mistakes with nesting. Added tests. Fix automatic suggestion on `use_self`. run ./util/dev update_lints add assert(true/false, some message) tests change assert_checks to assertions_on_constants run ./util/dev update_lints Add unreachable!() as option Add assert(true) and assert(false) lints ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 280069ddc750d..f1753522d8f3b 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 280069ddc750d8a20d075c76322c45d5db4a48f8 +Subproject commit f1753522d8f3bb2d218266b4760f7a99f027f5ca From f97856350cb3d390b23f30b7804f3fc6126740ac Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 25 Jan 2019 00:07:08 +0100 Subject: [PATCH 0308/1064] Update minifier version --- Cargo.lock | 6 +++--- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/html/render.rs | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01216deabba31..e20289e458fda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1407,7 +1407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "minifier" -version = "0.0.26" +version = "0.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2853,7 +2853,7 @@ dependencies = [ name = "rustdoc" version = "0.0.0" dependencies = [ - "minifier 0.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "minifier 0.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3890,7 +3890,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum minifier 0.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f299df45afd73332044ea9f717c816a84fc90c8b631409abf339ba93642a7985" +"checksum minifier 0.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "3a2898502751dcc9d66b6fff57f3cf63cc91605e83e1a33515396f5027f8e4ca" "checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649" "checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" "checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 4b421881db48d..20d5e672a8368 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -9,6 +9,6 @@ path = "lib.rs" [dependencies] pulldown-cmark = { version = "0.1.2", default-features = false } -minifier = "0.0.26" +minifier = "0.0.28" tempfile = "3" parking_lot = "0.6.4" diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..0b2e27eccff1b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -939,7 +939,7 @@ themePicker.onblur = handleThemeButtonsBlur; if path.exists() { for line in BufReader::new(File::open(path)?).lines() { let line = line?; - if for_search_index && line.starts_with("var r_") { + if for_search_index && line.starts_with("var R") { variables.push(line.clone()); // We need to check if the crate name has been put into a variable as well. let tokens = js::simple_minify(&line).apply(js::clean_tokens); @@ -1299,8 +1299,9 @@ fn write_minify_replacer( }) .apply(|f| { // We add a backline after the newly created variables. - minifier::js::aggregate_strings_with_separation( + minifier::js::aggregate_strings_into_array_with_separation( f, + "R", Token::Char(ReservedChar::Backline), ) }) From 1c8c94af51e10e0593163d6a8ff41513271d7eab Mon Sep 17 00:00:00 2001 From: Johnathan Van Why Date: Thu, 24 Jan 2019 16:06:35 -0800 Subject: [PATCH 0309/1064] Instead of adding a paragraph mentioning std::mem::transmute and core::mem::transmute, create documentation pages for them. This renders them discoverable via search. I removed the mention of the exports in the transmute documentation, but can re-add it if desired. --- src/libcore/intrinsics.rs | 4 ---- src/libcore/mem.rs | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 74c0eae939cb4..db19baf7a2c64 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -729,10 +729,6 @@ extern "rust-intrinsic" { /// cause [undefined behavior][ub] with this function. `transmute` should be /// the absolute last resort. /// - /// `transmute` is re-exported by [core::mem](../mem/index.html) as - /// `core::mem::transmute`, which may be used without the `core_intrinsics` - /// feature flag. - /// /// The [nomicon](../../nomicon/transmutes.html) has additional /// documentation. /// diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 8fcbb73d9ce46..4a9e0bb54cc08 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -15,6 +15,7 @@ use ptr; use ops::{Deref, DerefMut}; #[stable(feature = "rust1", since = "1.0.0")] +#[doc(inline)] pub use intrinsics::transmute; /// Takes ownership and "forgets" about the value **without running its destructor**. From f532dfe9c3d26cbc93f0cda9e206bfadf1359511 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Mon, 7 Jan 2019 14:52:05 -0500 Subject: [PATCH 0310/1064] Update Cargo.lock to use the latest `compiler_builtins` --- Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01216deabba31..8872cb99ab4ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -425,7 +425,7 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", @@ -716,7 +716,7 @@ name = "dlmalloc" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -874,7 +874,7 @@ name = "fortanix-sgx-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -1654,7 +1654,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1664,7 +1664,7 @@ name = "panic_unwind" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", "unwind 0.0.0", @@ -1837,8 +1837,8 @@ version = "0.0.0" name = "profiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2362,7 +2362,7 @@ name = "rustc-demangle" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -2462,7 +2462,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2656,7 +2656,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2708,7 +2708,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2822,7 +2822,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3070,8 +3070,8 @@ version = "0.0.0" dependencies = [ "alloc 0.0.0", "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3600,7 +3600,7 @@ dependencies = [ name = "unwind" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3791,8 +3791,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bd14d75a16b6c836c62350e2e8c85495ed8e13df30a7298c574cb1ee4cdac7bc" -"checksum compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0d76d4322a40f6b0db7259d4f2c8a65ed8b0d84fce0bbc61b98cf47f8ec6eec3" +"checksum compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6711d51cb46744dd8305293cc3fbc392aaff7a8f5095a7c4fae1e5113ef07c96" +"checksum compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89747fe073b7838343bd2c2445e7a7c2e0d415598f8925f0fa9205b9cdfc48cb" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" From 49700a0a67e98eb91bad49113c6c863d43247518 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Mon, 7 Jan 2019 12:14:59 -0700 Subject: [PATCH 0311/1064] The file should be fully consistent now. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8872cb99ab4ff..d41fecc50b2c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,7 +136,7 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", From 4092538770c165324dda7500f4bae722a2345643 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Tue, 8 Jan 2019 12:31:50 +0530 Subject: [PATCH 0312/1064] fix lock after running build --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index d41fecc50b2c5..0b0ef912134b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3792,7 +3792,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" "checksum compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6711d51cb46744dd8305293cc3fbc392aaff7a8f5095a7c4fae1e5113ef07c96" -"checksum compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89747fe073b7838343bd2c2445e7a7c2e0d415598f8925f0fa9205b9cdfc48cb" +"checksum compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0d76d4322a40f6b0db7259d4f2c8a65ed8b0d84fce0bbc61b98cf47f8ec6eec3" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" From 14a38b30aff4e50d9cc9df1c55474288c7f11b10 Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Thu, 17 Jan 2019 15:52:48 +0530 Subject: [PATCH 0313/1064] lock after rebase --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b0ef912134b6..a237c5916a314 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,7 +103,7 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -136,7 +136,7 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1837,7 +1837,7 @@ version = "0.0.0" name = "profiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3070,7 +3070,7 @@ version = "0.0.0" dependencies = [ "alloc 0.0.0", "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", From af153cef0ce27e3b525c2c161afe469d2ffdbb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Fri, 25 Jan 2019 08:43:56 +0100 Subject: [PATCH 0314/1064] Fix wording in diagnostics page --- src/librustc_typeck/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index c0a8dd87ee2d5..1f260d317e4c6 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -763,7 +763,7 @@ function's return type and the value being returned. "##, E0070: r##" -The left-hand side of an assignment operator must be a place expression. An +The left-hand side of an assignment operator must be a place expression. A place expression represents a memory location and can be a variable (with optional namespacing), a dereference, an indexing expression or a field reference. From 506393eaaf912ece2d216de4b6e2fd7ca04a945d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 23 Jan 2019 16:21:33 +0100 Subject: [PATCH 0315/1064] Add a compile-fail test for `Drop` in constants in the presence of `Option`s --- src/test/ui/static/static-drop-scope.nll.stderr | 14 +++++++++++++- src/test/ui/static/static-drop-scope.rs | 8 ++++++++ src/test/ui/static/static-drop-scope.stderr | 14 +++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/test/ui/static/static-drop-scope.nll.stderr b/src/test/ui/static/static-drop-scope.nll.stderr index 3c01f694bff47..df6383b4fc222 100644 --- a/src/test/ui/static/static-drop-scope.nll.stderr +++ b/src/test/ui/static/static-drop-scope.nll.stderr @@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time LL | (x, ()).1 | ^^^^^^^ constant functions cannot evaluate destructors -error: aborting due to 8 previous errors +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/static-drop-scope.rs:31:34 + | +LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1; + | ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/static-drop-scope.rs:36:43 + | +LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1; + | ^^^^^^^^^^^ constants cannot evaluate destructors + +error: aborting due to 10 previous errors Some errors occurred: E0493, E0716. For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/static/static-drop-scope.rs b/src/test/ui/static/static-drop-scope.rs index a11a9f020e0dc..e5a9f2a405644 100644 --- a/src/test/ui/static/static-drop-scope.rs +++ b/src/test/ui/static/static-drop-scope.rs @@ -28,4 +28,12 @@ const fn const_drop2(x: T) { //~^ ERROR destructors cannot be evaluated at compile-time } +const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1; +//~^ ERROR destructors cannot be evaluated at compile-time + +const HELPER: Option = Some(WithDtor); + +const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1; +//~^ ERROR destructors cannot be evaluated at compile-time + fn main () {} diff --git a/src/test/ui/static/static-drop-scope.stderr b/src/test/ui/static/static-drop-scope.stderr index 89b31d95a2a4e..3e3032eb4fb60 100644 --- a/src/test/ui/static/static-drop-scope.stderr +++ b/src/test/ui/static/static-drop-scope.stderr @@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time LL | (x, ()).1 | ^^^^^^^ constant functions cannot evaluate destructors -error: aborting due to 8 previous errors +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/static-drop-scope.rs:31:34 + | +LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1; + | ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/static-drop-scope.rs:36:43 + | +LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1; + | ^^^^^^^^^^^ constants cannot evaluate destructors + +error: aborting due to 10 previous errors Some errors occurred: E0493, E0597. For more information about an error, try `rustc --explain E0493`. From 463e623ca967c2bd301cc0291fae219130b53daf Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 24 Jan 2019 23:24:58 +0100 Subject: [PATCH 0316/1064] Suggestion moving types before associated types. This commit extends existing suggestions to move lifetimes before types in generic arguments to also suggest moving types behind associated type bindings. --- src/libsyntax/parse/parser.rs | 67 ++++++++++++++----- src/test/ui/parser/issue-32214.stderr | 4 ++ src/test/ui/suggestions/suggest-move-types.rs | 42 ++++++++++++ .../ui/suggestions/suggest-move-types.stderr | 49 ++++++++++++++ 4 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-move-types.rs create mode 100644 src/test/ui/suggestions/suggest-move-types.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c7e33a1656428..232b8bb5966c7 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5530,22 +5530,31 @@ impl<'a> Parser<'a> { fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { let mut args = Vec::new(); let mut bindings = Vec::new(); + let mut seen_type = false; let mut seen_binding = false; + + let mut last_comma_span = None; let mut first_type_or_binding_span: Option = None; + let mut first_binding_span: Option = None; + let mut bad_lifetime_pos = vec![]; - let mut last_comma_span = None; - let mut suggestions = vec![]; + let mut bad_type_pos = vec![]; + + let mut lifetime_suggestions = vec![]; + let mut type_suggestions = vec![]; loop { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. args.push(GenericArg::Lifetime(self.expect_lifetime())); + if seen_type || seen_binding { let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); bad_lifetime_pos.push(self.prev_span); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - suggestions.push((remove_sp, String::new())); - suggestions.push(( + lifetime_suggestions.push((remove_sp, String::new())); + lifetime_suggestions.push(( first_type_or_binding_span.unwrap().shrink_to_lo(), format!("{}, ", snippet))); } @@ -5563,24 +5572,29 @@ impl<'a> Parser<'a> { ty, span, }); + seen_binding = true; if first_type_or_binding_span.is_none() { first_type_or_binding_span = Some(span); } + if first_binding_span.is_none() { + first_binding_span = Some(span); + } } else if self.check_type() { // Parse type argument. let ty_param = self.parse_ty()?; if seen_binding { - self.struct_span_err( - ty_param.span, - "type parameters must be declared prior to associated type bindings" - ) - .span_label( - ty_param.span, - "must be declared prior to associated type bindings", - ) - .emit(); + let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); + bad_type_pos.push(self.prev_span); + + if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { + type_suggestions.push((remove_sp, String::new())); + type_suggestions.push(( + first_binding_span.unwrap().shrink_to_lo(), + format!("{}, ", snippet))); + } } + if first_type_or_binding_span.is_none() { first_type_or_binding_span = Some(ty_param.span); } @@ -5596,6 +5610,7 @@ impl<'a> Parser<'a> { last_comma_span = Some(self.prev_span); } } + if !bad_lifetime_pos.is_empty() { let mut err = self.struct_span_err( bad_lifetime_pos.clone(), @@ -5604,18 +5619,40 @@ impl<'a> Parser<'a> { for sp in &bad_lifetime_pos { err.span_label(*sp, "must be declared prior to type parameters"); } - if !suggestions.is_empty() { + if !lifetime_suggestions.is_empty() { err.multipart_suggestion_with_applicability( &format!( "move the lifetime parameter{} prior to the first type parameter", if bad_lifetime_pos.len() > 1 { "s" } else { "" }, ), - suggestions, + lifetime_suggestions, Applicability::MachineApplicable, ); } err.emit(); } + + if !bad_type_pos.is_empty() { + let mut err = self.struct_span_err( + bad_type_pos.clone(), + "type parameters must be declared prior to associated type bindings" + ); + for sp in &bad_type_pos { + err.span_label(*sp, "must be declared prior to associated type bindings"); + } + if !type_suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + &format!( + "move the type parameter{} prior to the first associated type binding", + if bad_type_pos.len() > 1 { "s" } else { "" }, + ), + type_suggestions, + Applicability::MachineApplicable, + ); + } + err.emit(); + } + Ok((args, bindings)) } diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr index a889513eaee52..660e517c85a13 100644 --- a/src/test/ui/parser/issue-32214.stderr +++ b/src/test/ui/parser/issue-32214.stderr @@ -3,6 +3,10 @@ error: type parameters must be declared prior to associated type bindings | LL | pub fn test >() {} | ^ must be declared prior to associated type bindings +help: move the type parameter prior to the first associated type binding + | +LL | pub fn test >() {} + | ^^ -- error: aborting due to previous error diff --git a/src/test/ui/suggestions/suggest-move-types.rs b/src/test/ui/suggestions/suggest-move-types.rs new file mode 100644 index 0000000000000..8f35e4ecbcace --- /dev/null +++ b/src/test/ui/suggestions/suggest-move-types.rs @@ -0,0 +1,42 @@ +#![allow(warnings)] + +// This test verifies that the suggestion to move types before associated type bindings +// is correct. + +trait One { + type A; +} + +trait Three { + type A; + type B; + type C; +} + +struct A> { //~ ERROR type parameters must be declared + m: M, + t: T, +} + +struct B> { //~ ERROR type parameters must be declared + m: M, + t: T, + u: U, + v: V, +} + +struct C> { //~ ERROR type parameters must be declared + m: M, + t: T, + u: U, + v: V, +} + +struct D> { //~ ERROR type parameters must be declared + m: M, + t: T, + u: U, + v: V, +} + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr new file mode 100644 index 0000000000000..c74f79a00c78c --- /dev/null +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -0,0 +1,49 @@ +error: type parameters must be declared prior to associated type bindings + --> $DIR/suggest-move-types.rs:16:26 + | +LL | struct A> { //~ ERROR type parameters must be declared + | ^ must be declared prior to associated type bindings +help: move the type parameter prior to the first associated type binding + | +LL | struct A> { //~ ERROR type parameters must be declared + | ^^ -- + +error: type parameters must be declared prior to associated type bindings + --> $DIR/suggest-move-types.rs:21:46 + | +LL | struct B> { //~ ERROR type parameters must be declared + | ^ ^ ^ must be declared prior to associated type bindings + | | | + | | must be declared prior to associated type bindings + | must be declared prior to associated type bindings +help: move the type parameters prior to the first associated type binding + | +LL | struct B> { //~ ERROR type parameters must be declared + | ^^ ^^ ^^ -- + +error: type parameters must be declared prior to associated type bindings + --> $DIR/suggest-move-types.rs:28:49 + | +LL | struct C> { //~ ERROR type parameters must be declared + | ^ ^ must be declared prior to associated type bindings + | | + | must be declared prior to associated type bindings +help: move the type parameters prior to the first associated type binding + | +LL | struct C> { //~ ERROR type parameters must be declared + | ^^ ^^ -- + +error: type parameters must be declared prior to associated type bindings + --> $DIR/suggest-move-types.rs:35:43 + | +LL | struct D> { //~ ERROR type parameters must be declared + | ^ ^ must be declared prior to associated type bindings + | | + | must be declared prior to associated type bindings +help: move the type parameters prior to the first associated type binding + | +LL | struct D> { //~ ERROR type parameters must be declared + | ^^ ^^ -- -- + +error: aborting due to 4 previous errors + From f4fe8085f827d0d8be25713b72bea90b31db1894 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 25 Jan 2019 11:23:08 +0100 Subject: [PATCH 0317/1064] bootstrap: Don't rely on any default settings regarding incr. comp. in Cargo. --- src/bootstrap/builder.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c3dc9458839e4..a69ba207495ae 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -991,6 +991,9 @@ impl<'a> Builder<'a> { if self.config.incremental { cargo.env("CARGO_INCREMENTAL", "1"); + } else { + // Don't rely on any default setting for incr. comp. in Cargo + cargo.env("CARGO_INCREMENTAL", "0"); } if let Some(ref on_fail) = self.config.on_fail { From 7a0abbff8be746e46841ac7eef5a17364d6b8b51 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 25 Jan 2019 00:36:28 +0100 Subject: [PATCH 0318/1064] Combining move lifetime and type suggestions. This commit combines the move lifetime and move type suggestions so that when rustfix applies them they don't conflict with each other. --- src/libsyntax/parse/parser.rs | 103 +++++++++++++----- src/test/ui/suggestions/suggest-move-types.rs | 43 ++++++++ .../ui/suggestions/suggest-move-types.stderr | 68 +++++++++++- 3 files changed, 179 insertions(+), 35 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 232b8bb5966c7..955dce47721e2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5611,49 +5611,92 @@ impl<'a> Parser<'a> { } } - if !bad_lifetime_pos.is_empty() { - let mut err = self.struct_span_err( + self.maybe_report_incorrect_generic_argument_order( + bad_lifetime_pos, bad_type_pos, lifetime_suggestions, type_suggestions + ); + + Ok((args, bindings)) + } + + /// Maybe report an error about incorrect generic argument order - "lifetime parameters + /// must be declared before type parameters", "type parameters must be declared before + /// associated type bindings" or both. + fn maybe_report_incorrect_generic_argument_order( + &self, + bad_lifetime_pos: Vec, + bad_type_pos: Vec, + lifetime_suggestions: Vec<(Span, String)>, + type_suggestions: Vec<(Span, String)>, + ) { + let mut err = if !bad_lifetime_pos.is_empty() && !bad_type_pos.is_empty() { + let mut positions = bad_lifetime_pos.clone(); + positions.extend_from_slice(&bad_type_pos); + + self.struct_span_err( + positions, + "generic arguments must declare lifetimes, types and associated type bindings in \ + that order", + ) + } else if !bad_lifetime_pos.is_empty() { + self.struct_span_err( bad_lifetime_pos.clone(), "lifetime parameters must be declared prior to type parameters" - ); + ) + } else if !bad_type_pos.is_empty() { + self.struct_span_err( + bad_type_pos.clone(), + "type parameters must be declared prior to associated type bindings" + ) + } else { + return; + }; + + if !bad_lifetime_pos.is_empty() { for sp in &bad_lifetime_pos { err.span_label(*sp, "must be declared prior to type parameters"); } - if !lifetime_suggestions.is_empty() { - err.multipart_suggestion_with_applicability( - &format!( - "move the lifetime parameter{} prior to the first type parameter", - if bad_lifetime_pos.len() > 1 { "s" } else { "" }, - ), - lifetime_suggestions, - Applicability::MachineApplicable, - ); - } - err.emit(); } if !bad_type_pos.is_empty() { - let mut err = self.struct_span_err( - bad_type_pos.clone(), - "type parameters must be declared prior to associated type bindings" - ); for sp in &bad_type_pos { err.span_label(*sp, "must be declared prior to associated type bindings"); } - if !type_suggestions.is_empty() { - err.multipart_suggestion_with_applicability( - &format!( - "move the type parameter{} prior to the first associated type binding", - if bad_type_pos.len() > 1 { "s" } else { "" }, - ), - type_suggestions, - Applicability::MachineApplicable, - ); - } - err.emit(); } - Ok((args, bindings)) + if !lifetime_suggestions.is_empty() && !type_suggestions.is_empty() { + let mut suggestions = lifetime_suggestions; + suggestions.extend_from_slice(&type_suggestions); + + let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1; + err.multipart_suggestion_with_applicability( + &format!( + "move the parameter{}", + if plural { "s" } else { "" }, + ), + suggestions, + Applicability::MachineApplicable, + ); + } else if !lifetime_suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + &format!( + "move the lifetime parameter{} prior to the first type parameter", + if bad_lifetime_pos.len() > 1 { "s" } else { "" }, + ), + lifetime_suggestions, + Applicability::MachineApplicable, + ); + } else if !type_suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + &format!( + "move the type parameter{} prior to the first associated type binding", + if bad_type_pos.len() > 1 { "s" } else { "" }, + ), + type_suggestions, + Applicability::MachineApplicable, + ); + } + + err.emit(); } /// Parses an optional `where` clause and places it in `generics`. diff --git a/src/test/ui/suggestions/suggest-move-types.rs b/src/test/ui/suggestions/suggest-move-types.rs index 8f35e4ecbcace..fd10ba4350c4a 100644 --- a/src/test/ui/suggestions/suggest-move-types.rs +++ b/src/test/ui/suggestions/suggest-move-types.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + #![allow(warnings)] // This test verifies that the suggestion to move types before associated type bindings @@ -7,17 +9,34 @@ trait One { type A; } +trait OneWithLifetime<'a, T> { + type A; +} + trait Three { type A; type B; type C; } +trait ThreeWithLifetime<'a, 'b, 'c, T, U, V> { + type A; + type B; + type C; +} + struct A> { //~ ERROR type parameters must be declared m: M, t: T, } + +struct Al<'a, T, M: OneWithLifetime> { +//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order + m: M, + t: &'a T, +} + struct B> { //~ ERROR type parameters must be declared m: M, t: T, @@ -25,6 +44,14 @@ struct B> { //~ ERROR type paramete v: V, } +struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { +//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order + m: M, + t: &'a T, + u: &'b U, + v: &'c V, +} + struct C> { //~ ERROR type parameters must be declared m: M, t: T, @@ -32,6 +59,14 @@ struct C> { //~ ERROR type paramete v: V, } +struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { +//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order + m: M, + t: &'a T, + u: &'b U, + v: &'c V, +} + struct D> { //~ ERROR type parameters must be declared m: M, t: T, @@ -39,4 +74,12 @@ struct D> { //~ ERROR type paramete v: V, } +struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { +//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order + m: M, + t: &'a T, + u: &'b U, + v: &'c V, +} + fn main() {} diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr index c74f79a00c78c..3643d9a912455 100644 --- a/src/test/ui/suggestions/suggest-move-types.stderr +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -1,5 +1,5 @@ error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:16:26 + --> $DIR/suggest-move-types.rs:28:26 | LL | struct A> { //~ ERROR type parameters must be declared | ^ must be declared prior to associated type bindings @@ -8,8 +8,20 @@ help: move the type parameter prior to the first associated type binding LL | struct A> { //~ ERROR type parameters must be declared | ^^ -- +error: generic arguments must declare lifetimes, types and associated type bindings in that order + --> $DIR/suggest-move-types.rs:34:46 + | +LL | struct Al<'a, T, M: OneWithLifetime> { + | ^ ^^ must be declared prior to type parameters + | | + | must be declared prior to associated type bindings +help: move the parameters + | +LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A=()>> { + | ^^^ ^^ -- + error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:21:46 + --> $DIR/suggest-move-types.rs:40:46 | LL | struct B> { //~ ERROR type parameters must be declared | ^ ^ ^ must be declared prior to associated type bindings @@ -21,8 +33,24 @@ help: move the type parameters prior to the first associated type binding LL | struct B> { //~ ERROR type parameters must be declared | ^^ ^^ ^^ -- +error: generic arguments must declare lifetimes, types and associated type bindings in that order + --> $DIR/suggest-move-types.rs:47:80 + | +LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^ ^ ^ ^^ ^^ ^^ must be declared prior to type parameters + | | | | | | + | | | | | must be declared prior to type parameters + | | | | must be declared prior to type parameters + | | | must be declared prior to associated type bindings + | | must be declared prior to associated type bindings + | must be declared prior to associated type bindings +help: move the parameters + | +LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> { + | ^^^ ^^^ ^^^ ^^ ^^ ^^ -- + error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:28:49 + --> $DIR/suggest-move-types.rs:55:49 | LL | struct C> { //~ ERROR type parameters must be declared | ^ ^ must be declared prior to associated type bindings @@ -33,8 +61,23 @@ help: move the type parameters prior to the first associated type binding LL | struct C> { //~ ERROR type parameters must be declared | ^^ ^^ -- +error: generic arguments must declare lifetimes, types and associated type bindings in that order + --> $DIR/suggest-move-types.rs:62:56 + | +LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^^ ^ ^^ ^ ^^ must be declared prior to type parameters + | | | | | + | | | | must be declared prior to associated type bindings + | | | must be declared prior to type parameters + | | must be declared prior to associated type bindings + | must be declared prior to type parameters +help: move the parameters + | +LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> { + | ^^^ ^^^ ^^^ -- ^^ ^^ -- + error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:35:43 + --> $DIR/suggest-move-types.rs:70:43 | LL | struct D> { //~ ERROR type parameters must be declared | ^ ^ must be declared prior to associated type bindings @@ -45,5 +88,20 @@ help: move the type parameters prior to the first associated type binding LL | struct D> { //~ ERROR type parameters must be declared | ^^ ^^ -- -- -error: aborting due to 4 previous errors +error: generic arguments must declare lifetimes, types and associated type bindings in that order + --> $DIR/suggest-move-types.rs:77:56 + | +LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^^ ^ ^^ ^ ^^ must be declared prior to type parameters + | | | | | + | | | | must be declared prior to associated type bindings + | | | must be declared prior to type parameters + | | must be declared prior to associated type bindings + | must be declared prior to type parameters +help: move the parameters + | +LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> { + | ^^^ ^^^ ^^^ -- ^^ ^^ -- -- + +error: aborting due to 8 previous errors From 620a03f5aa7490cc904f868c91fbb303ec6a3274 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 25 Jan 2019 15:19:37 +0100 Subject: [PATCH 0319/1064] Unit test from #57866. --- src/test/ui/issues/issue-57866.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/ui/issues/issue-57866.rs diff --git a/src/test/ui/issues/issue-57866.rs b/src/test/ui/issues/issue-57866.rs new file mode 100644 index 0000000000000..77c50e53868e1 --- /dev/null +++ b/src/test/ui/issues/issue-57866.rs @@ -0,0 +1,26 @@ +// compile-pass + +#![feature(type_alias_enum_variants)] + +enum Outer { + A(T) +} + +enum Inner { + A(i32) +} + +type OuterAlias = Outer; + +fn ice(x: OuterAlias) { + // Fine + match x { + OuterAlias::A(Inner::A(_)) => (), + } + // Not fine + match x { + OuterAlias::A(Inner::A(y)) => (), + } +} + +fn main() {} From 8e4c57fca2f4bae61f7b567e7c72f96245f385bc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 9 Jan 2019 15:16:32 -0500 Subject: [PATCH 0320/1064] distinguish "no data" from "heterogeneous" for ABI purposes Also, add a testing infrastructure and tests that lets us dump layout. --- src/librustc_driver/driver.rs | 5 +- src/librustc_passes/layout_test.rs | 132 ++++++++++++++++++ src/librustc_passes/lib.rs | 1 + src/librustc_target/abi/call/aarch64.rs | 2 +- src/librustc_target/abi/call/arm.rs | 2 +- src/librustc_target/abi/call/asmjs.rs | 2 +- src/librustc_target/abi/call/mod.rs | 79 +++++++++-- src/librustc_target/abi/call/powerpc64.rs | 2 +- src/librustc_target/abi/call/sparc64.rs | 2 +- src/librustc_target/abi/call/x86.rs | 2 +- src/libsyntax/feature_gate.rs | 7 + .../homogeneous-aggr-zero-sized-c-struct.rs | 36 +++++ ...omogeneous-aggr-zero-sized-c-struct.stderr | 14 ++ .../homogeneous-aggr-zero-sized-repr-rust.rs | 73 ++++++++++ ...mogeneous-aggr-zero-sized-repr-rust.stderr | 32 +++++ src/test/ui/layout/zero-sized-array-union.rs | 95 +++++++++++++ .../ui/layout/zero-sized-array-union.stderr | 26 ++++ 17 files changed, 492 insertions(+), 20 deletions(-) create mode 100644 src/librustc_passes/layout_test.rs create mode 100644 src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs create mode 100644 src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr create mode 100644 src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs create mode 100644 src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr create mode 100644 src/test/ui/layout/zero-sized-array-union.rs create mode 100644 src/test/ui/layout/zero-sized-array-union.stderr diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 142d60c8d00b2..55f9d8a1109ce 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -22,7 +22,7 @@ use rustc_incremental; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; use rustc_mir as mir; -use rustc_passes::{self, ast_validation, hir_stats, loops, rvalue_promotion}; +use rustc_passes::{self, ast_validation, hir_stats, loops, rvalue_promotion, layout_test}; use rustc_plugin as plugin; use rustc_plugin::registry::Registry; use rustc_privacy; @@ -1287,6 +1287,9 @@ where mir::transform::check_unsafety::check_unsafety(tcx, def_id) } }); + + time(sess, "layout testing", || layout_test::test_layout(tcx)); + // Avoid overwhelming user with errors if type checking failed. // I'm not sure how helpful this is, to be honest, but it avoids // a diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs new file mode 100644 index 0000000000000..d21707c578b2a --- /dev/null +++ b/src/librustc_passes/layout_test.rs @@ -0,0 +1,132 @@ +use rustc::hir; +use rustc::hir::def_id::DefId; +use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::ItemKind; +use rustc::ty::layout::HasDataLayout; +use rustc::ty::layout::HasTyCtxt; +use rustc::ty::layout::LayoutOf; +use rustc::ty::layout::TargetDataLayout; +use rustc::ty::layout::TyLayout; +use rustc::ty::ParamEnv; +use rustc::ty::Ty; +use rustc::ty::TyCtxt; +use syntax::ast::Attribute; + +pub fn test_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + if tcx.features().rustc_attrs { + // if the `rustc_attrs` feature is not enabled, don't bother testing layout + tcx.hir() + .krate() + .visit_all_item_likes(&mut VarianceTest { tcx }); + } +} + +struct VarianceTest<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, +} + +impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> { + fn visit_item(&mut self, item: &'tcx hir::Item) { + let item_def_id = self.tcx.hir().local_def_id(item.id); + + if let ItemKind::Ty(..) = item.node { + for attr in self.tcx.get_attrs(item_def_id).iter() { + if attr.check_name("rustc_layout") { + self.dump_layout_of(item_def_id, item, attr); + } + } + } + } + + fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {} + fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {} +} + +impl<'a, 'tcx> VarianceTest<'a, 'tcx> { + fn dump_layout_of(&self, item_def_id: DefId, item: &hir::Item, attr: &Attribute) { + let tcx = self.tcx; + let param_env = self.tcx.param_env(item_def_id); + let ty = self.tcx.type_of(item_def_id); + match self.tcx.layout_of(param_env.and(ty)) { + Ok(ty_layout) => { + // Check out the `#[rustc_layout(..)]` attribute to tell what to dump. + // The `..` are the names of fields to dump. + let meta_items = attr.meta_item_list().unwrap_or_default(); + for meta_item in meta_items { + let name = meta_item.word().map(|mi| mi.name().as_str()); + let name = name.as_ref().map(|s| &s[..]).unwrap_or(""); + + match name { + "abi" => { + self.tcx + .sess + .span_err(item.span, &format!("abi: {:?}", ty_layout.abi)); + } + + "align" => { + self.tcx + .sess + .span_err(item.span, &format!("align: {:?}", ty_layout.align)); + } + + "size" => { + self.tcx + .sess + .span_err(item.span, &format!("size: {:?}", ty_layout.size)); + } + + "homogeneous_aggregate" => { + self.tcx.sess.span_err( + item.span, + &format!( + "homogeneous_aggregate: {:?}", + ty_layout + .homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env }), + ), + ); + } + + _ => { + self.tcx.sess.span_err( + meta_item.span, + &format!("unrecognized field name `{}`", name), + ); + } + } + } + } + + Err(layout_error) => { + self.tcx + .sess + .span_err(item.span, &format!("layout error: {:?}", layout_error)); + } + } + } +} + +struct UnwrapLayoutCx<'me, 'tcx> { + tcx: TyCtxt<'me, 'tcx, 'tcx>, + param_env: ParamEnv<'tcx>, +} + +impl<'me, 'tcx> LayoutOf for UnwrapLayoutCx<'me, 'tcx> { + type Ty = Ty<'tcx>; + type TyLayout = TyLayout<'tcx>; + + fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { + self.tcx.layout_of(self.param_env.and(ty)).unwrap() + } +} + +impl<'me, 'tcx> HasTyCtxt<'tcx> for UnwrapLayoutCx<'me, 'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } +} + +impl<'me, 'tcx> HasDataLayout for UnwrapLayoutCx<'me, 'tcx> { + fn data_layout(&self) -> &TargetDataLayout { + self.tcx.data_layout() + } +} diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 829d4b34cf779..a181bc7e9b480 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -32,6 +32,7 @@ mod diagnostics; pub mod ast_validation; pub mod rvalue_promotion; pub mod hir_stats; +pub mod layout_test; pub mod loops; __build_diagnostic_array! { librustc_passes, DIAGNOSTICS } diff --git a/src/librustc_target/abi/call/aarch64.rs b/src/librustc_target/abi/call/aarch64.rs index 121f80c75b9ac..9f9bba14b963e 100644 --- a/src/librustc_target/abi/call/aarch64.rs +++ b/src/librustc_target/abi/call/aarch64.rs @@ -6,7 +6,7 @@ fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout { - arg.layout.homogeneous_aggregate(cx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { let size = arg.layout.size; // Ensure we have at most four uniquely addressable members. diff --git a/src/librustc_target/abi/call/arm.rs b/src/librustc_target/abi/call/arm.rs index 2b3588d31bf1f..228dd36216158 100644 --- a/src/librustc_target/abi/call/arm.rs +++ b/src/librustc_target/abi/call/arm.rs @@ -7,7 +7,7 @@ fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout { - arg.layout.homogeneous_aggregate(cx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { let size = arg.layout.size; // Ensure we have at most four uniquely addressable members. diff --git a/src/librustc_target/abi/call/asmjs.rs b/src/librustc_target/abi/call/asmjs.rs index 32c6634b3d250..85444500c5e11 100644 --- a/src/librustc_target/abi/call/asmjs.rs +++ b/src/librustc_target/abi/call/asmjs.rs @@ -11,7 +11,7 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>) C: LayoutOf> + HasDataLayout { if ret.layout.is_aggregate() { - if let Some(unit) = ret.layout.homogeneous_aggregate(cx) { + if let Some(unit) = ret.layout.homogeneous_aggregate(cx).unit() { let size = ret.layout.size; if unit.size == size { ret.cast_to(Uniform { diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 37bf6e68247d2..0d50439c67ec0 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -228,6 +228,33 @@ impl CastTarget { } } +/// Return value from the `homogeneous_aggregate` test function. +#[derive(Copy, Clone, Debug)] +pub enum HomogeneousAggregate { + /// Yes, all the "leaf fields" of this struct are passed in the + /// same way (specified in the `Reg` value). + Homogeneous(Reg), + + /// There are distinct leaf fields passed in different ways, + /// or this is uninhabited. + Heterogeneous, + + /// There are no leaf fields at all. + NoData, +} + +impl HomogeneousAggregate { + /// If this is a homogeneous aggregate, returns the homogeneous + /// unit, else `None`. + pub fn unit(self) -> Option { + if let HomogeneousAggregate::Homogeneous(r) = self { + Some(r) + } else { + None + } + } +} + impl<'a, Ty> TyLayout<'a, Ty> { fn is_aggregate(&self) -> bool { match self.abi { @@ -239,11 +266,21 @@ impl<'a, Ty> TyLayout<'a, Ty> { } } - fn homogeneous_aggregate(&self, cx: &C) -> Option + /// True if this layout is an aggregate containing fields of only + /// a single type (e.g., `(u32, u32)`). Such aggregates are often + /// special-cased in ABIs. + /// + /// Note: We generally ignore fields of zero-sized type when computing + /// this value (cc #56877). + /// + /// This is public so that it can be used in unit tests, but + /// should generally only be relevant to the ABI details of + /// specific targets. + pub fn homogeneous_aggregate(&self, cx: &C) -> HomogeneousAggregate where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf { match self.abi { - Abi::Uninhabited => None, + Abi::Uninhabited => HomogeneousAggregate::Heterogeneous, // The primitive for this algorithm. Abi::Scalar(ref scalar) => { @@ -252,14 +289,15 @@ impl<'a, Ty> TyLayout<'a, Ty> { abi::Pointer => RegKind::Integer, abi::Float(_) => RegKind::Float, }; - Some(Reg { + HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }) } Abi::Vector { .. } => { - Some(Reg { + assert!(!self.is_zst()); + HomogeneousAggregate::Homogeneous(Reg { kind: RegKind::Vector, size: self.size }) @@ -275,7 +313,7 @@ impl<'a, Ty> TyLayout<'a, Ty> { if count > 0 { return self.field(cx, 0).homogeneous_aggregate(cx); } else { - return None; + return HomogeneousAggregate::NoData; } } FieldPlacement::Union(_) => true, @@ -284,21 +322,27 @@ impl<'a, Ty> TyLayout<'a, Ty> { for i in 0..self.fields.count() { if !is_union && total != self.fields.offset(i) { - return None; + return HomogeneousAggregate::Heterogeneous; } let field = self.field(cx, i); + match (result, field.homogeneous_aggregate(cx)) { - // The field itself must be a homogeneous aggregate. - (_, None) => return None, + (_, HomogeneousAggregate::NoData) => { + // Ignore fields that have no data + } + (_, HomogeneousAggregate::Heterogeneous) => { + // The field itself must be a homogeneous aggregate. + return HomogeneousAggregate::Heterogeneous; + } // If this is the first field, record the unit. - (None, Some(unit)) => { + (None, HomogeneousAggregate::Homogeneous(unit)) => { result = Some(unit); } // For all following fields, the unit must be the same. - (Some(prev_unit), Some(unit)) => { + (Some(prev_unit), HomogeneousAggregate::Homogeneous(unit)) => { if prev_unit != unit { - return None; + return HomogeneousAggregate::Heterogeneous; } } } @@ -314,9 +358,18 @@ impl<'a, Ty> TyLayout<'a, Ty> { // There needs to be no padding. if total != self.size { - None + HomogeneousAggregate::Heterogeneous } else { - result + match result { + Some(reg) => { + assert_ne!(total, Size::ZERO); + HomogeneousAggregate::Homogeneous(reg) + } + None => { + assert_eq!(total, Size::ZERO); + HomogeneousAggregate::NoData + } + } } } } diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 3ae9ab9ac5ec9..305a2d4225056 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -18,7 +18,7 @@ fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: A where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout { - arg.layout.homogeneous_aggregate(cx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { // ELFv1 only passes one-member aggregates transparently. // ELFv2 passes up to eight uniquely addressable members. if (abi == ELFv1 && arg.layout.size > unit.size) diff --git a/src/librustc_target/abi/call/sparc64.rs b/src/librustc_target/abi/call/sparc64.rs index bb0c9b7967afc..150b48a8d0255 100644 --- a/src/librustc_target/abi/call/sparc64.rs +++ b/src/librustc_target/abi/call/sparc64.rs @@ -8,7 +8,7 @@ fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout { - arg.layout.homogeneous_aggregate(cx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).unit().and_then(|unit| { // Ensure we have at most eight uniquely addressable members. if arg.layout.size > unit.size.checked_mul(8, cx).unwrap() { return None; diff --git a/src/librustc_target/abi/call/x86.rs b/src/librustc_target/abi/call/x86.rs index 748bef4de66b3..648a4b5bb9d79 100644 --- a/src/librustc_target/abi/call/x86.rs +++ b/src/librustc_target/abi/call/x86.rs @@ -99,7 +99,7 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>, flavor: Fla }; // At this point we know this must be a primitive of sorts. - let unit = arg.layout.homogeneous_aggregate(cx).unwrap(); + let unit = arg.layout.homogeneous_aggregate(cx).unit().unwrap(); assert_eq!(unit.size, arg.layout.size); if unit.kind == RegKind::Float { continue; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9e107fee5bad3..85e80f7bdaf19 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -938,6 +938,13 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), + ("rustc_layout", Normal, template!(List: "field1, field2, ..."), + Gated(Stability::Unstable, + "rustc_attrs", + "the `#[rustc_layout]` attribute \ + is just used for rustc unit tests \ + and will never be stable", + cfg_fn!(rustc_attrs))), ("rustc_regions", Normal, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_regions]` attribute \ diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs new file mode 100644 index 0000000000000..622709e7de584 --- /dev/null +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs @@ -0,0 +1,36 @@ +#![feature(rustc_attrs)] + +// Show that `homogeneous_aggregate` code ignores zero-length C +// arrays. This matches the recent C standard, though not the +// behavior of all older compilers, which somtimes consider `T[0]` to +// be a "flexible array member" (see discussion on #56877 for +// details). + +#[repr(C)] +pub struct Foo { + x: u32 +} + +#[repr(C)] +pub struct Middle { + pub a: f32, + pub foo: [Foo; 0], + pub b: f32, +} + +#[rustc_layout(homogeneous_aggregate)] +pub type TestMiddle = Middle; +//~^ ERROR homogeneous_aggregate: Homogeneous + +#[repr(C)] +pub struct Final { + pub a: f32, + pub b: f32, + pub foo: [Foo; 0], +} + +#[rustc_layout(homogeneous_aggregate)] +pub type TestFinal = Final; +//~^ ERROR homogeneous_aggregate: Homogeneous + +fn main() { } diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr new file mode 100644 index 0000000000000..0d44260635187 --- /dev/null +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr @@ -0,0 +1,14 @@ +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:22:1 + | +LL | pub type TestMiddle = Middle; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:33:1 + | +LL | pub type TestFinal = Final; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs new file mode 100644 index 0000000000000..4b429412aebfc --- /dev/null +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs @@ -0,0 +1,73 @@ +#![feature(rustc_attrs)] + +// Regression test for #56877. We want to ensure that the presence of +// `PhantomData` does not prevent `Bar` from being considered a +// homogeneous aggregate. + +#[repr(C)] +pub struct BaseCase { + pub a: f32, + pub b: f32, +} + +#[repr(C)] +pub struct WithPhantomData { + pub a: f32, + pub b: f32, + pub _unit: std::marker::PhantomData<()>, +} + +pub struct EmptyRustStruct { +} + +#[repr(C)] +pub struct WithEmptyRustStruct { + pub a: f32, + pub b: f32, + pub _unit: EmptyRustStruct, +} + +pub struct TransitivelyEmptyRustStruct { + field: EmptyRustStruct, + array: [u32; 0], +} + +#[repr(C)] +pub struct WithTransitivelyEmptyRustStruct { + pub a: f32, + pub b: f32, + pub _unit: TransitivelyEmptyRustStruct, +} + +pub enum EmptyRustEnum { + Dummy, +} + +#[repr(C)] +pub struct WithEmptyRustEnum { + pub a: f32, + pub b: f32, + pub _unit: EmptyRustEnum, +} + +#[rustc_layout(homogeneous_aggregate)] +pub type Test1 = BaseCase; +//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test2 = WithPhantomData; +//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test3 = WithEmptyRustStruct; +//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test4 = WithTransitivelyEmptyRustStruct; +//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test5 = WithEmptyRustEnum; +//~^ ERROR homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + +fn main() { } diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr new file mode 100644 index 0000000000000..be04ba3e7f6cb --- /dev/null +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr @@ -0,0 +1,32 @@ +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:54:1 + | +LL | pub type Test1 = BaseCase; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:58:1 + | +LL | pub type Test2 = WithPhantomData; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:62:1 + | +LL | pub type Test3 = WithEmptyRustStruct; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:66:1 + | +LL | pub type Test4 = WithTransitivelyEmptyRustStruct; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:70:1 + | +LL | pub type Test5 = WithEmptyRustEnum; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/layout/zero-sized-array-union.rs b/src/test/ui/layout/zero-sized-array-union.rs new file mode 100644 index 0000000000000..68b218249eb9a --- /dev/null +++ b/src/test/ui/layout/zero-sized-array-union.rs @@ -0,0 +1,95 @@ +#![feature(rustc_attrs)] + +// Various tests around the behavior of zero-sized arrays and +// unions. This matches the behavior of modern C compilers, though +// older compilers (and sometimes clang) treat `T[0]` as a "flexible +// array member". See more +// details in #56877. + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty { } + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty2 { + e: Empty +} + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty3 { + z: [f32; 0], +} + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty4 { + e: Empty3 +} + +#[repr(C)] +union U1 { + s: Empty +} + +#[repr(C)] +union U2 { + s: Empty2 +} + +#[repr(C)] +union U3 { + s: Empty3 +} + +#[repr(C)] +union U4 { + s: Empty4 +} + +#[repr(C)] +struct Baz1 { + x: f32, + y: f32, + u: U1, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz1 = Baz1; +//~^ ERROR homogeneous_aggregate: Homogeneous + +#[repr(C)] +struct Baz2 { + x: f32, + y: f32, + u: U2, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz2 = Baz2; +//~^ ERROR homogeneous_aggregate: Homogeneous + +#[repr(C)] +struct Baz3 { + x: f32, + y: f32, + u: U3, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz3 = Baz3; +//~^ ERROR homogeneous_aggregate: Homogeneous + +#[repr(C)] +struct Baz4 { + x: f32, + y: f32, + u: U4, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz4 = Baz4; +//~^ ERROR homogeneous_aggregate: Homogeneous + +fn main() { } diff --git a/src/test/ui/layout/zero-sized-array-union.stderr b/src/test/ui/layout/zero-sized-array-union.stderr new file mode 100644 index 0000000000000..1bb31aaf7b7b9 --- /dev/null +++ b/src/test/ui/layout/zero-sized-array-union.stderr @@ -0,0 +1,26 @@ +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/zero-sized-array-union.rs:59:1 + | +LL | type TestBaz1 = Baz1; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/zero-sized-array-union.rs:70:1 + | +LL | type TestBaz2 = Baz2; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/zero-sized-array-union.rs:81:1 + | +LL | type TestBaz3 = Baz3; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Homogeneous(Reg { kind: Float, size: Size { raw: 4 } }) + --> $DIR/zero-sized-array-union.rs:92:1 + | +LL | type TestBaz4 = Baz4; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + From ce289c6c9911c7ea55b7f30b125d3c38ed359da4 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 19 Jan 2019 00:37:52 +0200 Subject: [PATCH 0321/1064] Resolve breakage --- src/librustc_codegen_llvm/attributes.rs | 41 +++++++++++-------- src/librustc_codegen_llvm/declare.rs | 24 +---------- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/diagnostics.rs | 2 +- src/libsyntax/feature_gate.rs | 2 +- .../ui/feature-gate-optimize_attribute.rs | 13 ++---- .../ui/feature-gate-optimize_attribute.stderr | 23 +++++++---- 7 files changed, 46 insertions(+), 61 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index a7d4f910f7a2d..e6bc7bca46bc9 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -144,6 +144,28 @@ pub fn non_lazy_bind(sess: &Session, llfn: &'ll Value) { } } +pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) { + match sess.opts.optimize { + OptLevel::Size => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + }, + OptLevel::SizeMin => { + llvm::Attribute::MinSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + } + OptLevel::No => { + llvm::Attribute::MinSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); + llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); + } + _ => {} + } +} + + /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. pub fn from_fn_attrs( @@ -157,24 +179,7 @@ pub fn from_fn_attrs( match codegen_fn_attrs.optimize { OptimizeAttr::None => { - match cx.tcx.sess.opts.optimize { - OptLevel::Size => { - llvm::Attribute::MinSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - }, - OptLevel::SizeMin => { - llvm::Attribute::MinSize.apply_llfn(Function, llfn); - llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - } - OptLevel::No => { - llvm::Attribute::MinSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - } - _ => {} - } + default_optimisation_attrs(cx.tcx.sess, llfn); } OptimizeAttr::Speed => { llvm::Attribute::MinSize.unapply_llfn(Function, llfn); diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index da45e0200d85f..6b7ee16cb71b4 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -15,7 +15,7 @@ use llvm; use llvm::AttributePlace::Function; use rustc::ty::{self, PolyFnSig}; use rustc::ty::layout::LayoutOf; -use rustc::session::config::{Sanitizer, OptLevel}; +use rustc::session::config::Sanitizer; use rustc_data_structures::small_c_str::SmallCStr; use abi::{FnType, FnTypeExt}; use attributes; @@ -65,28 +65,8 @@ fn declare_raw_fn( } } - // FIXME(opt): this is kinda duplicated with similar code in attributes::from_fn_attrs… - match cx.tcx.sess.opts.optimize { - OptLevel::Size => { - llvm::Attribute::MinSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - }, - OptLevel::SizeMin => { - llvm::Attribute::MinSize.apply_llfn(Function, llfn); - llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - } - OptLevel::No => { - llvm::Attribute::MinSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn); - llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - } - _ => {} - } - + attributes::default_optimisation_attrs(cx.tcx.sess, llfn); attributes::non_lazy_bind(cx.sess(), llfn); - llfn } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 2256dbcec002b..ade84faae8dbd 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2379,7 +2379,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen if attr.path != "optimize" { return ia; } - let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0720, "{}", s); + let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s); match attr.meta().map(|i| i.node) { Some(MetaItemKind::Word) => { err(attr.span, "expected one argument"); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 21dcdaf4fa0e7..e02111bf2bf3b 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4719,5 +4719,5 @@ register_diagnostics! { E0645, // trait aliases not finished E0698, // type inside generator must be known in this context E0719, // duplicate values for associated type binding - E0720, // Malformed #[optimize] attribute + E0722, // Malformed #[optimize] attribute } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index abbcf24fca50f..adc5affedc8c3 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1219,7 +1219,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu cfg_fn!(alloc_error_handler))), // RFC 2412 - ("optimize", Whitelisted, Gated(Stability::Unstable, + ("optimize", Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable, "optimize_attribute", "#[optimize] attribute is an unstable feature", cfg_fn!(optimize_attribute))), diff --git a/src/test/ui/feature-gate-optimize_attribute.rs b/src/test/ui/feature-gate-optimize_attribute.rs index 4c3126f534e4f..c1f7510014187 100644 --- a/src/test/ui/feature-gate-optimize_attribute.rs +++ b/src/test/ui/feature-gate-optimize_attribute.rs @@ -1,12 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. #![crate_type="rlib"] #![optimize(speed)] //~ ERROR #54882 @@ -19,7 +10,9 @@ fn size() {} #[optimize(speed)] //~ ERROR #54882 fn speed() {} -#[optimize(banana)] //~ ERROR #54882 +#[optimize(banana)] +//~^ ERROR #54882 +//~| ERROR E0722 fn not_known() {} } diff --git a/src/test/ui/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gate-optimize_attribute.stderr index cd790a0bb6a06..ddd4c457d731b 100644 --- a/src/test/ui/feature-gate-optimize_attribute.stderr +++ b/src/test/ui/feature-gate-optimize_attribute.stderr @@ -1,5 +1,5 @@ error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) - --> $DIR/feature-gate-optimize_attribute.rs:16:1 + --> $DIR/feature-gate-optimize_attribute.rs:7:1 | LL | #[optimize(size)] //~ ERROR #54882 | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[optimize(size)] //~ ERROR #54882 = help: add #![feature(optimize_attribute)] to the crate attributes to enable error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) - --> $DIR/feature-gate-optimize_attribute.rs:19:1 + --> $DIR/feature-gate-optimize_attribute.rs:10:1 | LL | #[optimize(speed)] //~ ERROR #54882 | ^^^^^^^^^^^^^^^^^^ @@ -15,15 +15,15 @@ LL | #[optimize(speed)] //~ ERROR #54882 = help: add #![feature(optimize_attribute)] to the crate attributes to enable error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) - --> $DIR/feature-gate-optimize_attribute.rs:22:1 + --> $DIR/feature-gate-optimize_attribute.rs:13:1 | -LL | #[optimize(banana)] //~ ERROR #54882 +LL | #[optimize(banana)] | ^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(optimize_attribute)] to the crate attributes to enable error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) - --> $DIR/feature-gate-optimize_attribute.rs:13:1 + --> $DIR/feature-gate-optimize_attribute.rs:4:1 | LL | #[optimize(size)] //~ ERROR #54882 | ^^^^^^^^^^^^^^^^^ @@ -31,13 +31,20 @@ LL | #[optimize(size)] //~ ERROR #54882 = help: add #![feature(optimize_attribute)] to the crate attributes to enable error[E0658]: #[optimize] attribute is an unstable feature (see issue #54882) - --> $DIR/feature-gate-optimize_attribute.rs:11:1 + --> $DIR/feature-gate-optimize_attribute.rs:2:1 | LL | #![optimize(speed)] //~ ERROR #54882 | ^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(optimize_attribute)] to the crate attributes to enable -error: aborting due to 5 previous errors +error[E0722]: invalid argument + --> $DIR/feature-gate-optimize_attribute.rs:13:12 + | +LL | #[optimize(banana)] + | ^^^^^^ + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors occurred: E0658, E0722. +For more information about an error, try `rustc --explain E0658`. From ac4b685650d1ba0a38806ce8f7cbf12e7a00f573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Mockers?= Date: Tue, 18 Dec 2018 02:22:08 +0100 Subject: [PATCH 0322/1064] #56411 do not suggest a fix for a import conflict in a macro --- src/librustc_resolve/lib.rs | 4 +++- src/test/ui/issues/issue-56411.rs | 17 +++++++++++++++ src/test/ui/issues/issue-56411.stderr | 31 +++++++++++++++++++++++++++ src/test/ui/issues/issue_56411.rs | 5 +++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-56411.rs create mode 100644 src/test/ui/issues/issue-56411.stderr create mode 100644 src/test/ui/issues/issue_56411.rs diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 4c9347afa611d..8dd09076a00ac 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -5147,11 +5147,13 @@ impl<'a> Resolver<'a> { if let ( Ok(snippet), NameBindingKind::Import { directive, ..}, - _dummy @ false, + false, + false, ) = ( cm.span_to_snippet(binding.span), binding.kind.clone(), binding.span.is_dummy(), + binding.span.ctxt().outer().expn_info().is_some(), ) { let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { format!("Other{}", name) diff --git a/src/test/ui/issues/issue-56411.rs b/src/test/ui/issues/issue-56411.rs new file mode 100644 index 0000000000000..599f277123cc8 --- /dev/null +++ b/src/test/ui/issues/issue-56411.rs @@ -0,0 +1,17 @@ +macro_rules! import { + ( $($name:ident),* ) => { + $( + mod $name; + pub use self::$name; + //~^ ERROR the name `issue_56411` is defined multiple times + //~| ERROR `issue_56411` is private, and cannot be re-exported + + )* + } +} + +import!(issue_56411); + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/issues/issue-56411.stderr b/src/test/ui/issues/issue-56411.stderr new file mode 100644 index 0000000000000..842d86f4a3a9c --- /dev/null +++ b/src/test/ui/issues/issue-56411.stderr @@ -0,0 +1,31 @@ +error[E0255]: the name `issue_56411` is defined multiple times + --> $DIR/issue-56411.rs:5:21 + | +LL | mod $name; + | ---------- previous definition of the module `issue_56411` here +LL | pub use self::$name; + | ^^^^^^^^^^^ + | | + | `issue_56411` reimported here + | you can use `as` to change the binding name of the import +... +LL | import!(issue_56411); + | --------------------- in this macro invocation + | + = note: `issue_56411` must be defined only once in the type namespace of this module + +error[E0365]: `issue_56411` is private, and cannot be re-exported + --> $DIR/issue-56411.rs:5:21 + | +LL | pub use self::$name; + | ^^^^^^^^^^^ re-export of private `issue_56411` +... +LL | import!(issue_56411); + | --------------------- in this macro invocation + | + = note: consider declaring type or module `issue_56411` with `pub` + +error: aborting due to 2 previous errors + +Some errors occurred: E0255, E0365. +For more information about an error, try `rustc --explain E0255`. diff --git a/src/test/ui/issues/issue_56411.rs b/src/test/ui/issues/issue_56411.rs new file mode 100644 index 0000000000000..bd689e913aba6 --- /dev/null +++ b/src/test/ui/issues/issue_56411.rs @@ -0,0 +1,5 @@ +// compile-pass + +struct T {} + +fn main() {} From 14b36fb15a49bc2d38964ec5bd93ca26adda0486 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Jan 2019 12:41:55 -0800 Subject: [PATCH 0323/1064] std: Stabilize fixed-width integer atomics This commit stabilizes the `Atomic{I,U}{8,16,32,64}` APIs in the `std::sync::atomic` and `core::sync::atomic` modules. Proposed in #56753 and tracked in #32976 this feature has been unstable for quite some time and is hopefully ready to go over the finish line now! The API is being stabilized as-is. The API of `AtomicU8` and friends mirrors that of `AtomicUsize`. A list of changes made here are: * A portability documentation section has been added to describe the current state of affairs. * Emulation of smaller-size atomics with larger-size atomics has been documented. * As an added bonus, `ATOMIC_*_INIT` is now scheduled for deprecation across the board in 1.34.0 now that `const` functions can be invoked in statics. Note that the 128-bit atomic types are omitted from this stabilization explicitly. They have far less platform support than the other atomic types, and will likely require further discussion about their best location. Closes #32976 Closes #56753 --- src/libcore/sync/atomic.rs | 151 +++++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 55 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 8992e513e83a4..b9ebf19b23cab 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -5,13 +5,16 @@ //! types. //! //! This module defines atomic versions of a select number of primitive -//! types, including [`AtomicBool`], [`AtomicIsize`], and [`AtomicUsize`]. +//! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`], +//! [`AtomicI8`], [`AtomicU16`], etc. //! Atomic types present operations that, when used correctly, synchronize //! updates between threads. //! //! [`AtomicBool`]: struct.AtomicBool.html //! [`AtomicIsize`]: struct.AtomicIsize.html //! [`AtomicUsize`]: struct.AtomicUsize.html +//! [`AtomicI8`]: struct.AtomicI8.html +//! [`AtomicU16`]: struct.AtomicU16.html //! //! Each method takes an [`Ordering`] which represents the strength of //! the memory barrier for that operation. These orderings are the @@ -31,11 +34,46 @@ //! [`Sync`]: ../../marker/trait.Sync.html //! [arc]: ../../../std/sync/struct.Arc.html //! -//! Most atomic types may be stored in static variables, initialized using -//! the provided static initializers like [`ATOMIC_BOOL_INIT`]. Atomic statics +//! Atomic types may be stored in static variables, initialized using +//! the constant initializers like [`AtomicBool::new`]. Atomic statics //! are often used for lazy global initialization. //! -//! [`ATOMIC_BOOL_INIT`]: constant.ATOMIC_BOOL_INIT.html +//! [`AtomicBool::new`]: struct.AtomicBool.html#method.new +//! +//! # Portability +//! +//! All atomic types in this module are guaranteed to be [lock-free] if they're +//! available. This means they don't internally acquire a global mutex. Atomic +//! types and operations are not guaranteed to be wait-free. This means that +//! operations like `fetch_or` may be implemented with a compare-and-swap loop. +//! +//! Atomic operations may be implemented at the instruction layer with +//! larger-size atomics. For example some platforms use 4-byte atomic +//! instructions to implement `AtomicI8`. Note that this emulation should not +//! have an impact on correctness of code, it's just something to be aware of. +//! +//! The atomic types in this module may not be available on all platforms. The +//! atomic types here are all widely available, however, and can generally be +//! relied upon existing. Some notable exceptions are: +//! +//! * PowerPC and MIPS platforms with 32-bit pointers do not have `AtomicU64` or +//! `AtomicI64` types. +//! * ARM platforms like `armv5te` that aren't for Linux do not have any atomics +//! at all. +//! * ARM targets with `thumbv6m` do not have atomic operations at all. +//! +//! Note that future platforms may be added that also do not have support for +//! some atomic operations. Maximally portable code will want to be careful +//! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are +//! generally the most portable, but even then they're not available everywhere. +//! For reference, the `std` library requires pointer-sized atomics, although +//! `core` does not. +//! +//! Currently you'll need to use `#[cfg(target_arch)]` primarily to +//! conditionally compile in code with atomics. There is an unstable +//! `#[cfg(target_has_atomic)]` as well which may be stabilized in the future. +//! +//! [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm //! //! # Examples //! @@ -66,9 +104,9 @@ //! Keep a global count of live threads: //! //! ``` -//! use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; +//! use std::sync::atomic::{AtomicUsize, Ordering}; //! -//! static GLOBAL_THREAD_COUNT: AtomicUsize = ATOMIC_USIZE_INIT; +//! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0); //! //! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::SeqCst); //! println!("live threads: {}", old_thread_count + 1); @@ -252,6 +290,7 @@ pub enum Ordering { /// [`AtomicBool`]: struct.AtomicBool.html #[cfg(target_has_atomic = "8")] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(since = "1.34.0", reason = "the `new` function is now preferred")] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); #[cfg(target_has_atomic = "8")] @@ -1097,7 +1136,8 @@ macro_rules! atomic_int { /// `]( #[doc = $int_ref] /// ). For more about the differences between atomic types and - /// non-atomic types, please see the [module-level documentation]. + /// non-atomic types as well as information about the portability of + /// this type, please see the [module-level documentation]. /// /// [module-level documentation]: index.html #[$stable] @@ -1108,6 +1148,7 @@ macro_rules! atomic_int { /// An atomic integer initialized to `0`. #[$stable] + #[rustc_deprecated(since = "1.34.0", reason = "the `new` function is now preferred")] pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] @@ -1827,12 +1868,12 @@ assert_eq!(min_foo, 12); #[cfg(target_has_atomic = "8")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "i8", "../../../std/primitive.i8.html", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -1841,12 +1882,12 @@ atomic_int! { } #[cfg(target_has_atomic = "8")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "u8", "../../../std/primitive.u8.html", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -1855,12 +1896,12 @@ atomic_int! { } #[cfg(target_has_atomic = "16")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "i16", "../../../std/primitive.i16.html", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -1869,12 +1910,12 @@ atomic_int! { } #[cfg(target_has_atomic = "16")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "u16", "../../../std/primitive.u16.html", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -1883,12 +1924,12 @@ atomic_int! { } #[cfg(target_has_atomic = "32")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "i32", "../../../std/primitive.i32.html", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -1897,12 +1938,12 @@ atomic_int! { } #[cfg(target_has_atomic = "32")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "u32", "../../../std/primitive.u32.html", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -1911,12 +1952,12 @@ atomic_int! { } #[cfg(target_has_atomic = "64")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "i64", "../../../std/primitive.i64.html", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -1925,12 +1966,12 @@ atomic_int! { } #[cfg(target_has_atomic = "64")] atomic_int! { - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), - unstable(feature = "integer_atomics", issue = "32976"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), + stable(feature = "integer_atomics_stable", since = "1.34.0"), "u64", "../../../std/primitive.u64.html", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, From 82fae2be049f37bc20d2bad6c6c482a7d957f687 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 23 Jan 2019 17:34:43 -0700 Subject: [PATCH 0324/1064] Correctly set filetime for copied LLVM This also makes compiletest no longer always retest everything. --- src/bootstrap/lib.rs | 14 +++++--- src/tools/compiletest/src/main.rs | 54 ++++++++++++++++++---------- src/tools/compiletest/src/runtest.rs | 3 +- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index bddc6362389ad..37451a74dfad6 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -135,7 +135,7 @@ use std::cell::{RefCell, Cell}; use std::collections::{HashSet, HashMap}; use std::env; use std::fs::{self, OpenOptions, File}; -use std::io::{self, Seek, SeekFrom, Write, Read}; +use std::io::{Seek, SeekFrom, Write, Read}; use std::path::{PathBuf, Path}; use std::process::{self, Command}; use std::slice; @@ -1263,9 +1263,15 @@ impl Build { if !src.exists() { panic!("Error: File \"{}\" not found!", src.display()); } - let mut s = t!(fs::File::open(&src)); - let mut d = t!(fs::File::create(&dst)); - io::copy(&mut s, &mut d).expect("failed to copy"); + let metadata = t!(src.symlink_metadata()); + if let Err(e) = fs::copy(&src, &dst) { + panic!("failed to copy `{}` to `{}`: {}", src.display(), + dst.display(), e) + } + t!(fs::set_permissions(&dst, metadata.permissions())); + let atime = FileTime::from_last_access_time(&metadata); + let mtime = FileTime::from_last_modification_time(&metadata); + t!(filetime::set_file_times(&dst, atime, mtime)); } chmod(&dst, perms); } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 2e5feca54151c..94317f541c311 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -669,15 +669,6 @@ fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> Path output_base_dir(config, testpaths, revision).join("stamp") } -/// Return an iterator over timestamps of files in the directory at `path`. -fn collect_timestamps(path: &PathBuf) -> impl Iterator { - WalkDir::new(path) - .into_iter() - .map(|entry| entry.unwrap()) - .filter(|entry| entry.file_type().is_file()) - .map(|entry| mtime(entry.path())) -} - fn up_to_date( config: &Config, testpaths: &TestPaths, @@ -700,13 +691,15 @@ fn up_to_date( let rust_src_dir = config .find_rust_src_root() .expect("Could not find Rust source root"); - let stamp = mtime(&stamp_name); - let mut inputs = vec![mtime(&testpaths.file), mtime(&config.rustc_path)]; + let stamp = Stamp::from_path(&stamp_name); + let mut inputs = vec![Stamp::from_path(&testpaths.file), Stamp::from_path(&config.rustc_path)]; inputs.extend( props .aux .iter() - .map(|aux| mtime(&testpaths.file.parent().unwrap().join("auxiliary").join(aux))), + .map(|aux| { + Stamp::from_path(&testpaths.file.parent().unwrap().join("auxiliary").join(aux)) + }), ); // Relevant pretty printer files let pretty_printer_files = [ @@ -717,24 +710,47 @@ fn up_to_date( "src/etc/lldb_rust_formatters.py", ]; inputs.extend(pretty_printer_files.iter().map(|pretty_printer_file| { - mtime(&rust_src_dir.join(pretty_printer_file)) + Stamp::from_path(&rust_src_dir.join(pretty_printer_file)) })); - inputs.extend(collect_timestamps(&config.run_lib_path)); + inputs.extend(Stamp::from_dir(&config.run_lib_path)); if let Some(ref rustdoc_path) = config.rustdoc_path { - inputs.push(mtime(&rustdoc_path)); - inputs.push(mtime(&rust_src_dir.join("src/etc/htmldocck.py"))); + inputs.push(Stamp::from_path(&rustdoc_path)); + inputs.push(Stamp::from_path(&rust_src_dir.join("src/etc/htmldocck.py"))); } // UI test files. inputs.extend(UI_EXTENSIONS.iter().map(|extension| { let path = &expected_output_path(testpaths, revision, &config.compare_mode, extension); - mtime(path) + Stamp::from_path(path) })); // Compiletest itself. - inputs.extend(collect_timestamps(&rust_src_dir.join("src/tools/compiletest/"))); + inputs.extend(Stamp::from_dir(&rust_src_dir.join("src/tools/compiletest/"))); - inputs.iter().any(|input| *input > stamp) + inputs.iter().any(|input| input > &stamp) +} + +#[derive(Debug, PartialEq, PartialOrd, Ord, Eq)] +struct Stamp { + time: FileTime, + file: PathBuf, +} + +impl Stamp { + fn from_path(p: &Path) -> Self { + Stamp { + time: mtime(&p), + file: p.into(), + } + } + + fn from_dir(path: &Path) -> impl Iterator { + WalkDir::new(path) + .into_iter() + .map(|entry| entry.unwrap()) + .filter(|entry| entry.file_type().is_file()) + .map(|entry| Stamp::from_path(entry.path())) + } } fn mtime(path: &Path) -> FileTime { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 400c205d44b20..3c2ca9702dc7f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1998,7 +1998,8 @@ impl<'test> TestCx<'test> { fn fatal(&self, err: &str) -> ! { self.error(err); - panic!(); + error!("fatal error, panic: {:?}", err); + panic!("fatal error"); } fn fatal_proc_rec(&self, err: &str, proc_res: &ProcRes) -> ! { From 1b659d69bc0ba7fe534cc26bda8544a558a7d2b2 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 26 Jan 2019 00:36:50 +0300 Subject: [PATCH 0325/1064] Address review comments and cleanup code --- src/librustc_resolve/lib.rs | 93 +++++++++---------- src/test/ui/issues/issue-56411.rs | 6 +- src/test/ui/issues/issue-56411.stderr | 22 ++--- .../{issue_56411.rs => issue_56411_aux.rs} | 0 4 files changed, 59 insertions(+), 62 deletions(-) rename src/test/ui/issues/{issue_56411.rs => issue_56411_aux.rs} (100%) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8dd09076a00ac..873ace9017260 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -5134,62 +5134,59 @@ impl<'a> Resolver<'a> { ); // See https://github.com/rust-lang/rust/issues/32354 - if old_binding.is_import() || new_binding.is_import() { - let binding = if new_binding.is_import() && !new_binding.span.is_dummy() { - new_binding + let directive = match (&new_binding.kind, &old_binding.kind) { + (NameBindingKind::Import { directive, .. }, _) if !new_binding.span.is_dummy() => + Some((directive, new_binding.span)), + (_, NameBindingKind::Import { directive, .. }) if !old_binding.span.is_dummy() => + Some((directive, old_binding.span)), + _ => None, + }; + if let Some((directive, binding_span)) = directive { + let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { + format!("Other{}", name) } else { - old_binding + format!("other_{}", name) }; - let cm = self.session.source_map(); - let rename_msg = "you can use `as` to change the binding name of the import"; - - if let ( - Ok(snippet), - NameBindingKind::Import { directive, ..}, - false, - false, - ) = ( - cm.span_to_snippet(binding.span), - binding.kind.clone(), - binding.span.is_dummy(), - binding.span.ctxt().outer().expn_info().is_some(), - ) { - let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { - format!("Other{}", name) - } else { - format!("other_{}", name) - }; + let mut suggestion = None; + match directive.subclass { + ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => + suggestion = Some(format!("self as {}", suggested_name)), + ImportDirectiveSubclass::SingleImport { source, .. } => { + if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0) + .map(|pos| pos as usize) { + if let Ok(snippet) = self.session.source_map() + .span_to_snippet(binding_span) { + if pos <= snippet.len() { + suggestion = Some(format!( + "{} as {}{}", + &snippet[..pos], + suggested_name, + if snippet.ends_with(";") { ";" } else { "" } + )) + } + } + } + } + ImportDirectiveSubclass::ExternCrate { source, target, .. } => + suggestion = Some(format!( + "extern crate {} as {};", + source.unwrap_or(target.name), + suggested_name, + )), + _ => unreachable!(), + } + let rename_msg = "you can use `as` to change the binding name of the import"; + if let Some(suggestion) = suggestion { err.span_suggestion_with_applicability( - binding.span, - &rename_msg, - match directive.subclass { - ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => - format!("self as {}", suggested_name), - ImportDirectiveSubclass::SingleImport { source, .. } => - format!( - "{} as {}{}", - &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)], - suggested_name, - if snippet.ends_with(";") { - ";" - } else { - "" - } - ), - ImportDirectiveSubclass::ExternCrate { source, target, .. } => - format!( - "extern crate {} as {};", - source.unwrap_or(target.name), - suggested_name, - ), - _ => unreachable!(), - }, + binding_span, + rename_msg, + suggestion, Applicability::MaybeIncorrect, ); } else { - err.span_label(binding.span, rename_msg); + err.span_label(binding_span, rename_msg); } } diff --git a/src/test/ui/issues/issue-56411.rs b/src/test/ui/issues/issue-56411.rs index 599f277123cc8..3561c21cc7ee3 100644 --- a/src/test/ui/issues/issue-56411.rs +++ b/src/test/ui/issues/issue-56411.rs @@ -3,14 +3,14 @@ macro_rules! import { $( mod $name; pub use self::$name; - //~^ ERROR the name `issue_56411` is defined multiple times - //~| ERROR `issue_56411` is private, and cannot be re-exported + //~^ ERROR the name `issue_56411_aux` is defined multiple times + //~| ERROR `issue_56411_aux` is private, and cannot be re-exported )* } } -import!(issue_56411); +import!(issue_56411_aux); fn main() { println!("Hello, world!"); diff --git a/src/test/ui/issues/issue-56411.stderr b/src/test/ui/issues/issue-56411.stderr index 842d86f4a3a9c..dd05852c09159 100644 --- a/src/test/ui/issues/issue-56411.stderr +++ b/src/test/ui/issues/issue-56411.stderr @@ -1,29 +1,29 @@ -error[E0255]: the name `issue_56411` is defined multiple times +error[E0255]: the name `issue_56411_aux` is defined multiple times --> $DIR/issue-56411.rs:5:21 | LL | mod $name; - | ---------- previous definition of the module `issue_56411` here + | ---------- previous definition of the module `issue_56411_aux` here LL | pub use self::$name; | ^^^^^^^^^^^ | | - | `issue_56411` reimported here + | `issue_56411_aux` reimported here | you can use `as` to change the binding name of the import ... -LL | import!(issue_56411); - | --------------------- in this macro invocation +LL | import!(issue_56411_aux); + | ------------------------- in this macro invocation | - = note: `issue_56411` must be defined only once in the type namespace of this module + = note: `issue_56411_aux` must be defined only once in the type namespace of this module -error[E0365]: `issue_56411` is private, and cannot be re-exported +error[E0365]: `issue_56411_aux` is private, and cannot be re-exported --> $DIR/issue-56411.rs:5:21 | LL | pub use self::$name; - | ^^^^^^^^^^^ re-export of private `issue_56411` + | ^^^^^^^^^^^ re-export of private `issue_56411_aux` ... -LL | import!(issue_56411); - | --------------------- in this macro invocation +LL | import!(issue_56411_aux); + | ------------------------- in this macro invocation | - = note: consider declaring type or module `issue_56411` with `pub` + = note: consider declaring type or module `issue_56411_aux` with `pub` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue_56411.rs b/src/test/ui/issues/issue_56411_aux.rs similarity index 100% rename from src/test/ui/issues/issue_56411.rs rename to src/test/ui/issues/issue_56411_aux.rs From df0466d0bb807a7266cc8ac9931cd43b3e84b62e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 16 Jan 2019 09:59:03 -0800 Subject: [PATCH 0326/1064] Rebase to the llvm-project monorepo The new git submodule src/llvm-project is a monorepo replacing src/llvm and src/tools/{clang,lld,lldb}. This also serves as a rebase for these projects to the new 8.x branch from trunk. The src/llvm-emscripten fork is unchanged for now. --- .gitmodules | 21 ++--- COPYRIGHT | 6 +- src/bootstrap/bootstrap.py | 12 +-- src/bootstrap/dist.rs | 25 +++++- src/bootstrap/native.rs | 14 ++-- src/ci/init_repo.sh | 3 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 15 ++-- src/librustc_codegen_llvm/llvm/ffi.rs | 22 +++-- src/llvm | 1 - src/llvm-project | 1 + src/rustllvm/PassWrapper.cpp | 7 +- src/rustllvm/RustWrapper.cpp | 93 ++++++++++++++++++++-- src/rustllvm/llvm-rebuild-trigger | 2 +- src/test/codegen/enum-debug-clike.rs | 5 +- src/tools/clang | 1 - src/tools/lld | 1 - src/tools/lldb | 1 - src/tools/tidy/src/lib.rs | 1 + 18 files changed, 166 insertions(+), 65 deletions(-) delete mode 160000 src/llvm create mode 160000 src/llvm-project delete mode 160000 src/tools/clang delete mode 160000 src/tools/lld delete mode 160000 src/tools/lldb diff --git a/.gitmodules b/.gitmodules index c4763612dbf3c..4e368c3ebafd8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ -[submodule "src/llvm"] - path = src/llvm - url = https://github.com/rust-lang/llvm.git - branch = master [submodule "src/rust-installer"] path = src/tools/rust-installer url = https://github.com/rust-lang/rust-installer.git @@ -38,20 +34,13 @@ [submodule "src/stdsimd"] path = src/stdsimd url = https://github.com/rust-lang-nursery/stdsimd.git -[submodule "src/tools/lld"] - path = src/tools/lld - url = https://github.com/rust-lang/lld.git -[submodule "src/tools/lldb"] - path = src/tools/lldb - url = https://github.com/rust-lang-nursery/lldb.git - branch = rust-release-80-v2 -[submodule "src/tools/clang"] - path = src/tools/clang - url = https://github.com/rust-lang-nursery/clang.git - branch = rust-release-80-v2 [submodule "src/doc/rustc-guide"] path = src/doc/rustc-guide url = https://github.com/rust-lang/rustc-guide.git [submodule "src/doc/edition-guide"] path = src/doc/edition-guide - url = https://github.com/rust-lang-nursery/edition-guide + url = https://github.com/rust-lang-nursery/edition-guide.git +[submodule "src/llvm-project"] + path = src/llvm-project + url = https://github.com/rust-lang/llvm-project.git + branch = rustc/8.0-2019-01-16 diff --git a/COPYRIGHT b/COPYRIGHT index 6596c5a3d9aff..dc9abf84b8e5a 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -23,7 +23,7 @@ The Rust Project includes packages written by third parties. The following third party packages are included, and carry their own copyright notices and license terms: -* LLVM. Code for this package is found in src/llvm. +* LLVM. Code for this package is found in src/llvm-project. Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign. All rights reserved. @@ -73,8 +73,8 @@ their own copyright notices and license terms: OTHER DEALINGS WITH THE SOFTWARE. * Additional libraries included in LLVM carry separate - BSD-compatible licenses. See src/llvm/LICENSE.txt for - details. + BSD-compatible licenses. See src/llvm-project/llvm/LICENSE.TXT + for details. * compiler-rt, in src/compiler-rt is dual licensed under LLVM's license and MIT: diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e8c1594bda343..119b38bcc99dc 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -701,21 +701,13 @@ def update_submodules(self): filtered_submodules = [] submodules_names = [] for module in submodules: - if module.endswith("llvm"): - if self.get_toml('llvm-config'): + if module.endswith("llvm-project"): + if self.get_toml('llvm-config') and self.get_toml('lld') != 'true': continue if module.endswith("llvm-emscripten"): backends = self.get_toml('codegen-backends') if backends is None or not 'emscripten' in backends: continue - if module.endswith("lld"): - config = self.get_toml('lld') - if config is None or config == 'false': - continue - if module.endswith("lldb") or module.endswith("clang"): - config = self.get_toml('lldb') - if config is None or config == 'false': - continue check = self.check_submodule(module, slow_submodules) filtered_submodules.append((module, check)) submodules_names.append(module) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 71662e8b94149..98d2fb1e2d039 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -788,7 +788,24 @@ fn copy_src_dirs(builder: &Builder, src_dirs: &[&str], exclude_dirs: &[&str], ds if spath.ends_with("~") || spath.ends_with(".pyc") { return false } - if (spath.contains("llvm/test") || spath.contains("llvm\\test")) && + + const LLVM_PROJECTS: &[&str] = &[ + "llvm-project/clang", "llvm-project\\clang", + "llvm-project/lld", "llvm-project\\lld", + "llvm-project/lldb", "llvm-project\\lldb", + "llvm-project/llvm", "llvm-project\\llvm", + ]; + if spath.contains("llvm-project") && !spath.ends_with("llvm-project") + && !LLVM_PROJECTS.iter().any(|path| spath.contains(path)) + { + return false; + } + + const LLVM_TEST: &[&str] = &[ + "llvm-project/llvm/test", "llvm-project\\llvm\\test", + "llvm-emscripten/test", "llvm-emscripten\\test", + ]; + if LLVM_TEST.iter().any(|path| spath.contains(path)) && (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s")) { @@ -2076,7 +2093,7 @@ impl Step for LlvmTools { } builder.info(&format!("Dist LlvmTools stage{} ({})", stage, target)); - let src = builder.src.join("src/llvm"); + let src = builder.src.join("src/llvm-project/llvm"); let name = pkgname(builder, "llvm-tools"); let tmp = tmpdir(builder); @@ -2135,7 +2152,7 @@ impl Step for Lldb { const DEFAULT: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { - run.path("src/tools/lldb") + run.path("src/llvm-project/lldb").path("src/tools/lldb") } fn make_run(run: RunConfig) { @@ -2160,7 +2177,7 @@ impl Step for Lldb { } builder.info(&format!("Dist Lldb ({})", target)); - let src = builder.src.join("src/tools/lldb"); + let src = builder.src.join("src/llvm-project/lldb"); let name = pkgname(builder, "lldb"); let tmp = tmpdir(builder); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index f5bacd63e6803..337c6965a30cf 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -36,7 +36,10 @@ impl Step for Llvm { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { - run.path("src/llvm").path("src/llvm-emscripten") + run.path("src/llvm-project") + .path("src/llvm-project/llvm") + .path("src/llvm") + .path("src/llvm-emscripten") } fn make_run(run: RunConfig) { @@ -97,7 +100,7 @@ impl Step for Llvm { t!(fs::create_dir_all(&out_dir)); // http://llvm.org/docs/CMake.html - let root = if self.emscripten { "src/llvm-emscripten" } else { "src/llvm" }; + let root = if self.emscripten { "src/llvm-emscripten" } else { "src/llvm-project/llvm" }; let mut cfg = cmake::Config::new(builder.src.join(root)); let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) { @@ -189,8 +192,7 @@ impl Step for Llvm { } if want_lldb { - cfg.define("LLVM_EXTERNAL_CLANG_SOURCE_DIR", builder.src.join("src/tools/clang")); - cfg.define("LLVM_EXTERNAL_LLDB_SOURCE_DIR", builder.src.join("src/tools/lldb")); + cfg.define("LLVM_ENABLE_PROJECTS", "clang;lldb"); // For the time being, disable code signing. cfg.define("LLDB_CODESIGN_IDENTITY", ""); } else { @@ -411,7 +413,7 @@ impl Step for Lld { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { - run.path("src/tools/lld") + run.path("src/llvm-project/lld").path("src/tools/lld") } fn make_run(run: RunConfig) { @@ -441,7 +443,7 @@ impl Step for Lld { let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); - let mut cfg = cmake::Config::new(builder.src.join("src/tools/lld")); + let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/lld")); configure_cmake(builder, target, &mut cfg); // This is an awful, awful hack. Discovered when we migrated to using diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index be2cadbbe6cf2..6de433fd4c2da 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -45,8 +45,7 @@ function fetch_submodule { rm $cached } -included="src/llvm src/llvm-emscripten src/doc/book src/doc/rust-by-example" -included="$included src/tools/lld src/tools/clang src/tools/lldb" +included="src/llvm-project src/llvm-emscripten src/doc/book src/doc/rust-by-example" modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)" modules=($modules) use_git="" diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index b504aa515fd44..113b9958c7f8c 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -12,7 +12,7 @@ use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags, - DILexicalBlock}; + DISPFlags, DILexicalBlock}; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::ty::subst::{Substs, UnpackedKind}; @@ -283,7 +283,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let linkage_name = mangled_name_of_instance(self, instance); let scope_line = span_start(self, span).line; - let is_local_to_unit = is_node_local_to_unit(self, def_id); let function_name = CString::new(name).unwrap(); let linkage_name = SmallCStr::new(&linkage_name.as_str()); @@ -300,6 +299,14 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { flags |= DIFlags::FlagNoReturn; } + let mut spflags = DISPFlags::SPFlagDefinition; + if is_node_local_to_unit(self, def_id) { + spflags |= DISPFlags::SPFlagLocalToUnit; + } + if self.sess().opts.optimize != config::OptLevel::No { + spflags |= DISPFlags::SPFlagOptimized; + } + let fn_metadata = unsafe { llvm::LLVMRustDIBuilderCreateFunction( DIB(self), @@ -309,11 +316,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { file_metadata, loc.line as c_uint, function_type_metadata, - is_local_to_unit, - true, scope_line as c_uint, flags, - self.sess().opts.optimize != config::OptLevel::No, + spflags, llfn, template_parameters, None) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 11e34f600c286..853c1ff0047e7 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -2,7 +2,7 @@ use super::debuginfo::{ DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, DIGlobalVariableExpression, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, - DINameSpace, DIFlags, + DINameSpace, DIFlags, DISPFlags, }; use libc::{c_uint, c_int, size_t, c_char}; @@ -591,6 +591,20 @@ pub mod debuginfo { const FlagMainSubprogram = (1 << 21); } } + + // These values **must** match with LLVMRustDISPFlags!! + bitflags! { + #[repr(C)] + #[derive(Default)] + pub struct DISPFlags: ::libc::uint32_t { + const SPFlagZero = 0; + const SPFlagVirtual = 1; + const SPFlagPureVirtual = 2; + const SPFlagLocalToUnit = (1 << 2); + const SPFlagDefinition = (1 << 3); + const SPFlagOptimized = (1 << 4); + } + } } extern { pub type ModuleBuffer; } @@ -1387,11 +1401,9 @@ extern "C" { File: &'a DIFile, LineNo: c_uint, Ty: &'a DIType, - isLocalToUnit: bool, - isDefinition: bool, ScopeLine: c_uint, Flags: DIFlags, - isOptimized: bool, + SPFlags: DISPFlags, Fn: &'a Value, TParam: &'a DIArray, Decl: Option<&'a DIDescriptor>) @@ -1529,7 +1541,7 @@ extern "C" { AlignInBits: u32, Elements: &'a DIArray, ClassType: &'a DIType, - IsFixed: bool) + IsScoped: bool) -> &'a DIType; pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder<'a>, diff --git a/src/llvm b/src/llvm deleted file mode 160000 index f4728ed8fa229..0000000000000 --- a/src/llvm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f4728ed8fa2296c5b009bb85550e157e1e57ed0b diff --git a/src/llvm-project b/src/llvm-project new file mode 160000 index 0000000000000..a27fbee5abaee --- /dev/null +++ b/src/llvm-project @@ -0,0 +1 @@ +Subproject commit a27fbee5abaee63ac45c8cb9a0c73889c3b98471 diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index df7a81643bcb6..18d277be21a16 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -789,7 +789,7 @@ struct LLVMRustThinLTOData { StringMap ModuleToDefinedGVSummaries; #if LLVM_VERSION_GE(7, 0) - LLVMRustThinLTOData() : Index(/* isPerformingAnalysis = */ false) {} + LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {} #endif }; @@ -865,7 +865,12 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, auto deadIsPrevailing = [&](GlobalValue::GUID G) { return PrevailingType::Unknown; }; +#if LLVM_VERSION_GE(8, 0) + computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, + deadIsPrevailing, /* ImportEnabled = */ true); +#else computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); +#endif #else computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols); #endif diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9d3e6f93b0c11..7905e9f0f237e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -294,7 +294,7 @@ extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) { extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name, LLVMAtomicOrdering Order) { - LoadInst *LI = new LoadInst(unwrap(Source), 0); + LoadInst *LI = new LoadInst(unwrap(Source)); LI->setAtomic(fromRust(Order)); return wrap(unwrap(B)->Insert(LI, Name)); } @@ -511,6 +511,71 @@ static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { return Result; } +// These values **must** match debuginfo::DISPFlags! They also *happen* +// to match LLVM, but that isn't required as we do giant sets of +// matching below. The value shouldn't be directly passed to LLVM. +enum class LLVMRustDISPFlags : uint32_t { + SPFlagZero = 0, + SPFlagVirtual = 1, + SPFlagPureVirtual = 2, + SPFlagLocalToUnit = (1 << 2), + SPFlagDefinition = (1 << 3), + SPFlagOptimized = (1 << 4), + // Do not add values that are not supported by the minimum LLVM + // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def + // (In LLVM < 8, createFunction supported these as separate bool arguments.) +}; + +inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) { + return static_cast(static_cast(A) & + static_cast(B)); +} + +inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) { + return static_cast(static_cast(A) | + static_cast(B)); +} + +inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) { + return A = A | B; +} + +inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; } + +inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) { + return static_cast(static_cast(F) & 0x3); +} + +#if LLVM_VERSION_GE(8, 0) +static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) { + DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero; + + switch (virtuality(SPFlags)) { + case LLVMRustDISPFlags::SPFlagVirtual: + Result |= DISubprogram::DISPFlags::SPFlagVirtual; + break; + case LLVMRustDISPFlags::SPFlagPureVirtual: + Result |= DISubprogram::DISPFlags::SPFlagPureVirtual; + break; + default: + // The rest are handled below + break; + } + + if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) { + Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit; + } + if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) { + Result |= DISubprogram::DISPFlags::SPFlagDefinition; + } + if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) { + Result |= DISubprogram::DISPFlags::SPFlagOptimized; + } + + return Result; +} +#endif + extern "C" uint32_t LLVMRustDebugMetadataVersion() { return DEBUG_METADATA_VERSION; } @@ -575,16 +640,26 @@ LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder, extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, const char *LinkageName, LLVMMetadataRef File, unsigned LineNo, - LLVMMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition, - unsigned ScopeLine, LLVMRustDIFlags Flags, bool IsOptimized, - LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) { + LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags, + LLVMRustDISPFlags SPFlags, LLVMValueRef Fn, LLVMMetadataRef TParam, + LLVMMetadataRef Decl) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap(TParam)); +#if LLVM_VERSION_GE(8, 0) + DISubprogram *Sub = Builder->createFunction( + unwrapDI(Scope), Name, LinkageName, unwrapDI(File), + LineNo, unwrapDI(Ty), ScopeLine, fromRust(Flags), + fromRust(SPFlags), TParams, unwrapDIPtr(Decl)); +#else + bool IsLocalToUnit = isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit); + bool IsDefinition = isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition); + bool IsOptimized = isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized); DISubprogram *Sub = Builder->createFunction( unwrapDI(Scope), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, IsDefinition, ScopeLine, fromRust(Flags), IsOptimized, TParams, unwrapDIPtr(Decl)); +#endif unwrap(Fn)->setSubprogram(Sub); return wrap(Sub); } @@ -773,14 +848,14 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef Elements, - LLVMMetadataRef ClassTy, bool IsFixed) { + LLVMMetadataRef ClassTy, bool IsScoped) { #if LLVM_VERSION_GE(7, 0) return wrap(Builder->createEnumerationType( unwrapDI(Scope), Name, unwrapDI(File), LineNumber, SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)), - unwrapDI(ClassTy), "", IsFixed)); + unwrapDI(ClassTy), "", IsScoped)); #else - // Ignore IsFixed on older LLVM. + // Ignore IsScoped on older LLVM. return wrap(Builder->createEnumerationType( unwrapDI(Scope), Name, unwrapDI(File), LineNumber, SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)), @@ -920,7 +995,11 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic( if (loc.isValid()) { *Line = loc.getLine(); *Column = loc.getColumn(); +#if LLVM_VERSION_GE(8, 0) + FilenameOS << loc.getAbsolutePath(); +#else FilenameOS << loc.getFilename(); +#endif } RawRustStringOstream MessageOS(MessageOut); diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger index a268838de4515..9ee1bceb632bd 100644 --- a/src/rustllvm/llvm-rebuild-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2018-12-13 +2019-01-16 diff --git a/src/test/codegen/enum-debug-clike.rs b/src/test/codegen/enum-debug-clike.rs index 98f07505f7539..62cfef5a845e9 100644 --- a/src/test/codegen/enum-debug-clike.rs +++ b/src/test/codegen/enum-debug-clike.rs @@ -8,8 +8,11 @@ // compile-flags: -g -C no-prepopulate-passes +// DIFlagFixedEnum was deprecated in 8.0, renamed to DIFlagEnumClass. +// We match either for compatibility. + // CHECK-LABEL: @main -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: DIFlagFixedEnum,{{.*}} +// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: {{(DIFlagEnumClass|DIFlagFixedEnum)}},{{.*}} // CHECK: {{.*}}DIEnumerator{{.*}}name: "A",{{.*}}value: {{[0-9].*}} // CHECK: {{.*}}DIEnumerator{{.*}}name: "B",{{.*}}value: {{[0-9].*}} // CHECK: {{.*}}DIEnumerator{{.*}}name: "C",{{.*}}value: {{[0-9].*}} diff --git a/src/tools/clang b/src/tools/clang deleted file mode 160000 index 032312dd0140a..0000000000000 --- a/src/tools/clang +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 032312dd0140a7074c9b89d305fe44eb0e44e407 diff --git a/src/tools/lld b/src/tools/lld deleted file mode 160000 index 1928c5eeb613a..0000000000000 --- a/src/tools/lld +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1928c5eeb613a4c6d232fc47ae91914bbfd92a79 diff --git a/src/tools/lldb b/src/tools/lldb deleted file mode 160000 index 8ad0817ce45b0..0000000000000 --- a/src/tools/lldb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8ad0817ce45b0eef9d374691b23f2bd69c164254 diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index a10332526d13b..022c53f909c75 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -47,6 +47,7 @@ pub mod libcoretest; fn filter_dirs(path: &Path) -> bool { let skip = [ "src/llvm", + "src/llvm-project", "src/llvm-emscripten", "src/libbacktrace", "src/librustc_data_structures/owning_ref", From 75d0bceb0aaa399a9c8de2913dd78cc6df295222 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 17 Jan 2019 12:56:50 -0800 Subject: [PATCH 0327/1064] Add two more wasm-related LLVM commits --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index a27fbee5abaee..25bfc9f499dec 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit a27fbee5abaee63ac45c8cb9a0c73889c3b98471 +Subproject commit 25bfc9f499dec435c8a7044b565a4bcd30d1fe00 From cff075009032d11cff3a625663cf460e71e81609 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 22 Jan 2019 13:01:14 -0800 Subject: [PATCH 0328/1064] Set the DICompileUnit emissionKind --- .../debuginfo/metadata.rs | 6 +++-- src/librustc_codegen_llvm/llvm/ffi.rs | 25 +++++++++++++++++-- src/rustllvm/RustWrapper.cpp | 25 +++++++++++++++++-- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 9f63038c3623b..3a7864cb7a5a8 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -13,7 +13,7 @@ use value::Value; use llvm; use llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor, - DICompositeType, DILexicalBlock, DIFlags}; + DICompositeType, DILexicalBlock, DIFlags, DebugEmissionKind}; use llvm_util; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -846,6 +846,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt, let producer = CString::new(producer).unwrap(); let flags = "\0"; let split_name = "\0"; + let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo); unsafe { let file_metadata = llvm::LLVMRustDIBuilderCreateFile( @@ -859,7 +860,8 @@ pub fn compile_unit_metadata(tcx: TyCtxt, tcx.sess.opts.optimize != config::OptLevel::No, flags.as_ptr() as *const _, 0, - split_name.as_ptr() as *const _); + split_name.as_ptr() as *const _, + kind); if tcx.sess.opts.debugging_opts.profile { let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 853c1ff0047e7..199c1220a2c4a 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -2,7 +2,7 @@ use super::debuginfo::{ DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, DIGlobalVariableExpression, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, - DINameSpace, DIFlags, DISPFlags, + DINameSpace, DIFlags, DISPFlags, DebugEmissionKind, }; use libc::{c_uint, c_int, size_t, c_char}; @@ -605,6 +605,26 @@ pub mod debuginfo { const SPFlagOptimized = (1 << 4); } } + + /// LLVMRustDebugEmissionKind + #[derive(Copy, Clone)] + #[repr(C)] + pub enum DebugEmissionKind { + NoDebug, + FullDebug, + LineTablesOnly, + } + + impl DebugEmissionKind { + pub fn from_generic(kind: rustc::session::config::DebugInfo) -> Self { + use rustc::session::config::DebugInfo; + match kind { + DebugInfo::None => DebugEmissionKind::NoDebug, + DebugInfo::Limited => DebugEmissionKind::LineTablesOnly, + DebugInfo::Full => DebugEmissionKind::FullDebug, + } + } + } } extern { pub type ModuleBuffer; } @@ -1381,7 +1401,8 @@ extern "C" { isOptimized: bool, Flags: *const c_char, RuntimeVer: c_uint, - SplitName: *const c_char) + SplitName: *const c_char, + kind: DebugEmissionKind) -> &'a DIDescriptor; pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder<'a>, diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 7905e9f0f237e..e973318057c67 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -576,6 +576,25 @@ static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) { } #endif +enum class LLVMRustDebugEmissionKind { + NoDebug, + FullDebug, + LineTablesOnly, +}; + +static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) { + switch (Kind) { + case LLVMRustDebugEmissionKind::NoDebug: + return DICompileUnit::DebugEmissionKind::NoDebug; + case LLVMRustDebugEmissionKind::FullDebug: + return DICompileUnit::DebugEmissionKind::FullDebug; + case LLVMRustDebugEmissionKind::LineTablesOnly: + return DICompileUnit::DebugEmissionKind::LineTablesOnly; + default: + report_fatal_error("bad DebugEmissionKind."); + } +} + extern "C" uint32_t LLVMRustDebugMetadataVersion() { return DEBUG_METADATA_VERSION; } @@ -616,11 +635,13 @@ extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) { extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit( LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef, const char *Producer, bool isOptimized, const char *Flags, - unsigned RuntimeVer, const char *SplitName) { + unsigned RuntimeVer, const char *SplitName, + LLVMRustDebugEmissionKind Kind) { auto *File = unwrapDI(FileRef); return wrap(Builder->createCompileUnit(Lang, File, Producer, isOptimized, - Flags, RuntimeVer, SplitName)); + Flags, RuntimeVer, SplitName, + fromRust(Kind))); } extern "C" LLVMMetadataRef From 8b88324c56c1d2b4a8e4e45960ade78992cf44aa Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 22 Jan 2019 19:50:45 -0800 Subject: [PATCH 0329/1064] Update LLVM for a CodeView fix --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 25bfc9f499dec..bf94cf8631db9 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 25bfc9f499dec435c8a7044b565a4bcd30d1fe00 +Subproject commit bf94cf8631db93c464b7842bf922724583ee15a1 From 400dec059e9d71b06e6cfa5cfe399b4c57eb8119 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 23 Jan 2019 16:17:24 -0800 Subject: [PATCH 0330/1064] librustc_llvm: default to libc++ for darwin --- src/librustc_llvm/build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index d4a3ae273fcd4..ec3dff783c47b 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -243,6 +243,8 @@ fn main() { "c++" } else if target.contains("freebsd") { "c++" + } else if target.contains("darwin") { + "c++" } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() { // NetBSD uses a separate library when relocation is required "stdc++_pic" From a920ed935c60faf851415bfdc636a6288dd29c49 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 24 Jan 2019 10:42:52 -0800 Subject: [PATCH 0331/1064] [rust-lldb] Adapt to changes in LLDB APIs --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index bf94cf8631db9..683d3522690b7 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit bf94cf8631db93c464b7842bf922724583ee15a1 +Subproject commit 683d3522690b7a9d0163e7e7e6586f2b1364ed02 From 15cf179c9316740fb5ddff3bf8075e5436cece11 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 24 Jan 2019 18:02:54 -0800 Subject: [PATCH 0332/1064] Set LLDB_NO_DEBUGSERVER=ON --- src/bootstrap/native.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 337c6965a30cf..b1bc2e6cad5bd 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -195,6 +195,7 @@ impl Step for Llvm { cfg.define("LLVM_ENABLE_PROJECTS", "clang;lldb"); // For the time being, disable code signing. cfg.define("LLDB_CODESIGN_IDENTITY", ""); + cfg.define("LLDB_NO_DEBUGSERVER", "ON"); } else { // LLDB requires libxml2; but otherwise we want it to be disabled. // See https://github.com/rust-lang/rust/pull/50104 From 059ed4f21f42914028af5fc0083d3eca13a49d6f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 25 Jan 2019 07:23:18 -0800 Subject: [PATCH 0333/1064] Update `dlmalloc` to 0.1.2 Remove usage of an old and removed wasm intrinsic --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a237c5916a314..f9385ee3a1b3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -713,7 +713,7 @@ dependencies = [ [[package]] name = "dlmalloc" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1969,7 +1969,7 @@ name = "rand_chacha" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1991,7 +1991,7 @@ name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2016,7 +2016,7 @@ name = "rand_xorshift" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3073,7 +3073,7 @@ dependencies = [ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dlmalloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)", "panic_abort 0.0.0", @@ -3816,7 +3816,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72d337a64190607d4fcca2cb78982c5dd57f4916e19696b48a575fa746b6cb0f" -"checksum dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c46c65de42b063004b31c67a98abe071089b289ff0919c660ed7ff4f59317f8" +"checksum dlmalloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d56ad71b31043818d0ee10a7fb9664882f8e45849c81647585e6a3124f185517" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455" "checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00" From b215fbdbb42e44e67f5bcaec6af45343ce33576a Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sat, 26 Jan 2019 15:50:05 +0900 Subject: [PATCH 0334/1064] Change crate-visibility-modifier issue number in The Unstable Book --- .../src/language-features/crate-visibility-modifier.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md b/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md index 11b3ee8edf0b1..b59859dd348e7 100644 --- a/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md +++ b/src/doc/unstable-book/src/language-features/crate-visibility-modifier.md @@ -1,8 +1,8 @@ # `crate_visibility_modifier` -The tracking issue for this feature is: [#45388] +The tracking issue for this feature is: [#53120] -[#45388]: https://github.com/rust-lang/rust/issues/45388 +[#53120]: https://github.com/rust-lang/rust/issues/53120 ----- From 7e7a43b8765307239a73fc72dddcd426ee5908c0 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Sat, 26 Jan 2019 14:46:39 +0530 Subject: [PATCH 0335/1064] Clean up build-x86_64-fortanix-unknown-sgx-toolchain.sh --- ...d-x86_64-fortanix-unknown-sgx-toolchain.sh | 33 ++++++++----------- src/ci/docker/dist-various-2/shared.sh | 15 ++++++++- src/ci/init_repo.sh | 7 ++-- src/ci/shared.sh | 1 + 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh index 76921316df2cc..f94cd36e8d6ec 100755 --- a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh @@ -12,8 +12,7 @@ target="x86_64-fortanix-unknown-sgx" url="https://github.com/fortanix/llvm-project/archive/${1}.tar.gz" repo_name="llvm-project" -install_prereq() -{ +install_prereq() { apt-get update apt-get install -y --no-install-recommends \ build-essential \ @@ -22,34 +21,30 @@ install_prereq() git } -# Clone Fortanix's port of llvm-project to build libunwind that would link with this target. -# The below method to download a single commit from llvm-project is based on fetch_submodule -# from init_repo.sh -fetch_llvm_commit() -{ - cached="download-${repo_name}.tar.gz" - curl -f -sSL -o ${cached} ${url} - tar -xvzf ${cached} - mkdir "./${repo_name}" && tar -xf ${cached} -C ${repo_name} --strip-components 1 -} - -build_unwind() -{ +build_unwind() { + set -x dir_name="${target}_temp" - rm -rf "./${dir_name}" + rm -rf ${dir_name} mkdir -p ${dir_name} - cd ${dir_name} + pushd ${dir_name} - retry fetch_llvm_commit + # Clone Fortanix's fork of llvm-project which has a port of libunwind + fetch_github_commit_archive "$repo_name" "$url" cd "${repo_name}/libunwind" # Build libunwind mkdir -p build cd build - cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" -DLLVM_PATH=../../llvm/ ../ + cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" \ + -DLLVM_ENABLE_WARNINGS=1 -DLIBUNWIND_ENABLE_WERROR=1 -DLIBUNWIND_ENABLE_PEDANTIC=0 \ + -DLLVM_PATH=../../llvm/ ../ make unwind_static install -D "lib/libunwind.a" "/${target}/lib/libunwind.a" + + popd rm -rf ${dir_name} + + { set +x; } 2>/dev/null } set -x diff --git a/src/ci/docker/dist-various-2/shared.sh b/src/ci/docker/dist-various-2/shared.sh index fb917b0510e40..7abace65b9c03 100644 --- a/src/ci/docker/dist-various-2/shared.sh +++ b/src/ci/docker/dist-various-2/shared.sh @@ -1,5 +1,5 @@ hide_output() { - set +x + { set +x; } 2>/dev/null on_err=" echo ERROR: An error was encountered with the build. cat /tmp/build.log @@ -14,6 +14,7 @@ exit 1 set -x } +# Copied from ../../shared.sh function retry { echo "Attempting with retry:" "$@" local n=1 @@ -31,3 +32,15 @@ function retry { } done } + +# Copied from ../../init_repo.sh +function fetch_github_commit_archive { + local module=$1 + local cached="download-${module//\//-}.tar.gz" + retry sh -c "rm -f $cached && \ + curl -f -sSL -o $cached $2" + mkdir $module + touch "$module/.git" + tar -C $module --strip-components=1 -xf $cached + rm $cached +} diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index 6de433fd4c2da..3dfd338157617 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -34,11 +34,12 @@ if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then git fetch origin --unshallow beta master fi -function fetch_submodule { +# Duplicated in docker/dist-various-2/shared.sh +function fetch_github_commit_archive { local module=$1 local cached="download-${module//\//-}.tar.gz" retry sh -c "rm -f $cached && \ - curl -sSL -o $cached $2" + curl -f -sSL -o $cached $2" mkdir $module touch "$module/.git" tar -C $module --strip-components=1 -xf $cached @@ -58,7 +59,7 @@ for i in ${!modules[@]}; do git rm $module url=${urls[$i]} url=${url/\.git/} - fetch_submodule $module "$url/archive/$commit.tar.gz" & + fetch_github_commit_archive $module "$url/archive/$commit.tar.gz" & continue else use_git="$use_git $module" diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 4a49f3441a41d..3ba64ad412064 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -5,6 +5,7 @@ # marked as an executable file in git. # See http://unix.stackexchange.com/questions/82598 +# Duplicated in docker/dist-various-2/shared.sh function retry { echo "Attempting with retry:" "$@" local n=1 From 9ce3cfa4f2e38493abd5a3141c31bd16f77d65ba Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Sat, 26 Jan 2019 14:58:11 +0530 Subject: [PATCH 0336/1064] Update SGX libunwind --- src/ci/docker/dist-various-2/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 952c1ba2ccb76..1d33fd0f7f4cf 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -32,7 +32,7 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc COPY dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/ # We pass the commit id of the port of LLVM's libunwind to the build script. # Any update to the commit id here, should cause the container image to be re-built from this point on. -RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "13fad13f8ea83a8da58d04a5faa45943151b3398" +RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "75628849f538a62712353ac6e4c9e789da90923e" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh From c375333362bd1b5f006f6d627ff129c2c54d620c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 26 Jan 2019 16:29:34 +0300 Subject: [PATCH 0337/1064] Pretty print `$crate` as `crate` or `crate_name` in more cases --- src/librustc_resolve/macros.rs | 10 +++++----- src/librustc_resolve/resolve_imports.rs | 5 +---- src/libsyntax/ext/base.rs | 16 ++-------------- src/libsyntax/ext/expand.rs | 7 +++---- src/test/pretty/dollar-crate.pp | 18 ++++++++++++++++++ src/test/pretty/dollar-crate.rs | 7 +++++++ 6 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 src/test/pretty/dollar-crate.pp create mode 100644 src/test/pretty/dollar-crate.rs diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 286f9a758830b..e552795260465 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -15,7 +15,7 @@ use syntax::ast::{self, Ident}; use syntax::attr; use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; -use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension}; +use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; use syntax::ext::tt::macro_rules; @@ -127,9 +127,9 @@ impl<'a> base::Resolver for Resolver<'a> { mark } - fn resolve_dollar_crates(&mut self, annotatable: &Annotatable) { - pub struct ResolveDollarCrates<'a, 'b: 'a> { - pub resolver: &'a mut Resolver<'b>, + fn resolve_dollar_crates(&mut self, fragment: &AstFragment) { + struct ResolveDollarCrates<'a, 'b: 'a> { + resolver: &'a mut Resolver<'b> } impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> { fn visit_ident(&mut self, ident: Ident) { @@ -144,7 +144,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn visit_mac(&mut self, _: &ast::Mac) {} } - annotatable.visit_with(&mut ResolveDollarCrates { resolver: self }); + fragment.visit_with(&mut ResolveDollarCrates { resolver: self }); } fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index fd55897522bf7..9a04c9d60b868 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -537,11 +537,8 @@ impl<'a> Resolver<'a> { primary_binding: &'a NameBinding<'a>, secondary_binding: &'a NameBinding<'a>) -> &'a NameBinding<'a> { self.arenas.alloc_name_binding(NameBinding { - kind: primary_binding.kind.clone(), ambiguity: Some((secondary_binding, kind)), - vis: primary_binding.vis, - span: primary_binding.span, - expansion: primary_binding.expansion, + ..primary_binding.clone() }) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 2793754e1033a..09e7e57f78cfa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -14,7 +14,6 @@ use parse::token; use ptr::P; use smallvec::SmallVec; use symbol::{keywords, Ident, Symbol}; -use visit::Visitor; use ThinVec; use rustc_data_structures::fx::FxHashMap; @@ -136,17 +135,6 @@ impl Annotatable { _ => false, } } - - pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { - match self { - Annotatable::Item(item) => visitor.visit_item(item), - Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item), - Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item), - Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item), - Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt), - Annotatable::Expr(expr) => visitor.visit_expr(expr), - } - } } // A more flexible ItemDecorator. @@ -742,7 +730,7 @@ pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; - fn resolve_dollar_crates(&mut self, annotatable: &Annotatable); + fn resolve_dollar_crates(&mut self, fragment: &AstFragment); fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, derives: &[Mark]); fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc); @@ -776,7 +764,7 @@ impl Resolver for DummyResolver { fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID } fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() } - fn resolve_dollar_crates(&mut self, _annotatable: &Annotatable) {} + fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {} fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment, _derives: &[Mark]) {} fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc) {} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9369e66cf83da..6e327c6a9dade 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -443,6 +443,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { /// prepares data for resolving paths of macro invocations. fn collect_invocations(&mut self, fragment: AstFragment, derives: &[Mark]) -> (AstFragment, Vec) { + // Resolve `$crate`s in the fragment for pretty-printing. + self.cx.resolver.resolve_dollar_crates(&fragment); + let (fragment_with_placeholders, invocations) = { let mut collector = InvocationCollector { cfg: StripUnconfigured { @@ -574,8 +577,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Some(invoc.fragment_kind.expect_from_annotatables(items)) } AttrProcMacro(ref mac, ..) => { - // Resolve `$crate`s in case we have to go though stringification. - self.cx.resolver.resolve_dollar_crates(&item); self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item { Annotatable::Item(item) => token::NtItem(item), @@ -917,8 +918,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { ProcMacroDerive(ref ext, ..) => { - // Resolve `$crate`s in case we have to go though stringification. - self.cx.resolver.resolve_dollar_crates(&item); invoc.expansion_data.mark.set_expn_info(expn_info); let span = span.with_ctxt(self.cx.backtrace()); let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this diff --git a/src/test/pretty/dollar-crate.pp b/src/test/pretty/dollar-crate.pp new file mode 100644 index 0000000000000..3d2d949be2b2e --- /dev/null +++ b/src/test/pretty/dollar-crate.pp @@ -0,0 +1,18 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use ::std::prelude::v1::*; +#[macro_use] +extern crate std; +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:dollar-crate.pp + +fn main() { + { + ::std::io::_print(::std::fmt::Arguments::new_v1(&["rust\n"], + &match () { + () => [], + })); + }; +} diff --git a/src/test/pretty/dollar-crate.rs b/src/test/pretty/dollar-crate.rs new file mode 100644 index 0000000000000..e46bc7f4859a7 --- /dev/null +++ b/src/test/pretty/dollar-crate.rs @@ -0,0 +1,7 @@ +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:dollar-crate.pp + +fn main() { + println!("rust"); +} From b7f030e114186890612872c89498cbc914c0220f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 19 Jan 2019 16:25:06 -0700 Subject: [PATCH 0338/1064] Bump bootstrap compiler to 1.33 beta --- src/bootstrap/channel.rs | 2 +- src/bootstrap/dist.rs | 2 +- src/bootstrap/lib.rs | 2 +- src/liballoc/benches/vec_deque_append.rs | 1 - src/libcore/intrinsics.rs | 1 - src/libcore/lib.rs | 7 +- src/libcore/mem.rs | 3 - src/libcore/num/bignum.rs | 11 -- src/libcore/num/mod.rs | 134 +---------------------- src/libcore/ops/deref.rs | 2 +- src/libpanic_abort/lib.rs | 1 - src/librustc_mir/lib.rs | 2 - src/libstd/lib.rs | 3 - src/libstd/net/ip.rs | 1 - src/libtest/lib.rs | 1 - src/libunwind/lib.rs | 1 - src/stage0.txt | 2 +- src/tools/linkchecker/main.rs | 6 +- src/tools/tidy/src/features.rs | 2 +- 19 files changed, 16 insertions(+), 168 deletions(-) diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 63741b9b677b4..0b2f62485c9ee 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -14,7 +14,7 @@ use crate::Build; use crate::config::Config; // The version number -pub const CFG_RELEASE_NUM: &str = "1.33.0"; +pub const CFG_RELEASE_NUM: &str = "1.34.0"; pub struct GitInfo { inner: Option, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 98d2fb1e2d039..116b2720f39a4 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -226,7 +226,7 @@ fn make_win_dist( let trim_chars: &[_] = &[' ', '=']; let value = line[(idx + 1)..] - .trim_left_matches(trim_chars) + .trim_start_matches(trim_chars) .split(';') .map(PathBuf::from); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index bddc6362389ad..7491385af7929 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -423,7 +423,7 @@ impl Build { Command::new(&build.initial_rustc).arg("--version").arg("--verbose")); let local_release = local_version_verbose .lines().filter(|x| x.starts_with("release:")) - .next().unwrap().trim_left_matches("release:").trim(); + .next().unwrap().trim_start_matches("release:").trim(); let my_version = channel::CFG_RELEASE_NUM; if local_release.split('.').take(2).eq(my_version.split('.').take(2)) { build.verbose(&format!("auto-detected local-rebuild {}", local_release)); diff --git a/src/liballoc/benches/vec_deque_append.rs b/src/liballoc/benches/vec_deque_append.rs index 2db8fbe130907..78ec91d9e3e9b 100644 --- a/src/liballoc/benches/vec_deque_append.rs +++ b/src/liballoc/benches/vec_deque_append.rs @@ -1,4 +1,3 @@ -#![cfg_attr(stage0, feature(duration_as_u128))] use std::{collections::VecDeque, time::Instant}; const VECDEQUE_LEN: i32 = 100000; diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index db19baf7a2c64..e66a846537043 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -692,7 +692,6 @@ extern "rust-intrinsic" { /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: /// This will statically either panic, or do nothing. - #[cfg(not(stage0))] pub fn panic_if_uninhabited(); /// Creates a value initialized to zero. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index df32cfa337313..45ef7fe70a0e7 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -71,7 +71,6 @@ #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] #![feature(const_fn)] -#![cfg_attr(stage0, feature(const_int_ops))] #![feature(const_fn_union)] #![feature(custom_attribute)] #![feature(doc_cfg)] @@ -112,19 +111,17 @@ #![feature(aarch64_target_feature)] #![feature(wasm_target_feature)] #![feature(avx512_target_feature)] -#![cfg_attr(not(stage0), feature(cmpxchg16b_target_feature))] +#![feature(cmpxchg16b_target_feature)] #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] -#![cfg_attr(stage0, feature(const_let))] -#![cfg_attr(stage0, feature(const_int_rotate))] #![feature(const_int_conversion)] #![feature(const_transmute)] #![feature(reverse_bits)] #![feature(non_exhaustive)] #![feature(structural_match)] #![feature(abi_unadjusted)] -#![cfg_attr(not(stage0), feature(adx_target_feature))] +#![feature(adx_target_feature)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 8fcbb73d9ce46..e661ea3f5037c 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -492,7 +492,6 @@ pub const fn needs_drop() -> bool { #[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::zeroed` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn zeroed() -> T { - #[cfg(not(stage0))] intrinsics::panic_if_uninhabited::(); intrinsics::init() } @@ -626,7 +625,6 @@ pub unsafe fn zeroed() -> T { #[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninitialized` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { - #[cfg(not(stage0))] intrinsics::panic_if_uninhabited::(); intrinsics::uninit() } @@ -1132,7 +1130,6 @@ impl MaybeUninit { #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub unsafe fn into_inner(self) -> T { - #[cfg(not(stage0))] intrinsics::panic_if_uninhabited::(); ManuallyDrop::into_inner(self.value) } diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs index 5326ef1e7c12e..c3a42a0fc0494 100644 --- a/src/libcore/num/bignum.rs +++ b/src/libcore/num/bignum.rs @@ -46,17 +46,6 @@ macro_rules! impl_full_ops { ($($ty:ty: add($addfn:path), mul/div($bigty:ident);)*) => ( $( impl FullOps for $ty { - #[cfg(stage0)] - fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) { - // This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`. - // FIXME: will LLVM optimize this into ADC or similar? - let (v, carry1) = unsafe { intrinsics::add_with_overflow(self, other) }; - let (v, carry2) = unsafe { - intrinsics::add_with_overflow(v, if carry {1} else {0}) - }; - (carry1 || carry2, v) - } - #[cfg(not(stage0))] fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) { // This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`. // FIXME: will LLVM optimize this into ADC or similar? diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 423b800d5852f..7cf2317f4b37f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -281,7 +281,6 @@ $EndFeature, " ``` "), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } } @@ -297,7 +296,6 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_zeros(self) -> u32 { (!self).count_ones() @@ -318,7 +316,6 @@ assert_eq!(n.leading_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn leading_zeros(self) -> u32 { (self as $UnsignedT).leading_zeros() @@ -339,7 +336,6 @@ assert_eq!(n.trailing_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn trailing_zeros(self) -> u32 { (self as $UnsignedT).trailing_zeros() @@ -363,7 +359,6 @@ let m = ", $rot_result, "; assert_eq!(n.rotate_left(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_left(self, n: u32) -> Self { (self as $UnsignedT).rotate_left(n) as Self @@ -388,7 +383,6 @@ let m = ", $rot_op, "; assert_eq!(n.rotate_right(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_right(self, n: u32) -> Self { (self as $UnsignedT).rotate_right(n) as Self @@ -410,7 +404,6 @@ let m = n.swap_bytes(); assert_eq!(m, ", $swapped, "); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn swap_bytes(self) -> Self { (self as $UnsignedT).swap_bytes() as Self @@ -460,7 +453,6 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_be(x: Self) -> Self { #[cfg(target_endian = "big")] @@ -494,7 +486,6 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_le(x: Self) -> Self { #[cfg(target_endian = "little")] @@ -528,7 +519,6 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_be(self) -> Self { // or not to be? #[cfg(target_endian = "big")] @@ -562,7 +552,6 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_le(self) -> Self { #[cfg(target_endian = "little")] @@ -998,14 +987,8 @@ assert_eq!(", stringify!($SelfT), "::max_value().wrapping_add(2), ", stringify!( $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_add(self, rhs: Self) -> Self { - #[cfg(stage0)] - unsafe { - intrinsics::overflowing_add(self, rhs) - } - #[cfg(not(stage0))] intrinsics::overflowing_add(self, rhs) } } @@ -1025,14 +1008,8 @@ stringify!($SelfT), "::max_value());", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_sub(self, rhs: Self) -> Self { - #[cfg(stage0)] - unsafe { - intrinsics::overflowing_sub(self, rhs) - } - #[cfg(not(stage0))] intrinsics::overflowing_sub(self, rhs) } } @@ -1051,14 +1028,8 @@ assert_eq!(11i8.wrapping_mul(12), -124);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { - #[cfg(stage0)] - unsafe { - intrinsics::overflowing_mul(self, rhs) - } - #[cfg(not(stage0))] intrinsics::overflowing_mul(self, rhs) } } @@ -1218,7 +1189,6 @@ assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shl(self, rhs: u32) -> Self { unsafe { @@ -1246,7 +1216,6 @@ assert_eq!((-128i16).wrapping_shr(64), -128);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shr(self, rhs: u32) -> Self { unsafe { @@ -1343,14 +1312,8 @@ assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($Sel "::MIN, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) { - #[cfg(stage0)] - let (a, b) = unsafe { - intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT) - }; - #[cfg(not(stage0))] let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT); (a as Self, b) } @@ -1374,14 +1337,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($Sel "::MAX, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) { - #[cfg(stage0)] - let (a, b) = unsafe { - intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT) - }; - #[cfg(not(stage0))] let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT); (a as Self, b) } @@ -1403,14 +1360,8 @@ assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) { - #[cfg(stage0)] - let (a, b) = unsafe { - intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT) - }; - #[cfg(not(stage0))] let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT); (a as Self, b) } @@ -1594,7 +1545,6 @@ assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) { (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) @@ -1618,7 +1568,6 @@ assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) @@ -2242,13 +2191,9 @@ Basic usage: assert_eq!(n.count_ones(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_ones(self) -> u32 { - #[cfg(stage0)] - unsafe { intrinsics::ctpop(self as $ActualT) as u32 } - #[cfg(not(stage0))] - { intrinsics::ctpop(self as $ActualT) as u32 } + intrinsics::ctpop(self as $ActualT) as u32 } } @@ -2263,7 +2208,6 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_zeros(self) -> u32 { (!self).count_ones() @@ -2283,13 +2227,9 @@ Basic usage: assert_eq!(n.leading_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn leading_zeros(self) -> u32 { - #[cfg(stage0)] - unsafe { intrinsics::ctlz(self as $ActualT) as u32 } - #[cfg(not(stage0))] - { intrinsics::ctlz(self as $ActualT) as u32 } + intrinsics::ctlz(self as $ActualT) as u32 } } @@ -2307,13 +2247,9 @@ Basic usage: assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn trailing_zeros(self) -> u32 { - #[cfg(stage0)] - unsafe { intrinsics::cttz(self) as u32 } - #[cfg(not(stage0))] - { intrinsics::cttz(self) as u32 } + intrinsics::cttz(self) as u32 } } @@ -2334,12 +2270,8 @@ let m = ", $rot_result, "; assert_eq!(n.rotate_left(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_left(self, n: u32) -> Self { - #[cfg(stage0)] - unsafe { intrinsics::rotate_left(self, n as $SelfT) } - #[cfg(not(stage0))] intrinsics::rotate_left(self, n as $SelfT) } } @@ -2362,12 +2294,8 @@ let m = ", $rot_op, "; assert_eq!(n.rotate_right(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_right(self, n: u32) -> Self { - #[cfg(stage0)] - unsafe { intrinsics::rotate_right(self, n as $SelfT) } - #[cfg(not(stage0))] intrinsics::rotate_right(self, n as $SelfT) } } @@ -2387,13 +2315,9 @@ let m = n.swap_bytes(); assert_eq!(m, ", $swapped, "); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn swap_bytes(self) -> Self { - #[cfg(stage0)] - unsafe { intrinsics::bswap(self as $ActualT) as Self } - #[cfg(not(stage0))] - { intrinsics::bswap(self as $ActualT) as Self } + intrinsics::bswap(self as $ActualT) as Self } } @@ -2413,13 +2337,9 @@ let m = n.reverse_bits(); assert_eq!(m, ", $reversed, "); ```"), #[unstable(feature = "reverse_bits", issue = "48763")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_conversion"))] #[inline] pub const fn reverse_bits(self) -> Self { - #[cfg(stage0)] - unsafe { intrinsics::bitreverse(self as $ActualT) as Self } - #[cfg(not(stage0))] - { intrinsics::bitreverse(self as $ActualT) as Self } + intrinsics::bitreverse(self as $ActualT) as Self } } @@ -2443,7 +2363,6 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_be(x: Self) -> Self { #[cfg(target_endian = "big")] @@ -2477,7 +2396,6 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_le(x: Self) -> Self { #[cfg(target_endian = "little")] @@ -2511,7 +2429,6 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_be(self) -> Self { // or not to be? #[cfg(target_endian = "big")] @@ -2545,7 +2462,6 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_le(self) -> Self { #[cfg(target_endian = "little")] @@ -2918,14 +2834,8 @@ assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::ma $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_add(self, rhs: Self) -> Self { - #[cfg(stage0)] - unsafe { - intrinsics::overflowing_add(self, rhs) - } - #[cfg(not(stage0))] intrinsics::overflowing_add(self, rhs) } } @@ -2944,14 +2854,8 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::ma $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_sub(self, rhs: Self) -> Self { - #[cfg(stage0)] - unsafe { - intrinsics::overflowing_sub(self, rhs) - } - #[cfg(not(stage0))] intrinsics::overflowing_sub(self, rhs) } } @@ -2971,14 +2875,8 @@ $EndFeature, " /// assert_eq!(25u8.wrapping_mul(12), 44); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { - #[cfg(stage0)] - unsafe { - intrinsics::overflowing_mul(self, rhs) - } - #[cfg(not(stage0))] intrinsics::overflowing_mul(self, rhs) } @@ -3124,7 +3022,6 @@ Basic usage: assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shl(self, rhs: u32) -> Self { unsafe { @@ -3154,7 +3051,6 @@ Basic usage: assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shr(self, rhs: u32) -> Self { unsafe { @@ -3218,14 +3114,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false)); assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) { - #[cfg(stage0)] - let (a, b) = unsafe { - intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT) - }; - #[cfg(not(stage0))] let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT); (a as Self, b) } @@ -3250,14 +3140,8 @@ assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) { - #[cfg(stage0)] - let (a, b) = unsafe { - intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT) - }; - #[cfg(not(stage0))] let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT); (a as Self, b) } @@ -3281,14 +3165,8 @@ $EndFeature, " /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true)); /// ``` #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) { - #[cfg(stage0)] - let (a, b) = unsafe { - intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT) - }; - #[cfg(not(stage0))] let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT); (a as Self, b) } @@ -3447,7 +3325,6 @@ Basic usage assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) { (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) @@ -3472,7 +3349,6 @@ Basic usage assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))] #[inline] pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs index 075c3a084f41d..42bb5cabb48cd 100644 --- a/src/libcore/ops/deref.rs +++ b/src/libcore/ops/deref.rs @@ -171,7 +171,7 @@ impl DerefMut for &mut T { /// Indicates that a struct can be used as a method receiver, without the /// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box`, /// `Rc`, `&T`, and `Pin

`. -#[cfg_attr(not(stage0), lang = "receiver")] +#[lang = "receiver"] #[unstable(feature = "receiver_trait", issue = "0")] #[doc(hidden)] pub trait Receiver { diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 8832a16d4ca4e..f6306d23c30c0 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -12,7 +12,6 @@ #![panic_runtime] #![allow(unused_features)] -#![cfg_attr(stage0, feature(cfg_target_vendor))] #![feature(core_intrinsics)] #![feature(libc)] #![feature(nll)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 9395da60b3886..ccfc15bac042c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,10 +24,8 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(unicode_internals)] #![feature(step_trait)] #![feature(slice_concat_ext)] -#![cfg_attr(stage0, feature(if_while_or_patterns))] #![feature(try_from)] #![feature(reverse_bits)] -#![cfg_attr(stage0, feature(underscore_imports))] #![recursion_limit="256"] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 82f3463dba0fc..c94a33da03790 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -234,12 +234,9 @@ #![feature(c_variadic)] #![feature(cfg_target_has_atomic)] #![feature(cfg_target_thread_local)] -#![cfg_attr(stage0, feature(cfg_target_vendor))] #![feature(char_error_internals)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] -#![cfg_attr(stage0, feature(const_int_ops))] -#![cfg_attr(stage0, feature(const_ip))] #![feature(const_raw_ptr_deref)] #![feature(const_cstr_unchecked)] #![feature(core_intrinsics)] diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index f98113e0896f7..f45cd8b8c101a 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -328,7 +328,6 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(stage0, rustc_const_unstable(feature = "const_ip"))] pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { Ipv4Addr { inner: c::in_addr { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 2cc80ddea2df4..7547814129d6c 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -23,7 +23,6 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] #![feature(asm)] -#![cfg_attr(stage0, feature(cfg_target_vendor))] #![feature(fnbox)] #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))] #![feature(nll)] diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index 7ed7837268dcd..5f9c82431b786 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -1,7 +1,6 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] -#![cfg_attr(stage0, feature(cfg_target_vendor))] #![feature(link_cfg)] #![feature(nll)] #![feature(staged_api)] diff --git a/src/stage0.txt b/src/stage0.txt index 2e376ed1cede5..36d30b7d27342 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2019-01-04 +date: 2019-01-18 rustc: beta cargo: beta diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 59662be349dcb..2cf0fcfd34cd6 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -78,7 +78,7 @@ impl FileEntry { fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut bool) { if self.ids.is_empty() { with_attrs_in_source(contents, " id", |fragment, i, _| { - let frag = fragment.trim_left_matches("#").to_owned(); + let frag = fragment.trim_start_matches("#").to_owned(); let encoded = small_url_encode(&frag); if !self.ids.insert(frag) { *errors = true; @@ -343,7 +343,7 @@ fn with_attrs_in_source(contents: &str, attr: &str, Some(i) => i, None => continue, }; - if rest[..pos_equals].trim_left_matches(" ") != "" { + if rest[..pos_equals].trim_start_matches(" ") != "" { continue; } @@ -355,7 +355,7 @@ fn with_attrs_in_source(contents: &str, attr: &str, }; let quote_delim = rest.as_bytes()[pos_quote] as char; - if rest[..pos_quote].trim_left_matches(" ") != "" { + if rest[..pos_quote].trim_start_matches(" ") != "" { continue; } let rest = &rest[pos_quote + 1..]; diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 16f2e3ba27dbb..7126c0c2f6ecf 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -188,7 +188,7 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features { } let mut parts = line.split(','); - let level = match parts.next().map(|l| l.trim().trim_left_matches('(')) { + let level = match parts.next().map(|l| l.trim().trim_start_matches('(')) { Some("active") => Status::Unstable, Some("removed") => Status::Removed, Some("accepted") => Status::Stable, From 2d21df8a3fd7a68ba9f52389ead7f06f13190c12 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 21 Jan 2019 17:47:57 -0700 Subject: [PATCH 0339/1064] Workaround presence of LLVM library in stage0/lib This commit works around the newly-introduced LLVM shared library. This is needed such that llvm-config run from librustc_llvm's build script can correctly locate it's own LLVM, not the one in stage0/lib. The LLVM build system uses the DT_RUNPATH/RUNPATH header within the llvm-config binary, which we want to use, but because Cargo always adds the host compiler's "libdir" (stage0/lib in our case) to the dynamic linker's search path, we weren't properly finding the freshly-built LLVM in llvm/lib. By restoring the environment variable setting the search path to what bootstrap sees, the problem is resolved and librustc_llvm correctly links and finds the appropriate LLVM. Several run-make-fulldeps tests are also updated with similar handling. --- src/bootstrap/builder.rs | 9 ++++++++- src/bootstrap/compile.rs | 1 + src/bootstrap/util.rs | 6 +++++- src/build_helper/lib.rs | 19 +++++++++++++++++++ src/librustc_asan/build.rs | 2 ++ src/librustc_llvm/build.rs | 2 ++ src/librustc_lsan/build.rs | 2 ++ src/librustc_msan/build.rs | 2 ++ src/librustc_tsan/build.rs | 2 ++ .../cross-lang-lto-upstream-rlibs/Makefile | 4 ++-- .../run-make-fulldeps/cross-lang-lto/Makefile | 19 ++++++++++--------- 11 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a69ba207495ae..f742bce180c05 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -21,7 +21,7 @@ use crate::install; use crate::native; use crate::test; use crate::tool; -use crate::util::{add_lib_path, exe, libdir}; +use crate::util::{self, add_lib_path, exe, libdir}; use crate::{Build, DocTests, Mode, GitRepo}; pub use crate::Compiler; @@ -791,6 +791,13 @@ impl<'a> Builder<'a> { .env("CARGO_TARGET_DIR", out_dir) .arg(cmd); + // See comment in librustc_llvm/build.rs for why this is necessary, largely llvm-config + // needs to not accidentally link to libLLVM in stage0/lib. + cargo.env("REAL_LIBRARY_PATH_VAR", &util::dylib_path_var()); + if let Some(e) = env::var_os(util::dylib_path_var()) { + cargo.env("REAL_LIBRARY_PATH", e); + } + if cmd != "install" { cargo.arg("--target") .arg(target); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b581271663e7e..ec04dee6c32f0 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -712,6 +712,7 @@ pub fn build_codegen_backend(builder: &Builder, if builder.is_rust_llvm(target) && backend != "emscripten" { cargo.env("LLVM_RUSTLLVM", "1"); } + cargo.env("LLVM_CONFIG", &llvm_config); if backend != "emscripten" { let target_config = builder.config.target_config.get(&target); diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 2880f1a084be0..37c6c040da8e8 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -70,7 +70,11 @@ pub fn dylib_path_var() -> &'static str { /// Parses the `dylib_path_var()` environment variable, returning a list of /// paths that are members of this lookup path. pub fn dylib_path() -> Vec { - env::split_paths(&env::var_os(dylib_path_var()).unwrap_or_default()).collect() + let var = match env::var_os(dylib_path_var()) { + Some(v) => v, + None => return vec![], + }; + env::split_paths(&var).collect() } /// `push` all components to `buf`. On windows, append `.exe` to the last component. diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 5a704e557751d..c66c5c9249087 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -23,6 +23,25 @@ macro_rules! t { }; } +// Because Cargo adds the compiler's dylib path to our library search path, llvm-config may +// break: the dylib path for the compiler, as of this writing, contains a copy of the LLVM +// shared library, which means that when our freshly built llvm-config goes to load it's +// associated LLVM, it actually loads the compiler's LLVM. In particular when building the first +// compiler (i.e., in stage 0) that's a problem, as the compiler's LLVM is likely different from +// the one we want to use. As such, we restore the environment to what bootstrap saw. This isn't +// perfect -- we might actually want to see something from Cargo's added library paths -- but +// for now it works. +pub fn restore_library_path() { + println!("cargo:rerun-if-env-changed=REAL_LIBRARY_PATH_VAR"); + println!("cargo:rerun-if-env-changed=REAL_LIBRARY_PATH"); + let key = env::var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); + if let Some(env) = env::var_os("REAL_LIBRARY_PATH") { + env::set_var(&key, &env); + } else { + env::remove_var(&key); + } +} + pub fn run(cmd: &mut Command) { println!("running: {:?}", cmd); run_silent(cmd); diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs index 2d921b666944b..b42d775deb393 100644 --- a/src/librustc_asan/build.rs +++ b/src/librustc_asan/build.rs @@ -8,6 +8,8 @@ use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + build_helper::restore_library_path(); + let (native, target) = match sanitizer_lib_boilerplate("asan") { Ok(native) => native, _ => return, diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index ec3dff783c47b..cd91fcb2995ee 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -24,6 +24,8 @@ fn main() { return; } + build_helper::restore_library_path(); + let target = env::var("TARGET").expect("TARGET was not set"); let llvm_config = env::var_os("LLVM_CONFIG") .map(PathBuf::from) diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs index 470f2bb3e5c85..ad528bb03902c 100644 --- a/src/librustc_lsan/build.rs +++ b/src/librustc_lsan/build.rs @@ -8,6 +8,8 @@ use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + build_helper::restore_library_path(); + let (native, target) = match sanitizer_lib_boilerplate("lsan") { Ok(native) => native, _ => return, diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs index e1140278f2b4e..085514b5a0108 100644 --- a/src/librustc_msan/build.rs +++ b/src/librustc_msan/build.rs @@ -8,6 +8,8 @@ use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + build_helper::restore_library_path(); + let (native, target) = match sanitizer_lib_boilerplate("msan") { Ok(native) => native, _ => return, diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs index f63bb46b87468..0db3db392dddc 100644 --- a/src/librustc_tsan/build.rs +++ b/src/librustc_tsan/build.rs @@ -8,6 +8,8 @@ use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + build_helper::restore_library_path(); + let (native, target) = match sanitizer_lib_boilerplate("tsan") { Ok(native) => native, _ => return, diff --git a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile index 0a6f226a027f3..6992dab1a1bf1 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile @@ -9,7 +9,7 @@ all: staticlib.rs upstream.rs # Check No LTO $(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -L. -o $(TMPDIR)/staticlib.a - (cd $(TMPDIR); llvm-ar x ./staticlib.a) + (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a) # Make sure the upstream object file was included ls $(TMPDIR)/upstream.*.rcgu.o @@ -19,5 +19,5 @@ all: staticlib.rs upstream.rs # Check ThinLTO $(RUSTC) upstream.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin $(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a - (cd $(TMPDIR); llvm-ar x ./staticlib.a) + (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a) ls $(TMPDIR)/upstream.*.rcgu.o diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile index 1d072e03de307..4d1fb7b953739 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile @@ -5,8 +5,9 @@ # LLVM bitcode files (as used by linker LTO plugins) when compiling with # -Z cross-lang-lto. -ASSERT_IS_BITCODE_OBJ=llvm-bcanalyzer # this only succeeds for bitcode files -EXTRACT_OBJS=(cd $(TMPDIR); rm -f ./*.o; llvm-ar x $(1)) +# this only succeeds for bitcode files +ASSERT_IS_BITCODE_OBJ=($(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-bcanalyzer $(1)) +EXTRACT_OBJS=(cd $(TMPDIR); rm -f ./*.o; $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x $(1)) BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 --emit=obj @@ -16,31 +17,31 @@ all: staticlib staticlib-fat-lto staticlib-thin-lto rlib exe cdylib rdylib staticlib: lib.rs $(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib.a $(call EXTRACT_OBJS, liblib.a) - for file in $(TMPDIR)/liblib.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done + for file in $(TMPDIR)/liblib.*.rcgu.o; do $(call ASSERT_IS_BITCODE_OBJ, $$file); done staticlib-fat-lto: lib.rs $(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib-fat-lto.a -Clto=fat $(call EXTRACT_OBJS, liblib-fat-lto.a) - for file in $(TMPDIR)/liblib-fat-lto.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done + for file in $(TMPDIR)/liblib-fat-lto.*.rcgu.o; do $(call ASSERT_IS_BITCODE_OBJ, $$file); done staticlib-thin-lto: lib.rs $(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib-thin-lto.a -Clto=thin $(call EXTRACT_OBJS, liblib-thin-lto.a) - for file in $(TMPDIR)/liblib-thin-lto.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done + for file in $(TMPDIR)/liblib-thin-lto.*.rcgu.o; do $(call ASSERT_IS_BITCODE_OBJ, $$file); done rlib: lib.rs $(BUILD_LIB) --crate-type=rlib -o $(TMPDIR)/liblib.rlib $(call EXTRACT_OBJS, liblib.rlib) - for file in $(TMPDIR)/liblib.*.rcgu.o; do $(ASSERT_IS_BITCODE_OBJ) $$file; done + for file in $(TMPDIR)/liblib.*.rcgu.o; do $(call ASSERT_IS_BITCODE_OBJ, $$file); done cdylib: lib.rs $(BUILD_LIB) --crate-type=cdylib --emit=obj -o $(TMPDIR)/cdylib.o - $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/cdylib.o + $(call ASSERT_IS_BITCODE_OBJ, $(TMPDIR)/cdylib.o) rdylib: lib.rs $(BUILD_LIB) --crate-type=dylib --emit=obj -o $(TMPDIR)/rdylib.o - $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/rdylib.o + $(call ASSERT_IS_BITCODE_OBJ, $(TMPDIR)/rdylib.o) exe: lib.rs $(BUILD_EXE) -o $(TMPDIR)/exe.o - $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/exe.o + $(call ASSERT_IS_BITCODE_OBJ, $(TMPDIR)/exe.o) From abe36c4741e780ba3ed3e9b48d823ac8007f786a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 24 Jan 2019 12:17:02 -0700 Subject: [PATCH 0340/1064] Ignore LLVM-dependent run-make tests on Windows This should solve the PATH issue, and we don't need to test cross-lang LTO working on all OS-es. --- .../cross-lang-lto-upstream-rlibs/Makefile | 11 ++++++++++- src/test/run-make-fulldeps/cross-lang-lto/Makefile | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile index 6992dab1a1bf1..4f33b1c59e084 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile @@ -1,6 +1,9 @@ - -include ../tools.mk +# ignore windows due to libLLVM being present in PATH and the PATH and library path being the same +# (so fixing it is harder). See #57765 for context +ifndef IS_WINDOWS + # This test makes sure that we don't loose upstream object files when compiling # staticlibs with -Zcross-lang-lto @@ -21,3 +24,9 @@ all: staticlib.rs upstream.rs $(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a (cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a) ls $(TMPDIR)/upstream.*.rcgu.o + +else + +all: + +endif diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile index 4d1fb7b953739..57a19a0ccb037 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile @@ -1,6 +1,10 @@ -include ../tools.mk +# ignore windows due to libLLVM being present in PATH and the PATH and library path being the same +# (so fixing it is harder). See #57765 for context +ifndef IS_WINDOWS + # This test makes sure that the object files we generate are actually # LLVM bitcode files (as used by linker LTO plugins) when compiling with # -Z cross-lang-lto. @@ -45,3 +49,9 @@ rdylib: lib.rs exe: lib.rs $(BUILD_EXE) -o $(TMPDIR)/exe.o $(call ASSERT_IS_BITCODE_OBJ, $(TMPDIR)/exe.o) + +else + +all: + +endif From 8db66ca53e9521f5ff52541e5793652688c3c367 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 26 Jan 2019 12:54:09 -0500 Subject: [PATCH 0341/1064] use `SOURCE_DATE_EPOCH` for man page time if set --- src/bootstrap/dist.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 98d2fb1e2d039..c41df3209c8ff 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -23,7 +23,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::compile; use crate::tool::{self, Tool}; use crate::cache::{INTERNER, Interned}; -use time; +use time::{self, Timespec}; pub fn pkgname(builder: &Builder, component: &str) -> String { if component == "cargo" { @@ -528,7 +528,19 @@ impl Step for Rustc { t!(fs::create_dir_all(image.join("share/man/man1"))); let man_src = builder.src.join("src/doc/man"); let man_dst = image.join("share/man/man1"); - let month_year = t!(time::strftime("%B %Y", &time::now())); + + // Reproducible builds: If SOURCE_DATE_EPOCH is set, use that as the time. + let time = env::var("SOURCE_DATE_EPOCH") + .map(|timestamp| { + let epoch = timestamp.parse().map_err(|err| { + format!("could not parse SOURCE_DATE_EPOCH: {}", err) + }).unwrap(); + + time::at(Timespec::new(epoch, 0)) + }) + .unwrap_or_else(|_| time::now()); + + let month_year = t!(time::strftime("%B %Y", &time)); // don't use our `bootstrap::util::{copy, cp_r}`, because those try // to hardlink, and we don't want to edit the source templates for file_entry in builder.read_dir(&man_src) { From 607c5431ae90caed561ca6a8f4846bfa4b953689 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sat, 26 Jan 2019 16:42:42 -0500 Subject: [PATCH 0342/1064] Enable RISC-V atomic compare and swap --- src/librustc_target/spec/riscv32imac_unknown_none_elf.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs index b199a50f0ca38..f05a5712f5acf 100644 --- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs @@ -28,7 +28,7 @@ pub fn target() -> TargetResult { linker: Some("rust-lld".to_string()), cpu: "generic-rv32".to_string(), max_atomic_width: Some(32), - atomic_cas: false, // incomplete +a extension + atomic_cas: true, features: "+m,+a,+c".to_string(), executables: true, panic_strategy: PanicStrategy::Abort, From b4d3c87ebc32ed4b96dc64cc9b45758e356df17a Mon Sep 17 00:00:00 2001 From: Simon Heath Date: Sat, 26 Jan 2019 16:46:15 -0500 Subject: [PATCH 0343/1064] Tiny improvement to docs for `core::convert`. This is not really significant, accept or reject as you wish. I just want to make sure I understand how the PR process works and I'm doing it right before doing a bigger one for #33417. --- src/libcore/convert.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 203be541e492f..d4a1d15e4e7e1 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -17,7 +17,10 @@ //! [`TryFrom`][`TryFrom`] rather than [`Into`][`Into`] or [`TryInto`][`TryInto`], //! as [`From`] and [`TryFrom`] provide greater flexibility and offer //! equivalent [`Into`] or [`TryInto`] implementations for free, thanks to a -//! blanket implementation in the standard library. +//! blanket implementation in the standard library. However, there are some cases +//! where this is not possible, such as creating conversions into a type defined +//! outside your library, so implementing [`Into`] instead of [`From`] is +//! sometimes necessary. //! //! # Generic Implementations //! From 9c9144fc1bed833663b26219e735c83708ac6821 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sat, 26 Jan 2019 21:52:20 +0000 Subject: [PATCH 0344/1064] Remove lexical scope examples from std::mem::drop The example no longer produces an error in the 2018 edition --- src/libcore/mem.rs | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 9e100d0a58d17..0b6fb0db1d6f7 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -713,8 +713,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// Disposes of a value. /// -/// While this does call the argument's implementation of [`Drop`][drop], -/// it will not release any borrows, as borrows are based on lexical scope. +/// This does call the argument's implementation of [`Drop`][drop]. /// /// This effectively does nothing for types which implement `Copy`, e.g. /// integers. Such values are copied and _then_ moved into the function, so the @@ -741,32 +740,6 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// drop(v); // explicitly drop the vector /// ``` /// -/// Borrows are based on lexical scope, so this produces an error: -/// -/// ```compile_fail,E0502 -/// let mut v = vec![1, 2, 3]; -/// let x = &v[0]; -/// -/// drop(x); // explicitly drop the reference, but the borrow still exists -/// -/// v.push(4); // error: cannot borrow `v` as mutable because it is also -/// // borrowed as immutable -/// ``` -/// -/// An inner scope is needed to fix this: -/// -/// ``` -/// let mut v = vec![1, 2, 3]; -/// -/// { -/// let x = &v[0]; -/// -/// drop(x); // this is now redundant, as `x` is going out of scope anyway -/// } -/// -/// v.push(4); // no problems -/// ``` -/// /// Since [`RefCell`] enforces the borrow rules at runtime, `drop` can /// release a [`RefCell`] borrow: /// From 7a58c6d1deec25c37c93ae4cf9ec2432918bc360 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 26 Jan 2019 09:14:49 -0700 Subject: [PATCH 0345/1064] Replace deprecated ATOMIC_INIT consts --- src/liballoc/tests/binary_heap.rs | 4 +- src/liballoc/tests/slice.rs | 4 +- src/libcore/sync/atomic.rs | 5 +-- src/librustc_driver/lib.rs | 4 +- src/librustc_mir/diagnostics.rs | 8 ++-- src/libstd/alloc.rs | 4 +- src/libstd/sys/redox/thread_local.rs | 4 +- src/libstd/sys/sgx/abi/tls.rs | 41 +++++++++++++++++-- src/libstd/sys/unix/pipe.rs | 4 +- src/libstd/sys/windows/pipe.rs | 4 +- .../allocator/auxiliary/custom-as-global.rs | 4 +- src/test/run-pass/allocator/custom.rs | 4 +- src/test/run-pass/allocator/xcrate-use.rs | 4 +- src/test/run-pass/allocator/xcrate-use2.rs | 5 +-- src/test/run-pass/atomic-access-bool.rs | 4 +- src/test/run-pass/atomic-compare_exchange.rs | 4 +- .../run-pass/deriving/deriving-copyclone.rs | 5 +-- .../run-pass/generator/conditional-drop.rs | 4 +- src/test/run-pass/generator/drop-env.rs | 4 +- src/test/run-pass/generator/panic-drops.rs | 4 +- src/test/run-pass/issues/issue-34053.rs | 4 +- src/test/run-pass/mir/mir_fat_ptr_drop.rs | 2 +- .../panics/panic-recover-propagate.rs | 4 +- .../threads-sendsync/tls-init-on-init.rs | 4 +- .../issue-47215-ice-from-drop-elab.rs | 2 +- src/test/ui/error-codes/E0492.rs | 4 +- src/tools/remote-test-server/src/main.rs | 4 +- 27 files changed, 89 insertions(+), 59 deletions(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 6af1cf4080947..94ae43237d19c 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -2,7 +2,7 @@ use std::cmp; use std::collections::BinaryHeap; use std::collections::binary_heap::{Drain, PeekMut}; use std::panic::{self, AssertUnwindSafe}; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; use rand::{thread_rng, seq::SliceRandom}; @@ -283,7 +283,7 @@ fn assert_covariance() { // Destructors must be called exactly once per element. #[test] fn panic_safe() { - static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; + static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); #[derive(Eq, PartialEq, Ord, Clone, Debug)] struct PanicOrd(T, bool); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 8ecd17236c048..0300bd7f3f6d4 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -5,7 +5,7 @@ use std::mem; use std::panic; use std::rc::Rc; use std::sync::atomic::Ordering::Relaxed; -use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize}; +use std::sync::atomic::AtomicUsize; use std::thread; use rand::{Rng, RngCore, thread_rng, seq::SliceRandom}; @@ -1500,7 +1500,7 @@ static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [ AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), ]; -static VERSIONS: AtomicUsize = ATOMIC_USIZE_INIT; +static VERSIONS: AtomicUsize = AtomicUsize::new(0); #[derive(Clone, Eq)] struct DropCounter { diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index b9ebf19b23cab..bcedff5abc70c 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -2413,12 +2413,11 @@ pub fn fence(order: Ordering) { /// /// ``` /// use std::sync::atomic::{AtomicBool, AtomicUsize}; -/// use std::sync::atomic::{ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT}; /// use std::sync::atomic::Ordering; /// use std::sync::atomic::compiler_fence; /// -/// static IMPORTANT_VARIABLE: AtomicUsize = ATOMIC_USIZE_INIT; -/// static IS_READY: AtomicBool = ATOMIC_BOOL_INIT; +/// static IMPORTANT_VARIABLE: AtomicUsize = AtomicUsize::new(0); +/// static IS_READY: AtomicBool = AtomicBool::new(false); /// /// fn main() { /// IMPORTANT_VARIABLE.store(42, Ordering::Relaxed); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index abcdf175ada99..a95ce810ffaeb 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -91,7 +91,7 @@ use std::panic; use std::path::{PathBuf, Path}; use std::process::{self, Command, Stdio}; use std::str; -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Once, ONCE_INIT}; use std::thread; @@ -254,7 +254,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { // general this assertion never trips due to the once guard in `get_codegen_backend`, // but there's a few manual calls to this function in this file we protect // against. - static LOADED: AtomicBool = ATOMIC_BOOL_INIT; + static LOADED: AtomicBool = AtomicBool::new(false); assert!(!LOADED.fetch_or(true, Ordering::SeqCst), "cannot load the default codegen backend twice"); diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index ea9e19c75c215..74394165a5f84 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -1127,9 +1127,9 @@ A borrow of a constant containing interior mutability was attempted. Erroneous code example: ```compile_fail,E0492 -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; +use std::sync::atomic::AtomicUsize; -const A: AtomicUsize = ATOMIC_USIZE_INIT; +const A: AtomicUsize = AtomicUsize::new(0); static B: &'static AtomicUsize = &A; // error: cannot borrow a constant which may contain interior mutability, // create a static instead @@ -1145,9 +1145,9 @@ explicitly a single memory location, which can be mutated at will. So, in order to solve this error, either use statics which are `Sync`: ``` -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; +use std::sync::atomic::AtomicUsize; -static A: AtomicUsize = ATOMIC_USIZE_INIT; +static A: AtomicUsize = AtomicUsize::new(0); static B: &'static AtomicUsize = &A; // ok! ``` diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 537f56a8da71d..8b6e5680c2d6c 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -95,11 +95,11 @@ pub use alloc_crate::alloc::*; /// /// ```rust /// use std::alloc::{System, GlobalAlloc, Layout}; -/// use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering::SeqCst}; +/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; /// /// struct Counter; /// -/// static ALLOCATED: AtomicUsize = ATOMIC_USIZE_INIT; +/// static ALLOCATED: AtomicUsize = AtomicUsize::new(0); /// /// unsafe impl GlobalAlloc for Counter { /// unsafe fn alloc(&self, layout: Layout) -> *mut u8 { diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs index a1c4b10e45063..a1929b941659d 100644 --- a/src/libstd/sys/redox/thread_local.rs +++ b/src/libstd/sys/redox/thread_local.rs @@ -2,13 +2,13 @@ use collections::BTreeMap; use ptr; -use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use sync::atomic::{AtomicUsize, Ordering}; pub type Key = usize; type Dtor = unsafe extern fn(*mut u8); -static NEXT_KEY: AtomicUsize = ATOMIC_USIZE_INIT; +static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); static mut KEYS: *mut BTreeMap> = ptr::null_mut(); diff --git a/src/libstd/sys/sgx/abi/tls.rs b/src/libstd/sys/sgx/abi/tls.rs index aba93db915fe8..b8e09d58debad 100644 --- a/src/libstd/sys/sgx/abi/tls.rs +++ b/src/libstd/sys/sgx/abi/tls.rs @@ -1,4 +1,4 @@ -use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use sync::atomic::{AtomicUsize, Ordering}; use ptr; use mem; use cell::Cell; @@ -15,7 +15,40 @@ macro_rules! dup { ((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* )); (() $($val:tt)*) => ([$($val),*]) } -static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) ATOMIC_USIZE_INIT); +static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = [ + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), +]; extern "C" { fn get_tls_ptr() -> *const u8; @@ -119,7 +152,7 @@ impl Tls { } mod sync_bitset { - use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + use sync::atomic::{AtomicUsize, Ordering}; use iter::{Enumerate, Peekable}; use slice::Iter; use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS}; @@ -128,7 +161,7 @@ mod sync_bitset { pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]); pub(super) const SYNC_BITSET_INIT: SyncBitset = - SyncBitset([ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT]); + SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]); impl SyncBitset { pub fn get(&self, index: usize) -> bool { diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 91793a0d5ec3f..a746d982c6ca9 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -1,7 +1,7 @@ use io; use libc::{self, c_int}; use mem; -use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; +use sync::atomic::{AtomicBool, Ordering}; use sys::fd::FileDesc; use sys::{cvt, cvt_r}; @@ -13,7 +13,7 @@ pub struct AnonPipe(FileDesc); pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { syscall! { fn pipe2(fds: *mut c_int, flags: c_int) -> c_int } - static INVALID: AtomicBool = ATOMIC_BOOL_INIT; + static INVALID: AtomicBool = AtomicBool::new(false); let mut fds = [0; 2]; diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 2b1dbe310eea4..0d9195a5c9716 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -7,7 +7,7 @@ use path::Path; use ptr; use slice; use sync::atomic::Ordering::SeqCst; -use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; +use sync::atomic::AtomicUsize; use sys::c; use sys::fs::{File, OpenOptions}; use sys::handle::Handle; @@ -148,7 +148,7 @@ pub fn anon_pipe(ours_readable: bool) -> io::Result { } fn random_number() -> usize { - static N: AtomicUsize = ATOMIC_USIZE_INIT; + static N: AtomicUsize = AtomicUsize::new(0); loop { if N.load(SeqCst) != 0 { return N.fetch_add(1, SeqCst) diff --git a/src/test/run-pass/allocator/auxiliary/custom-as-global.rs b/src/test/run-pass/allocator/auxiliary/custom-as-global.rs index 6842e2c33b217..a5e96e7750184 100644 --- a/src/test/run-pass/allocator/auxiliary/custom-as-global.rs +++ b/src/test/run-pass/allocator/auxiliary/custom-as-global.rs @@ -4,12 +4,12 @@ extern crate custom; -use std::sync::atomic::{ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; use custom::A; #[global_allocator] -static ALLOCATOR: A = A(ATOMIC_USIZE_INIT); +static ALLOCATOR: A = A(AtomicUsize::new(0)); pub fn get() -> usize { ALLOCATOR.0.load(Ordering::SeqCst) diff --git a/src/test/run-pass/allocator/custom.rs b/src/test/run-pass/allocator/custom.rs index a8c6e0325e126..71f72ae46c23f 100644 --- a/src/test/run-pass/allocator/custom.rs +++ b/src/test/run-pass/allocator/custom.rs @@ -8,9 +8,9 @@ extern crate helper; use std::alloc::{self, Global, Alloc, System, Layout}; -use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; +use std::sync::atomic::{AtomicUsize, Ordering}; -static HITS: AtomicUsize = ATOMIC_USIZE_INIT; +static HITS: AtomicUsize = AtomicUsize::new(0); struct A; diff --git a/src/test/run-pass/allocator/xcrate-use.rs b/src/test/run-pass/allocator/xcrate-use.rs index eb911a62e91cb..039c70e77bedf 100644 --- a/src/test/run-pass/allocator/xcrate-use.rs +++ b/src/test/run-pass/allocator/xcrate-use.rs @@ -10,10 +10,10 @@ extern crate custom; extern crate helper; use std::alloc::{Global, Alloc, System, Layout}; -use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT}; +use std::sync::atomic::{Ordering, AtomicUsize}; #[global_allocator] -static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT); +static GLOBAL: custom::A = custom::A(AtomicUsize::new(0)); fn main() { unsafe { diff --git a/src/test/run-pass/allocator/xcrate-use2.rs b/src/test/run-pass/allocator/xcrate-use2.rs index be657f127bbc2..d8478fb5eaa41 100644 --- a/src/test/run-pass/allocator/xcrate-use2.rs +++ b/src/test/run-pass/allocator/xcrate-use2.rs @@ -12,9 +12,9 @@ extern crate custom_as_global; extern crate helper; use std::alloc::{alloc, dealloc, GlobalAlloc, System, Layout}; -use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT}; +use std::sync::atomic::{AtomicUsize, Ordering}; -static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT); +static GLOBAL: custom::A = custom::A(AtomicUsize::new(0)); fn main() { unsafe { @@ -45,4 +45,3 @@ fn main() { assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2); } } - diff --git a/src/test/run-pass/atomic-access-bool.rs b/src/test/run-pass/atomic-access-bool.rs index 4f804bcdef235..8522493232f98 100644 --- a/src/test/run-pass/atomic-access-bool.rs +++ b/src/test/run-pass/atomic-access-bool.rs @@ -1,9 +1,9 @@ #![allow(stable_features)] #![feature(atomic_access)] -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT}; +use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering::*; -static mut ATOMIC: AtomicBool = ATOMIC_BOOL_INIT; +static mut ATOMIC: AtomicBool = AtomicBool::new(false); fn main() { unsafe { diff --git a/src/test/run-pass/atomic-compare_exchange.rs b/src/test/run-pass/atomic-compare_exchange.rs index c7b80c42c1baa..77da820e07c56 100644 --- a/src/test/run-pass/atomic-compare_exchange.rs +++ b/src/test/run-pass/atomic-compare_exchange.rs @@ -1,10 +1,10 @@ #![allow(stable_features)] #![feature(extended_compare_and_swap)] -use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; +use std::sync::atomic::AtomicIsize; use std::sync::atomic::Ordering::*; -static ATOMIC: AtomicIsize = ATOMIC_ISIZE_INIT; +static ATOMIC: AtomicIsize = AtomicIsize::new(0); fn main() { // Make sure codegen can emit all the intrinsics correctly diff --git a/src/test/run-pass/deriving/deriving-copyclone.rs b/src/test/run-pass/deriving/deriving-copyclone.rs index cdeb5d03d35c6..78d74a11ffc8b 100644 --- a/src/test/run-pass/deriving/deriving-copyclone.rs +++ b/src/test/run-pass/deriving/deriving-copyclone.rs @@ -2,7 +2,7 @@ //! Test that #[derive(Copy, Clone)] produces a shallow copy //! even when a member violates RFC 1521 -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; +use std::sync::atomic::{AtomicBool, Ordering}; /// A struct that pretends to be Copy, but actually does something /// in its Clone impl @@ -10,7 +10,7 @@ use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; struct Liar; /// Static cooperating with the rogue Clone impl -static CLONED: AtomicBool = ATOMIC_BOOL_INIT; +static CLONED: AtomicBool = AtomicBool::new(false); impl Clone for Liar { fn clone(&self) -> Self { @@ -36,4 +36,3 @@ fn main() { // if Innocent was byte-for-byte copied, CLONED will still be false assert!(!CLONED.load(Ordering::SeqCst)); } - diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/run-pass/generator/conditional-drop.rs index b7d7681d25c9e..766eef9e3f3c3 100644 --- a/src/test/run-pass/generator/conditional-drop.rs +++ b/src/test/run-pass/generator/conditional-drop.rs @@ -3,9 +3,9 @@ #![feature(generators, generator_trait)] use std::ops::Generator; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; -static A: AtomicUsize = ATOMIC_USIZE_INIT; +static A: AtomicUsize = AtomicUsize::new(0); struct B; diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs index bd988897710f7..252f2c0f07da7 100644 --- a/src/test/run-pass/generator/drop-env.rs +++ b/src/test/run-pass/generator/drop-env.rs @@ -3,9 +3,9 @@ #![feature(generators, generator_trait)] use std::ops::Generator; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; -static A: AtomicUsize = ATOMIC_USIZE_INIT; +static A: AtomicUsize = AtomicUsize::new(0); struct B; diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs index ce12f4225ef0a..8640a6539195b 100644 --- a/src/test/run-pass/generator/panic-drops.rs +++ b/src/test/run-pass/generator/panic-drops.rs @@ -6,9 +6,9 @@ use std::ops::Generator; use std::panic; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; -static A: AtomicUsize = ATOMIC_USIZE_INIT; +static A: AtomicUsize = AtomicUsize::new(0); struct B; diff --git a/src/test/run-pass/issues/issue-34053.rs b/src/test/run-pass/issues/issue-34053.rs index ec5a0cbf6bbd5..fa23ae8f95bee 100644 --- a/src/test/run-pass/issues/issue-34053.rs +++ b/src/test/run-pass/issues/issue-34053.rs @@ -1,7 +1,7 @@ // run-pass -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; -static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; +static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); struct A(i32); diff --git a/src/test/run-pass/mir/mir_fat_ptr_drop.rs b/src/test/run-pass/mir/mir_fat_ptr_drop.rs index 9f4f3d6c5d306..d865c3499b270 100644 --- a/src/test/run-pass/mir/mir_fat_ptr_drop.rs +++ b/src/test/run-pass/mir/mir_fat_ptr_drop.rs @@ -10,7 +10,7 @@ use std::sync::atomic; use std::sync::atomic::Ordering::SeqCst; -static COUNTER: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT; +static COUNTER: atomic::AtomicUsize = atomic::AtomicUsize::new(0); struct DropMe { } diff --git a/src/test/run-pass/panics/panic-recover-propagate.rs b/src/test/run-pass/panics/panic-recover-propagate.rs index 0a15417f72a4e..7969336ca749b 100644 --- a/src/test/run-pass/panics/panic-recover-propagate.rs +++ b/src/test/run-pass/panics/panic-recover-propagate.rs @@ -1,11 +1,11 @@ // run-pass // ignore-emscripten no threads support -use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::panic; use std::thread; -static A: AtomicUsize = ATOMIC_USIZE_INIT; +static A: AtomicUsize = AtomicUsize::new(0); fn main() { panic::set_hook(Box::new(|_| { diff --git a/src/test/run-pass/threads-sendsync/tls-init-on-init.rs b/src/test/run-pass/threads-sendsync/tls-init-on-init.rs index 6ac7a9253cdd3..193c18151059a 100644 --- a/src/test/run-pass/threads-sendsync/tls-init-on-init.rs +++ b/src/test/run-pass/threads-sendsync/tls-init-on-init.rs @@ -6,13 +6,13 @@ #![feature(thread_local_try_with)] use std::thread; -use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; +use std::sync::atomic::{AtomicUsize, Ordering}; struct Foo { cnt: usize } thread_local!(static FOO: Foo = Foo::init()); -static CNT: AtomicUsize = ATOMIC_USIZE_INIT; +static CNT: AtomicUsize = AtomicUsize::new(0); impl Foo { fn init() -> Foo { diff --git a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs index 670c6bb869d59..7477947b89ca4 100644 --- a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs +++ b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs @@ -10,7 +10,7 @@ #![feature(thread_local)] #[thread_local] -static mut X: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT; +static mut X: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0); fn main() { unsafe { diff --git a/src/test/ui/error-codes/E0492.rs b/src/test/ui/error-codes/E0492.rs index b1824941adf00..2de4c12eb64fb 100644 --- a/src/test/ui/error-codes/E0492.rs +++ b/src/test/ui/error-codes/E0492.rs @@ -1,6 +1,6 @@ -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; +use std::sync::atomic::AtomicUsize; -const A: AtomicUsize = ATOMIC_USIZE_INIT; +const A: AtomicUsize = AtomicUsize::new(0); static B: &'static AtomicUsize = &A; //~ ERROR E0492 fn main() { diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index 74dde8bf0e2c9..3f56d4da6a3ed 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -20,7 +20,7 @@ use std::os::unix::prelude::*; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::thread; @@ -31,7 +31,7 @@ macro_rules! t { }) } -static TEST: AtomicUsize = ATOMIC_USIZE_INIT; +static TEST: AtomicUsize = AtomicUsize::new(0); struct Config { pub remote: bool, From 1ac727772bd91b6e35b624e3252e6a6bd681c70b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 6 Dec 2018 22:47:09 +0100 Subject: [PATCH 0346/1064] Remove rustdoc old style files generation --- src/librustdoc/html/render.rs | 22 +--------------------- src/test/rustdoc/issue-19190.rs | 3 --- src/test/rustdoc/issue-21092.rs | 1 - src/test/rustdoc/issue-35169-2.rs | 8 -------- src/test/rustdoc/issue-35169.rs | 8 -------- src/test/rustdoc/macros.rs | 2 -- src/test/rustdoc/old-style-files.rs | 23 +++++++++++++++++++++++ src/test/rustdoc/src-links.rs | 2 -- src/test/rustdoc/structfields.rs | 5 ----- 9 files changed, 24 insertions(+), 50 deletions(-) create mode 100644 src/test/rustdoc/old-style-files.rs diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..4f237dc85a5ee 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -33,7 +33,7 @@ use std::default::Default; use std::error; use std::fmt::{self, Display, Formatter, Write as FmtWrite}; use std::ffi::OsStr; -use std::fs::{self, File, OpenOptions}; +use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter, BufReader}; use std::mem; @@ -2229,26 +2229,6 @@ impl Context { if !self.render_redirect_pages { all.append(full_path(self, &item), &item_type); } - // Redirect from a sane URL using the namespace to Rustdoc's - // URL for the page. - let redir_name = format!("{}.{}.html", name, item_type.name_space()); - let redir_dst = self.dst.join(redir_name); - if let Ok(redirect_out) = OpenOptions::new().create_new(true) - .write(true) - .open(&redir_dst) { - let mut redirect_out = BufWriter::new(redirect_out); - try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst); - } - - // If the item is a macro, redirect from the old macro URL (with !) - // to the new one (without). - if item_type == ItemType::Macro { - let redir_name = format!("{}.{}!.html", item_type, name); - let redir_dst = self.dst.join(redir_name); - let redirect_out = try_err!(File::create(&redir_dst), &redir_dst); - let mut redirect_out = BufWriter::new(redirect_out); - try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst); - } } } Ok(()) diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs index a7c25538f7c44..4d3b76229702b 100644 --- a/src/test/rustdoc/issue-19190.rs +++ b/src/test/rustdoc/issue-19190.rs @@ -13,9 +13,6 @@ impl Deref for Bar { fn deref(&self) -> &Foo { loop {} } } -// @has issue_19190/Bar.t.html // @has issue_19190/struct.Bar.html -// @has - '//*[@id="foo.v"]' 'fn foo(&self)' // @has - '//*[@id="method.foo"]' 'fn foo(&self)' -// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-21092.rs b/src/test/rustdoc/issue-21092.rs index 14f547abd9a68..b054145a4831a 100644 --- a/src/test/rustdoc/issue-21092.rs +++ b/src/test/rustdoc/issue-21092.rs @@ -3,7 +3,6 @@ extern crate issue_21092; -// @has issue_21092/Bar.t.html // @has issue_21092/struct.Bar.html // @has - '//*[@id="associatedtype.Bar"]' 'type Bar = i32' pub use issue_21092::{Foo, Bar}; diff --git a/src/test/rustdoc/issue-35169-2.rs b/src/test/rustdoc/issue-35169-2.rs index 0caead100d666..7dea268ec0258 100644 --- a/src/test/rustdoc/issue-35169-2.rs +++ b/src/test/rustdoc/issue-35169-2.rs @@ -23,19 +23,11 @@ impl DerefMut for Bar { fn deref_mut(&mut self) -> &mut Foo { loop {} } } -// @has issue_35169_2/Bar.t.html // @has issue_35169_2/struct.Bar.html -// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)' // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)' -// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)' // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)' -// @has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)' // @has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)' -// @has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)' // @has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)' -// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box)' // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box)' -// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box)' // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box)' -// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-35169.rs b/src/test/rustdoc/issue-35169.rs index 0978b103076fe..883d5d0158d7e 100644 --- a/src/test/rustdoc/issue-35169.rs +++ b/src/test/rustdoc/issue-35169.rs @@ -18,19 +18,11 @@ impl Deref for Bar { fn deref(&self) -> &Foo { loop {} } } -// @has issue_35169/Bar.t.html // @has issue_35169/struct.Bar.html -// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)' // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)' -// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)' // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)' -// @!has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)' // @!has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)' -// @!has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)' // @!has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)' -// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box)' // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box)' -// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box)' // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box)' -// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/macros.rs b/src/test/rustdoc/macros.rs index c66a2c845bfd8..fb4f02ad16052 100644 --- a/src/test/rustdoc/macros.rs +++ b/src/test/rustdoc/macros.rs @@ -2,8 +2,6 @@ // @has - //pre '() => { ... };' // @has - //pre '($a:tt) => { ... };' // @has - //pre '($e:expr) => { ... };' -// @has macros/macro.my_macro!.html -// @has - //a 'macro.my_macro.html' #[macro_export] macro_rules! my_macro { () => []; diff --git a/src/test/rustdoc/old-style-files.rs b/src/test/rustdoc/old-style-files.rs new file mode 100644 index 0000000000000..fb6697e18fbc4 --- /dev/null +++ b/src/test/rustdoc/old-style-files.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// @has foo/macro.bar.html +// @!has foo/macro.bar!.html +// @!has foo/bar.m.html +#[macro_export] +macro_rules! bar { + () => {} +} + +// @has foo/struct.Bar.html +// @!has foo/Bar.t.html +pub struct Bar; diff --git a/src/test/rustdoc/src-links.rs b/src/test/rustdoc/src-links.rs index 902a319a7b906..353ce10243e00 100644 --- a/src/test/rustdoc/src-links.rs +++ b/src/test/rustdoc/src-links.rs @@ -14,13 +14,11 @@ pub mod bar { // @has foo/bar/baz/index.html '//a/@href' '../../../src/foo/src-links.rs.html' pub mod baz { /// Dox - // @has foo/bar/baz/baz.v.html // @has foo/bar/baz/fn.baz.html '//a/@href' '../../../src/foo/src-links.rs.html' pub fn baz() { } } /// Dox - // @has foo/bar/Foobar.t.html // @has foo/bar/trait.Foobar.html '//a/@href' '../../src/foo/src-links.rs.html' pub trait Foobar { fn dummy(&self) { } } diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs index 35cea8afe2146..cd8957aa2ecb9 100644 --- a/src/test/rustdoc/structfields.rs +++ b/src/test/rustdoc/structfields.rs @@ -1,6 +1,5 @@ // @has structfields/Foo.t.html // @has - struct.Foo.html -// @has structfields/struct.Foo.html pub struct Foo { // @has - //pre "pub a: ()" pub a: (), @@ -14,8 +13,6 @@ pub struct Foo { pub d: usize, } -// @has structfields/Bar.t.html -// @has - struct.Bar.html // @has structfields/struct.Bar.html pub struct Bar { // @has - //pre "pub a: ()" @@ -23,8 +20,6 @@ pub struct Bar { // @!has - //pre "// some fields omitted" } -// @has structfields/Qux.t.html -// @has - enum.Qux.html // @has structfields/enum.Qux.html pub enum Qux { Quz { From 8eaa84c79f5491735dc616d8591318e954e57a68 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 25 Jan 2019 14:56:27 -0500 Subject: [PATCH 0347/1064] document `Applicability` --- src/librustc_errors/lib.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 3e25f98ccd27c..64d5ca0c2a742 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -54,12 +54,28 @@ use syntax_pos::{BytePos, Span, NO_EXPANSION}; +/// Indicates the confidence in the correctness of a suggestion. +/// +/// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion +/// to determine whether it should be automatically applied or if the user should be consulted +/// before applying the suggestion. #[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub enum Applicability { + /// The suggestion is definitely what the user intended. This suggestion should be + /// automatically applied. MachineApplicable, - HasPlaceholders, + + /// The suggestion may be what the user intended, but it is uncertain. The suggestion should + /// result in valid Rust code if it is applied. MaybeIncorrect, - Unspecified + + /// The suggestion contains placeholders like `(...)` or `{ /* fields */ }`. The suggestion + /// cannot be applied automatically because it will not result in valid Rust code. The user + /// will need to fill in the placeholders. + HasPlaceholders, + + /// The applicability of the suggestion is unknown. + Unspecified, } #[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] From 0897ffc28f68fab862e970599c95bb65b280b48b Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 25 Jan 2019 16:03:27 -0500 Subject: [PATCH 0348/1064] remove `_with_applicability` from suggestion fns --- src/librustc/hir/lowering.rs | 2 +- src/librustc/infer/error_reporting/mod.rs | 8 +- .../nice_region_error/named_anon_conflict.rs | 2 +- .../nice_region_error/static_impl_trait.rs | 2 +- src/librustc/lint/builtin.rs | 13 +- src/librustc/lint/levels.rs | 6 +- src/librustc/middle/liveness.rs | 14 ++- src/librustc/middle/resolve_lifetime.rs | 8 +- src/librustc/session/mod.rs | 2 +- src/librustc/traits/error_reporting.rs | 24 ++-- src/librustc/ty/error.rs | 2 +- .../borrowck/gather_loans/move_error.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 12 +- src/librustc_borrowck/borrowck/unused.rs | 5 +- src/librustc_errors/diagnostic.rs | 114 ++++-------------- src/librustc_errors/diagnostic_builder.rs | 99 +++++---------- src/librustc_lint/builtin.rs | 32 ++--- src/librustc_lint/nonstandard_style.rs | 6 +- src/librustc_lint/types.rs | 4 +- src/librustc_lint/unused.rs | 12 +- .../borrow_check/error_reporting.rs | 4 +- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/borrow_check/move_errors.rs | 6 +- .../borrow_check/mutability_errors.rs | 8 +- .../nll/region_infer/error_reporting/mod.rs | 2 +- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/librustc_passes/ast_validation.rs | 4 +- src/librustc_passes/loops.rs | 2 +- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/lib.rs | 32 ++--- src/librustc_resolve/macros.rs | 4 +- src/librustc_typeck/astconv.rs | 8 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/callee.rs | 4 +- src/librustc_typeck/check/cast.rs | 10 +- src/librustc_typeck/check/compare_method.rs | 6 +- src/librustc_typeck/check/demand.rs | 45 +++---- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 30 ++--- src/librustc_typeck/check/mod.rs | 39 +++--- src/librustc_typeck/check/op.rs | 6 +- src/librustc_typeck/check_unused.rs | 4 +- src/librustc_typeck/structured_errors.rs | 2 +- .../passes/check_code_block_syntax.rs | 2 +- src/libsyntax/attr/builtin.rs | 6 +- src/libsyntax/config.rs | 2 +- src/libsyntax/ext/expand.rs | 6 +- src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 4 +- src/libsyntax/parse/lexer/unicode_chars.rs | 2 +- src/libsyntax/parse/parser.rs | 108 ++++++++--------- src/libsyntax_ext/format.rs | 4 +- 53 files changed, 315 insertions(+), 418 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 905a3ceed81c9..51dbad92225e1 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1829,7 +1829,7 @@ impl<'a> LoweringContext<'a> { if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { // Do not suggest going from `Trait()` to `Trait<>` if data.inputs.len() > 0 { - err.span_suggestion_with_applicability( + err.span_suggestion( data.span, "use angle brackets instead", format!("<{}>", &snippet[1..snippet.len() - 1]), diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 35f6e6aa610ad..66e4cd49c807f 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(ty::error::ExpectedFound { found, .. }) = exp_found { if ty.is_box() && ty.boxed_ty() == found { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "consider dereferencing the boxed value", format!("*{}", snippet), @@ -532,7 +532,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(then, "expected because of this"); outer.map(|sp| err.span_label(sp, "if and else have incompatible types")); if let Some(sp) = semicolon { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, "consider removing this semicolon", String::new(), @@ -1084,7 +1084,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.sess.source_map().span_to_snippet(span), show_suggestion, ) { - diag.span_suggestion_with_applicability( + diag.span_suggestion( span, msg, format!("{}.as_ref()", snippet), @@ -1273,7 +1273,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let tail = if has_lifetimes { " + " } else { "" }; format!("{}: {}{}", bound_kind, sub, tail) }; - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, &consider, suggestion, diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index daab0a8e96263..918a46aacd041 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { E0621, "explicit lifetime required in {}", error_var - ).span_suggestion_with_applicability( + ).span_suggestion( new_ty_span, &format!("add explicit lifetime `{}` to {}", named, span_label_var), new_ty.to_string(), diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9fc3bb05cdab1..7501e2f210888 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { _ => "'_".to_owned(), }; if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) { - err.span_suggestion_with_applicability( + err.span_suggestion( return_sp, &format!( "you can add a constraint to the return type to make it last \ diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 2b5fcafc90505..35a0382359572 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -473,7 +473,7 @@ impl BuiltinLintDiagnostics { Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders) }; - db.span_suggestion_with_applicability(span, "use `dyn`", sugg, app); + db.span_suggestion(span, "use `dyn`", sugg, app); } BuiltinLintDiagnostics::AbsPathWithModule(span) => { let (sugg, app) = match sess.source_map().span_to_snippet(span) { @@ -490,7 +490,7 @@ impl BuiltinLintDiagnostics { } Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders) }; - db.span_suggestion_with_applicability(span, "use `crate`", sugg, app); + db.span_suggestion(span, "use `crate`", sugg, app); } BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => { db.span_label(later_span, format!("`{}` already exported", ident)); @@ -531,7 +531,7 @@ impl BuiltinLintDiagnostics { (insertion_span, anon_lts) } }; - db.span_suggestion_with_applicability( + db.span_suggestion( replace_span, &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }), suggestion, @@ -539,12 +539,7 @@ impl BuiltinLintDiagnostics { ); } BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { - db.span_suggestion_with_applicability( - span, - ¬e, - sugg, - Applicability::MaybeIncorrect - ); + db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); } } } diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 8b45a5a1504b5..616915769435d 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -324,7 +324,7 @@ impl<'a> LintLevelsBuilder<'a> { Some(li.span.into()), &msg, ); - err.span_suggestion_with_applicability( + err.span_suggestion( li.span, "change it to", new_lint_name.to_string(), @@ -362,7 +362,7 @@ impl<'a> LintLevelsBuilder<'a> { Some(li.span.into()), &msg); if let Some(new_name) = renamed { - err.span_suggestion_with_applicability( + err.span_suggestion( li.span, "use the new name", new_name, @@ -386,7 +386,7 @@ impl<'a> LintLevelsBuilder<'a> { &msg); if let Some(suggestion) = suggestion { - db.span_suggestion_with_applicability( + db.span_suggestion( li.span, "did you mean", suggestion.to_string(), diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 220bec735a473..cc0dd71738fce 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1600,12 +1600,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let mut err = self.ir.tcx .struct_span_lint_hir(lint::builtin::UNUSED_VARIABLES, hir_id, sp, &msg); if self.ir.variable_is_shorthand(var) { - err.span_suggestion_with_applicability(sp, "try ignoring the field", - format!("{}: _", name), - Applicability::MachineApplicable); + err.span_suggestion( + sp, + "try ignoring the field", + format!("{}: _", name), + Applicability::MachineApplicable, + ); } else { - err.span_suggestion_short_with_applicability( - sp, &suggest_underscore_msg, + err.span_suggestion_short( + sp, + &suggest_underscore_msg, format!("_{}", name), Applicability::MachineApplicable, ); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 2d3653464d538..34db30a1706b9 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1526,14 +1526,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // place ("start at" because the latter includes trailing // whitespace), then this is an in-band lifetime if decl_span.shrink_to_lo() == use_span.shrink_to_lo() { - err.span_suggestion_with_applicability( + err.span_suggestion( use_span, "elide the single-use lifetime", String::new(), Applicability::MachineApplicable, ); } else { - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( "elide the single-use lifetime", vec![(decl_span, String::new()), (use_span, String::new())], Applicability::MachineApplicable, @@ -1644,7 +1644,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if let Some(generics) = self.tcx.hir().get_generics(parent_def_id) { let unused_lt_span = self.lifetime_deletion_span(name, generics); if let Some(span) = unused_lt_span { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "elide the unused lifetime", String::new(), @@ -2350,7 +2350,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } else { (format!("{} + 'static", snippet), Applicability::MaybeIncorrect) }; - db.span_suggestion_with_applicability(span, msg, sugg, applicability); + db.span_suggestion(span, msg, sugg, applicability); false } Err(_) => { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index cf00bf330deea..875021e20d420 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -435,7 +435,7 @@ impl Session { } DiagnosticBuilderMethod::SpanSuggestion(suggestion) => { let span = span_maybe.expect("span_suggestion_* needs a span"); - diag_builder.span_suggestion_with_applicability( + diag_builder.span_suggestion( span, message, suggestion, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1c92e2da588a0..5debb11902988 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -904,7 +904,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(ref expr) = local.init { if let hir::ExprKind::Index(_, _) = expr.node { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, "consider borrowing here", format!("&{}", snippet), @@ -952,7 +952,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let format_str = format!("consider removing {} leading `&`-references", remove_refs); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, &format_str, String::new(), Applicability::MachineApplicable ); break; @@ -1109,7 +1109,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // For example, if `expected_args_length` is 2, suggest `|_, _|`. if found_args.is_empty() && is_closure { let underscores = vec!["_"; expected_args.len()].join(", "); - err.span_suggestion_with_applicability( + err.span_suggestion( pipe_span, &format!( "consider changing the closure to take and ignore the expected argument{}", @@ -1130,11 +1130,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .map(|(name, _)| name.to_owned()) .collect::>() .join(", "); - err.span_suggestion_with_applicability(found_span, - "change the closure to take multiple \ - arguments instead of a single tuple", - format!("|{}|", sugg), - Applicability::MachineApplicable); + err.span_suggestion( + found_span, + "change the closure to take multiple arguments instead of a single tuple", + format!("|{}|", sugg), + Applicability::MachineApplicable, + ); } } if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] { @@ -1162,12 +1163,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { String::new() }, ); - err.span_suggestion_with_applicability( + err.span_suggestion( found_span, - "change the closure to accept a tuple instead of \ - individual arguments", + "change the closure to accept a tuple instead of individual arguments", sugg, - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 834b541d4c01b..f444013e2a3bd 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -237,7 +237,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { { if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) { if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { - db.span_suggestion_with_applicability( + db.span_suggestion( sp, "use a float literal", format!("{}.0", snippet), diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index 588b2344a18e0..00cbc250bd686 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -70,7 +70,7 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &[MoveErr let initializer = e.init.as_ref().expect("should have an initializer to get an error"); if let Ok(snippet) = bccx.tcx.sess.source_map().span_to_snippet(initializer.span) { - err.span_suggestion_with_applicability( + err.span_suggestion( initializer.span, "consider using a reference instead", format!("&{}", snippet), diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 72963cb7e7fb4..5c11d622d0a8a 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -850,7 +850,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { }) = cmt.cat { db.note(fn_closure_msg); } else { - db.span_suggestion_with_applicability( + db.span_suggestion( sp, msg, suggestion, @@ -858,7 +858,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { ); } } else { - db.span_suggestion_with_applicability( + db.span_suggestion( sp, msg, suggestion, @@ -1229,7 +1229,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { let let_span = self.tcx.hir().span(node_id); let suggestion = suggest_ref_mut(self.tcx, let_span); if let Some(replace_str) = suggestion { - db.span_suggestion_with_applicability( + db.span_suggestion( let_span, "use a mutable reference instead", replace_str, @@ -1291,7 +1291,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { )) = ty.map(|t| &t.node) { let borrow_expr_id = self.tcx.hir().get_parent_node(borrowed_node_id); - db.span_suggestion_with_applicability( + db.span_suggestion( self.tcx.hir().span(borrow_expr_id), "consider removing the `&mut`, as it is an \ immutable binding to a mutable reference", @@ -1299,7 +1299,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else { - db.span_suggestion_with_applicability( + db.span_suggestion( let_span, "make this binding mutable", format!("mut {}", snippet), @@ -1326,7 +1326,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { &cmt_path_or_string, capture_span, Origin::Ast) - .span_suggestion_with_applicability( + .span_suggestion( err.span, &format!("to force the closure to take ownership of {} \ (and any other referenced variables), \ diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs index 7340c7addb505..5db98f0e223e4 100644 --- a/src/librustc_borrowck/borrowck/unused.rs +++ b/src/librustc_borrowck/borrowck/unused.rs @@ -78,11 +78,12 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> { hir_id, span, "variable does not need to be mutable") - .span_suggestion_short_with_applicability( + .span_suggestion_short( mut_span, "remove this `mut`", String::new(), - Applicability::MachineApplicable) + Applicability::MachineApplicable, + ) .emit(); } } diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 3fa391c84ab25..06a1761a1e76f 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -229,59 +229,7 @@ impl Diagnostic { self } - /// Prints out a message with a suggested edit of the code. If the suggestion is presented - /// inline it will only show the text message and not the text. - /// - /// See `CodeSuggestion` for more information. - #[deprecated(note = "Use `span_suggestion_short_with_applicability`")] - pub fn span_suggestion_short(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self { - self.suggestions.push(CodeSuggestion { - substitutions: vec![Substitution { - parts: vec![SubstitutionPart { - snippet: suggestion, - span: sp, - }], - }], - msg: msg.to_owned(), - show_code_when_inline: false, - applicability: Applicability::Unspecified, - }); - self - } - - /// Prints out a message with a suggested edit of the code. - /// - /// In case of short messages and a simple suggestion, - /// rustc displays it as a label like - /// - /// "try adding parentheses: `(tup.0).1`" - /// - /// The message - /// - /// * should not end in any punctuation (a `:` is added automatically) - /// * should not be a question - /// * should not contain any parts like "the following", "as shown" - /// * may look like "to do xyz, use" or "to do xyz, use abc" - /// * may contain a name of a function, variable or type, but not whole expressions - /// - /// See `CodeSuggestion` for more information. - #[deprecated(note = "Use `span_suggestion_with_applicability`")] - pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self { - self.suggestions.push(CodeSuggestion { - substitutions: vec![Substitution { - parts: vec![SubstitutionPart { - snippet: suggestion, - span: sp, - }], - }], - msg: msg.to_owned(), - show_code_when_inline: true, - applicability: Applicability::Unspecified, - }); - self - } - - pub fn multipart_suggestion_with_applicability( + pub fn multipart_suggestion( &mut self, msg: &str, suggestion: Vec<(Span, String)>, @@ -301,39 +249,24 @@ impl Diagnostic { self } - #[deprecated(note = "Use `multipart_suggestion_with_applicability`")] - pub fn multipart_suggestion( - &mut self, - msg: &str, - suggestion: Vec<(Span, String)>, - ) -> &mut Self { - self.multipart_suggestion_with_applicability( - msg, - suggestion, - Applicability::Unspecified, - ) - } - - /// Prints out a message with multiple suggested edits of the code. - #[deprecated(note = "Use `span_suggestions_with_applicability`")] - pub fn span_suggestions(&mut self, sp: Span, msg: &str, suggestions: Vec) -> &mut Self { - self.suggestions.push(CodeSuggestion { - substitutions: suggestions.into_iter().map(|snippet| Substitution { - parts: vec![SubstitutionPart { - snippet, - span: sp, - }], - }).collect(), - msg: msg.to_owned(), - show_code_when_inline: true, - applicability: Applicability::Unspecified, - }); - self - } - - /// This is a suggestion that may contain mistakes or fillers and should - /// be read and understood by a human. - pub fn span_suggestion_with_applicability(&mut self, sp: Span, msg: &str, + /// Prints out a message with a suggested edit of the code. + /// + /// In case of short messages and a simple suggestion, rustc displays it as a label: + /// + /// ```text + /// try adding parentheses: `(tup.0).1` + /// ``` + /// + /// The message + /// + /// * should not end in any punctuation (a `:` is added automatically) + /// * should not be a question (avoid language like "did you mean") + /// * should not contain any phrases like "the following", "as shown", etc. + /// * may look like "to do xyz, use" or "to do xyz, use abc" + /// * may contain a name of a function, variable, or type, but not whole expressions + /// + /// See `CodeSuggestion` for more information. + pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability) -> &mut Self { self.suggestions.push(CodeSuggestion { @@ -350,7 +283,8 @@ impl Diagnostic { self } - pub fn span_suggestions_with_applicability(&mut self, sp: Span, msg: &str, + /// Prints out a message with multiple suggested edits of the code. + pub fn span_suggestions(&mut self, sp: Span, msg: &str, suggestions: impl Iterator, applicability: Applicability) -> &mut Self { self.suggestions.push(CodeSuggestion { @@ -367,7 +301,11 @@ impl Diagnostic { self } - pub fn span_suggestion_short_with_applicability( + /// Prints out a message with a suggested edit of the code. If the suggestion is presented + /// inline, it will only show the message and not the suggestion. + /// + /// See `CodeSuggestion` for more information. + pub fn span_suggestion_short( &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability ) -> &mut Self { self.suggestions.push(CodeSuggestion { diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 736cca6bd64af..f423a4cd1a7bf 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -39,7 +39,6 @@ macro_rules! forward { ) => { $(#[$attrs])* pub fn $n(&self, $($name: $ty),*) -> &Self { - #[allow(deprecated)] self.diagnostic.$n($($name),*); self } @@ -52,7 +51,6 @@ macro_rules! forward { ) => { $(#[$attrs])* pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { - #[allow(deprecated)] self.diagnostic.$n($($name),*); self } @@ -70,7 +68,6 @@ macro_rules! forward { ) => { $(#[$attrs])* pub fn $n>(&mut self, $($name: $ty),*) -> &mut Self { - #[allow(deprecated)] self.diagnostic.$n($($name),*); self } @@ -190,53 +187,16 @@ impl<'a> DiagnosticBuilder<'a> { msg: &str, ) -> &mut Self); - forward!( - #[deprecated(note = "Use `span_suggestion_short_with_applicability`")] - pub fn span_suggestion_short( - &mut self, - sp: Span, - msg: &str, - suggestion: String, - ) -> &mut Self - ); - - forward!( - #[deprecated(note = "Use `multipart_suggestion_with_applicability`")] - pub fn multipart_suggestion( - &mut self, - msg: &str, - suggestion: Vec<(Span, String)>, - ) -> &mut Self - ); - - forward!( - #[deprecated(note = "Use `span_suggestion_with_applicability`")] - pub fn span_suggestion( - &mut self, - sp: Span, - msg: &str, - suggestion: String, - ) -> &mut Self - ); - - forward!( - #[deprecated(note = "Use `span_suggestions_with_applicability`")] - pub fn span_suggestions(&mut self, - sp: Span, - msg: &str, - suggestions: Vec, - ) -> &mut Self - ); - - pub fn multipart_suggestion_with_applicability(&mut self, - msg: &str, - suggestion: Vec<(Span, String)>, - applicability: Applicability, - ) -> &mut Self { + pub fn multipart_suggestion( + &mut self, + msg: &str, + suggestion: Vec<(Span, String)>, + applicability: Applicability, + ) -> &mut Self { if !self.allow_suggestions { return self } - self.diagnostic.multipart_suggestion_with_applicability( + self.diagnostic.multipart_suggestion( msg, suggestion, applicability, @@ -244,16 +204,17 @@ impl<'a> DiagnosticBuilder<'a> { self } - pub fn span_suggestion_with_applicability(&mut self, - sp: Span, - msg: &str, - suggestion: String, - applicability: Applicability) - -> &mut Self { + pub fn span_suggestion( + &mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability, + ) -> &mut Self { if !self.allow_suggestions { return self } - self.diagnostic.span_suggestion_with_applicability( + self.diagnostic.span_suggestion( sp, msg, suggestion, @@ -262,16 +223,17 @@ impl<'a> DiagnosticBuilder<'a> { self } - pub fn span_suggestions_with_applicability(&mut self, - sp: Span, - msg: &str, - suggestions: impl Iterator, - applicability: Applicability) - -> &mut Self { + pub fn span_suggestions( + &mut self, + sp: Span, + msg: &str, + suggestions: impl Iterator, + applicability: Applicability, + ) -> &mut Self { if !self.allow_suggestions { return self } - self.diagnostic.span_suggestions_with_applicability( + self.diagnostic.span_suggestions( sp, msg, suggestions, @@ -280,16 +242,17 @@ impl<'a> DiagnosticBuilder<'a> { self } - pub fn span_suggestion_short_with_applicability(&mut self, - sp: Span, - msg: &str, - suggestion: String, - applicability: Applicability) - -> &mut Self { + pub fn span_suggestion_short( + &mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability, + ) -> &mut Self { if !self.allow_suggestions { return self } - self.diagnostic.span_suggestion_short_with_applicability( + self.diagnostic.span_suggestion_short( sp, msg, suggestion, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d648472024b12..46e784c4099c8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -78,7 +78,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue { let msg = "denote infinite loops with `loop { ... }`"; let condition_span = cx.tcx.sess.source_map().def_span(e.span); let mut err = cx.struct_span_lint(WHILE_TRUE, condition_span, msg); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( condition_span, "use `loop`", "loop".to_owned(), @@ -199,7 +199,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { &format!("the `{}:` in this pattern is redundant", ident)); let subspan = cx.tcx.sess.source_map().span_through_char(fieldpat.span, ':'); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( subspan, "remove this", ident.to_string(), @@ -704,7 +704,7 @@ impl EarlyLintPass for AnonymousParameters { arg.pat.span, "anonymous parameters are deprecated and will be \ removed in the next edition." - ).span_suggestion_with_applicability( + ).span_suggestion( arg.pat.span, "Try naming the parameter or explicitly \ ignoring it", @@ -759,7 +759,7 @@ impl EarlyLintPass for DeprecatedAttr { let msg = format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); let mut err = cx.struct_span_lint(DEPRECATED, attr.span, &msg); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( attr.span, suggestion.unwrap_or("remove this attribute"), String::new(), @@ -906,7 +906,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { it.span, "functions generic over \ types must be mangled"); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( no_mangle_attr.span, "remove this attribute", String::new(), @@ -934,7 +934,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { .unwrap_or(0) as u32; // `const` is 5 chars let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5)); - err.span_suggestion_with_applicability( + err.span_suggestion( const_span, "try a static value", "pub static".to_owned(), @@ -1116,10 +1116,12 @@ impl UnreachablePub { "pub(crate)" }.to_owned(); - err.span_suggestion_with_applicability(vis.span, - "consider restricting its visibility", - replacement, - applicability); + err.span_suggestion( + vis.span, + "consider restricting its visibility", + replacement, + applicability, + ); if exportable { err.help("or consider exporting it for use by other crates"); } @@ -1452,7 +1454,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { if parenthesise { *visit_subpats = false; let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, msg); - err.span_suggestion_with_applicability( + err.span_suggestion( pat.span, suggestion, format!("&({}..={})", expr_to_string(&start), expr_to_string(&end)), @@ -1461,7 +1463,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { err.emit(); } else { let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, msg); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( join, suggestion, "..=".to_owned(), @@ -1613,7 +1615,7 @@ impl EarlyLintPass for KeywordIdents { E0721, "`await` is a keyword in the {} edition", cur_edition, ); - err.span_suggestion_with_applicability( + err.span_suggestion( ident.span, "you can use a raw identifier to stay compatible", "r#await".to_string(), @@ -1637,7 +1639,7 @@ impl EarlyLintPass for KeywordIdents { ident.as_str(), next_edition), ); - lint.span_suggestion_with_applicability( + lint.span_suggestion( ident.span, "you can use a raw identifier to stay compatible", format!("r#{}", ident.as_str()), @@ -1865,7 +1867,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { lint_spans.clone(), "outlives requirements can be inferred" ); - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( if bound_count == 1 { "remove this bound" } else { diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index 256d28a39794e..bbf0edc6efb75 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -93,7 +93,7 @@ impl NonCamelCaseTypes { let msg = format!("{} `{}` should have a camel case name", sort, name); cx.struct_span_lint(NON_CAMEL_CASE_TYPES, ident.span, &msg) - .span_suggestion_with_applicability( + .span_suggestion( ident.span, "convert the identifier to camel case", c, @@ -223,7 +223,7 @@ impl NonSnakeCase { // We have a valid span in almost all cases, but we don't have one when linting a crate // name provided via the command line. if !ident.span.is_dummy() { - err.span_suggestion_with_applicability( + err.span_suggestion( ident.span, "convert the identifier to snake case", sc, @@ -377,7 +377,7 @@ impl NonUpperCaseGlobals { let msg = format!("{} `{}` should have an upper case name", sort, name); cx.struct_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, &msg) - .span_suggestion_with_applicability( + .span_suggestion( ident.span, "convert the identifier to upper case", uc, diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 0c4698c025412..4abd55b7e31f7 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -143,7 +143,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { OVERFLOWING_LITERALS, parent_expr.span, "only u8 can be cast into char"); - err.span_suggestion_with_applicability( + err.span_suggestion( parent_expr.span, &"use a char literal instead", format!("'\\u{{{:X}}}'", lit_val), @@ -401,7 +401,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { { if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { let (sans_suffix, _) = repr_str.split_at(pos); - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("consider using `{}` instead", sugg_ty), format!("{}{}", sans_suffix, sugg_ty), diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index a6cc7c2daeeec..acf5da1e1886a 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -366,12 +366,12 @@ impl UnusedParens { _ => false, } }).to_owned(); - err.span_suggestion_short_with_applicability( - span, - "remove these parentheses", - parens_removed, - Applicability::MachineApplicable - ); + err.span_suggestion_short( + span, + "remove these parentheses", + parens_removed, + Applicability::MachineApplicable, + ); err.emit(); } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 56b87feb82b2c..b070031756798 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1139,7 +1139,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Err(_) => "move || ".to_string() }; - err.span_suggestion_with_applicability( + err.span_suggestion( args_span, &format!("to force the closure to take ownership of {} (and any \ other referenced variables), use the `move` keyword", @@ -1428,7 +1428,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if let Some(decl) = local_decl { if let Some(name) = decl.name { if decl.can_be_made_mutable() { - err.span_suggestion_with_applicability( + err.span_suggestion( decl.source_info.span, "make this binding mutable", format!("mut {}", name), diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 9d49814c35a34..5597e4a6c597e 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -307,7 +307,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( span, "variable does not need to be mutable", ) - .span_suggestion_short_with_applicability( + .span_suggestion_short( mut_span, "remove this `mut`", String::new(), diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index 3c62614ce4766..8539b5c26cee8 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -368,14 +368,14 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { // expressions `a[b]`, which roughly desugar to // `*Index::index(&a, b)` or // `*IndexMut::index_mut(&mut a, b)`. - err.span_suggestion_with_applicability( + err.span_suggestion( span, "consider removing the `*`", snippet[1..].to_owned(), Applicability::Unspecified, ); } else { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "consider borrowing here", format!("&{}", snippet), @@ -439,7 +439,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { suggestions.sort_unstable_by_key(|&(span, _, _)| span); suggestions.dedup_by_key(|&mut (span, _, _)| span); for (span, to_remove, suggestion) in suggestions { - err.span_suggestion_with_applicability( + err.span_suggestion( span, &format!("consider removing the `{}`", to_remove), suggestion, diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 63bf6faed40d4..4755c6daf0a77 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -231,7 +231,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx), field, ) { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "consider changing this to be mutable", message, @@ -285,7 +285,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { assert_eq!(local_decl.mutability, Mutability::Not); err.span_label(span, format!("cannot {ACT}", ACT = act)); - err.span_suggestion_with_applicability( + err.span_suggestion( local_decl.source_info.span, "consider changing this to be mutable", format!("mut {}", local_decl.name.unwrap()), @@ -316,7 +316,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { _, ) = pat.node { - err.span_suggestion_with_applicability( + err.span_suggestion( upvar_ident.span, "consider changing this to be mutable", format!("mut {}", upvar_ident.name), @@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { }; if let Some((err_help_span, suggested_code)) = suggestion { - err.span_suggestion_with_applicability( + err.span_suggestion( err_help_span, &format!("consider changing this to be a mutable {}", pointer_desc), suggested_code, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 2a858bdd601ae..f07880075c100 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -626,7 +626,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { "'_".to_string() }; - diag.span_suggestion_with_applicability( + diag.span_suggestion( span, &format!( "to allow this impl Trait to capture borrowed data with lifetime \ diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 10213beba2a6d..10a4575d81220 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -313,7 +313,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor, pat: &Pat) { "pattern binding `{}` is named the same as one \ of the variants of the type `{}`", ident, ty_path); - err.span_suggestion_with_applicability( + err.span_suggestion( p.span, "to match on the variant, qualify the path", format!("{}::{}", ty_path, ident), diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index d1a3d7c1f81e0..3b6328f320f78 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -237,7 +237,7 @@ impl<'a> AstValidator<'a> { ); if let Ok(snippet) = self.session.source_map().span_to_snippet(span) { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "consider adding parentheses", format!("({})", snippet), Applicability::MachineApplicable, ); @@ -290,7 +290,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ); match val.node { ExprKind::Lit(ref v) if v.node.is_numeric() => { - err.span_suggestion_with_applicability( + err.span_suggestion( place.span.between(val.span), "if you meant to write a comparison against a negative value, add a \ space in between `<` and `-`", diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 7d9165a82bc8f..0dcfc72d10bc0 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -140,7 +140,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { .span_label(e.span, "can only break with a value inside \ `loop` or breakable block") - .span_suggestion_with_applicability( + .span_suggestion( e.span, &format!( "instead, use `break` on its own \ diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 31f8ce26225cd..3752d953f8afa 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -347,7 +347,7 @@ impl<'a> Resolver<'a> { let module = if orig_name.is_none() && ident.name == keywords::SelfLower.name() { self.session .struct_span_err(item.span, "`extern crate self;` requires renaming") - .span_suggestion_with_applicability( + .span_suggestion( item.span, "try", "extern crate self as name;".into(), diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 873ace9017260..55d5cdedd6ddd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -247,7 +247,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, let sugg_msg = "try using a local type parameter instead"; if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) { // Suggest the modification to the user - err.span_suggestion_with_applicability( + err.span_suggestion( sugg_span, sugg_msg, new_snippet, @@ -3175,7 +3175,7 @@ impl<'a> Resolver<'a> { // Emit help message for fake-self from other languages like `this`(javascript) if ["this", "my"].contains(&&*item_str.as_str()) && this.self_value_is_available(path[0].ident.span, span) { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "did you mean", "self".to_string(), @@ -3239,7 +3239,7 @@ impl<'a> Resolver<'a> { }; let msg = format!("{}try using the variant's enum", preamble); - err.span_suggestions_with_applicability( + err.span_suggestions( span, &msg, enum_candidates.into_iter() @@ -3262,7 +3262,7 @@ impl<'a> Resolver<'a> { let self_is_available = this.self_value_is_available(path[0].ident.span, span); match candidate { AssocSuggestion::Field => { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try", format!("self.{}", path_str), @@ -3275,7 +3275,7 @@ impl<'a> Resolver<'a> { } } AssocSuggestion::MethodWithSelf if self_is_available => { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try", format!("self.{}", path_str), @@ -3283,7 +3283,7 @@ impl<'a> Resolver<'a> { ); } AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try", format!("Self::{}", path_str), @@ -3304,7 +3304,7 @@ impl<'a> Resolver<'a> { "{} {} with a similar name exists", suggestion.article, suggestion.kind ); - err.span_suggestion_with_applicability( + err.span_suggestion( ident_span, &msg, suggestion.candidate.to_string(), @@ -3318,7 +3318,7 @@ impl<'a> Resolver<'a> { if let Some(def) = def { match (def, source) { (Def::Macro(..), _) => { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "use `!` to invoke the macro", format!("{}!", path_str), @@ -3335,7 +3335,7 @@ impl<'a> Resolver<'a> { } (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { ExprKind::Field(_, ident) => { - err.span_suggestion_with_applicability( + err.span_suggestion( parent.span, "use the path separator to refer to an item", format!("{}::{}", path_str, ident), @@ -3345,7 +3345,7 @@ impl<'a> Resolver<'a> { } ExprKind::MethodCall(ref segment, ..) => { let span = parent.span.with_hi(segment.ident.span.hi()); - err.span_suggestion_with_applicability( + err.span_suggestion( span, "use the path separator to refer to an item", format!("{}::{}", path_str, segment.ident), @@ -3428,7 +3428,7 @@ impl<'a> Resolver<'a> { PathSource::Expr(Some(parent)) => { match parent.node { ExprKind::MethodCall(ref path_assignment, _) => { - err.span_suggestion_with_applicability( + err.span_suggestion( sm.start_point(parent.span) .to(path_assignment.ident.span), "use `::` to access an associated function", @@ -3451,7 +3451,7 @@ impl<'a> Resolver<'a> { }, PathSource::Expr(None) if followed_by_brace == true => { if let Some((sp, snippet)) = closing_brace { - err.span_suggestion_with_applicability( + err.span_suggestion( sp, "surround the struct literal with parenthesis", format!("({})", snippet), @@ -3589,7 +3589,7 @@ impl<'a> Resolver<'a> { err.span_label(base_span, "expecting a type here because of type ascription"); if line_sp != line_base_sp { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, "did you mean to use `;` here instead?", ";".to_string(), @@ -4866,7 +4866,7 @@ impl<'a> Resolver<'a> { } else if ident.span.rust_2018() { let msg = "relative paths are not supported in visibilities on 2018 edition"; self.session.struct_span_err(ident.span, msg) - .span_suggestion_with_applicability( + .span_suggestion( path.span, "try", format!("crate::{}", path), @@ -5179,7 +5179,7 @@ impl<'a> Resolver<'a> { let rename_msg = "you can use `as` to change the binding name of the import"; if let Some(suggestion) = suggestion { - err.span_suggestion_with_applicability( + err.span_suggestion( binding_span, rename_msg, suggestion, @@ -5302,7 +5302,7 @@ fn show_candidates(err: &mut DiagnosticBuilder, *candidate = format!("use {};\n{}", candidate, additional_newline); } - err.span_suggestions_with_applicability( + err.span_suggestions( span, &msg, path_strings.into_iter(), diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 286f9a758830b..fb5b6c97689d0 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1021,14 +1021,14 @@ impl<'a> Resolver<'a> { if let Some(suggestion) = suggestion { if suggestion != name { if let MacroKind::Bang = kind { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "you could try the macro", suggestion.to_string(), Applicability::MaybeIncorrect ); } else { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try", suggestion.to_string(), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index e89506aaf99f9..61674070fbcb2 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1096,7 +1096,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { if !suggestions.is_empty() { let msg = format!("if you meant to specify the associated {}, write", if suggestions.len() == 1 { "type" } else { "types" }); - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( &msg, suggestions, Applicability::MaybeIncorrect, @@ -1172,7 +1172,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { trait_str: &str, name: &str) { struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type") - .span_suggestion_with_applicability( + .span_suggestion( span, "use fully-qualified syntax", format!("<{} as {}>::{}", type_str, trait_str, name), @@ -1353,7 +1353,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { &assoc_ident.as_str(), None, ) { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "did you mean", format!("{}::{}", qself_ty, suggested_name), @@ -1407,7 +1407,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { could_refer_to(variant_def, ""); could_refer_to(def, " also"); - err.span_suggestion_with_applicability( + err.span_suggestion( span, "use fully-qualified syntax", format!("<{} as {}>::{}", qself_ty, "Trait", assoc_ident), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 47f258e1aea74..141b8222b1f33 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -990,7 +990,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); let suggested_name = find_best_match_for_name(input, &ident.as_str(), None); if let Some(suggested_name) = suggested_name { - err.span_suggestion_with_applicability( + err.span_suggestion( *span, "did you mean", suggested_name.to_string(), diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index c59c143f74b62..0afc1697d316e 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -269,7 +269,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); if let Some(ref path) = unit_variant { - err.span_suggestion_with_applicability( + err.span_suggestion( call_expr.span, &format!( "`{}` is a unit variant, you need to write it \ @@ -294,7 +294,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tcx.sess.source_map().is_multiline(call_expr.span); if call_is_multiline { let span = self.tcx.sess.source_map().next_point(callee.span); - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try adding a semicolon", ";".to_owned(), diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 3f185ba194903..85cae17fd8524 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -213,7 +213,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fcx.ty_to_string(self.expr_ty), cast_ty)); if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) { - err.span_suggestion_with_applicability( + err.span_suggestion( self.expr.span, "dereference the expression", format!("*{}", snippet), @@ -263,7 +263,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { if self.expr_ty.is_numeric() { match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) { Ok(snippet) => { - err.span_suggestion_with_applicability( + err.span_suggestion( self.span, "compare with zero instead", format!("{} != 0", snippet), @@ -314,7 +314,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { err.note("The type information given here is insufficient to check whether \ the pointer cast is valid"); if unknown_cast_to { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( self.cast_span, "consider giving more type information", String::new(), @@ -345,7 +345,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { if self.cast_ty.is_trait() { match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) { Ok(s) => { - err.span_suggestion_with_applicability( + err.span_suggestion( self.cast_span, "try casting to a reference instead", format!("&{}{}", mtstr, s), @@ -367,7 +367,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { ty::Adt(def, ..) if def.is_box() => { match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) { Ok(s) => { - err.span_suggestion_with_applicability( + err.span_suggestion( self.cast_span, "try casting to a `Box` instead", format!("Box<{}>", s), diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 8c193cc8ff1a3..0eb8d7d06b1f6 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -316,7 +316,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(trait_err_span) = trait_err_span { if let Ok(trait_err_str) = tcx.sess.source_map() .span_to_snippet(trait_err_span) { - diag.span_suggestion_with_applicability( + diag.span_suggestion( impl_err_span, "consider change the type to match the mutability in trait", trait_err_str, @@ -784,7 +784,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .span_to_snippet(trait_m.generics.span) .ok()?; - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( "try changing the `impl Trait` argument to a generic parameter", vec![ // replace `impl Trait` with `T` @@ -855,7 +855,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .span_to_snippet(bounds) .ok()?; - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( "try removing the generic parameter and using `impl Trait` instead", vec![ // delete generic parameters diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index d985bdae491d0..0d4690c83170a 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -143,7 +143,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr)); let suggestions = compatible_variants .map(|v| format!("{}({})", v, expr_text)); - err.span_suggestions_with_applicability( + err.span_suggestions( expr.span, "try using a variant of the expected type", suggestions, @@ -558,7 +558,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if needs_paren { ")" } else { "" }, ); - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &suggest_msg, if literal_is_ty_suffixed(expr) { @@ -575,7 +575,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match (found.bit_width(), exp.bit_width()) { (Some(found), Some(exp)) if found > exp => { if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_truncate), cast_suggestion, @@ -585,7 +585,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (None, _) | (_, None) => { if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, depending_on_isize), cast_suggestion, @@ -606,7 +606,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match (found.bit_width(), exp.bit_width()) { (Some(found), Some(exp)) if found > exp => { if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_truncate), cast_suggestion, @@ -616,7 +616,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (None, _) | (_, None) => { if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, depending_on_usize), cast_suggestion, @@ -637,7 +637,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if can_cast { match (found.bit_width(), exp.bit_width()) { (Some(found), Some(exp)) if found > exp - 1 => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_truncate), cast_suggestion, @@ -645,7 +645,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } (None, None) => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_truncate), cast_suggestion, @@ -653,7 +653,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } (None, _) => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, depending_on_isize), cast_suggestion, @@ -661,7 +661,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } (_, None) => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, depending_on_usize), cast_suggestion, @@ -669,7 +669,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } _ => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_zero_extend), cast_suggestion, @@ -684,7 +684,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if can_cast { match (found.bit_width(), exp.bit_width()) { (Some(found), Some(exp)) if found - 1 > exp => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_truncate), cast_suggestion, @@ -692,7 +692,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } (None, None) => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_sign_extend), cast_suggestion, @@ -700,7 +700,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } (None, _) => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, depending_on_usize), cast_suggestion, @@ -708,7 +708,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } (_, None) => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, depending_on_isize), cast_suggestion, @@ -716,7 +716,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } _ => { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, which {}", msg, will_sign_extend), cast_suggestion, @@ -734,7 +734,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None, ); } else if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, producing the closest possible value", msg), cast_suggestion, @@ -745,7 +745,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (&ty::Uint(_), &ty::Float(_)) | (&ty::Int(_), &ty::Float(_)) => { if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, rounding the float towards zero", msg), cast_suggestion, @@ -760,7 +760,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (&ty::Float(ref exp), &ty::Uint(ref found)) => { // if `found` is `None` (meaning found is `usize`), don't suggest `.into()` if exp.bit_width() > found.bit_width().unwrap_or(256) { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, producing the floating point representation of the \ integer", @@ -769,7 +769,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Applicability::MachineApplicable ); } else if can_cast { - err.span_suggestion_with_applicability(expr.span, + err.span_suggestion( + expr.span, &format!("{}, producing the floating point representation of the \ integer, rounded if necessary", msg), @@ -782,7 +783,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (&ty::Float(ref exp), &ty::Int(ref found)) => { // if `found` is `None` (meaning found is `isize`), don't suggest `.into()` if exp.bit_width() > found.bit_width().unwrap_or(256) { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, producing the floating point representation of the \ integer", @@ -791,7 +792,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Applicability::MachineApplicable ); } else if can_cast { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("{}, producing the floating point representation of the \ integer, rounded if necessary", diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index e71dc019471bd..b7d015729b42d 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -157,7 +157,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (format!("{}()", method_name), Applicability::MaybeIncorrect) }; - err.span_suggestion_with_applicability(method_name.span, msg, suggestion, applicability); + err.span_suggestion(method_name.span, msg, suggestion, applicability); } /// Performs method lookup. If lookup is successful, it will return the callee diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index b849be52a9223..623677482db34 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1144,7 +1144,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { "a method with this name may be added to the standard library in the future", ); - // FIXME: This should be a `span_suggestion_with_applicability` instead of `help` + // FIXME: This should be a `span_suggestion` instead of `help` // However `self.span` only // highlights the method name, so we can't use it. Also consider reusing the code from // `report_method_error()`. diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f71a163cee261..55b6e8f099ea9 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -237,15 +237,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let snippet = tcx.sess.source_map().span_to_snippet(lit.span) .unwrap_or_else(|_| "".to_owned()); - err.span_suggestion_with_applicability( - lit.span, - &format!("you must specify a concrete type for \ - this numeric value, like `{}`", - concrete_type), - format!("{}_{}", - snippet, - concrete_type), - Applicability::MaybeIncorrect, + err.span_suggestion( + lit.span, + &format!("you must specify a concrete type for \ + this numeric value, like `{}`", concrete_type), + format!("{}_{}", snippet, concrete_type), + Applicability::MaybeIncorrect, ); } ExprKind::Path(ref qpath) => { @@ -271,7 +268,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty, .. })) => { - err.span_suggestion_with_applicability( + err.span_suggestion( // account for `let x: _ = 42;` // ^^^^ span.to(ty.as_ref().map(|ty| ty.span) @@ -304,7 +301,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); if let Some(suggestion) = suggestion { // enum variant - err.span_suggestion_with_applicability( + err.span_suggestion( item_name.span, "did you mean", suggestion.to_string(), @@ -404,7 +401,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if static_sources.len() == 1 { if let SelfSource::MethodCall(expr) = source { - err.span_suggestion_with_applicability(expr.span.to(span), + err.span_suggestion(expr.span.to(span), "use associated function syntax instead", format!("{}::{}", self.ty_to_string(actual), @@ -445,7 +442,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if let Some(lev_candidate) = lev_candidate { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "did you mean", lev_candidate.ident.to_string(), @@ -522,12 +519,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ) }); - err.span_suggestions_with_applicability( - span, - &msg, - path_strings, - Applicability::MaybeIncorrect, - ); + err.span_suggestions(span, &msg, path_strings, Applicability::MaybeIncorrect); } else { let limit = if candidates.len() == 5 { 5 } else { 4 }; for (i, trait_did) in candidates.iter().take(limit).enumerate() { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 240db801fb2f2..c94713980d8c0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2903,7 +2903,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let sugg_span = tcx.sess.source_map().end_point(expr_sp); // remove closing `)` from the span let sugg_span = sugg_span.shrink_to_lo(); - err.span_suggestion_with_applicability( + err.span_suggestion( sugg_span, "expected the unit value `()`; create it with empty parentheses", String::from("()"), @@ -3170,7 +3170,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tcx.sess.source_map().span_to_snippet(lhs.span), self.tcx.sess.source_map().span_to_snippet(rhs.span)) { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, msg, format!("{} == {}", left, right), @@ -3587,7 +3587,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(suggested_field_name) = Self::suggest_field_name(def.non_enum_variant(), &field.as_str(), vec![]) { - err.span_suggestion_with_applicability( + err.span_suggestion( field.span, "a field with a similar name exists", suggested_field_name.to_string(), @@ -3618,7 +3618,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { Applicability::MaybeIncorrect }; - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, help, suggestion, applicability ); } @@ -3629,7 +3629,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .unwrap_or_else(|_| self.tcx.hir().node_to_pretty_string(base.id)); let msg = format!("`{}` is a raw pointer; try dereferencing it", base); let suggestion = format!("(*{}).{}", base, field); - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &msg, suggestion, @@ -3719,12 +3719,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(field_name) = Self::suggest_field_name(variant, &field.ident.as_str(), skip_fields.collect()) { - err.span_suggestion_with_applicability( - field.ident.span, - "a field with a similar name exists", - field_name.to_string(), - Applicability::MaybeIncorrect, - ); + err.span_suggestion( + field.ident.span, + "a field with a similar name exists", + field_name.to_string(), + Applicability::MaybeIncorrect, + ); } else { match ty.sty { ty::Adt(adt, ..) => { @@ -4670,11 +4670,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ast::LitIntType::Unsuffixed) = lit.node { let snip = tcx.sess.source_map().span_to_snippet(base.span); if let Ok(snip) = snip { - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, "to access tuple elements, use", format!("{}.{}", snip, i), - Applicability::MachineApplicable); + Applicability::MachineApplicable, + ); needs_note = false; } } @@ -5106,7 +5107,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { found: Ty<'tcx>, ) { if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) { - err.span_suggestion_with_applicability( + err.span_suggestion( sp, msg, suggestion, @@ -5133,7 +5134,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }).peekable(); if suggestions.peek().is_some() { - err.span_suggestions_with_applicability( + err.span_suggestions( expr.span, "try using a conversion method", suggestions, @@ -5172,7 +5173,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ExprKind::Match(..) | ExprKind::Block(..) => { let sp = self.tcx.sess.source_map().next_point(cause_span); - err.span_suggestion_with_applicability( + err.span_suggestion( sp, "try adding a semicolon", ";".to_string(), @@ -5206,7 +5207,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // haven't set a return type at all (and aren't `fn main()` or an impl). match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) { (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try adding a return type", format!("-> {} ", self.resolve_type_vars_with_obligations(found)), @@ -5260,7 +5261,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err: &mut DiagnosticBuilder, ) { if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) { - err.span_suggestion_with_applicability( + err.span_suggestion( span_semi, "consider removing this semicolon", String::new(), @@ -5436,7 +5437,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }, AdtKind::Struct | AdtKind::Union => { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "use curly brackets", String::from("Self { /* fields */ }"), diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 7c871601af308..5efa9f08404d9 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { rty, lstring, ); - err.span_suggestion_with_applicability( + err.span_suggestion( lhs_expr.span, msg, format!("*{}", lstring), @@ -434,7 +434,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err.span_label(expr.span, "`+` can't be used to concatenate two `&str` strings"); match source_map.span_to_snippet(lhs_expr.span) { - Ok(lstring) => err.span_suggestion_with_applicability( + Ok(lstring) => err.span_suggestion( lhs_expr.span, msg, format!("{}.to_owned()", lstring), @@ -455,7 +455,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { is_assign, ) { (Ok(l), Ok(r), false) => { - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( msg, vec![ (lhs_expr.span, format!("{}.to_owned()", l)), diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index bf767726ef715..a7e19fc4237cc 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -136,7 +136,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { .fold(span, |acc, attr_span| acc.to(attr_span)); tcx.struct_span_lint_node(lint, id, span, msg) - .span_suggestion_short_with_applicability( + .span_suggestion_short( span_with_attrs, "remove it", String::new(), @@ -178,7 +178,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { }; let replacement = visibility_qualified(&item.vis, base_replacement); tcx.struct_span_lint_node(lint, id, extern_crate.span, msg) - .span_suggestion_short_with_applicability( + .span_suggestion_short( extern_crate.span, &help, replacement, diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs index 7e1ef8e021350..f75ab47e1ab70 100644 --- a/src/librustc_typeck/structured_errors.rs +++ b/src/librustc_typeck/structured_errors.rs @@ -63,7 +63,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> { ) }; if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) { - err.span_suggestion_with_applicability( + err.span_suggestion( self.span, &format!("cast the value to `{}`", self.cast_ty), format!("{} as {}", snippet, self.cast_ty), diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index a013cc36c722d..8ccd55c17d060 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -62,7 +62,7 @@ impl<'a, 'tcx, 'rcx> SyntaxChecker<'a, 'tcx, 'rcx> { if code_block.syntax.is_none() && code_block.is_fenced { let sp = sp.from_inner_byte_pos(0, 3); - diag.span_suggestion_with_applicability( + diag.span_suggestion( sp, "mark blocks that do not contain Rust code as text", String::from("```text"), diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 1a4b45e76b42d..08c7c617a7bef 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -42,7 +42,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { let mut err = struct_span_err!(diag, span, E0565, "{}", msg); if is_bytestr { if let Ok(lint_str) = sess.source_map().span_to_snippet(span) { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "consider removing the prefix", format!("{}", &lint_str[1..]), @@ -794,7 +794,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { "incorrect `repr(align)` attribute format"); match value.node { ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { - err.span_suggestion_with_applicability( + err.span_suggestion( item.span, "use parentheses instead", format!("align({})", int), @@ -802,7 +802,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { ); } ast::LitKind::Str(s, _) => { - err.span_suggestion_with_applicability( + err.span_suggestion( item.span, "use parentheses instead", format!("align({})", s), diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 50e0056f3b9f1..2930ce079c848 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -155,7 +155,7 @@ impl<'a> StripUnconfigured<'a> { let error = |span, msg, suggestion: &str| { let mut err = self.sess.span_diagnostic.struct_span_err(span, msg); if !suggestion.is_empty() { - err.span_suggestion_with_applicability( + err.span_suggestion( span, "expected syntax is", suggestion.into(), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9369e66cf83da..d1f7b4df9bea4 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -361,7 +361,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let trait_list = traits.iter() .map(|t| t.to_string()).collect::>(); let suggestion = format!("#[derive({})]", trait_list.join(", ")); - err.span_suggestion_with_applicability( + err.span_suggestion( span, "try an outer attribute", suggestion, // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT Applicability::MaybeIncorrect @@ -1043,7 +1043,7 @@ impl<'a> Parser<'a> { let semi_full_span = semi_span.to(self.sess.source_map().next_point(semi_span)); match self.sess.source_map().span_to_snippet(semi_full_span) { Ok(ref snippet) if &snippet[..] != ";" && kind_name == "expression" => { - err.span_suggestion_with_applicability( + err.span_suggestion( semi_span, "you might be missing a semicolon here", ";".to_owned(), @@ -1574,7 +1574,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { _ => (String::from(""), Applicability::HasPlaceholders), }; - err.span_suggestion_with_applicability( + err.span_suggestion( it.span, "provide a file path with `=`", format!("include = \"{}\"", path), diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 9a129e7e8fcd8..176575b67ea92 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -221,7 +221,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, if comma_span.is_dummy() { err.note("you might be missing a comma"); } else { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( comma_span, "missing comma here", ", ".to_string(), diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 8827e04802c33..06f9162a400f6 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -949,7 +949,7 @@ impl<'a> StringReader<'a> { } if i != 0 { suggestion.push('}'); - err.span_suggestion_with_applicability( + err.span_suggestion( self.mk_sp(start, self.pos), "format of unicode escape sequences uses braces", suggestion, @@ -1427,7 +1427,7 @@ impl<'a> StringReader<'a> { self.sess.span_diagnostic .struct_span_err(span, "character literal may only contain one codepoint") - .span_suggestion_with_applicability( + .span_suggestion( span, "if you meant to write a `str` literal, use double quotes", format!("\"{}\"", &self.src[start..end]), diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index c31756714a6c3..7da4284c0e4aa 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -336,7 +336,7 @@ crate fn check_for_substitution<'a>(reader: &StringReader<'a>, let msg = format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", ch, u_name, ascii_char, ascii_name); - err.span_suggestion_with_applicability( + err.span_suggestion( span, &msg, ascii_char.to_string(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 92da05a648152..65572102c5981 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -736,7 +736,7 @@ impl<'a> Parser<'a> { }; let mut err = self.fatal(&msg_exp); if self.token.is_ident_named("and") { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( self.span, "use `&&` instead of `and` for the boolean operator", "&&".to_string(), @@ -744,7 +744,7 @@ impl<'a> Parser<'a> { ); } if self.token.is_ident_named("or") { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( self.span, "use `||` instead of `or` for the boolean operator", "||".to_string(), @@ -810,7 +810,7 @@ impl<'a> Parser<'a> { if ident.is_reserved() && !ident.is_path_segment_keyword() && ident.name != keywords::Underscore.name() { - err.span_suggestion_with_applicability( + err.span_suggestion( self.span, "you can escape reserved keywords to use them as identifiers", format!("r#{}", ident), @@ -823,7 +823,7 @@ impl<'a> Parser<'a> { } else { err.span_label(self.span, "expected identifier"); if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) { - err.span_suggestion_with_applicability( + err.span_suggestion( self.span, "remove this comma", String::new(), @@ -1696,7 +1696,7 @@ impl<'a> Parser<'a> { if !allow_plus && impl_dyn_multi { let sum_with_parens = format!("({})", pprust::ty_to_string(&ty)); self.struct_span_err(ty.span, "ambiguous `+` in a type") - .span_suggestion_with_applicability( + .span_suggestion( ty.span, "use parentheses to disambiguate", sum_with_parens, @@ -1731,7 +1731,7 @@ impl<'a> Parser<'a> { s.print_type_bounds(" +", &bounds)?; s.pclose() }); - err.span_suggestion_with_applicability( + err.span_suggestion( sum_span, "try adding parentheses", sum_with_parens, @@ -1774,7 +1774,7 @@ impl<'a> Parser<'a> { self.diagnostic() .struct_span_err(span, "missing angle brackets in associated item path") - .span_suggestion_with_applicability( // this is a best-effort recovery + .span_suggestion( // this is a best-effort recovery span, "try", recovered.to_string(), Applicability::MaybeIncorrect ).emit(); @@ -1878,7 +1878,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident().unwrap(); let span = pat.span.with_hi(ident.span.hi()); - err.span_suggestion_with_applicability( + err.span_suggestion( span, "declare the type after the parameter binding", String::from(": "), @@ -1886,7 +1886,7 @@ impl<'a> Parser<'a> { ); } else if require_name && is_trait_item { if let PatKind::Ident(_, ident, _) = pat.node { - err.span_suggestion_with_applicability( + err.span_suggestion( pat.span, "explicitly ignore parameter", format!("_: {}", ident), @@ -1937,7 +1937,7 @@ impl<'a> Parser<'a> { "patterns aren't allowed in methods without bodies", DiagnosticId::Error("E0642".into()), ); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( pat.span, "give this argument a name or use an underscore to ignore it", "_".to_owned(), @@ -2034,7 +2034,7 @@ impl<'a> Parser<'a> { let sp = lo.to(self.prev_span); let mut err = self.diagnostic() .struct_span_err(sp, "float literals must have an integer part"); - err.span_suggestion_with_applicability( + err.span_suggestion( sp, "must have an integer part", format!("0.{}{}", val, suffix), @@ -2365,7 +2365,7 @@ impl<'a> Parser<'a> { if self.token == token::Eq { self.diagnostic() .struct_span_err(self.span, "expected `:`, found `=`") - .span_suggestion_with_applicability( + .span_suggestion( fieldname.span.shrink_to_hi().to(self.span), "replace equals symbol with a colon", ":".to_string(), @@ -2751,7 +2751,7 @@ impl<'a> Parser<'a> { exp_span.to(self.prev_span), "cannot use a comma after the base struct", ); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( self.span, "remove this comma", String::new(), @@ -3019,7 +3019,7 @@ impl<'a> Parser<'a> { span, &format!("unmatched angle bracket{}", if plural { "s" } else { "" }), ) - .span_suggestion_with_applicability( + .span_suggestion( span, &format!("remove extra angle bracket{}", if plural { "s" } else { "" }), String::new(), @@ -3072,7 +3072,7 @@ impl<'a> Parser<'a> { s.s.word(".")?; s.s.word(fstr.splitn(2, ".").last().unwrap().to_string()) }); - err.span_suggestion_with_applicability( + err.span_suggestion( lo.to(self.prev_span), "try parenthesizing the first index", sugg, @@ -3219,7 +3219,7 @@ impl<'a> Parser<'a> { let span_of_tilde = lo; let mut err = self.diagnostic() .struct_span_err(span_of_tilde, "`~` cannot be used as a unary operator"); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( span_of_tilde, "use `!` to perform bitwise negation", "!".to_owned(), @@ -3292,7 +3292,7 @@ impl<'a> Parser<'a> { // trailing whitespace after the `!` in our suggestion let to_replace = self.sess.source_map() .span_until_non_whitespace(lo.to(self.span)); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( to_replace, "use `!` to perform logical negation", "!".to_owned(), @@ -3393,7 +3393,7 @@ impl<'a> Parser<'a> { let cur_pos = cm.lookup_char_pos(self.span.lo()); let op_pos = cm.lookup_char_pos(cur_op_span.hi()); if cur_pos.line != op_pos.line { - err.span_suggestion_with_applicability( + err.span_suggestion( cur_op_span, "try using a semicolon", ";".to_string(), @@ -3552,7 +3552,7 @@ impl<'a> Parser<'a> { let expr_str = self.sess.source_map().span_to_snippet(expr.span) .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - err.span_suggestion_with_applicability( + err.span_suggestion( expr.span, &format!("try {} the cast value", op_verb), format!("({})", expr_str), @@ -3768,7 +3768,7 @@ impl<'a> Parser<'a> { let in_span = self.prev_span.between(self.span); let mut err = self.sess.span_diagnostic .struct_span_err(in_span, "missing `in` in `for` loop"); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( in_span, "try adding `in` here", " in ".into(), // has been misleading, at least in the past (closed Issue #48492) Applicability::MaybeIncorrect @@ -3782,7 +3782,7 @@ impl<'a> Parser<'a> { self.prev_span, "expected iterable, found keyword `in`", ); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( in_span.until(self.prev_span), "remove the duplicated `in`", String::new(), @@ -3874,7 +3874,7 @@ impl<'a> Parser<'a> { None)?; if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) { if self.token == token::Token::Semi { - e.span_suggestion_short_with_applicability( + e.span_suggestion_short( match_span, "try removing this `match`", String::new(), @@ -3949,7 +3949,7 @@ impl<'a> Parser<'a> { // | - ^^ self.span // | | // | parsed until here as `"y" & X` - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( cm.next_point(arm_start_span), "missing a comma here to end this `match` arm", ",".to_owned(), @@ -4026,7 +4026,7 @@ impl<'a> Parser<'a> { if self.token == token::OrOr { let mut err = self.struct_span_err(self.span, "unexpected token `||` after pattern"); - err.span_suggestion_with_applicability( + err.span_suggestion( self.span, "use a single `|` to specify multiple patterns", "|".to_owned(), @@ -4234,7 +4234,7 @@ impl<'a> Parser<'a> { // Accept `...` as if it were `..` to avoid further errors let mut err = self.struct_span_err(self.span, "expected field pattern, found `...`"); - err.span_suggestion_with_applicability( + err.span_suggestion( self.span, "to omit remaining fields, use one fewer `.`", "..".to_owned(), @@ -4266,7 +4266,7 @@ impl<'a> Parser<'a> { if self.token == token::CloseDelim(token::Brace) { // If the struct looks otherwise well formed, recover and continue. if let Some(sp) = comma_sp { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, "remove this comma", String::new(), @@ -4308,7 +4308,7 @@ impl<'a> Parser<'a> { if let Some(mut err) = delayed_err { if let Some(etc_span) = etc_span { - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( "move the `..` to the end of the field list", vec![ (etc_span, String::new()), @@ -4379,7 +4379,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern"); if let Ok(seq_snippet) = self.sess.source_map().span_to_snippet(seq_span) { - err.span_suggestion_with_applicability( + err.span_suggestion( seq_span, "try adding parentheses", format!("({})", seq_snippet), @@ -4447,7 +4447,7 @@ impl<'a> Parser<'a> { let binding_mode = if self.eat_keyword(keywords::Ref) { self.diagnostic() .struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect") - .span_suggestion_with_applicability( + .span_suggestion( mutref_span, "try switching the order", "ref mut".into(), @@ -4591,7 +4591,7 @@ impl<'a> Parser<'a> { pat.span, "the range pattern here has ambiguous interpretation", ); - err.span_suggestion_with_applicability( + err.span_suggestion( pat.span, "add parentheses to clarify the precedence", format!("({})", pprust::pat_to_string(&pat)), @@ -4667,7 +4667,7 @@ impl<'a> Parser<'a> { (Ok(init), Some((_, colon_sp, mut err))) => { // init parsed, ty error // Could parse the type as if it were the initializer, it is likely there was a // typo in the code: `:` instead of `=`. Add suggestion and emit the error. - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( colon_sp, "use `=` if you meant to assign", "=".to_string(), @@ -5170,7 +5170,7 @@ impl<'a> Parser<'a> { self.token.is_keyword(keywords::In) || self.token == token::Colon; if self.token.is_ident_named("and") { - e.span_suggestion_short_with_applicability( + e.span_suggestion_short( self.span, "use `&&` instead of `and` for the boolean operator", "&&".to_string(), @@ -5178,7 +5178,7 @@ impl<'a> Parser<'a> { ); } if self.token.is_ident_named("or") { - e.span_suggestion_short_with_applicability( + e.span_suggestion_short( self.span, "use `||` instead of `or` for the boolean operator", "||".to_string(), @@ -5213,7 +5213,7 @@ impl<'a> Parser<'a> { s.print_stmt(&stmt)?; s.bclose_maybe_open(stmt.span, INDENT_UNIT, false) }); - e.span_suggestion_with_applicability( + e.span_suggestion( stmt_span, "try placing this code inside a block", sugg, @@ -5331,10 +5331,10 @@ impl<'a> Parser<'a> { fn err_dotdotdot_syntax(&self, span: Span) { self.diagnostic().struct_span_err(span, { "unexpected token: `...`" - }).span_suggestion_with_applicability( + }).span_suggestion( span, "use `..` for an exclusive range", "..".to_owned(), Applicability::MaybeIncorrect - ).span_suggestion_with_applicability( + ).span_suggestion( span, "or `..=` for an inclusive range", "..=".to_owned(), Applicability::MaybeIncorrect ).emit(); @@ -5534,7 +5534,7 @@ impl<'a> Parser<'a> { "lifetime parameters must be declared prior to type parameters", ); if !suggestions.is_empty() { - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( "move the lifetime parameter prior to the first type parameter", suggestions, Applicability::MachineApplicable, @@ -5702,7 +5702,7 @@ impl<'a> Parser<'a> { if plural { "s" } else { "" } ), ) - .span_suggestion_with_applicability( + .span_suggestion( span, &format!( "remove extra angle bracket{}", @@ -5863,7 +5863,7 @@ impl<'a> Parser<'a> { suggestions.extend_from_slice(&type_suggestions); let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1; - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( &format!( "move the parameter{}", if plural { "s" } else { "" }, @@ -5872,7 +5872,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } else if !lifetime_suggestions.is_empty() { - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( &format!( "move the lifetime parameter{} prior to the first type parameter", if bad_lifetime_pos.len() > 1 { "s" } else { "" }, @@ -5881,7 +5881,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } else if !type_suggestions.is_empty() { - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( &format!( "move the type parameter{} prior to the first associated type binding", if bad_type_pos.len() > 1 { "s" } else { "" }, @@ -6385,7 +6385,7 @@ impl<'a> Parser<'a> { let mut err = if is_macro_rules { let mut err = self.diagnostic() .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`"); - err.span_suggestion_with_applicability( + err.span_suggestion( sp, "try exporting the macro", "#[macro_export]".to_owned(), @@ -6593,7 +6593,7 @@ impl<'a> Parser<'a> { // impl Trait for Type if !has_for { self.struct_span_err(missing_for_span, "missing `for` in a trait impl") - .span_suggestion_short_with_applicability( + .span_suggestion_short( missing_for_span, "add `for` here", " for ".to_string(), @@ -6817,7 +6817,7 @@ impl<'a> Parser<'a> { } else { if seen_comma == false { let sp = self.sess.source_map().next_point(previous_span); - err.span_suggestion_with_applicability( + err.span_suggestion( sp, "missing comma here", ",".into(), @@ -6833,7 +6833,7 @@ impl<'a> Parser<'a> { self.this_token_descr())); if self.token.is_ident() { // This is likely another field; emit the diagnostic and keep going - err.span_suggestion_with_applicability( + err.span_suggestion( sp, "try adding a comma", ",".into(), @@ -6931,7 +6931,7 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Paren))?; // `)` let mut err = struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg); err.help(suggestion); - err.span_suggestion_with_applicability( + err.span_suggestion( sp, &help_msg, format!("in {}", path), Applicability::MachineApplicable ); err.emit(); // emit diagnostic, but continue with public visibility @@ -6962,7 +6962,7 @@ impl<'a> Parser<'a> { fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { if self.eat(&token::Semi) { let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`"); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( self.prev_span, "remove this semicolon", String::new(), @@ -7390,7 +7390,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(fixed_name_sp, error_msg); err.span_label(fixed_name_sp, "dash-separated idents are not valid"); - err.multipart_suggestion_with_applicability( + err.multipart_suggestion( suggestion_msg, replacement, Applicability::MachineApplicable, @@ -7759,7 +7759,7 @@ impl<'a> Parser<'a> { let mut err = self.diagnostic() .struct_span_err(prev_span, "const globals cannot be mutable"); err.span_label(prev_span, "cannot be mutable"); - err.span_suggestion_with_applicability( + err.span_suggestion( const_span, "you might want to declare a static instead", "static".to_owned(), @@ -7996,7 +7996,7 @@ impl<'a> Parser<'a> { ident); let mut err = self.diagnostic() .struct_span_err(sp, "missing `struct` for struct definition"); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, &msg, " struct ".into(), Applicability::MaybeIncorrect // speculative ); return Err(err); @@ -8031,12 +8031,12 @@ impl<'a> Parser<'a> { kw, ident, kw_name); - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, &suggestion, format!(" {} ", kw), Applicability::MachineApplicable ); } else { if let Ok(snippet) = self.sess.source_map().span_to_snippet(ident_sp) { - err.span_suggestion_with_applicability( + err.span_suggestion( full_sp, "if you meant to call a macro, try", format!("{}!", snippet), @@ -8067,7 +8067,7 @@ impl<'a> Parser<'a> { let msg = format!("missing `{}` for {} definition", kw, kw_name); let mut err = self.diagnostic().struct_span_err(sp, &msg); if !ambiguous { - err.span_suggestion_short_with_applicability( + err.span_suggestion_short( sp, &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name), format!(" {} ", kw), @@ -8094,7 +8094,7 @@ impl<'a> Parser<'a> { if self.token.is_keyword(keywords::Const) { self.diagnostic() .struct_span_err(self.span, "extern items cannot be `const`") - .span_suggestion_with_applicability( + .span_suggestion( self.span, "try using a static value", "static".to_owned(), diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 215df4224c5f1..4c473fe7612af 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -763,7 +763,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, 0 => "{}".to_string(), _ => format!("{}{{}}", "{} ".repeat(args.len())), }; - err.span_suggestion_with_applicability( + err.span_suggestion( fmt_sp.shrink_to_lo(), "you might be missing a string literal to format with", format!("\"{}\", ", sugg_fmt), @@ -1080,7 +1080,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, )); } if suggestions.len() > 0 { - diag.multipart_suggestion_with_applicability( + diag.multipart_suggestion( "format specifiers use curly braces", suggestions, Applicability::MachineApplicable, From c1437c944c280ff9d761c45912167f1023d0e24c Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 25 Jan 2019 18:22:44 +0100 Subject: [PATCH 0349/1064] Make NiceRegionError use the `InferCtxt` instead of its `TyCtxt` Some errors (e.g placeholder errors) have unresolved type vars so this will allow to use `resolve_type_vars_if_possible` when needed. --- .../nice_region_error/different_lifetimes.rs | 6 +++--- .../nice_region_error/find_anon_type.rs | 8 ++++---- .../error_reporting/nice_region_error/mod.rs | 18 ++++++++++------- .../nice_region_error/named_anon_conflict.rs | 10 +++++----- .../nice_region_error/outlives_closure.rs | 4 ++-- .../nice_region_error/placeholder_error.rs | 20 +++++++++---------- .../nice_region_error/static_impl_trait.rs | 10 +++++----- .../error_reporting/nice_region_error/util.rs | 14 ++++++------- .../nll/region_infer/error_reporting/mod.rs | 2 +- 9 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index bfb5b61d0aa1f..8be49b2792441 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -46,9 +46,9 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let (span, sub, sup) = self.get_regions(); // Determine whether the sub and sup consist of both anonymous (elided) regions. - let anon_reg_sup = self.tcx.is_suitable_region(sup)?; + let anon_reg_sup = self.tcx().is_suitable_region(sup)?; - let anon_reg_sub = self.tcx.is_suitable_region(sub)?; + let anon_reg_sub = self.tcx().is_suitable_region(sub)?; let scope_def_id_sup = anon_reg_sup.def_id; let bregion_sup = anon_reg_sup.boundregion; let scope_def_id_sub = anon_reg_sub.def_id; @@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { }; - struct_span_err!(self.tcx.sess, span, E0623, "lifetime mismatch") + struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch") .span_label(span_1, main_label) .span_label(span_2, String::new()) .span_label(span, span_label) diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs index d230ce55471e9..eeaa01375ed4d 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -26,10 +26,10 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { region: Region<'tcx>, br: &ty::BoundRegion, ) -> Option<(&hir::Ty, &hir::FnDecl)> { - if let Some(anon_reg) = self.tcx.is_suitable_region(region) { + if let Some(anon_reg) = self.tcx().is_suitable_region(region) { let def_id = anon_reg.def_id; - if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) { - let fndecl = match self.tcx.hir().get(node_id) { + if let Some(node_id) = self.tcx().hir().as_local_node_id(def_id) { + let fndecl = match self.tcx().hir().get(node_id) { Node::Item(&hir::Item { node: hir::ItemKind::Fn(ref fndecl, ..), .. @@ -64,7 +64,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { br: &ty::BoundRegion, ) -> Option<(&'gcx hir::Ty)> { let mut nested_visitor = FindNestedTypeVisitor { - tcx: self.tcx, + tcx: self.tcx(), bound_region: *br, found_type: None, current_index: ty::INNERMOST, diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index f7ba546fa7f3b..d34b71c33f4b4 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -22,15 +22,15 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { if let Some(tables) = self.in_progress_tables { let tables = tables.borrow(); - NiceRegionError::new(self.tcx, error.clone(), Some(&tables)).try_report().is_some() + NiceRegionError::new(self, error.clone(), Some(&tables)).try_report().is_some() } else { - NiceRegionError::new(self.tcx, error.clone(), None).try_report().is_some() + NiceRegionError::new(self, error.clone(), None).try_report().is_some() } } } pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> { - tcx: TyCtxt<'cx, 'gcx, 'tcx>, + infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, error: Option>, regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>, tables: Option<&'cx ty::TypeckTables<'tcx>>, @@ -38,21 +38,25 @@ pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> { impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> { pub fn new( - tcx: TyCtxt<'cx, 'gcx, 'tcx>, + infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, error: RegionResolutionError<'tcx>, tables: Option<&'cx ty::TypeckTables<'tcx>>, ) -> Self { - Self { tcx, error: Some(error), regions: None, tables } + Self { infcx, error: Some(error), regions: None, tables } } pub fn new_from_span( - tcx: TyCtxt<'cx, 'gcx, 'tcx>, + infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, span: Span, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, tables: Option<&'cx ty::TypeckTables<'tcx>>, ) -> Self { - Self { tcx, error: None, regions: Some((span, sub, sup)), tables } + Self { infcx, error: None, regions: Some((span, sub, sup)), tables } + } + + fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> { + self.infcx.tcx } pub fn try_report_from_nll(&self) -> Option { diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 918a46aacd041..05333f4337336 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -24,23 +24,23 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { // version new_ty of its type where the anonymous region is replaced // with the named one.//scope_def_id let (named, anon, anon_arg_info, region_info) = if self.is_named_region(sub) - && self.tcx.is_suitable_region(sup).is_some() + && self.tcx().is_suitable_region(sup).is_some() && self.find_arg_with_region(sup, sub).is_some() { ( sub, sup, self.find_arg_with_region(sup, sub).unwrap(), - self.tcx.is_suitable_region(sup).unwrap(), + self.tcx().is_suitable_region(sup).unwrap(), ) - } else if self.is_named_region(sup) && self.tcx.is_suitable_region(sub).is_some() + } else if self.is_named_region(sup) && self.tcx().is_suitable_region(sub).is_some() && self.find_arg_with_region(sub, sup).is_some() { ( sup, sub, self.find_arg_with_region(sub, sup).unwrap(), - self.tcx.is_suitable_region(sub).unwrap(), + self.tcx().is_suitable_region(sub).unwrap(), ) } else { return None; // inapplicable @@ -97,7 +97,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { }; struct_span_err!( - self.tcx.sess, + self.tcx().sess, span, E0621, "explicit lifetime required in {}", diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs index c4c71037d8b35..cbd36a8b2db8a 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs @@ -47,7 +47,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { // closure, provide a specific message pointing this out. if let (&SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span), &RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) { - let hir = &self.tcx.hir(); + let hir = &self.tcx().hir(); if let Some(node_id) = hir.as_local_node_id(free_region.scope) { if let Node::Expr(Expr { node: Closure(_, _, _, closure_span, None), @@ -55,7 +55,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { }) = hir.get(node_id) { let sup_sp = sup_origin.span(); let origin_sp = origin.span(); - let mut err = self.tcx.sess.struct_span_err( + let mut err = self.tcx().sess.struct_span_err( sup_sp, "borrowed data cannot be stored outside of its closure"); err.span_label(sup_sp, "cannot be stored outside of its closure"); diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 0dda636a9bd53..7ece3d38a7f3e 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -38,7 +38,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { if expected.def_id == found.def_id => { Some(self.try_report_placeholders_trait( - Some(self.tcx.mk_region(ty::ReVar(*vid))), + Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, Some(sub_placeholder), Some(sup_placeholder), @@ -62,7 +62,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { if expected.def_id == found.def_id => { Some(self.try_report_placeholders_trait( - Some(self.tcx.mk_region(ty::ReVar(*vid))), + Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, Some(sub_placeholder), None, @@ -86,7 +86,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { if expected.def_id == found.def_id => { Some(self.try_report_placeholders_trait( - Some(self.tcx.mk_region(ty::ReVar(*vid))), + Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, None, Some(*sup_placeholder), @@ -182,11 +182,11 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { expected_substs: &'tcx Substs<'tcx>, actual_substs: &'tcx Substs<'tcx>, ) -> ErrorReported { - let mut err = self.tcx.sess.struct_span_err( - cause.span(&self.tcx), + let mut err = self.tcx().sess.struct_span_err( + cause.span(&self.tcx()), &format!( "implementation of `{}` is not general enough", - self.tcx.item_path_str(trait_def_id), + self.tcx().item_path_str(trait_def_id), ), ); @@ -194,7 +194,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { ObligationCauseCode::ItemObligation(def_id) => { err.note(&format!( "Due to a where-clause on `{}`,", - self.tcx.item_path_str(def_id), + self.tcx().item_path_str(def_id), )); } _ => (), @@ -220,7 +220,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { let mut has_sup = None; let mut has_vid = None; - self.tcx.for_each_free_region(&expected_trait_ref, |r| { + self.tcx().for_each_free_region(&expected_trait_ref, |r| { if Some(r) == sub_placeholder && has_sub.is_none() { has_sub = Some(counter); counter += 1; @@ -230,7 +230,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } }); - self.tcx.for_each_free_region(&actual_trait_ref, |r| { + self.tcx().for_each_free_region(&actual_trait_ref, |r| { if Some(r) == vid && has_vid.is_none() { has_vid = Some(counter); counter += 1; @@ -238,7 +238,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { }); let self_ty_has_vid = self - .tcx + .tcx() .any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid); RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || { diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs index 7501e2f210888..4331518d403dd 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -19,13 +19,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { sup_r, ) = error.clone() { - let anon_reg_sup = self.tcx.is_suitable_region(sup_r)?; + let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; if sub_r == &RegionKind::ReStatic && - self.tcx.return_type_impl_trait(anon_reg_sup.def_id).is_some() + self.tcx().return_type_impl_trait(anon_reg_sup.def_id).is_some() { let sp = var_origin.span(); let return_sp = sub_origin.span(); - let mut err = self.tcx.sess.struct_span_err( + let mut err = self.tcx().sess.struct_span_err( sp, "cannot infer an appropriate lifetime", ); @@ -38,7 +38,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { "...but this borrow...", ); - let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r); + let (lifetime, lt_sp_opt) = self.tcx().msg_span_from_free_region(sup_r); if let Some(lifetime_sp) = lt_sp_opt { err.span_note( lifetime_sp, @@ -52,7 +52,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { }) => name.to_string(), _ => "'_".to_owned(), }; - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) { + if let Ok(snippet) = self.tcx().sess.source_map().span_to_snippet(return_sp) { err.span_suggestion( return_sp, &format!( diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index 43590a606ae90..dd8a33829eb53 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -44,13 +44,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let (id, bound_region) = match *anon_region { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ref ebr) => ( - self.tcx.parent_def_id(ebr.def_id).unwrap(), + self.tcx().parent_def_id(ebr.def_id).unwrap(), ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region }; - let hir = &self.tcx.hir(); + let hir = &self.tcx().hir(); if let Some(node_id) = hir.as_local_node_id(id) { if let Some(body_id) = hir.maybe_body_owned_by(node_id) { let body = hir.body(body_id); @@ -66,7 +66,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let arg_ty_span = hir.span(hir.hir_to_node_id(ty_hir_id)); let ty = tables.node_id_to_type_opt(arg.hir_id)?; let mut found_anon_region = false; - let new_arg_ty = self.tcx.fold_regions(&ty, &mut false, |r, _| { + let new_arg_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| { if *r == *anon_region { found_anon_region = true; replace_region @@ -108,10 +108,10 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { br: ty::BoundRegion, decl: &hir::FnDecl, ) -> Option { - let ret_ty = self.tcx.type_of(scope_def_id); + let ret_ty = self.tcx().type_of(scope_def_id); if let ty::FnDef(_, _) = ret_ty.sty { - let sig = ret_ty.fn_sig(self.tcx); - let late_bound_regions = self.tcx + let sig = ret_ty.fn_sig(self.tcx()); + let late_bound_regions = self.tcx() .collect_referenced_late_bound_regions(&sig.output()); if late_bound_regions.iter().any(|r| *r == br) { return Some(decl.output.span()); @@ -126,7 +126,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { // enable E0621 for it. pub(super) fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool { is_first - && self.tcx + && self.tcx() .opt_associated_item(scope_def_id) .map(|i| i.method_has_self_argument) == Some(true) } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index f07880075c100..ec68ddaf3c852 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -243,7 +243,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let tables = infcx.tcx.typeck_tables_of(mir_def_id); - let nice = NiceRegionError::new_from_span(infcx.tcx, span, o, f, Some(tables)); + let nice = NiceRegionError::new_from_span(infcx, span, o, f, Some(tables)); if let Some(_error_reported) = nice.try_report_from_nll() { return; } From a6028263d2c9c3568f86e57d6b8400e05d3cfe1b Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 25 Jan 2019 18:35:47 +0100 Subject: [PATCH 0350/1064] Handle higher-ranked lifetime conflict errors where the subtype is the `sup` region These are happening since the switch to universes, and will now go through the "placeholder error" path, instead of the current fallback of E308 "mismatched types" errors. --- .../nice_region_error/placeholder_error.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 7ece3d38a7f3e..636b66bef01cf 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -96,6 +96,30 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { )) } + Some(RegionResolutionError::SubSupConflict( + vid, + _, + _, + _, + SubregionOrigin::Subtype(TypeTrace { + cause, + values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), + }), + sup_placeholder @ ty::RePlaceholder(_), + )) + if expected.def_id == found.def_id => + { + Some(self.try_report_placeholders_trait( + Some(self.tcx().mk_region(ty::ReVar(*vid))), + cause, + None, + Some(*sup_placeholder), + expected.def_id, + expected.substs, + found.substs, + )) + } + Some(RegionResolutionError::ConcreteFailure( SubregionOrigin::Subtype(TypeTrace { cause, From 823c888be297230389a25c9e79e39811a6f61537 Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 25 Jan 2019 18:39:51 +0100 Subject: [PATCH 0351/1064] Try to resolve type vars in the placeholder errors trait refs These can sometimes be unresolved: some of the rustc UI tests show this. --- .../nice_region_error/placeholder_error.rs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 636b66bef01cf..892c56bf834fe 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -224,14 +224,18 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { _ => (), } - let expected_trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: expected_substs, - }; - let actual_trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: actual_substs, - }; + let expected_trait_ref = self.infcx.resolve_type_vars_if_possible( + &ty::TraitRef { + def_id: trait_def_id, + substs: expected_substs, + } + ); + let actual_trait_ref = self.infcx.resolve_type_vars_if_possible( + &ty::TraitRef { + def_id: trait_def_id, + substs: actual_substs, + } + ); // Search the expected and actual trait references to see (a) // whether the sub/sup placeholders appear in them (sometimes From 55389f9171d3e8e05230ae5ea3d07b9c7e54705d Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 25 Jan 2019 19:02:38 +0100 Subject: [PATCH 0352/1064] Try to reword placeholder error messages to make them clearer --- .../nice_region_error/placeholder_error.rs | 76 +++++++++++-------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 892c56bf834fe..b5187d2dbb6ce 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -246,7 +246,9 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { let mut counter = 0; let mut has_sub = None; let mut has_sup = None; - let mut has_vid = None; + + let mut actual_has_vid = None; + let mut expected_has_vid = None; self.tcx().for_each_free_region(&expected_trait_ref, |r| { if Some(r) == sub_placeholder && has_sub.is_none() { @@ -256,11 +258,16 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { has_sup = Some(counter); counter += 1; } + + if Some(r) == vid && expected_has_vid.is_none() { + expected_has_vid = Some(counter); + counter += 1; + } }); self.tcx().for_each_free_region(&actual_trait_ref, |r| { - if Some(r) == vid && has_vid.is_none() { - has_vid = Some(counter); + if Some(r) == vid && actual_has_vid.is_none() { + actual_has_vid = Some(counter); counter += 1; } }); @@ -274,60 +281,67 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { match (has_sub, has_sup) { (Some(n1), Some(n2)) => { err.note(&format!( - "`{}` must implement `{}` \ - for any two lifetimes `'{}` and `'{}`", - expected_trait_ref.self_ty(), + "`{}` would have to be implemented for the type `{}`, \ + for any two lifetimes `'{}` and `'{}`", expected_trait_ref, + expected_trait_ref.self_ty(), std::cmp::min(n1, n2), std::cmp::max(n1, n2), )); } (Some(n), _) | (_, Some(n)) => { err.note(&format!( - "`{}` must implement `{}` \ - for any lifetime `'{}`", - expected_trait_ref.self_ty(), + "`{}` would have to be implemented for the type `{}`, \ + for any lifetime `'{}`", expected_trait_ref, + expected_trait_ref.self_ty(), n, )); } (None, None) => { err.note(&format!( - "`{}` must implement `{}`", - expected_trait_ref.self_ty(), + "`{}` would have to be implemented for the type `{}`", expected_trait_ref, + expected_trait_ref.self_ty(), )); } } }) }); - RegionHighlightMode::maybe_highlighting_region(vid, has_vid, || match has_vid { - Some(n) => { - if self_ty_has_vid { + RegionHighlightMode::maybe_highlighting_region( + vid, + actual_has_vid.or(expected_has_vid), + || match actual_has_vid { + Some(n) => { + if self_ty_has_vid { + err.note(&format!( + "but `{}` is actually implemented for the type `{}`, \ + for the specific lifetime `'{}`", + actual_trait_ref, + actual_trait_ref.self_ty(), + n + )); + } else { + err.note(&format!( + "but `{}` is actually implemented for the type `{}`, \ + for some lifetime `'{}`", + actual_trait_ref, + actual_trait_ref.self_ty(), + n + )); + } + } + + _ => { err.note(&format!( - "but `{}` only implements `{}` for the lifetime `'{}`", - actual_trait_ref.self_ty(), + "but `{}` is actually implemented for the type `{}`", actual_trait_ref, - n - )); - } else { - err.note(&format!( - "but `{}` only implements `{}` for some lifetime `'{}`", actual_trait_ref.self_ty(), - actual_trait_ref, - n )); } } - None => { - err.note(&format!( - "but `{}` only implements `{}`", - actual_trait_ref.self_ty(), - actual_trait_ref, - )); - } - }); + ); err.emit(); ErrorReported From ce61b1b9fac1d175e13a5f21ffe93cd76dd64481 Mon Sep 17 00:00:00 2001 From: lqd Date: Fri, 25 Jan 2019 19:04:26 +0100 Subject: [PATCH 0353/1064] Update two E308 tests to the new placeholder error --- src/test/ui/associated-types/higher-ranked-projection.rs | 2 +- src/test/ui/hrtb/hrtb-perfect-forwarding.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs index 5b380c982f041..1280c8cb4cb09 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.rs +++ b/src/test/ui/associated-types/higher-ranked-projection.rs @@ -23,5 +23,5 @@ fn foo(_t: T) #[rustc_error] fn main() { //[good]~ ERROR compilation successful foo(()); - //[bad]~^ ERROR E0308 + //[bad]~^ ERROR not general enough } diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs index 7bd89960e42e5..0094091c6bd76 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs @@ -43,7 +43,7 @@ fn foo_hrtb_bar_not<'b,T>(mut t: T) // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where // clause only specifies `T : Bar<&'b isize>`. - foo_hrtb_bar_not(&mut t); //~ ERROR E0308 + foo_hrtb_bar_not(&mut t); //~ ERROR not general enough } fn foo_hrtb_bar_hrtb(mut t: T) From a79f135be616588e83d18b4694d97470e986497a Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Fri, 25 Jan 2019 19:17:38 +0100 Subject: [PATCH 0354/1064] Update test expectations for new placeholder error messages --- .../associated-types-eq-hr.stderr | 12 ++++++------ .../higher-ranked-projection.bad.stderr | 10 +++++----- .../higher-ranked-projection.good.stderr | 2 +- src/test/ui/generator/auto-trait-regions.stderr | 8 ++++---- src/test/ui/hrtb/hrtb-cache-issue-54302.stderr | 4 ++-- src/test/ui/hrtb/hrtb-conflate-regions.stderr | 4 ++-- .../hrtb-exists-forall-trait-invariant.stderr | 4 ++-- src/test/ui/hrtb/hrtb-just-for-static.stderr | 8 ++++---- src/test/ui/hrtb/hrtb-perfect-forwarding.stderr | 12 ++++++------ src/test/ui/issues/issue-54302-cases.stderr | 16 ++++++++-------- src/test/ui/issues/issue-54302.stderr | 4 ++-- .../ui/where-clauses/where-for-self-2.stderr | 4 ++-- 12 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index d3eaa894b5043..0e471a78d9ed8 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -41,8 +41,8 @@ LL | tuple_one::(); | ^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `tuple_one`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>` for any two lifetimes `'0` and `'1` - = note: but `Tuple` only implements `TheTrait<(&'2 isize, &'2 isize)>` for some lifetime `'2` + = note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1` + = note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2` error: implementation of `TheTrait` is not general enough --> $DIR/associated-types-eq-hr.rs:96:5 @@ -51,8 +51,8 @@ LL | tuple_two::(); | ^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `tuple_two`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>` for any two lifetimes `'0` and `'1` - = note: but `Tuple` only implements `TheTrait<(&'2 isize, &'2 isize)>` for some lifetime `'2` + = note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1` + = note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2` error: implementation of `TheTrait` is not general enough --> $DIR/associated-types-eq-hr.rs:105:5 @@ -61,8 +61,8 @@ LL | tuple_four::(); | ^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `tuple_four`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>` for any two lifetimes `'0` and `'1` - = note: but `Tuple` only implements `TheTrait<(&'2 isize, &'2 isize)>` for some lifetime `'2` + = note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1` + = note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2` error: aborting due to 5 previous errors diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index e4704494e1492..69fa1ce30aa8f 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -1,12 +1,12 @@ -error[E0308]: mismatched types +error: implementation of `Mirror` is not general enough --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^ one type is more general than the other + | ^^^ | - = note: expected type `Mirror` - found type `Mirror` + = note: Due to a where-clause on `foo`, + = note: `Mirror` would have to be implemented for the type `&'0 ()`, for any lifetime `'0` + = note: but `Mirror` is actually implemented for the type `&'1 ()`, for the specific lifetime `'1` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr index db15ec51d87c6..c5c8451a5a9db 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr @@ -3,7 +3,7 @@ error: compilation successful | LL | / fn main() { //[good]~ ERROR compilation successful LL | | foo(()); -LL | | //[bad]~^ ERROR E0308 +LL | | //[bad]~^ ERROR not general enough LL | | } | |_^ diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index 1b4dfe2df1c0c..680a7bbc50e5e 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -4,8 +4,8 @@ error: implementation of `Foo` is not general enough LL | assert_foo(gen); | ^^^^^^^^^^ | - = note: `&'0 OnlyFooIfStaticRef` must implement `Foo` for any lifetime `'0` - = note: but `&'1 OnlyFooIfStaticRef` only implements `Foo` for the lifetime `'1` + = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0` + = note: but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for the specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:48:5 @@ -13,8 +13,8 @@ error: implementation of `Foo` is not general enough LL | assert_foo(gen); | ^^^^^^^^^^ | - = note: `A<'0, '1>` must implement `Foo` for any two lifetimes `'0` and `'1` - = note: but `A<'_, '2>` only implements `Foo` for the lifetime `'2` + = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1` + = note: but `Foo` is actually implemented for the type `A<'_, '2>`, for the specific lifetime `'2` error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr index e82fa51524ef1..1aa0a7ca32bd1 100644 --- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr +++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr @@ -4,8 +4,8 @@ error: implementation of `Deserialize` is not general enough LL | assert_deserialize_owned::<&'static str>(); //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `&'static str` must implement `Deserialize<'0>` for any lifetime `'0` - = note: but `&str` only implements `Deserialize<'1>` for some lifetime `'1` + = note: `Deserialize<'0>` would have to be implemented for the type `&'static str`, for any lifetime `'0` + = note: but `Deserialize<'1>` is actually implemented for the type `&str`, for some lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr index 2ee398e3dd3b2..4c4f797988049 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr @@ -5,8 +5,8 @@ LL | fn b() { want_foo2::(); } //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `want_foo2`, - = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>` for any two lifetimes `'0` and `'1` - = note: but `SomeStruct` only implements `Foo<(&'2 isize, &'2 isize)>` for some lifetime `'2` + = note: `Foo<(&'0 isize, &'1 isize)>` would have to be implemented for the type `SomeStruct`, for any two lifetimes `'0` and `'1` + = note: but `Foo<(&'2 isize, &'2 isize)>` is actually implemented for the type `SomeStruct`, for some lifetime `'2` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr index 6a61181e2407c..916a524939b6b 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr @@ -5,8 +5,8 @@ LL | foo::<()>(); //~ ERROR not general enough | ^^^^^^^^^ | = note: Due to a where-clause on `foo`, - = note: `()` must implement `Trait fn(std::cell::Cell<&'b u32>)>` - = note: but `()` only implements `Trait)>` for some lifetime `'0` + = note: `Trait fn(std::cell::Cell<&'b u32>)>` would have to be implemented for the type `()` + = note: but `Trait)>` is actually implemented for the type `()`, for some lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr index 094c449802415..bd6e3dbebd2f5 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr @@ -5,8 +5,8 @@ LL | want_hrtb::() //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `want_hrtb`, - = note: `StaticInt` must implement `Foo<&'0 isize>` for any lifetime `'0` - = note: but `StaticInt` only implements `Foo<&'1 isize>` for some lifetime `'1` + = note: `Foo<&'0 isize>` would have to be implemented for the type `StaticInt`, for any lifetime `'0` + = note: but `Foo<&'1 isize>` is actually implemented for the type `StaticInt`, for some lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/hrtb-just-for-static.rs:30:5 @@ -15,8 +15,8 @@ LL | want_hrtb::<&'a u32>() //~ ERROR | ^^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `want_hrtb`, - = note: `&'a u32` must implement `Foo<&'0 isize>` for any lifetime `'0` - = note: but `&'1 u32` only implements `Foo<&'1 isize>` for the lifetime `'1` + = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0` + = note: but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for the specific lifetime `'1` error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index ec3bf8a1a1be3..8b71a8a800e50 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -1,12 +1,12 @@ -error[E0308]: mismatched types +error: implementation of `Foo` is not general enough --> $DIR/hrtb-perfect-forwarding.rs:46:5 | -LL | foo_hrtb_bar_not(&mut t); //~ ERROR E0308 - | ^^^^^^^^^^^^^^^^ one type is more general than the other +LL | foo_hrtb_bar_not(&mut t); //~ ERROR not general enough + | ^^^^^^^^^^^^^^^^ | - = note: expected type `Foo<&'a isize>` - found type `Foo<&isize>` + = note: Due to a where-clause on `foo_hrtb_bar_not`, + = note: `Foo<&'0 isize>` would have to be implemented for the type `&mut T`, for any lifetime `'0` + = note: but `Foo<&'1 isize>` is actually implemented for the type `&mut T`, for some lifetime `'1` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-54302-cases.stderr b/src/test/ui/issues/issue-54302-cases.stderr index c1329d331a181..377bac3b24524 100644 --- a/src/test/ui/issues/issue-54302-cases.stderr +++ b/src/test/ui/issues/issue-54302-cases.stderr @@ -4,8 +4,8 @@ error: implementation of `Foo` is not general enough LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `&'0 u32` must implement `Foo<'static, u32>` for any lifetime `'0` - = note: but `&'1 _` only implements `Foo<'_, _>` for the lifetime `'1` + = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` + = note: but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for the specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:69:5 @@ -13,8 +13,8 @@ error: implementation of `Foo` is not general enough LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `&'0 i32` must implement `Foo<'static, i32>` for any lifetime `'0` - = note: but `&'1 _` only implements `Foo<'_, _>` for the lifetime `'1` + = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0` + = note: but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for the specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:75:5 @@ -22,8 +22,8 @@ error: implementation of `Foo` is not general enough LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `&'0 u64` must implement `Foo<'static, u64>` for any lifetime `'0` - = note: but `&'1 _` only implements `Foo<'_, _>` for the lifetime `'1` + = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0` + = note: but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for the specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:81:5 @@ -31,8 +31,8 @@ error: implementation of `Foo` is not general enough LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `&'0 i64` must implement `Foo<'static, i64>` for any lifetime `'0` - = note: but `&'1 _` only implements `Foo<'_, _>` for the lifetime `'1` + = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0` + = note: but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for the specific lifetime `'1` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr index 1b255204b6ef7..ddf0414faf63f 100644 --- a/src/test/ui/issues/issue-54302.stderr +++ b/src/test/ui/issues/issue-54302.stderr @@ -4,8 +4,8 @@ error: implementation of `Deserialize` is not general enough LL | assert_deserialize_owned::<&'static str>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `&'static str` must implement `Deserialize<'0>` for any lifetime `'0` - = note: but `&str` only implements `Deserialize<'1>` for some lifetime `'1` + = note: `Deserialize<'0>` would have to be implemented for the type `&'static str`, for any lifetime `'0` + = note: but `Deserialize<'1>` is actually implemented for the type `&str`, for some lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr index afc80bf4d8ee6..4d827e6ce4fd6 100644 --- a/src/test/ui/where-clauses/where-for-self-2.stderr +++ b/src/test/ui/where-clauses/where-for-self-2.stderr @@ -5,8 +5,8 @@ LL | foo(&X); //~ ERROR implementation of `Bar` is not general enough | ^^^ | = note: Due to a where-clause on `foo`, - = note: `&'0 _` must implement `Bar` for any lifetime `'0` - = note: but `&'1 u32` only implements `Bar` for the lifetime `'1` + = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` + = note: but `Bar` is actually implemented for the type `&'1 u32`, for the specific lifetime `'1` error: aborting due to previous error From f5a74d40d9ceef0d27d8d60e1b867e6cbf3f6883 Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Fri, 25 Jan 2019 19:35:35 +0100 Subject: [PATCH 0355/1064] Test new placeholder error messages in previously untested combinations --- src/test/ui/issues/issue-57362.rs | 41 +++++++++++++++++++++++++++ src/test/ui/issues/issue-57362.stderr | 20 +++++++++++++ 2 files changed, 61 insertions(+) create mode 100755 src/test/ui/issues/issue-57362.rs create mode 100644 src/test/ui/issues/issue-57362.stderr diff --git a/src/test/ui/issues/issue-57362.rs b/src/test/ui/issues/issue-57362.rs new file mode 100755 index 0000000000000..d5b506f3c2c9c --- /dev/null +++ b/src/test/ui/issues/issue-57362.rs @@ -0,0 +1,41 @@ +// Test for issue #57362, ensuring that the self ty is shown in cases of higher-ranked lifetimes +// conflicts: the `expected` and `found` trait refs would otherwise be printed the same, leading +// to confusing notes such as: +// = note: expected type `Trait` +// found type `Trait` + +// from issue #57362 +trait Trait { + fn f(self); +} + +impl Trait for fn(&T) { + fn f(self) { + println!("f"); + } +} + +fn f() { + let a: fn(_) = |_: &u8| {}; + a.f(); //~ ERROR not general enough +} + +// extracted from a similar issue: #57642 +trait X { + type G; + fn make_g() -> Self::G; +} + +impl<'a> X for fn(&'a ()) { + type G = &'a (); + + fn make_g() -> Self::G { + &() + } +} + +fn g() { + let x = ::make_g(); //~ ERROR not general enough +} + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/issues/issue-57362.stderr b/src/test/ui/issues/issue-57362.stderr new file mode 100644 index 0000000000000..d7886e5af2710 --- /dev/null +++ b/src/test/ui/issues/issue-57362.stderr @@ -0,0 +1,20 @@ +error: implementation of `Trait` is not general enough + --> $DIR/issue-57362.rs:20:7 + | +LL | a.f(); //~ ERROR not general enough + | ^ + | + = note: `Trait` would have to be implemented for the type `fn(&u8)` + = note: but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)` + +error: implementation of `X` is not general enough + --> $DIR/issue-57362.rs:38:13 + | +LL | let x = ::make_g(); //~ ERROR not general enough + | ^^^^^^^^^^^^^^^^^^ + | + = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())` + = note: but `X` is actually implemented for the type `fn(&'0 ())`, for the specific lifetime `'0` + +error: aborting due to 2 previous errors + From c5dea5753fd1c1a77813b7829573025e28c214b5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 25 Jan 2019 14:53:59 -0500 Subject: [PATCH 0356/1064] break apart tests --- src/test/ui/issues/issue-57362-1.rs | 23 +++++++++++++++++++ ...ssue-57362.stderr => issue-57362-1.stderr} | 0 .../{issue-57362.rs => issue-57362-2.rs} | 18 +-------------- 3 files changed, 24 insertions(+), 17 deletions(-) create mode 100755 src/test/ui/issues/issue-57362-1.rs rename src/test/ui/issues/{issue-57362.stderr => issue-57362-1.stderr} (100%) rename src/test/ui/issues/{issue-57362.rs => issue-57362-2.rs} (71%) mode change 100755 => 100644 diff --git a/src/test/ui/issues/issue-57362-1.rs b/src/test/ui/issues/issue-57362-1.rs new file mode 100755 index 0000000000000..fe6b69f00977d --- /dev/null +++ b/src/test/ui/issues/issue-57362-1.rs @@ -0,0 +1,23 @@ +// Test for issue #57362, ensuring that the self ty is shown in cases of higher-ranked lifetimes +// conflicts: the `expected` and `found` trait refs would otherwise be printed the same, leading +// to confusing notes such as: +// = note: expected type `Trait` +// found type `Trait` + +// from issue #57362 +trait Trait { + fn f(self); +} + +impl Trait for fn(&T) { + fn f(self) { + println!("f"); + } +} + +fn f() { + let a: fn(_) = |_: &u8| {}; + a.f(); //~ ERROR not general enough +} + +fn main() {} diff --git a/src/test/ui/issues/issue-57362.stderr b/src/test/ui/issues/issue-57362-1.stderr similarity index 100% rename from src/test/ui/issues/issue-57362.stderr rename to src/test/ui/issues/issue-57362-1.stderr diff --git a/src/test/ui/issues/issue-57362.rs b/src/test/ui/issues/issue-57362-2.rs old mode 100755 new mode 100644 similarity index 71% rename from src/test/ui/issues/issue-57362.rs rename to src/test/ui/issues/issue-57362-2.rs index d5b506f3c2c9c..436a4a904576d --- a/src/test/ui/issues/issue-57362.rs +++ b/src/test/ui/issues/issue-57362-2.rs @@ -4,22 +4,6 @@ // = note: expected type `Trait` // found type `Trait` -// from issue #57362 -trait Trait { - fn f(self); -} - -impl Trait for fn(&T) { - fn f(self) { - println!("f"); - } -} - -fn f() { - let a: fn(_) = |_: &u8| {}; - a.f(); //~ ERROR not general enough -} - // extracted from a similar issue: #57642 trait X { type G; @@ -38,4 +22,4 @@ fn g() { let x = ::make_g(); //~ ERROR not general enough } -fn main() {} \ No newline at end of file +fn main() {} From ab80162e3ffe52ded81917b8f0c032c9bc9d3c58 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 25 Jan 2019 14:54:42 -0500 Subject: [PATCH 0357/1064] add a lot more `debug!` to `try_report_placeholders_trait` --- .../nice_region_error/placeholder_error.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index b5187d2dbb6ce..94e20731bfe7c 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -206,6 +206,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { expected_substs: &'tcx Substs<'tcx>, actual_substs: &'tcx Substs<'tcx>, ) -> ErrorReported { + debug!("try_report_placeholders_trait(\ + vid={:?}, \ + sub_placeholder={:?}, \ + sup_placeholder={:?}, \ + trait_def_id={:?}, \ + expected_substs={:?}, \ + actual_substs={:?})", + vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs); + let mut err = self.tcx().sess.struct_span_err( cause.span(&self.tcx()), &format!( @@ -276,6 +285,12 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { .tcx() .any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid); + debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid); + debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid); + debug!("try_report_placeholders_trait: has_sub={:?}", has_sub); + debug!("try_report_placeholders_trait: has_sup={:?}", has_sup); + debug!("try_report_placeholders_trait: self_ty_has_vid={:?}", self_ty_has_vid); + RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || { RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { match (has_sub, has_sup) { From ec6405bccd8b1f0933a3604bdd86c43707350275 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 25 Jan 2019 15:23:13 -0500 Subject: [PATCH 0358/1064] identify when implemented for "some specific lifetime" --- .../nice_region_error/placeholder_error.rs | 247 +++++++++--------- src/test/ui/issues/issue-57362-1.stderr | 15 +- src/test/ui/issues/issue-57362-2.stderr | 11 + 3 files changed, 134 insertions(+), 139 deletions(-) create mode 100644 src/test/ui/issues/issue-57362-2.stderr diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 94e20731bfe7c..f5c51f8ee2608 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -34,19 +34,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { sub_placeholder @ ty::RePlaceholder(_), _, sup_placeholder @ ty::RePlaceholder(_), - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - Some(self.tcx().mk_region(ty::ReVar(*vid))), - cause, - Some(sub_placeholder), - Some(sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(self.tcx().mk_region(ty::ReVar(*vid))), + cause, + Some(sub_placeholder), + Some(sup_placeholder), + expected.def_id, + expected.substs, + found.substs, + )), Some(RegionResolutionError::SubSupConflict( vid, @@ -58,19 +54,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { sub_placeholder @ ty::RePlaceholder(_), _, _, - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - Some(self.tcx().mk_region(ty::ReVar(*vid))), - cause, - Some(sub_placeholder), - None, - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(self.tcx().mk_region(ty::ReVar(*vid))), + cause, + Some(sub_placeholder), + None, + expected.def_id, + expected.substs, + found.substs, + )), Some(RegionResolutionError::SubSupConflict( vid, @@ -82,19 +74,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { _, _, sup_placeholder @ ty::RePlaceholder(_), - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - Some(self.tcx().mk_region(ty::ReVar(*vid))), - cause, - None, - Some(*sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(self.tcx().mk_region(ty::ReVar(*vid))), + cause, + None, + Some(*sup_placeholder), + expected.def_id, + expected.substs, + found.substs, + )), Some(RegionResolutionError::SubSupConflict( vid, @@ -106,19 +94,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), }), sup_placeholder @ ty::RePlaceholder(_), - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - Some(self.tcx().mk_region(ty::ReVar(*vid))), - cause, - None, - Some(*sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(self.tcx().mk_region(ty::ReVar(*vid))), + cause, + None, + Some(*sup_placeholder), + expected.def_id, + expected.substs, + found.substs, + )), Some(RegionResolutionError::ConcreteFailure( SubregionOrigin::Subtype(TypeTrace { @@ -127,19 +111,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { }), sub_region @ ty::RePlaceholder(_), sup_region @ ty::RePlaceholder(_), - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - None, - cause, - Some(*sub_region), - Some(*sup_region), - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + None, + cause, + Some(*sub_region), + Some(*sup_region), + expected.def_id, + expected.substs, + found.substs, + )), Some(RegionResolutionError::ConcreteFailure( SubregionOrigin::Subtype(TypeTrace { @@ -148,19 +128,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { }), sub_region @ ty::RePlaceholder(_), sup_region, - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - Some(sup_region), - cause, - Some(*sub_region), - None, - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(sup_region), + cause, + Some(*sub_region), + None, + expected.def_id, + expected.substs, + found.substs, + )), Some(RegionResolutionError::ConcreteFailure( SubregionOrigin::Subtype(TypeTrace { @@ -169,19 +145,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { }), sub_region, sup_region @ ty::RePlaceholder(_), - )) - if expected.def_id == found.def_id => - { - Some(self.try_report_placeholders_trait( - Some(sub_region), - cause, - None, - Some(*sup_region), - expected.def_id, - expected.substs, - found.substs, - )) - } + )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + Some(sub_region), + cause, + None, + Some(*sup_region), + expected.def_id, + expected.substs, + found.substs, + )), _ => None, } @@ -206,14 +178,16 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { expected_substs: &'tcx Substs<'tcx>, actual_substs: &'tcx Substs<'tcx>, ) -> ErrorReported { - debug!("try_report_placeholders_trait(\ - vid={:?}, \ - sub_placeholder={:?}, \ - sup_placeholder={:?}, \ - trait_def_id={:?}, \ - expected_substs={:?}, \ - actual_substs={:?})", - vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs); + debug!( + "try_report_placeholders_trait(\ + vid={:?}, \ + sub_placeholder={:?}, \ + sup_placeholder={:?}, \ + trait_def_id={:?}, \ + expected_substs={:?}, \ + actual_substs={:?})", + vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs + ); let mut err = self.tcx().sess.struct_span_err( cause.span(&self.tcx()), @@ -233,18 +207,14 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { _ => (), } - let expected_trait_ref = self.infcx.resolve_type_vars_if_possible( - &ty::TraitRef { - def_id: trait_def_id, - substs: expected_substs, - } - ); - let actual_trait_ref = self.infcx.resolve_type_vars_if_possible( - &ty::TraitRef { - def_id: trait_def_id, - substs: actual_substs, - } - ); + let expected_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef { + def_id: trait_def_id, + substs: expected_substs, + }); + let actual_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef { + def_id: trait_def_id, + substs: actual_substs, + }); // Search the expected and actual trait references to see (a) // whether the sub/sup placeholders appear in them (sometimes @@ -285,11 +255,20 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { .tcx() .any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid); - debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid); - debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid); + debug!( + "try_report_placeholders_trait: actual_has_vid={:?}", + actual_has_vid + ); + debug!( + "try_report_placeholders_trait: expected_has_vid={:?}", + expected_has_vid + ); debug!("try_report_placeholders_trait: has_sub={:?}", has_sub); debug!("try_report_placeholders_trait: has_sup={:?}", has_sup); - debug!("try_report_placeholders_trait: self_ty_has_vid={:?}", self_ty_has_vid); + debug!( + "try_report_placeholders_trait: self_ty_has_vid={:?}", + self_ty_has_vid + ); RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || { RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { @@ -297,7 +276,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { (Some(n1), Some(n2)) => { err.note(&format!( "`{}` would have to be implemented for the type `{}`, \ - for any two lifetimes `'{}` and `'{}`", + for any two lifetimes `'{}` and `'{}`", expected_trait_ref, expected_trait_ref.self_ty(), std::cmp::min(n1, n2), @@ -307,32 +286,46 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { (Some(n), _) | (_, Some(n)) => { err.note(&format!( "`{}` would have to be implemented for the type `{}`, \ - for any lifetime `'{}`", + for any lifetime `'{}`", expected_trait_ref, expected_trait_ref.self_ty(), n, )); } - (None, None) => { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - )); - } + (None, None) => RegionHighlightMode::maybe_highlighting_region( + vid, + expected_has_vid, + || { + if let Some(n) = expected_has_vid { + err.note(&format!( + "`{}` would have to be implemented for the type `{}`, \ + for some specific lifetime `'{}`", + expected_trait_ref, + expected_trait_ref.self_ty(), + n, + )); + } else { + err.note(&format!( + "`{}` would have to be implemented for the type `{}`", + expected_trait_ref, + expected_trait_ref.self_ty(), + )); + } + }, + ), } }) }); RegionHighlightMode::maybe_highlighting_region( vid, - actual_has_vid.or(expected_has_vid), + actual_has_vid, || match actual_has_vid { Some(n) => { if self_ty_has_vid { err.note(&format!( "but `{}` is actually implemented for the type `{}`, \ - for the specific lifetime `'{}`", + for the specific lifetime `'{}`", actual_trait_ref, actual_trait_ref.self_ty(), n @@ -340,7 +333,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } else { err.note(&format!( "but `{}` is actually implemented for the type `{}`, \ - for some lifetime `'{}`", + for some lifetime `'{}`", actual_trait_ref, actual_trait_ref.self_ty(), n @@ -355,7 +348,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { actual_trait_ref.self_ty(), )); } - } + }, ); err.emit(); diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index d7886e5af2710..06946bcf744a7 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -1,20 +1,11 @@ error: implementation of `Trait` is not general enough - --> $DIR/issue-57362.rs:20:7 + --> $DIR/issue-57362-1.rs:20:7 | LL | a.f(); //~ ERROR not general enough | ^ | - = note: `Trait` would have to be implemented for the type `fn(&u8)` + = note: `Trait` would have to be implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0` = note: but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)` -error: implementation of `X` is not general enough - --> $DIR/issue-57362.rs:38:13 - | -LL | let x = ::make_g(); //~ ERROR not general enough - | ^^^^^^^^^^^^^^^^^^ - | - = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())` - = note: but `X` is actually implemented for the type `fn(&'0 ())`, for the specific lifetime `'0` - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr new file mode 100644 index 0000000000000..782c78da3a22c --- /dev/null +++ b/src/test/ui/issues/issue-57362-2.stderr @@ -0,0 +1,11 @@ +error: implementation of `X` is not general enough + --> $DIR/issue-57362-2.rs:22:13 + | +LL | let x = ::make_g(); //~ ERROR not general enough + | ^^^^^^^^^^^^^^^^^^ + | + = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())` + = note: but `X` is actually implemented for the type `fn(&'0 ())`, for the specific lifetime `'0` + +error: aborting due to previous error + From 790ed9128ad301806621901e8d82e1d6d21cbff2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 25 Jan 2019 15:43:36 -0500 Subject: [PATCH 0359/1064] comment the pattern --- .../nice_region_error/placeholder_error.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index f5c51f8ee2608..a0ce250d7e977 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -270,6 +270,21 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { self_ty_has_vid ); + // The weird thing here with the `maybe_highlighting_region` calls and the + // the match inside is meant to be like this: + // + // - The match checks whether the given things (placeholders, etc) appear + // in the types are about to print + // - Meanwhile, the `maybe_highlighting_region` calls set up + // highlights so that, if they do appear, we will replace + // them `'0` and whatever. (This replacement takes place + // inside the closure given to `maybe_highlighting_region`.) + // + // There is some duplication between the calls -- i.e., the + // `maybe_highlighting_region` checks if (e.g.) `has_sub` is + // None, an then we check again inside the closure, but this + // setup sort of minimized the number of calls and so form. + RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || { RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { match (has_sub, has_sup) { From 1730ad4d1cbb703be970f8494ec349bf2c38e3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81my=20Rakic?= Date: Fri, 25 Jan 2019 23:37:56 +0100 Subject: [PATCH 0360/1064] Fix issue-57362-1.rs attributes --- src/test/ui/issues/issue-57362-1.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/test/ui/issues/issue-57362-1.rs diff --git a/src/test/ui/issues/issue-57362-1.rs b/src/test/ui/issues/issue-57362-1.rs old mode 100755 new mode 100644 From 489bc4a2c6ec47eb35dc066247e11f335b278333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81my=20Rakic?= Date: Sat, 26 Jan 2019 20:25:36 +0100 Subject: [PATCH 0361/1064] When mentioning lifetimes, put either the trait ref or the self type closer to the lifetimes When mentioning lifetimes, only invert wording between the expected trait and the self type when the self type has the vid. This way, the lifetimes always stay close to the self type or trait ref that actually contains them. --- .../nice_region_error/placeholder_error.rs | 89 +++++++++++++------ .../associated-types-eq-hr.stderr | 12 +-- .../ui/hrtb/hrtb-cache-issue-54302.stderr | 4 +- src/test/ui/hrtb/hrtb-conflate-regions.stderr | 4 +- .../hrtb-exists-forall-trait-invariant.stderr | 4 +- src/test/ui/hrtb/hrtb-just-for-static.stderr | 4 +- .../ui/hrtb/hrtb-perfect-forwarding.stderr | 4 +- src/test/ui/issues/issue-54302.stderr | 4 +- 8 files changed, 81 insertions(+), 44 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index a0ce250d7e977..391539b77bc46 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -251,10 +251,16 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } }); - let self_ty_has_vid = self + let actual_self_ty_has_vid = self .tcx() .any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid); + let expected_self_ty_has_vid = self + .tcx() + .any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid); + + let self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid; + debug!( "try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid @@ -266,8 +272,12 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { debug!("try_report_placeholders_trait: has_sub={:?}", has_sub); debug!("try_report_placeholders_trait: has_sup={:?}", has_sup); debug!( - "try_report_placeholders_trait: self_ty_has_vid={:?}", - self_ty_has_vid + "try_report_placeholders_trait: actual_self_ty_has_vid={:?}", + actual_self_ty_has_vid + ); + debug!( + "try_report_placeholders_trait: expected_self_ty_has_vid={:?}", + expected_self_ty_has_vid ); // The weird thing here with the `maybe_highlighting_region` calls and the @@ -289,23 +299,43 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { match (has_sub, has_sup) { (Some(n1), Some(n2)) => { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for any two lifetimes `'{}` and `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - std::cmp::min(n1, n2), - std::cmp::max(n1, n2), - )); + if self_ty_has_vid { + err.note(&format!( + "`{}` would have to be implemented for the type `{}`, \ + for any two lifetimes `'{}` and `'{}`", + expected_trait_ref, + expected_trait_ref.self_ty(), + std::cmp::min(n1, n2), + std::cmp::max(n1, n2), + )); + } else { + err.note(&format!( + "`{}` must implement `{}`, \ + for any two lifetimes `'{}` and `'{}`", + expected_trait_ref.self_ty(), + expected_trait_ref, + std::cmp::min(n1, n2), + std::cmp::max(n1, n2), + )); + } } (Some(n), _) | (_, Some(n)) => { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for any lifetime `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - n, - )); + if self_ty_has_vid { + err.note(&format!( + "`{}` would have to be implemented for the type `{}`, \ + for any lifetime `'{}`", + expected_trait_ref, + expected_trait_ref.self_ty(), + n, + )); + } else { + err.note(&format!( + "`{}` must implement `{}`, for any lifetime `'{}`", + expected_trait_ref.self_ty(), + expected_trait_ref, + n, + )); + } } (None, None) => RegionHighlightMode::maybe_highlighting_region( vid, @@ -320,11 +350,19 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { n, )); } else { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - )); + if self_ty_has_vid { + err.note(&format!( + "`{}` would have to be implemented for the type `{}`", + expected_trait_ref, + expected_trait_ref.self_ty(), + )); + } else { + err.note(&format!( + "`{}` must implement `{}`", + expected_trait_ref.self_ty(), + expected_trait_ref, + )); + } } }, ), @@ -347,10 +385,9 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { )); } else { err.note(&format!( - "but `{}` is actually implemented for the type `{}`, \ - for some lifetime `'{}`", - actual_trait_ref, + "but `{}` actually implements `{}`, for some lifetime `'{}`", actual_trait_ref.self_ty(), + actual_trait_ref, n )); } diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index 0e471a78d9ed8..5a074fe345734 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -41,8 +41,8 @@ LL | tuple_one::(); | ^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `tuple_one`, - = note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1` - = note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2` + = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` + = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2` error: implementation of `TheTrait` is not general enough --> $DIR/associated-types-eq-hr.rs:96:5 @@ -51,8 +51,8 @@ LL | tuple_two::(); | ^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `tuple_two`, - = note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1` - = note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2` + = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` + = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2` error: implementation of `TheTrait` is not general enough --> $DIR/associated-types-eq-hr.rs:105:5 @@ -61,8 +61,8 @@ LL | tuple_four::(); | ^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `tuple_four`, - = note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1` - = note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2` + = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` + = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2` error: aborting due to 5 previous errors diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr index 1aa0a7ca32bd1..d0bcebeac4f70 100644 --- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr +++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr @@ -4,8 +4,8 @@ error: implementation of `Deserialize` is not general enough LL | assert_deserialize_owned::<&'static str>(); //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Deserialize<'0>` would have to be implemented for the type `&'static str`, for any lifetime `'0` - = note: but `Deserialize<'1>` is actually implemented for the type `&str`, for some lifetime `'1` + = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0` + = note: but `&str` actually implements `Deserialize<'1>`, for some lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr index 4c4f797988049..aa91314b350a1 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr @@ -5,8 +5,8 @@ LL | fn b() { want_foo2::(); } //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `want_foo2`, - = note: `Foo<(&'0 isize, &'1 isize)>` would have to be implemented for the type `SomeStruct`, for any two lifetimes `'0` and `'1` - = note: but `Foo<(&'2 isize, &'2 isize)>` is actually implemented for the type `SomeStruct`, for some lifetime `'2` + = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` + = note: but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some lifetime `'2` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr index 916a524939b6b..91b5db6cd664f 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr @@ -5,8 +5,8 @@ LL | foo::<()>(); //~ ERROR not general enough | ^^^^^^^^^ | = note: Due to a where-clause on `foo`, - = note: `Trait fn(std::cell::Cell<&'b u32>)>` would have to be implemented for the type `()` - = note: but `Trait)>` is actually implemented for the type `()`, for some lifetime `'0` + = note: `()` must implement `Trait fn(std::cell::Cell<&'b u32>)>` + = note: but `()` actually implements `Trait)>`, for some lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr index bd6e3dbebd2f5..24edcd910764e 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr @@ -5,8 +5,8 @@ LL | want_hrtb::() //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `want_hrtb`, - = note: `Foo<&'0 isize>` would have to be implemented for the type `StaticInt`, for any lifetime `'0` - = note: but `Foo<&'1 isize>` is actually implemented for the type `StaticInt`, for some lifetime `'1` + = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0` + = note: but `StaticInt` actually implements `Foo<&'1 isize>`, for some lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/hrtb-just-for-static.rs:30:5 diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index 8b71a8a800e50..a87fa6d3012da 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -5,8 +5,8 @@ LL | foo_hrtb_bar_not(&mut t); //~ ERROR not general enough | ^^^^^^^^^^^^^^^^ | = note: Due to a where-clause on `foo_hrtb_bar_not`, - = note: `Foo<&'0 isize>` would have to be implemented for the type `&mut T`, for any lifetime `'0` - = note: but `Foo<&'1 isize>` is actually implemented for the type `&mut T`, for some lifetime `'1` + = note: `&mut T` must implement `Foo<&'0 isize>`, for any lifetime `'0` + = note: but `&mut T` actually implements `Foo<&'1 isize>`, for some lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr index ddf0414faf63f..442d32eb9f1e9 100644 --- a/src/test/ui/issues/issue-54302.stderr +++ b/src/test/ui/issues/issue-54302.stderr @@ -4,8 +4,8 @@ error: implementation of `Deserialize` is not general enough LL | assert_deserialize_owned::<&'static str>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Deserialize<'0>` would have to be implemented for the type `&'static str`, for any lifetime `'0` - = note: but `Deserialize<'1>` is actually implemented for the type `&str`, for some lifetime `'1` + = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0` + = note: but `&str` actually implements `Deserialize<'1>`, for some lifetime `'1` error: aborting due to previous error From 43c0518d5b004f4096e5c3cf3e302322988adcd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81my=20Rakic?= Date: Sat, 26 Jan 2019 21:32:09 +0100 Subject: [PATCH 0362/1064] Extract the notes explaining the placeholder region errors to a helper fn --- .../nice_region_error/placeholder_error.rs | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 391539b77bc46..21d6c562e4dc9 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,3 +1,4 @@ +use errors::DiagnosticBuilder; use hir::def_id::DefId; use infer::error_reporting::nice_region_error::NiceRegionError; use infer::lexical_region_resolve::RegionResolutionError; @@ -259,7 +260,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { .tcx() .any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid); - let self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid; + let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid; debug!( "try_report_placeholders_trait: actual_has_vid={:?}", @@ -280,6 +281,43 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { expected_self_ty_has_vid ); + self.explain_actual_impl_that_was_found( + &mut err, + sub_placeholder, + sup_placeholder, + has_sub, + has_sup, + expected_trait_ref, + actual_trait_ref, + vid, + expected_has_vid, + actual_has_vid, + any_self_ty_has_vid, + ); + + err.emit(); + ErrorReported + } + + /// Add notes with details about the expected and actual trait refs, with attention to cases + /// when placeholder regions are involved: either the trait or the self type containing + /// them needs to be mentioned the closest to the placeholders. + /// This makes the error messages read better, however at the cost of some complexity + /// due to the number of combinations we have to deal with. + fn explain_actual_impl_that_was_found( + &self, + err: &mut DiagnosticBuilder<'_>, + sub_placeholder: Option>, + sup_placeholder: Option>, + has_sub: Option, + has_sup: Option, + expected_trait_ref: ty::TraitRef<'_>, + actual_trait_ref: ty::TraitRef<'_>, + vid: Option>, + expected_has_vid: Option, + actual_has_vid: Option, + any_self_ty_has_vid: bool, + ) { // The weird thing here with the `maybe_highlighting_region` calls and the // the match inside is meant to be like this: // @@ -299,7 +337,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { match (has_sub, has_sup) { (Some(n1), Some(n2)) => { - if self_ty_has_vid { + if any_self_ty_has_vid { err.note(&format!( "`{}` would have to be implemented for the type `{}`, \ for any two lifetimes `'{}` and `'{}`", @@ -320,7 +358,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } } (Some(n), _) | (_, Some(n)) => { - if self_ty_has_vid { + if any_self_ty_has_vid { err.note(&format!( "`{}` would have to be implemented for the type `{}`, \ for any lifetime `'{}`", @@ -350,7 +388,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { n, )); } else { - if self_ty_has_vid { + if any_self_ty_has_vid { err.note(&format!( "`{}` would have to be implemented for the type `{}`", expected_trait_ref, @@ -375,7 +413,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { actual_has_vid, || match actual_has_vid { Some(n) => { - if self_ty_has_vid { + if any_self_ty_has_vid { err.note(&format!( "but `{}` is actually implemented for the type `{}`, \ for the specific lifetime `'{}`", @@ -402,8 +440,5 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } }, ); - - err.emit(); - ErrorReported } } From e077501b54f175b3cd9947dd032a55196fb6d989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81my=20Rakic?= Date: Sat, 26 Jan 2019 21:39:47 +0100 Subject: [PATCH 0363/1064] Fix stray typo --- .../error_reporting/nice_region_error/placeholder_error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 21d6c562e4dc9..98458796ef4d6 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -13,7 +13,7 @@ use util::ppaux::RegionHighlightMode; impl NiceRegionError<'me, 'gcx, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and - /// an anonymous region, emit an descriptive diagnostic error. + /// an anonymous region, emit a descriptive diagnostic error. pub(super) fn try_report_placeholder_conflict(&self) -> Option { match &self.error { /////////////////////////////////////////////////////////////////////////// From 270151bffb0be259ff20feee3801bb124c2c39ec Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Dec 2018 00:33:00 +0100 Subject: [PATCH 0364/1064] Add generate-old-style-files option to rustdoc --- src/bootstrap/doc.rs | 4 +++- src/librustdoc/config.rs | 4 ++++ src/librustdoc/html/render.rs | 27 ++++++++++++++++++++++++++- src/librustdoc/lib.rs | 5 +++++ src/test/rustdoc/issue-19190.rs | 5 +++++ src/test/rustdoc/issue-35169-2.rs | 7 +++++++ src/test/rustdoc/issue-35169.rs | 7 +++++++ src/test/rustdoc/old-style-files.rs | 23 ----------------------- src/test/rustdoc/structfields.rs | 7 +++++++ src/test/rustdoc/without-redirect.rs | 13 +++++++++++++ 10 files changed, 77 insertions(+), 25 deletions(-) delete mode 100644 src/test/rustdoc/old-style-files.rs create mode 100644 src/test/rustdoc/without-redirect.rs diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index eec193c21f5db..0028997a7df09 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -317,7 +317,8 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned Vec { "Directory to persist doctest executables into", "PATH") }), + stable("generate-redirect-pages", |o| { + o.optflag("", + "generate-redirect-pages", + "Generate extra pages to support legacy URLs and tool links") + }), ] } diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs index 4d3b76229702b..e023e79fcde6b 100644 --- a/src/test/rustdoc/issue-19190.rs +++ b/src/test/rustdoc/issue-19190.rs @@ -1,3 +1,5 @@ +// compile-flags:--generate-redirect-pages + use std::ops::Deref; pub struct Foo; @@ -13,6 +15,9 @@ impl Deref for Bar { fn deref(&self) -> &Foo { loop {} } } +// @has issue_19190/Bar.t.html // @has issue_19190/struct.Bar.html +// @has - '//*[@id="foo.v"]' 'fn foo(&self)' // @has - '//*[@id="method.foo"]' 'fn foo(&self)' +// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-35169-2.rs b/src/test/rustdoc/issue-35169-2.rs index 7dea268ec0258..33f7646ced68b 100644 --- a/src/test/rustdoc/issue-35169-2.rs +++ b/src/test/rustdoc/issue-35169-2.rs @@ -24,10 +24,17 @@ impl DerefMut for Bar { } // @has issue_35169_2/struct.Bar.html +// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)' // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)' +// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)' // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)' +// @has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)' // @has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)' +// @has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)' // @has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)' +// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box)' // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box)' +// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box)' // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box)' +// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-35169.rs b/src/test/rustdoc/issue-35169.rs index 883d5d0158d7e..04fffc40572a6 100644 --- a/src/test/rustdoc/issue-35169.rs +++ b/src/test/rustdoc/issue-35169.rs @@ -19,10 +19,17 @@ impl Deref for Bar { } // @has issue_35169/struct.Bar.html +// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)' // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)' +// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)' // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)' +// @!has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)' // @!has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)' +// @!has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)' // @!has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)' +// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box)' // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box)' +// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box)' // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box)' +// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/old-style-files.rs b/src/test/rustdoc/old-style-files.rs deleted file mode 100644 index fb6697e18fbc4..0000000000000 --- a/src/test/rustdoc/old-style-files.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_name = "foo"] - -// @has foo/macro.bar.html -// @!has foo/macro.bar!.html -// @!has foo/bar.m.html -#[macro_export] -macro_rules! bar { - () => {} -} - -// @has foo/struct.Bar.html -// @!has foo/Bar.t.html -pub struct Bar; diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs index cd8957aa2ecb9..bfe116acffc1e 100644 --- a/src/test/rustdoc/structfields.rs +++ b/src/test/rustdoc/structfields.rs @@ -1,5 +1,8 @@ +// compile-flags:--generate-redirect-pages + // @has structfields/Foo.t.html // @has - struct.Foo.html +// @has structfields/struct.Foo.html pub struct Foo { // @has - //pre "pub a: ()" pub a: (), @@ -13,6 +16,8 @@ pub struct Foo { pub d: usize, } +// @has structfields/Bar.t.html +// @has - struct.Bar.html // @has structfields/struct.Bar.html pub struct Bar { // @has - //pre "pub a: ()" @@ -20,6 +25,8 @@ pub struct Bar { // @!has - //pre "// some fields omitted" } +// @has structfields/Qux.t.html +// @has - enum.Qux.html // @has structfields/enum.Qux.html pub enum Qux { Quz { diff --git a/src/test/rustdoc/without-redirect.rs b/src/test/rustdoc/without-redirect.rs new file mode 100644 index 0000000000000..d473dd8f428d2 --- /dev/null +++ b/src/test/rustdoc/without-redirect.rs @@ -0,0 +1,13 @@ +#![crate_name = "foo"] + +// @has foo/macro.bar.html +// @!has foo/macro.bar!.html +// @!has foo/bar.m.html +#[macro_export] +macro_rules! bar { + () => {} +} + +// @has foo/struct.Bar.html +// @!has foo/Bar.t.html +pub struct Bar; From 65440a3f4fe42acbe9970638b567ee3fa68d4824 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 27 Jan 2019 00:44:33 +0100 Subject: [PATCH 0365/1064] Make 'generate-redirect-pages' option unstable --- src/librustdoc/lib.rs | 2 +- src/test/rustdoc/issue-19190.rs | 2 +- src/test/rustdoc/structfields.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 290f958640430..4e0302b0224fe 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -348,7 +348,7 @@ fn opts() -> Vec { "Directory to persist doctest executables into", "PATH") }), - stable("generate-redirect-pages", |o| { + unstable("generate-redirect-pages", |o| { o.optflag("", "generate-redirect-pages", "Generate extra pages to support legacy URLs and tool links") diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs index e023e79fcde6b..c6bac51c5740d 100644 --- a/src/test/rustdoc/issue-19190.rs +++ b/src/test/rustdoc/issue-19190.rs @@ -1,4 +1,4 @@ -// compile-flags:--generate-redirect-pages +// compile-flags:-Z unstable-options --generate-redirect-pages use std::ops::Deref; diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs index bfe116acffc1e..235f0e852da2c 100644 --- a/src/test/rustdoc/structfields.rs +++ b/src/test/rustdoc/structfields.rs @@ -1,4 +1,4 @@ -// compile-flags:--generate-redirect-pages +// compile-flags:-Z unstable-options --generate-redirect-pages // @has structfields/Foo.t.html // @has - struct.Foo.html From d3903d5f9c4e58cc3fa256ec5be52717b84e6308 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Sat, 19 Jan 2019 21:59:34 +0100 Subject: [PATCH 0366/1064] Create `nvptx64-nvidia-cuda` target specification --- src/bootstrap/lib.rs | 1 + src/bootstrap/sanity.rs | 4 +- src/librustc/ty/context.rs | 6 + src/librustc_codegen_ssa/back/link.rs | 1 + src/librustc_codegen_ssa/back/linker.rs | 125 ++++++++++++++++++ src/librustc_codegen_utils/lib.rs | 1 + src/librustc_codegen_utils/symbol_names.rs | 57 +++++--- src/librustc_target/spec/mod.rs | 4 + .../spec/nvptx64_nvidia_cuda.rs | 73 ++++++++++ src/test/run-make/nvptx-binary-crate/Makefile | 9 ++ src/test/run-make/nvptx-binary-crate/main.rs | 28 ++++ src/test/run-make/nvptx-dylib-crate/Makefile | 10 ++ src/test/run-make/nvptx-dylib-crate/dep.rs | 14 ++ src/test/run-make/nvptx-dylib-crate/kernel.rs | 67 ++++++++++ src/test/run-make/nvptx-emit-asm/Makefile | 9 ++ src/test/run-make/nvptx-emit-asm/kernel.rs | 41 ++++++ 16 files changed, 433 insertions(+), 17 deletions(-) create mode 100644 src/librustc_target/spec/nvptx64_nvidia_cuda.rs create mode 100644 src/test/run-make/nvptx-binary-crate/Makefile create mode 100644 src/test/run-make/nvptx-binary-crate/main.rs create mode 100644 src/test/run-make/nvptx-dylib-crate/Makefile create mode 100644 src/test/run-make/nvptx-dylib-crate/dep.rs create mode 100644 src/test/run-make/nvptx-dylib-crate/kernel.rs create mode 100644 src/test/run-make/nvptx-emit-asm/Makefile create mode 100644 src/test/run-make/nvptx-emit-asm/kernel.rs diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 37451a74dfad6..b0bbf2395e2fc 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -831,6 +831,7 @@ impl Build { !target.contains("msvc") && !target.contains("emscripten") && !target.contains("wasm32") && + !target.contains("nvptx") && !target.contains("fuchsia") { Some(self.cc(target)) } else { diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index fe547a6b151c2..ff4fb85bbfad3 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -156,7 +156,7 @@ pub fn check(build: &mut Build) { panic!("the iOS target is only supported on macOS"); } - if target.contains("-none-") { + if target.contains("-none-") || target.contains("nvptx") { if build.no_std(*target).is_none() { let target = build.config.target_config.entry(target.clone()) .or_default(); @@ -165,7 +165,7 @@ pub fn check(build: &mut Build) { } if build.no_std(*target) == Some(false) { - panic!("All the *-none-* targets are no-std targets") + panic!("All the *-none-* and nvptx* targets are no-std targets") } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4c8f81411163c..c126bff42582a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1675,6 +1675,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } false } + + /// Determine whether identifiers in the assembly have strict naming rules. + /// Currently, only NVPTX* targets need it. + pub fn has_strict_asm_symbol_naming(&self) -> bool { + self.gcx.sess.target.target.arch.contains("nvptx") + } } impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index d03bb0a3d73a4..2a5ecf9a0593f 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -149,6 +149,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { LinkerFlavor::Ld => "ld", LinkerFlavor::Msvc => "link.exe", LinkerFlavor::Lld(_) => "lld", + LinkerFlavor::PtxLinker => "rust-ptx-linker", }), flavor)), (Some(linker), None) => { let stem = if linker.extension().and_then(|ext| ext.to_str()) == Some("exe") { diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index ad61f8f01d8d4..5e9aeed7107ac 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -83,6 +83,10 @@ impl LinkerInfo { LinkerFlavor::Lld(LldFlavor::Wasm) => { Box::new(WasmLd::new(cmd, sess, self)) as Box } + + LinkerFlavor::PtxLinker => { + Box::new(PtxLinker { cmd, sess }) as Box + } } } } @@ -1080,3 +1084,124 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { symbols } + +/// Much simplified and explicit CLI for the NVPTX linker. The linker operates +/// with bitcode and uses LLVM backend to generate a PTX assembly. +pub struct PtxLinker<'a> { + cmd: Command, + sess: &'a Session, +} + +impl<'a> Linker for PtxLinker<'a> { + fn link_rlib(&mut self, path: &Path) { + self.cmd.arg("--rlib").arg(path); + } + + fn link_whole_rlib(&mut self, path: &Path) { + self.cmd.arg("--rlib").arg(path); + } + + fn include_path(&mut self, path: &Path) { + self.cmd.arg("-L").arg(path); + } + + fn debuginfo(&mut self) { + self.cmd.arg("--debug"); + } + + fn add_object(&mut self, path: &Path) { + self.cmd.arg("--bitcode").arg(path); + } + + fn args(&mut self, args: &[String]) { + self.cmd.args(args); + } + + fn optimize(&mut self) { + self.cmd.arg(match self.sess.opts.optimize { + OptLevel::No => "-O0", + OptLevel::Less => "-O1", + OptLevel::Default => "-O2", + OptLevel::Aggressive => "-O3", + OptLevel::Size => "-Os", + OptLevel::SizeMin => "-Os" + }); + } + + fn output_filename(&mut self, path: &Path) { + self.cmd.arg("-o").arg(path); + } + + fn finalize(&mut self) -> Command { + ::std::mem::replace(&mut self.cmd, Command::new("")) + } + + fn link_dylib(&mut self, _lib: &str) { + panic!("external dylibs not supported") + } + + fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) { + panic!("external dylibs not supported") + } + + fn link_staticlib(&mut self, _lib: &str) { + panic!("staticlibs not supported") + } + + fn link_whole_staticlib(&mut self, _lib: &str, _search_path: &[PathBuf]) { + panic!("staticlibs not supported") + } + + fn framework_path(&mut self, _path: &Path) { + panic!("frameworks not supported") + } + + fn link_framework(&mut self, _framework: &str) { + panic!("frameworks not supported") + } + + fn position_independent_executable(&mut self) { + } + + fn full_relro(&mut self) { + } + + fn partial_relro(&mut self) { + } + + fn no_relro(&mut self) { + } + + fn build_static_executable(&mut self) { + } + + fn gc_sections(&mut self, _keep_metadata: bool) { + } + + fn pgo_gen(&mut self) { + } + + fn no_default_libraries(&mut self) { + } + + fn build_dylib(&mut self, _out_filename: &Path) { + } + + fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) { + } + + fn subsystem(&mut self, _subsystem: &str) { + } + + fn no_position_independent_executable(&mut self) { + } + + fn group_start(&mut self) { + } + + fn group_end(&mut self) { + } + + fn cross_lang_lto(&mut self) { + } +} diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 1f590d46ed8c6..8e96f98540117 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -12,6 +12,7 @@ #![feature(nll)] #![allow(unused_attributes)] #![feature(rustc_diagnostic_macros)] +#![feature(in_band_lifetimes)] #![recursion_limit="256"] diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 9267f14f24234..f2014f7421289 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance; use syntax_pos::symbol::Symbol; -use std::fmt::Write; +use std::fmt::{self, Write}; use std::mem::discriminant; pub fn provide(providers: &mut Providers) { @@ -221,7 +221,7 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - let mut buffer = SymbolPathBuffer::new(); + let mut buffer = SymbolPathBuffer::new(tcx); item_path::with_forced_absolute_paths(|| { tcx.push_item_path(&mut buffer, def_id, false); }); @@ -317,7 +317,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs); - let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id)); + let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx); if instance.is_vtable_shim() { buf.push("{{vtable-shim}}"); @@ -339,26 +339,28 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance // // To be able to work on all platforms and get *some* reasonable output, we // use C++ name-mangling. -#[derive(Debug)] -struct SymbolPathBuffer { +struct SymbolPathBuffer<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, result: String, temp_buf: String, } -impl SymbolPathBuffer { - fn new() -> Self { +impl SymbolPathBuffer<'a, 'tcx> { + fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), + tcx, }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName) -> Self { + fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), + tcx, }; result.result.push_str(&symbol.as_str()); result @@ -377,7 +379,7 @@ impl SymbolPathBuffer { } } -impl ItemPathBuffer for SymbolPathBuffer { +impl ItemPathBuffer for SymbolPathBuffer<'a, 'tcx> { fn root_mode(&self) -> &RootMode { const ABSOLUTE: &RootMode = &RootMode::Absolute; ABSOLUTE @@ -385,7 +387,7 @@ impl ItemPathBuffer for SymbolPathBuffer { fn push(&mut self, text: &str) { self.temp_buf.clear(); - let need_underscore = sanitize(&mut self.temp_buf, text); + let need_underscore = sanitize(&mut self.temp_buf, text, self.tcx); let _ = write!( self.result, "{}", @@ -398,12 +400,24 @@ impl ItemPathBuffer for SymbolPathBuffer { } } +// Manual Debug implementation to omit non-Debug `tcx` field. +impl fmt::Debug for SymbolPathBuffer<'_, '_> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("SymbolPathBuffer") + .field("result", &self.result) + .field("temp_buf", &self.temp_buf) + .finish() + } +} + // Name sanitation. LLVM will happily accept identifiers with weird names, but // gas doesn't! // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ +// NVPTX assembly has more strict naming rules than gas, so additionally, dots +// are replaced with '$' there. // // returns true if an underscore must be added at the start -pub fn sanitize(result: &mut String, s: &str) -> bool { +pub fn sanitize(result: &mut String, s: &str, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { for c in s.chars() { match c { // Escape these with $ sequences @@ -416,12 +430,25 @@ pub fn sanitize(result: &mut String, s: &str) -> bool { ')' => result.push_str("$RP$"), ',' => result.push_str("$C$"), - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - '-' | ':' => result.push('.'), + '-' | ':' => if tcx.has_strict_asm_symbol_naming() { + // NVPTX doesn't support these characters in symbol names. + result.push('$') + } + else { + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + result.push('.') + }, + + '.' => if tcx.has_strict_asm_symbol_naming() { + result.push('$') + } + else { + result.push('.') + }, // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c), + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => result.push(c), _ => { result.push('$'); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index e47da3cff95b6..aeecce49b0c67 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -75,6 +75,7 @@ pub enum LinkerFlavor { Ld, Msvc, Lld(LldFlavor), + PtxLinker, } #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, @@ -143,6 +144,7 @@ flavor_mappings! { ((LinkerFlavor::Gcc), "gcc"), ((LinkerFlavor::Ld), "ld"), ((LinkerFlavor::Msvc), "msvc"), + ((LinkerFlavor::PtxLinker), "ptx-linker"), ((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"), ((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"), ((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"), @@ -455,6 +457,8 @@ supported_targets! { ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx), ("x86_64-unknown-uefi", x86_64_unknown_uefi), + + ("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda), } /// Everything `rustc` knows about how to compile for a specific target. diff --git a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs new file mode 100644 index 0000000000000..ed5d0f2450623 --- /dev/null +++ b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs @@ -0,0 +1,73 @@ +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy, MergeFunctions}; +use spec::abi::Abi; + +pub fn target() -> TargetResult { + Ok(Target { + arch: "nvptx64".to_string(), + data_layout: "e-i64:64-i128:128-v16:16-v32:32-n16:32:64".to_string(), + llvm_target: "nvptx64-nvidia-cuda".to_string(), + + target_os: "cuda".to_string(), + target_vendor: "nvidia".to_string(), + target_env: String::new(), + + linker_flavor: LinkerFlavor::PtxLinker, + + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + + options: TargetOptions { + // The linker can be installed from `crates.io`. + linker: Some("rust-ptx-linker".to_string()), + + // With `ptx-linker` approach, it can be later overriden via link flags. + cpu: "sm_20".to_string(), + + // TODO(denzp): create tests for the atomics. + max_atomic_width: Some(64), + + // Unwinding on CUDA is neither feasible nor useful. + panic_strategy: PanicStrategy::Abort, + + // Needed to use `dylib` and `bin` crate types and the linker. + dynamic_linking: true, + executables: true, + + // Avoid using dylib because it contain metadata not supported + // by LLVM NVPTX backend. + only_cdylib: true, + + // Let the `ptx-linker` to handle LLVM lowering into MC / assembly. + obj_is_bitcode: true, + + // Convinient and predicable naming scheme. + dll_prefix: "".to_string(), + dll_suffix: ".ptx".to_string(), + exe_suffix: ".ptx".to_string(), + + // Disable MergeFunctions LLVM optimisation pass because it can + // produce kernel functions that call other kernel functions. + // This behavior is not supported by PTX ISA. + merge_functions: MergeFunctions::Disabled, + + // TODO(denzp): enable compilation tests for the target and + // create the tests for this. + abi_blacklist: vec![ + Abi::Cdecl, + Abi::Stdcall, + Abi::Fastcall, + Abi::Vectorcall, + Abi::Thiscall, + Abi::Aapcs, + Abi::Win64, + Abi::SysV64, + Abi::Msp430Interrupt, + Abi::X86Interrupt, + Abi::AmdGpuKernel, + ], + + .. Default::default() + }, + }) +} diff --git a/src/test/run-make/nvptx-binary-crate/Makefile b/src/test/run-make/nvptx-binary-crate/Makefile new file mode 100644 index 0000000000000..4c22dae265c14 --- /dev/null +++ b/src/test/run-make/nvptx-binary-crate/Makefile @@ -0,0 +1,9 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),nvptx64-nvidia-cuda) +all: + $(RUSTC) main.rs -Clink-arg=--arch=sm_60 --crate-type="bin" -O --target $(TARGET) + FileCheck main.rs --input-file $(TMPDIR)/main.ptx +else +all: +endif diff --git a/src/test/run-make/nvptx-binary-crate/main.rs b/src/test/run-make/nvptx-binary-crate/main.rs new file mode 100644 index 0000000000000..826bc3a47bbd6 --- /dev/null +++ b/src/test/run-make/nvptx-binary-crate/main.rs @@ -0,0 +1,28 @@ +#![no_std] +#![no_main] +#![deny(warnings)] +#![feature(abi_ptx, core_intrinsics)] + +// Check the overriden CUDA arch. +// CHECK: .target sm_60 +// CHECK: .address_size 64 + +// Verify that no extra function declarations are present. +// CHECK-NOT: .func + +// CHECK-LABEL: .visible .entry top_kernel( +#[no_mangle] +pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) { + // CHECK: add.s32 %{{r[0-9]+}}, %{{r[0-9]+}}, 5; + *b = *a + 5; +} + +// Verify that no extra function definitions are there. +// CHECK-NOT: .func +// CHECK-NOT: .entry + +#[panic_handler] +unsafe fn breakpoint_panic_handler(_: &::core::panic::PanicInfo) -> ! { + core::intrinsics::breakpoint(); + core::hint::unreachable_unchecked(); +} diff --git a/src/test/run-make/nvptx-dylib-crate/Makefile b/src/test/run-make/nvptx-dylib-crate/Makefile new file mode 100644 index 0000000000000..7284e9d1a7c99 --- /dev/null +++ b/src/test/run-make/nvptx-dylib-crate/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),nvptx64-nvidia-cuda) +all: + $(RUSTC) dep.rs --crate-type="rlib" --target $(TARGET) + $(RUSTC) kernel.rs --crate-type="cdylib" -O --target $(TARGET) + FileCheck kernel.rs --input-file $(TMPDIR)/kernel.ptx +else +all: +endif diff --git a/src/test/run-make/nvptx-dylib-crate/dep.rs b/src/test/run-make/nvptx-dylib-crate/dep.rs new file mode 100644 index 0000000000000..57f3ee87cdb9d --- /dev/null +++ b/src/test/run-make/nvptx-dylib-crate/dep.rs @@ -0,0 +1,14 @@ +#![no_std] +#![deny(warnings)] + +#[inline(never)] +#[no_mangle] +pub fn wrapping_external_fn(a: u32) -> u32 { + a.wrapping_mul(a) +} + +#[inline(never)] +#[no_mangle] +pub fn panicking_external_fn(a: u32) -> u32 { + a * a +} diff --git a/src/test/run-make/nvptx-dylib-crate/kernel.rs b/src/test/run-make/nvptx-dylib-crate/kernel.rs new file mode 100644 index 0000000000000..a889e23018d81 --- /dev/null +++ b/src/test/run-make/nvptx-dylib-crate/kernel.rs @@ -0,0 +1,67 @@ +#![no_std] +#![deny(warnings)] +#![feature(abi_ptx, core_intrinsics)] + +extern crate dep; + +// Verify the default CUDA arch. +// CHECK: .target sm_20 +// CHECK: .address_size 64 + +// Make sure declarations are there. +// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn +// CHECK: .func (.param .b32 func_retval0) panicking_external_fn +// CHECK: .func [[PANIC_HANDLER:_ZN4core9panicking5panic[a-zA-Z0-9]+]] +// CHECK: .func [[PANIC_FMT:_ZN4core9panicking9panic_fmt[a-zA-Z0-9]+]] + +// CHECK-LABEL: .visible .entry top_kernel( +#[no_mangle] +pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) { + // CHECK: call.uni (retval0), + // CHECK-NEXT: wrapping_external_fn + // CHECK: ld.param.b32 %[[LHS:r[0-9]+]], [retval0+0]; + let lhs = dep::wrapping_external_fn(*a); + + // CHECK: call.uni (retval0), + // CHECK-NEXT: panicking_external_fn + // CHECK: ld.param.b32 %[[RHS:r[0-9]+]], [retval0+0]; + let rhs = dep::panicking_external_fn(*a); + + // CHECK: add.s32 %[[RES:r[0-9]+]], %[[RHS]], %[[LHS]]; + // CHECK: st.global.u32 [%{{rd[0-9]+}}], %[[RES]]; + *b = lhs + rhs; +} + +// Verify that external function bodies are available. +// CHECK-LABEL: .func (.param .b32 func_retval0) wrapping_external_fn +// CHECK: { +// CHECK: st.param.b32 [func_retval0+0], %{{r[0-9]+}}; +// CHECK: } + +// Also verify panic behavior. +// CHECK-LABEL: .func (.param .b32 func_retval0) panicking_external_fn +// CHECK: { +// CHECK: %{{p[0-9]+}} bra [[PANIC_LABEL:[a-zA-Z0-9_]+]]; +// CHECK: [[PANIC_LABEL]]: +// CHECK: call.uni +// CHECK: [[PANIC_HANDLER]] +// CHECK: } + +// Verify whether panic handler is present. +// CHECK: .func [[PANIC_HANDLER]]() +// CHECK: { +// CHECK: call.uni +// CHECK: [[PANIC_FMT]] +// CHECK: } + +// And finally, check the dummy panic formatter. +// CHECK: .func [[PANIC_FMT]]() +// CHECK: { +// CHECK: trap; +// CHECK: } + +#[panic_handler] +unsafe fn breakpoint_panic_handler(_: &::core::panic::PanicInfo) -> ! { + core::intrinsics::breakpoint(); + core::hint::unreachable_unchecked(); +} diff --git a/src/test/run-make/nvptx-emit-asm/Makefile b/src/test/run-make/nvptx-emit-asm/Makefile new file mode 100644 index 0000000000000..e03601878bdee --- /dev/null +++ b/src/test/run-make/nvptx-emit-asm/Makefile @@ -0,0 +1,9 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),nvptx64-nvidia-cuda) +all: + $(RUSTC) kernel.rs --crate-type="rlib" --emit asm,llvm-ir -O --target $(TARGET) + FileCheck kernel.rs --input-file $(TMPDIR)/kernel.s +else +all: +endif diff --git a/src/test/run-make/nvptx-emit-asm/kernel.rs b/src/test/run-make/nvptx-emit-asm/kernel.rs new file mode 100644 index 0000000000000..070a6efd2d547 --- /dev/null +++ b/src/test/run-make/nvptx-emit-asm/kernel.rs @@ -0,0 +1,41 @@ +#![no_std] +#![deny(warnings)] +#![feature(abi_ptx)] + +// Verify the default CUDA arch. +// CHECK: .target sm_20 +// CHECK: .address_size 64 + +// Verify function name doesn't contain unacceaptable characters. +// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN:_ZN[a-zA-Z0-9$_]+square[a-zA-Z0-9$_]+]] + +// CHECK-LABEL: .visible .entry top_kernel( +#[no_mangle] +pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) { + // CHECK: call.uni (retval0), + // CHECK-NEXT: [[IMPL_FN]] + *b = deep::private::MyStruct::new(*a).square(); +} + +pub mod deep { + pub mod private { + pub struct MyStruct(T); + + impl MyStruct { + pub fn new(a: u32) -> Self { + MyStruct(a) + } + + #[inline(never)] + pub fn square(&self) -> u32 { + self.0.wrapping_mul(self.0) + } + } + } +} + +// Verify that external function bodies are available. +// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN]] +// CHECK: { +// CHECK: mul.lo.s32 %{{r[0-9]+}}, %{{r[0-9]+}}, %{{r[0-9]+}} +// CHECK: } From 97c8e82fe03c079368e7913c46f6b26fefa30150 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Thu, 24 Jan 2019 01:13:52 +0100 Subject: [PATCH 0367/1064] Enable CI for `nvptx64-nvidia-cuda` --- .travis.yml | 2 ++ src/ci/docker/dist-various-2/Dockerfile | 1 + src/ci/docker/nvptx-cuda/Dockerfile | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 src/ci/docker/nvptx-cuda/Dockerfile diff --git a/.travis.yml b/.travis.yml index c4efa88460325..a8e1bfbbfa93a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -186,6 +186,8 @@ matrix: if: branch = auto - env: IMAGE=mingw-check if: type = pull_request OR branch = auto + - env: IMAGE=nvptx-cuda + if: branch = auto - stage: publish toolstate if: branch = master AND type = push diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 952c1ba2ccb76..66cbb43196aa2 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -70,6 +70,7 @@ ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx +ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/" diff --git a/src/ci/docker/nvptx-cuda/Dockerfile b/src/ci/docker/nvptx-cuda/Dockerfile new file mode 100644 index 0000000000000..cdb1f565bd22e --- /dev/null +++ b/src/ci/docker/nvptx-cuda/Dockerfile @@ -0,0 +1,18 @@ +FROM ubuntu:18.04 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + g++ make file curl ca-certificates python git \ + cmake sudo gdb + +# TODO(denzp): setup `ptx-linker` CI for auttomatic binary releases. +RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha/rust-ptx-linker.linux64.tar.gz | \ + tar -xzvC /usr/bin + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV TARGETS=nvptx64-nvidia-cuda + +ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \ + src/test/run-make From cd39cf748e3a5ab7cc4449ba9acfddb969c79209 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 27 Jan 2019 08:43:30 -0700 Subject: [PATCH 0368/1064] Update cargo to fix deprecation warnings Implemented in rust-lang/cargo#6600 --- Cargo.lock | 8 ++++---- src/tools/cargo | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9385ee3a1b3d..1cfe57da6974d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,7 +204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo" -version = "0.34.0" +version = "0.35.0" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -212,7 +212,7 @@ dependencies = [ "bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crates-io 0.22.0", + "crates-io 0.23.0", "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -496,7 +496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crates-io" -version = "0.22.0" +version = "0.23.0" dependencies = [ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2113,7 +2113,7 @@ dependencies = [ name = "rls" version = "1.31.6" dependencies = [ - "cargo 0.34.0", + "cargo 0.35.0", "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.212", "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/cargo b/src/tools/cargo index 907c0febe7045..245818076052d 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 907c0febe7045fa02dff2a35c5e36d3bd59ea50d +Subproject commit 245818076052dd7178f5bb7585f5aec5b6c1e03e From e0bc0ba281b0efd67a3afc5f9b9dd36fab479800 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 25 Jan 2019 18:44:50 -0700 Subject: [PATCH 0369/1064] Update comment in test which has changed its purpose --- src/test/ui/parser/regions-out-of-scope-slice.rs | 4 +--- src/test/ui/parser/regions-out-of-scope-slice.stderr | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/ui/parser/regions-out-of-scope-slice.rs b/src/test/ui/parser/regions-out-of-scope-slice.rs index 2cc9b1ac45c7d..21369d0be61b1 100644 --- a/src/test/ui/parser/regions-out-of-scope-slice.rs +++ b/src/test/ui/parser/regions-out-of-scope-slice.rs @@ -1,8 +1,6 @@ -// blk region isn't supported in the front-end +// This basically tests the parser's recovery on `'blk` in the wrong place. fn foo(cond: bool) { - // Here we will infer a type that uses the - // region of the if stmt then block, but in the scope: let mut x; if cond { diff --git a/src/test/ui/parser/regions-out-of-scope-slice.stderr b/src/test/ui/parser/regions-out-of-scope-slice.stderr index 026d14ca41392..cd56dfa6aeb7b 100644 --- a/src/test/ui/parser/regions-out-of-scope-slice.stderr +++ b/src/test/ui/parser/regions-out-of-scope-slice.stderr @@ -1,5 +1,5 @@ error: expected `:`, found `[` - --> $DIR/regions-out-of-scope-slice.rs:9:19 + --> $DIR/regions-out-of-scope-slice.rs:7:19 | LL | x = &'blk [1,2,3]; //~ ERROR expected `:`, found `[` | ^ expected `:` From 1578955500ab438f80f27361b74a82364caa499f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 8 Jan 2019 09:25:06 +0100 Subject: [PATCH 0370/1064] Fix indentation --- src/librustc/ty/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4c8f81411163c..a0da7cf2137d0 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1767,7 +1767,7 @@ macro_rules! nop_list_lift { impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { type Lifted = &'tcx List<$lifted>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - if self.is_empty() { + if self.is_empty() { return Some(List::empty()); } if tcx.interners.arena.in_arena(*self as *const _) { From 2a1748834e80b2461be4e18d420503d60e687312 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 8 Jan 2019 12:40:25 +0100 Subject: [PATCH 0371/1064] Add some size assertions for const eval types --- src/librustc/mir/interpret/pointer.rs | 2 ++ src/librustc/mir/interpret/value.rs | 6 ++++++ src/librustc/ty/sty.rs | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index a046825f088bb..498c0b5b917e9 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -76,6 +76,8 @@ pub struct Pointer { pub tag: Tag, } +static_assert!(POINTER_SIZE: ::std::mem::size_of::() == 16); + /// Produces a `Pointer` which points to the beginning of the Allocation impl From for Pointer { #[inline(always)] diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 76eb43e73d166..896e2ab960cb4 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -32,6 +32,9 @@ pub enum ConstValue<'tcx> { ByRef(AllocId, &'tcx Allocation, Size), } +#[cfg(target_arch = "x86_64")] +static_assert!(CONST_SIZE: ::std::mem::size_of::>() == 56); + impl<'tcx> ConstValue<'tcx> { #[inline] pub fn try_to_scalar(&self) -> Option { @@ -90,6 +93,9 @@ pub enum Scalar { Ptr(Pointer), } +#[cfg(target_arch = "x86_64")] +static_assert!(SCALAR_SIZE: ::std::mem::size_of::() == 24); + impl fmt::Display for Scalar { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index b98369b62ea37..a42b80e594c64 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -2063,6 +2063,9 @@ pub enum LazyConst<'tcx> { Evaluated(Const<'tcx>), } +#[cfg(target_arch = "x86_64")] +static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::>() == 72); + impl<'tcx> LazyConst<'tcx> { pub fn map_evaluated(self, f: impl FnOnce(Const<'tcx>) -> Option) -> Option { match self { @@ -2089,6 +2092,9 @@ pub struct Const<'tcx> { pub val: ConstValue<'tcx>, } +#[cfg(target_arch = "x86_64")] +static_assert!(CONST_SIZE: ::std::mem::size_of::>() == 64); + impl<'tcx> Const<'tcx> { #[inline] pub fn from_scalar( From fe50b4eb1d6f7a31c53798bca3d0fa2b0670fa3d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 8 Jan 2019 13:49:37 +0100 Subject: [PATCH 0372/1064] `ConstValue::ScalarPair` only needs to represent slices --- src/librustc/ich/impls_ty.rs | 2 +- src/librustc/mir/interpret/value.rs | 24 +++++++---------- src/librustc/mir/mod.rs | 30 ++++++++++------------ src/librustc/ty/structural_impls.rs | 2 +- src/librustc/ty/sty.rs | 4 +-- src/librustc_codegen_ssa/mir/operand.rs | 12 +++------ src/librustc_mir/const_eval.rs | 9 +++---- src/librustc_mir/hair/constant.rs | 4 +-- src/librustc_mir/hair/pattern/_match.rs | 23 +++++++++-------- src/librustc_mir/hair/pattern/mod.rs | 20 ++++++--------- src/librustc_mir/interpret/operand.rs | 4 +-- src/librustc_mir/monomorphize/collector.rs | 7 +---- 12 files changed, 59 insertions(+), 82 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 79c2b89522dbf..bd2349161f74a 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -302,7 +302,7 @@ impl_stable_hash_for!(struct ty::FieldDef { impl_stable_hash_for!( impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] { Scalar(val), - ScalarPair(a, b), + Slice(a, b), ByRef(id, alloc, offset), } ); diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 896e2ab960cb4..4ac84bcfd1903 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -22,10 +22,13 @@ pub enum ConstValue<'tcx> { /// Not using the enum `Value` to encode that this must not be `Undef` Scalar(Scalar), - /// Used only for *fat pointers* with layout::abi::ScalarPair + /// Used only for slices and strings (`&[T]`, `&str`, `*const [T]`, `*mut str`, `Box`, ...) /// - /// Needed for pattern matching code related to slices and strings. - ScalarPair(Scalar, Scalar), + /// Empty slices don't necessarily have an address backed by an `AllocId`, thus we also need to + /// enable integer pointers. The `Scalar` type covers exactly those two cases. While we could + /// create dummy-`AllocId`s, the additional code effort for the conversions doesn't seem worth + /// it. + Slice(Scalar, u64), /// An allocation + offset into the allocation. /// Invariant: The AllocId matches the allocation. @@ -33,14 +36,14 @@ pub enum ConstValue<'tcx> { } #[cfg(target_arch = "x86_64")] -static_assert!(CONST_SIZE: ::std::mem::size_of::>() == 56); +static_assert!(CONST_SIZE: ::std::mem::size_of::>() == 40); impl<'tcx> ConstValue<'tcx> { #[inline] pub fn try_to_scalar(&self) -> Option { match *self { ConstValue::ByRef(..) | - ConstValue::ScalarPair(..) => None, + ConstValue::Slice(..) => None, ConstValue::Scalar(val) => Some(val), } } @@ -59,17 +62,8 @@ impl<'tcx> ConstValue<'tcx> { pub fn new_slice( val: Scalar, len: u64, - cx: &impl HasDataLayout ) -> Self { - ConstValue::ScalarPair(val, Scalar::Bits { - bits: len as u128, - size: cx.data_layout().pointer_size.bytes() as u8, - }) - } - - #[inline] - pub fn new_dyn_trait(val: Scalar, vtable: Pointer) -> Self { - ConstValue::ScalarPair(val, Scalar::Ptr(vtable)) + ConstValue::Slice(val, len) } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index f824ab7e5b395..82083b4f69964 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2702,23 +2702,21 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul return write!(f, "{}", item_path_str(did)); } // print string literals - if let ConstValue::ScalarPair(ptr, len) = value { + if let ConstValue::Slice(ptr, len) = value { if let Scalar::Ptr(ptr) = ptr { - if let Scalar::Bits { bits: len, .. } = len { - if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty { - return ty::tls::with(|tcx| { - let alloc = tcx.alloc_map.lock().get(ptr.alloc_id); - if let Some(interpret::AllocKind::Memory(alloc)) = alloc { - assert_eq!(len as usize as u128, len); - let slice = - &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)]; - let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri"); - write!(f, "{:?}", s) - } else { - write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len) - } - }); - } + if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty { + return ty::tls::with(|tcx| { + let alloc = tcx.alloc_map.lock().get(ptr.alloc_id); + if let Some(interpret::AllocKind::Memory(alloc)) = alloc { + assert_eq!(len as usize as u64, len); + let slice = + &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)]; + let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri"); + write!(f, "{:?}", s) + } else { + write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len) + } + }); } } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 258470bf6f860..28f5a65374d98 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -498,7 +498,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> { fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { match *self { ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)), - ConstValue::ScalarPair(x, y) => Some(ConstValue::ScalarPair(x, y)), + ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)), ConstValue::ByRef(x, alloc, z) => Some(ConstValue::ByRef( x, alloc.lift_to_tcx(tcx)?, z, )), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index a42b80e594c64..671a0fc2d5d7a 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -2064,7 +2064,7 @@ pub enum LazyConst<'tcx> { } #[cfg(target_arch = "x86_64")] -static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::>() == 72); +static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::>() == 56); impl<'tcx> LazyConst<'tcx> { pub fn map_evaluated(self, f: impl FnOnce(Const<'tcx>) -> Option) -> Option { @@ -2093,7 +2093,7 @@ pub struct Const<'tcx> { } #[cfg(target_arch = "x86_64")] -static_assert!(CONST_SIZE: ::std::mem::size_of::>() == 64); +static_assert!(CONST_SIZE: ::std::mem::size_of::>() == 48); impl<'tcx> Const<'tcx> { #[inline] diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 2026e042ef0eb..8aad4c1f6e1c0 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -88,9 +88,9 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { ); OperandValue::Immediate(llval) }, - ConstValue::ScalarPair(a, b) => { - let (a_scalar, b_scalar) = match layout.abi { - layout::Abi::ScalarPair(ref a, ref b) => (a, b), + ConstValue::Slice(a, b) => { + let a_scalar = match layout.abi { + layout::Abi::ScalarPair(ref a, _) => a, _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout) }; let a_llval = bx.cx().scalar_to_backend( @@ -98,11 +98,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { a_scalar, bx.cx().scalar_pair_element_backend_type(layout, 0, true), ); - let b_llval = bx.cx().scalar_to_backend( - b, - b_scalar, - bx.cx().scalar_pair_element_backend_type(layout, 1, true), - ); + let b_llval = bx.cx().const_usize(b); OperandValue::Pair(a_llval, b_llval) }, ConstValue::ByRef(_, alloc, offset) => { diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 9ed480a9af5bb..f83a930353b73 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -67,14 +67,11 @@ pub fn op_to_const<'tcx>( op: OpTy<'tcx>, may_normalize: bool, ) -> EvalResult<'tcx, ty::Const<'tcx>> { - // We do not normalize just any data. Only scalar layout and fat pointers. + // We do not normalize just any data. Only scalar layout and slices. let normalize = may_normalize && match op.layout.abi { layout::Abi::Scalar(..) => true, - layout::Abi::ScalarPair(..) => { - // Must be a fat pointer - op.layout.ty.builtin_deref(true).is_some() - }, + layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(), _ => false, }; let normalized_op = if normalize { @@ -103,7 +100,7 @@ pub fn op_to_const<'tcx>( Ok(Immediate::Scalar(x)) => ConstValue::Scalar(x.not_undef()?), Ok(Immediate::ScalarPair(a, b)) => - ConstValue::ScalarPair(a.not_undef()?, b.not_undef()?), + ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?), }; Ok(ty::Const { val, ty: op.layout.ty }) } diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs index f63c3e2ff6142..21c471d49ee66 100644 --- a/src/librustc_mir/hair/constant.rs +++ b/src/librustc_mir/hair/constant.rs @@ -35,13 +35,13 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>( LitKind::Str(ref s, _) => { let s = s.as_str(); let id = tcx.allocate_bytes(s.as_bytes()); - ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx) + ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64) }, LitKind::Err(ref s) => { let s = s.as_str(); let id = tcx.allocate_bytes(s.as_bytes()); return Ok(ty::Const { - val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx), + val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64), ty: tcx.types.err, }); }, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 9cc5c93de41d8..7f5b1a761d261 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -221,13 +221,16 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> { // unsize array to slice if pattern is array but match value or other patterns are slice (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => { assert_eq!(t, u); - ConstValue::ScalarPair( + ConstValue::Slice( Scalar::Ptr(p), - n.map_evaluated(|val| val.val.try_to_scalar()).unwrap(), + n.map_evaluated(|val| val.val.try_to_scalar()) + .unwrap() + .to_usize(&self.tcx) + .unwrap(), ) }, // fat pointers stay the same - (ConstValue::ScalarPair(..), _, _) => val, + (ConstValue::Slice(..), _, _) => val, // FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;` being used _ => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty), } @@ -788,9 +791,9 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>( max_fixed_len, n.unwrap_usize(cx.tcx), ), - (ConstValue::ScalarPair(_, n), ty::Slice(_)) => max_fixed_len = cmp::max( + (ConstValue::Slice(_, n), ty::Slice(_)) => max_fixed_len = cmp::max( max_fixed_len, - n.to_usize(&cx.tcx).unwrap(), + n, ), _ => {}, } @@ -1432,7 +1435,7 @@ fn slice_pat_covered_by_const<'tcx>( alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap() }, // a slice fat pointer to a zero length slice - (ConstValue::ScalarPair(Scalar::Bits { .. }, n), ty::Slice(t)) => { + (ConstValue::Slice(Scalar::Bits { .. }, 0), ty::Slice(t)) => { if *t != tcx.types.u8 { // FIXME(oli-obk): can't mix const patterns with slice patterns and get // any sort of exhaustiveness/unreachable check yet @@ -1440,11 +1443,10 @@ fn slice_pat_covered_by_const<'tcx>( // are definitely unreachable. return Ok(false); } - assert_eq!(n.to_usize(&tcx).unwrap(), 0); &[] }, // - (ConstValue::ScalarPair(Scalar::Ptr(ptr), n), ty::Slice(t)) => { + (ConstValue::Slice(Scalar::Ptr(ptr), n), ty::Slice(t)) => { if *t != tcx.types.u8 { // FIXME(oli-obk): can't mix const patterns with slice patterns and get // any sort of exhaustiveness/unreachable check yet @@ -1452,7 +1454,6 @@ fn slice_pat_covered_by_const<'tcx>( // are definitely unreachable. return Ok(false); } - let n = n.to_usize(&tcx).unwrap(); tcx.alloc_map .lock() .unwrap_memory(ptr.alloc_id) @@ -1784,12 +1785,12 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>( }, ty::TyKind::Slice(t) => { match value.val { - ConstValue::ScalarPair(ptr, n) => ( + ConstValue::Slice(ptr, n) => ( ptr.to_ptr().ok().map(|ptr| ( ptr, cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), )), - n.to_bits(cx.tcx.data_layout.pointer_size).unwrap() as u64, + n, t, ), _ => span_bug!( diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 06a50f35be1cf..7d48cdc1d8aef 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -1218,25 +1218,21 @@ pub fn compare_const_vals<'a, 'gcx, 'tcx>( if let ty::Str = ty.value.sty { match (a.val, b.val) { ( - ConstValue::ScalarPair( + ConstValue::Slice( Scalar::Ptr(ptr_a), len_a, ), - ConstValue::ScalarPair( + ConstValue::Slice( Scalar::Ptr(ptr_b), len_b, ), ) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => { - if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) { - if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) { - if len_a == len_b { - let map = tcx.alloc_map.lock(); - let alloc_a = map.unwrap_memory(ptr_a.alloc_id); - let alloc_b = map.unwrap_memory(ptr_b.alloc_id); - if alloc_a.bytes.len() as u128 == len_a { - return from_bool(alloc_a == alloc_b); - } - } + if len_a == len_b { + let map = tcx.alloc_map.lock(); + let alloc_a = map.unwrap_memory(ptr_a.alloc_id); + let alloc_b = map.unwrap_memory(ptr_b.alloc_id); + if alloc_a.bytes.len() as u64 == len_a { + return from_bool(alloc_a == alloc_b); } } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 8741571342f83..e4bee24c88cfa 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -555,10 +555,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> MemPlace::from_ptr(Pointer::new(id, offset), alloc.align) ).with_default_tag()) }, - ConstValue::ScalarPair(a, b) => + ConstValue::Slice(a, b) => Ok(Operand::Immediate(Immediate::ScalarPair( a.into(), - b.into(), + Scalar::from_uint(b, self.tcx.data_layout.pointer_size).into(), )).with_default_tag()), ConstValue::Scalar(x) => Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()), diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index bc63f8b6ac854..e713ab17c3af5 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1254,12 +1254,7 @@ fn collect_const<'a, 'tcx>( debug!("visiting const {:?}", constant); match constant.val { - ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => { - collect_miri(tcx, a.alloc_id, output); - collect_miri(tcx, b.alloc_id, output); - } - ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) | - ConstValue::ScalarPair(Scalar::Ptr(ptr), _) | + ConstValue::Slice(Scalar::Ptr(ptr), _) | ConstValue::Scalar(Scalar::Ptr(ptr)) => collect_miri(tcx, ptr.alloc_id, output), ConstValue::ByRef(_id, alloc, _offset) => { From a3fdee9a7523a72a5ee72cdb4c1cf3c2cec444bc Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Thu, 4 Oct 2018 20:49:38 +0200 Subject: [PATCH 0373/1064] Change generator trait to use pinning --- .../src/language-features/generators.md | 31 +++++++++------- src/liballoc/boxed.rs | 13 +++---- src/libcore/ops/generator.rs | 37 ++++++++++++------- src/librustc_mir/diagnostics.rs | 25 ++++++++----- src/libstd/future.rs | 4 +- src/test/run-pass/drop/dynamic-drop.rs | 3 +- .../run-pass/generator/auxiliary/xcrate.rs | 3 +- .../run-pass/generator/conditional-drop.rs | 9 +++-- src/test/run-pass/generator/control-flow.rs | 6 ++- src/test/run-pass/generator/drop-env.rs | 5 ++- src/test/run-pass/generator/issue-44197.rs | 7 ++-- src/test/run-pass/generator/iterator-count.rs | 8 ++-- .../generator/live-upvar-across-yield.rs | 3 +- .../run-pass/generator/nested_generators.rs | 9 ++--- src/test/run-pass/generator/panic-drops.rs | 5 ++- src/test/run-pass/generator/panic-safe.rs | 5 ++- .../run-pass/generator/resume-after-return.rs | 5 ++- src/test/run-pass/generator/smoke.rs | 29 ++++++++------- .../run-pass/generator/static-generators.rs | 10 +++-- .../run-pass/generator/xcrate-reachable.rs | 3 +- src/test/run-pass/generator/xcrate.rs | 7 ++-- src/test/ui/generator/borrowing.nll.stderr | 16 ++++---- src/test/ui/generator/borrowing.rs | 3 +- src/test/ui/generator/borrowing.stderr | 12 +++--- src/test/ui/generator/dropck.nll.stderr | 4 +- src/test/ui/generator/dropck.rs | 3 +- src/test/ui/generator/dropck.stderr | 4 +- .../generator-region-requirements.ast.stderr | 2 +- .../generator-region-requirements.nll.stderr | 2 +- .../generator-region-requirements.rs | 3 +- .../ref-escapes-but-not-over-yield.nll.stderr | 2 +- .../ref-escapes-but-not-over-yield.rs | 5 +-- .../ref-escapes-but-not-over-yield.stderr | 2 +- src/test/ui/generator/sized-yield.rs | 3 +- src/test/ui/generator/sized-yield.stderr | 8 ++-- .../yield-while-iterating.nll.stderr | 8 ++-- .../ui/generator/yield-while-iterating.rs | 13 ++++--- .../ui/generator/yield-while-iterating.stderr | 6 +-- .../generator/yield-while-local-borrowed.rs | 13 ++++--- .../yield-while-local-borrowed.stderr | 8 ++-- .../yield-while-ref-reborrowed.nll.stderr | 6 +-- .../generator/yield-while-ref-reborrowed.rs | 13 ++++--- .../yield-while-ref-reborrowed.stderr | 4 +- src/test/ui/nll/issue-55850.rs | 12 +++--- 44 files changed, 209 insertions(+), 170 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md index 968534e58bd9e..426fc01a6b051 100644 --- a/src/doc/unstable-book/src/language-features/generators.md +++ b/src/doc/unstable-book/src/language-features/generators.md @@ -29,6 +29,7 @@ A syntactical example of a generator is: #![feature(generators, generator_trait)] use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; fn main() { let mut generator = || { @@ -36,11 +37,11 @@ fn main() { return "foo" }; - match unsafe { generator.resume() } { + match Pin::new(&mut generator).resume() { GeneratorState::Yielded(1) => {} _ => panic!("unexpected value from resume"), } - match unsafe { generator.resume() } { + match Pin::new(&mut generator).resume() { GeneratorState::Complete("foo") => {} _ => panic!("unexpected value from resume"), } @@ -60,6 +61,7 @@ prints all numbers in order: #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; fn main() { let mut generator = || { @@ -69,9 +71,9 @@ fn main() { }; println!("1"); - unsafe { generator.resume() }; + Pin::new(&mut generator).resume(); println!("3"); - unsafe { generator.resume() }; + Pin::new(&mut generator).resume(); println!("5"); } ``` @@ -86,13 +88,14 @@ Feedback on the design and usage is always appreciated! The `Generator` trait in `std::ops` currently looks like: ``` -# #![feature(generator_trait)] +# #![feature(arbitrary_self_types, generator_trait)] # use std::ops::GeneratorState; +# use std::pin::Pin; pub trait Generator { type Yield; type Return; - unsafe fn resume(&mut self) -> GeneratorState; + fn resume(self: Pin<&mut Self>) -> GeneratorState; } ``` @@ -167,6 +170,7 @@ Let's take a look at an example to see what's going on here: #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; fn main() { let ret = "foo"; @@ -175,17 +179,18 @@ fn main() { return ret }; - unsafe { generator.resume() }; - unsafe { generator.resume() }; + Pin::new(&mut generator).resume(); + Pin::new(&mut generator).resume(); } ``` This generator literal will compile down to something similar to: ```rust -#![feature(generators, generator_trait)] +#![feature(arbitrary_self_types, generators, generator_trait)] use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; fn main() { let ret = "foo"; @@ -200,9 +205,9 @@ fn main() { type Yield = i32; type Return = &'static str; - unsafe fn resume(&mut self) -> GeneratorState { + fn resume(mut self: Pin<&mut Self>) -> GeneratorState { use std::mem; - match mem::replace(self, __Generator::Done) { + match mem::replace(&mut *self, __Generator::Done) { __Generator::Start(s) => { *self = __Generator::Yield1(s); GeneratorState::Yielded(1) @@ -223,8 +228,8 @@ fn main() { __Generator::Start(ret) }; - unsafe { generator.resume() }; - unsafe { generator.resume() }; + Pin::new(&mut generator).resume(); + Pin::new(&mut generator).resume(); } ``` diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 1c459f5c4250e..1fd8aa98cc355 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -873,13 +873,12 @@ impl AsMut for Box { impl Unpin for Box { } #[unstable(feature = "generator_trait", issue = "43122")] -impl Generator for Box - where T: Generator + ?Sized -{ - type Yield = T::Yield; - type Return = T::Return; - unsafe fn resume(&mut self) -> GeneratorState { - (**self).resume() +impl Generator for Box { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>) -> GeneratorState { + G::resume(Pin::new(&mut *self)) } } diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs index 1542cd6397e78..5401fff860e9b 100644 --- a/src/libcore/ops/generator.rs +++ b/src/libcore/ops/generator.rs @@ -1,3 +1,6 @@ +use crate::marker::Unpin; +use crate::pin::Pin; + /// The result of a generator resumption. /// /// This enum is returned from the `Generator::resume` method and indicates the @@ -39,6 +42,7 @@ pub enum GeneratorState { /// #![feature(generators, generator_trait)] /// /// use std::ops::{Generator, GeneratorState}; +/// use std::pin::Pin; /// /// fn main() { /// let mut generator = || { @@ -46,11 +50,11 @@ pub enum GeneratorState { /// return "foo" /// }; /// -/// match unsafe { generator.resume() } { +/// match Pin::new(&mut generator).resume() { /// GeneratorState::Yielded(1) => {} /// _ => panic!("unexpected return from resume"), /// } -/// match unsafe { generator.resume() } { +/// match Pin::new(&mut generator).resume() { /// GeneratorState::Complete("foo") => {} /// _ => panic!("unexpected return from resume"), /// } @@ -88,10 +92,6 @@ pub trait Generator { /// generator will continue executing until it either yields or returns, at /// which point this function will return. /// - /// The function is unsafe because it can be used on an immovable generator. - /// After such a call, the immovable generator must not move again, but - /// this is not enforced by the compiler. - /// /// # Return value /// /// The `GeneratorState` enum returned from this function indicates what @@ -110,16 +110,25 @@ pub trait Generator { /// been returned previously. While generator literals in the language are /// guaranteed to panic on resuming after `Complete`, this is not guaranteed /// for all implementations of the `Generator` trait. - unsafe fn resume(&mut self) -> GeneratorState; + fn resume(self: Pin<&mut Self>) -> GeneratorState; +} + +#[unstable(feature = "generator_trait", issue = "43122")] +impl Generator for Pin<&mut G> { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>) -> GeneratorState { + G::resume((*self).as_mut()) + } } #[unstable(feature = "generator_trait", issue = "43122")] -impl Generator for &mut T - where T: Generator + ?Sized -{ - type Yield = T::Yield; - type Return = T::Return; - unsafe fn resume(&mut self) -> GeneratorState { - (**self).resume() +impl Generator for &mut G { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>) -> GeneratorState { + G::resume(Pin::new(&mut *self)) } } diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 74394165a5f84..eb72175421638 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -2119,14 +2119,15 @@ This error occurs because a borrow in a generator persists across a yield point. ```compile_fail,E0626 -# #![feature(generators, generator_trait)] +# #![feature(generators, generator_trait, pin)] # use std::ops::Generator; +# use std::pin::Pin; let mut b = || { let a = &String::new(); // <-- This borrow... yield (); // ...is still in scope here, when the yield occurs. println!("{}", a); }; -unsafe { b.resume() }; +Pin::new(&mut b).resume(); ``` At present, it is not permitted to have a yield that occurs while a @@ -2137,14 +2138,15 @@ resolve the previous example by removing the borrow and just storing the integer by value: ``` -# #![feature(generators, generator_trait)] +# #![feature(generators, generator_trait, pin)] # use std::ops::Generator; +# use std::pin::Pin; let mut b = || { let a = 3; yield (); println!("{}", a); }; -unsafe { b.resume() }; +Pin::new(&mut b).resume(); ``` This is a very simple case, of course. In more complex cases, we may @@ -2154,37 +2156,40 @@ in those cases, something like the `Rc` or `Arc` types may be useful. This error also frequently arises with iteration: ```compile_fail,E0626 -# #![feature(generators, generator_trait)] +# #![feature(generators, generator_trait, pin)] # use std::ops::Generator; +# use std::pin::Pin; let mut b = || { let v = vec![1,2,3]; for &x in &v { // <-- borrow of `v` is still in scope... yield x; // ...when this yield occurs. } }; -unsafe { b.resume() }; +Pin::new(&mut b).resume(); ``` Such cases can sometimes be resolved by iterating "by value" (or using `into_iter()`) to avoid borrowing: ``` -# #![feature(generators, generator_trait)] +# #![feature(generators, generator_trait, pin)] # use std::ops::Generator; +# use std::pin::Pin; let mut b = || { let v = vec![1,2,3]; for x in v { // <-- Take ownership of the values instead! yield x; // <-- Now yield is OK. } }; -unsafe { b.resume() }; +Pin::new(&mut b).resume(); ``` If taking ownership is not an option, using indices can work too: ``` -# #![feature(generators, generator_trait)] +# #![feature(generators, generator_trait, pin)] # use std::ops::Generator; +# use std::pin::Pin; let mut b = || { let v = vec![1,2,3]; let len = v.len(); // (*) @@ -2193,7 +2198,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -unsafe { b.resume() }; +Pin::new(&mut b).resume(); // (*) -- Unfortunately, these temporaries are currently required. // See . diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 22900c3067b11..d1203be3cf011 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -33,7 +33,9 @@ impl> !Unpin for GenFuture {} impl> Future for GenFuture { type Output = T::Return; fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { - set_task_waker(lw, || match unsafe { Pin::get_unchecked_mut(self).0.resume() } { + // Safe because we're !Unpin + !Drop mapping to a ?Unpin value + let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) }; + set_task_waker(lw, || match gen.resume() { GeneratorState::Yielded(()) => Poll::Pending, GeneratorState::Complete(x) => Poll::Ready(x), }) diff --git a/src/test/run-pass/drop/dynamic-drop.rs b/src/test/run-pass/drop/dynamic-drop.rs index 41814f2af16b4..97e4cded80b9a 100644 --- a/src/test/run-pass/drop/dynamic-drop.rs +++ b/src/test/run-pass/drop/dynamic-drop.rs @@ -12,6 +12,7 @@ use std::cell::{Cell, RefCell}; use std::ops::Generator; use std::panic; +use std::pin::Pin; use std::usize; struct InjectedFailure; @@ -172,7 +173,7 @@ fn generator(a: &Allocator, run_count: usize) { ); }; for _ in 0..run_count { - unsafe { gen.resume(); } + Pin::new(&mut gen).resume(); } } diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/run-pass/generator/auxiliary/xcrate.rs index 8e08de28bc6b2..831c248bf909c 100644 --- a/src/test/run-pass/generator/auxiliary/xcrate.rs +++ b/src/test/run-pass/generator/auxiliary/xcrate.rs @@ -1,5 +1,6 @@ #![feature(generators, generator_trait)] +use std::marker::Unpin; use std::ops::Generator; pub fn foo() -> impl Generator { @@ -10,7 +11,7 @@ pub fn foo() -> impl Generator { } } -pub fn bar(t: T) -> Box> { +pub fn bar(t: T) -> Box + Unpin> { Box::new(|| { yield t; }) diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/run-pass/generator/conditional-drop.rs index 766eef9e3f3c3..907f7a3c06de7 100644 --- a/src/test/run-pass/generator/conditional-drop.rs +++ b/src/test/run-pass/generator/conditional-drop.rs @@ -3,6 +3,7 @@ #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; use std::sync::atomic::{AtomicUsize, Ordering}; static A: AtomicUsize = AtomicUsize::new(0); @@ -34,9 +35,9 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - unsafe { a.resume() }; + Pin::new(&mut a).resume(); assert_eq!(A.load(Ordering::SeqCst), n + 1); - unsafe { a.resume() }; + Pin::new(&mut a).resume(); assert_eq!(A.load(Ordering::SeqCst), n + 1); } @@ -50,8 +51,8 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - unsafe { a.resume() }; + Pin::new(&mut a).resume(); assert_eq!(A.load(Ordering::SeqCst), n); - unsafe { a.resume() }; + Pin::new(&mut a).resume(); assert_eq!(A.load(Ordering::SeqCst), n + 1); } diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs index 2f499834796cc..df70e013bd330 100644 --- a/src/test/run-pass/generator/control-flow.rs +++ b/src/test/run-pass/generator/control-flow.rs @@ -2,13 +2,15 @@ #![feature(generators, generator_trait)] +use std::marker::Unpin; use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; fn finish(mut amt: usize, mut t: T) -> T::Return - where T: Generator + where T: Generator + Unpin, { loop { - match unsafe { t.resume() } { + match Pin::new(&mut t).resume() { GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), GeneratorState::Complete(ret) => { assert_eq!(amt, 0); diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs index 252f2c0f07da7..ac4e06656285e 100644 --- a/src/test/run-pass/generator/drop-env.rs +++ b/src/test/run-pass/generator/drop-env.rs @@ -3,6 +3,7 @@ #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; use std::sync::atomic::{AtomicUsize, Ordering}; static A: AtomicUsize = AtomicUsize::new(0); @@ -29,7 +30,7 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - drop(unsafe { foo.resume() }); + drop(Pin::new(&mut foo).resume()); assert_eq!(A.load(Ordering::SeqCst), n); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); @@ -42,7 +43,7 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - drop(unsafe { foo.resume() }); + drop(Pin::new(&mut foo).resume()); assert_eq!(A.load(Ordering::SeqCst), n + 1); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs index 4a6e5b88b235a..6efaff50c1e62 100644 --- a/src/test/run-pass/generator/issue-44197.rs +++ b/src/test/run-pass/generator/issue-44197.rs @@ -3,6 +3,7 @@ #![feature(generators, generator_trait)] use std::ops::{ Generator, GeneratorState }; +use std::pin::Pin; fn foo(_: &str) -> String { String::new() @@ -27,8 +28,6 @@ fn bar2(baz: String) -> impl Generator { } fn main() { - unsafe { - assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new())); - assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(())); - } + assert_eq!(Pin::new(&mut bar(String::new())).resume(), GeneratorState::Yielded(String::new())); + assert_eq!(Pin::new(&mut bar2(String::new())).resume(), GeneratorState::Complete(())); } diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs index 1011d54bdb33c..ac7e122dd5802 100644 --- a/src/test/run-pass/generator/iterator-count.rs +++ b/src/test/run-pass/generator/iterator-count.rs @@ -2,24 +2,26 @@ #![feature(generators, generator_trait)] +use std::marker::Unpin; use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; struct W(T); // This impl isn't safe in general, but the generator used in this test is movable // so it won't cause problems. -impl> Iterator for W { +impl + Unpin> Iterator for W { type Item = T::Yield; fn next(&mut self) -> Option { - match unsafe { self.0.resume() } { + match Pin::new(&mut self.0).resume() { GeneratorState::Complete(..) => None, GeneratorState::Yielded(v) => Some(v), } } } -fn test() -> impl Generator { +fn test() -> impl Generator + Unpin { || { for i in 1..6 { yield i diff --git a/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/run-pass/generator/live-upvar-across-yield.rs index b643809e50382..a1064165b2f7a 100644 --- a/src/test/run-pass/generator/live-upvar-across-yield.rs +++ b/src/test/run-pass/generator/live-upvar-across-yield.rs @@ -3,11 +3,12 @@ #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; fn main() { let b = |_| 3; let mut a = || { b(yield); }; - unsafe { a.resume() }; + Pin::new(&mut a).resume(); } diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/run-pass/generator/nested_generators.rs index e837e5fc9c1fe..b56cce1dc44f1 100644 --- a/src/test/run-pass/generator/nested_generators.rs +++ b/src/test/run-pass/generator/nested_generators.rs @@ -1,10 +1,9 @@ // run-pass -#![feature(generators)] -#![feature(generator_trait)] +#![feature(generators, generator_trait)] -use std::ops::Generator; -use std::ops::GeneratorState; +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; fn main() { let _generator = || { @@ -12,7 +11,7 @@ fn main() { yield 2; }; - match unsafe { sub_generator.resume() } { + match Pin::new(&mut sub_generator).resume() { GeneratorState::Yielded(x) => { yield x; } diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs index 8640a6539195b..5ac97585f4b57 100644 --- a/src/test/run-pass/generator/panic-drops.rs +++ b/src/test/run-pass/generator/panic-drops.rs @@ -6,6 +6,7 @@ use std::ops::Generator; use std::panic; +use std::pin::Pin; use std::sync::atomic::{AtomicUsize, Ordering}; static A: AtomicUsize = AtomicUsize::new(0); @@ -34,7 +35,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 0); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - unsafe { foo.resume() } + Pin::new(&mut foo).resume() })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); @@ -49,7 +50,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 1); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - unsafe { foo.resume() } + Pin::new(&mut foo).resume() })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs index 134debdd23bc5..5f6778674dce1 100644 --- a/src/test/run-pass/generator/panic-safe.rs +++ b/src/test/run-pass/generator/panic-safe.rs @@ -5,6 +5,7 @@ #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; use std::panic; fn main() { @@ -16,13 +17,13 @@ fn main() { }; let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - unsafe { foo.resume() } + Pin::new(&mut foo).resume() })); assert!(res.is_err()); for _ in 0..10 { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - unsafe { foo.resume() } + Pin::new(&mut foo).resume() })); assert!(res.is_err()); } diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs index 2213c2f3fbae3..71a68ff684af3 100644 --- a/src/test/run-pass/generator/resume-after-return.rs +++ b/src/test/run-pass/generator/resume-after-return.rs @@ -5,6 +5,7 @@ #![feature(generators, generator_trait)] use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; use std::panic; fn main() { @@ -15,12 +16,12 @@ fn main() { yield; }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } - match panic::catch_unwind(move || unsafe { foo.resume() }) { + match panic::catch_unwind(move || Pin::new(&mut foo).resume()) { Ok(_) => panic!("generator successfully resumed"), Err(_) => {} } diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs index 8582941d610ca..533f2399084fa 100644 --- a/src/test/run-pass/generator/smoke.rs +++ b/src/test/run-pass/generator/smoke.rs @@ -6,6 +6,7 @@ #![feature(generators, generator_trait)] use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; use std::thread; #[test] @@ -16,7 +17,7 @@ fn simple() { } }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -32,7 +33,7 @@ fn return_capture() { a }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -44,11 +45,11 @@ fn simple_yield() { yield; }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -61,11 +62,11 @@ fn yield_capture() { yield b; }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -78,11 +79,11 @@ fn simple_yield_value() { return String::from("foo") }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(ref s) if *s == "bar" => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -96,11 +97,11 @@ fn return_after_yield() { return a }; - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -148,11 +149,11 @@ fn send_and_sync() { fn send_over_threads() { let mut foo = || { yield }; thread::spawn(move || { - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -161,11 +162,11 @@ fn send_over_threads() { let a = String::from("a"); let mut foo = || { yield a }; thread::spawn(move || { - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(ref s) if *s == "a" => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs index eeaba3fe3c4c3..965d3c61c22d5 100644 --- a/src/test/run-pass/generator/static-generators.rs +++ b/src/test/run-pass/generator/static-generators.rs @@ -2,6 +2,7 @@ #![feature(generators, generator_trait)] +use std::pin::Pin; use std::ops::{Generator, GeneratorState}; fn main() { @@ -11,8 +12,9 @@ fn main() { yield; assert_eq!(b as *const _, &a as *const _); }; - unsafe { - assert_eq!(generator.resume(), GeneratorState::Yielded(())); - assert_eq!(generator.resume(), GeneratorState::Complete(())); - } + // Safety: We shadow the original generator variable so have no safe API to + // move it after this point. + let mut generator = unsafe { Pin::new_unchecked(&mut generator) }; + assert_eq!(generator.as_mut().resume(), GeneratorState::Yielded(())); + assert_eq!(generator.as_mut().resume(), GeneratorState::Complete(())); } diff --git a/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/run-pass/generator/xcrate-reachable.rs index 403c920786e9c..9483ad7395ea1 100644 --- a/src/test/run-pass/generator/xcrate-reachable.rs +++ b/src/test/run-pass/generator/xcrate-reachable.rs @@ -7,7 +7,8 @@ extern crate xcrate_reachable as foo; use std::ops::Generator; +use std::pin::Pin; fn main() { - unsafe { foo::foo().resume(); } + Pin::new(&mut foo::foo()).resume(); } diff --git a/src/test/run-pass/generator/xcrate.rs b/src/test/run-pass/generator/xcrate.rs index 571b8fa9170f4..febf5c3583f30 100644 --- a/src/test/run-pass/generator/xcrate.rs +++ b/src/test/run-pass/generator/xcrate.rs @@ -7,22 +7,23 @@ extern crate xcrate; use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; fn main() { let mut foo = xcrate::foo(); - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } let mut foo = xcrate::bar(3); - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Yielded(3) => {} s => panic!("bad state: {:?}", s), } - match unsafe { foo.resume() } { + match Pin::new(&mut foo).resume() { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/ui/generator/borrowing.nll.stderr b/src/test/ui/generator/borrowing.nll.stderr index af6ec4941d890..3c9221d28e74d 100644 --- a/src/test/ui/generator/borrowing.nll.stderr +++ b/src/test/ui/generator/borrowing.nll.stderr @@ -1,12 +1,12 @@ error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:8:29 + --> $DIR/borrowing.rs:9:33 | -LL | unsafe { (|| yield &a).resume() } - | -----------^- - | || | - | || borrowed value does not live long enough - | |value captured here by generator - | a temporary with access to the borrow is created here ... +LL | Pin::new(&mut || yield &a).resume() + | ----------^ + | | | + | | borrowed value does not live long enough + | value captured here by generator + | a temporary with access to the borrow is created here ... LL | //~^ ERROR: `a` does not live long enough LL | }; | -- ... and the borrow might be used here, when that temporary is dropped and runs the destructor for generator @@ -16,7 +16,7 @@ LL | }; = note: The temporary is part of an expression at the end of a block. Consider forcing this temporary to be dropped sooner, before the block's local variables are dropped. For example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block. error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:15:20 + --> $DIR/borrowing.rs:16:20 | LL | let _b = { | -- borrow later stored here diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs index 88a0cf9a77a54..9f8fc7483f64d 100644 --- a/src/test/ui/generator/borrowing.rs +++ b/src/test/ui/generator/borrowing.rs @@ -1,11 +1,12 @@ #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; fn main() { let _b = { let a = 3; - unsafe { (|| yield &a).resume() } + Pin::new(&mut || yield &a).resume() //~^ ERROR: `a` does not live long enough }; diff --git a/src/test/ui/generator/borrowing.stderr b/src/test/ui/generator/borrowing.stderr index 3f5d32e1c3358..169e4a8561c1d 100644 --- a/src/test/ui/generator/borrowing.stderr +++ b/src/test/ui/generator/borrowing.stderr @@ -1,10 +1,10 @@ error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:8:29 + --> $DIR/borrowing.rs:9:33 | -LL | unsafe { (|| yield &a).resume() } - | -- ^ borrowed value does not live long enough - | | - | capture occurs here +LL | Pin::new(&mut || yield &a).resume() + | -- ^ borrowed value does not live long enough + | | + | capture occurs here LL | //~^ ERROR: `a` does not live long enough LL | }; | - borrowed value only lives until here @@ -13,7 +13,7 @@ LL | } | - borrowed value needs to live until here error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:15:20 + --> $DIR/borrowing.rs:16:20 | LL | || { | -- capture occurs here diff --git a/src/test/ui/generator/dropck.nll.stderr b/src/test/ui/generator/dropck.nll.stderr index 1f6b7db2bd853..a90a47fe9aa01 100644 --- a/src/test/ui/generator/dropck.nll.stderr +++ b/src/test/ui/generator/dropck.nll.stderr @@ -1,5 +1,5 @@ error[E0597]: `*cell` does not live long enough - --> $DIR/dropck.rs:9:40 + --> $DIR/dropck.rs:10:40 | LL | let ref_ = Box::leak(Box::new(Some(cell.borrow_mut()))); | ^^^^ borrowed value does not live long enough @@ -13,7 +13,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are defined error[E0597]: `ref_` does not live long enough - --> $DIR/dropck.rs:14:18 + --> $DIR/dropck.rs:15:18 | LL | gen = || { | -- value captured here by generator diff --git a/src/test/ui/generator/dropck.rs b/src/test/ui/generator/dropck.rs index 1b0c1ebe517b4..65c61fbaac4e2 100644 --- a/src/test/ui/generator/dropck.rs +++ b/src/test/ui/generator/dropck.rs @@ -2,6 +2,7 @@ use std::cell::RefCell; use std::ops::Generator; +use std::pin::Pin; fn main() { let (mut gen, cell); @@ -14,6 +15,6 @@ fn main() { let _d = ref_.take(); //~ ERROR `ref_` does not live long enough yield; }; - unsafe { gen.resume(); } + Pin::new(&mut gen).resume(); // drops the RefCell and then the Ref, leading to use-after-free } diff --git a/src/test/ui/generator/dropck.stderr b/src/test/ui/generator/dropck.stderr index 281c9647bc3e1..fdaa5cfbae3e6 100644 --- a/src/test/ui/generator/dropck.stderr +++ b/src/test/ui/generator/dropck.stderr @@ -1,5 +1,5 @@ error[E0597]: `*cell` does not live long enough - --> $DIR/dropck.rs:9:40 + --> $DIR/dropck.rs:10:40 | LL | let ref_ = Box::leak(Box::new(Some(cell.borrow_mut()))); | ^^^^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `ref_` does not live long enough - --> $DIR/dropck.rs:14:18 + --> $DIR/dropck.rs:15:18 | LL | gen = || { | -- capture occurs here diff --git a/src/test/ui/generator/generator-region-requirements.ast.stderr b/src/test/ui/generator/generator-region-requirements.ast.stderr index 6a423aea7eceb..8a96d187f6b1c 100644 --- a/src/test/ui/generator/generator-region-requirements.ast.stderr +++ b/src/test/ui/generator/generator-region-requirements.ast.stderr @@ -1,5 +1,5 @@ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/generator-region-requirements.rs:15:51 + --> $DIR/generator-region-requirements.rs:16:51 | LL | fn dangle(x: &mut i32) -> &'static mut i32 { | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32` diff --git a/src/test/ui/generator/generator-region-requirements.nll.stderr b/src/test/ui/generator/generator-region-requirements.nll.stderr index 6a423aea7eceb..8a96d187f6b1c 100644 --- a/src/test/ui/generator/generator-region-requirements.nll.stderr +++ b/src/test/ui/generator/generator-region-requirements.nll.stderr @@ -1,5 +1,5 @@ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/generator-region-requirements.rs:15:51 + --> $DIR/generator-region-requirements.rs:16:51 | LL | fn dangle(x: &mut i32) -> &'static mut i32 { | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32` diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs index 2cda483b6a1c2..9738f6c3932ed 100644 --- a/src/test/ui/generator/generator-region-requirements.rs +++ b/src/test/ui/generator/generator-region-requirements.rs @@ -4,6 +4,7 @@ #![feature(generators, generator_trait)] #![cfg_attr(nll, feature(nll))] use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; fn dangle(x: &mut i32) -> &'static mut i32 { let mut g = || { @@ -11,7 +12,7 @@ fn dangle(x: &mut i32) -> &'static mut i32 { x }; loop { - match unsafe { g.resume() } { + match Pin::new(&mut g).resume() { GeneratorState::Complete(c) => return c, //[nll]~^ ERROR explicit lifetime required //[ast]~^^ ERROR explicit lifetime required diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr index 72a4654dec8b2..01eea627351fb 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of generator - --> $DIR/ref-escapes-but-not-over-yield.rs:14:9 + --> $DIR/ref-escapes-but-not-over-yield.rs:11:9 | LL | let mut a = &3; | ----- `a` is declared here, outside of the generator body diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.rs b/src/test/ui/generator/ref-escapes-but-not-over-yield.rs index 332e074e9fe64..8c576581ad8dd 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.rs +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.rs @@ -1,7 +1,4 @@ -#![feature(generators, generator_trait)] - -use std::ops::{GeneratorState, Generator}; -use std::cell::Cell; +#![feature(generators)] fn foo(x: &i32) { // In this case, a reference to `b` escapes the generator, but not diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr index e1d718e847f8f..29299b2405a00 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr @@ -1,5 +1,5 @@ error[E0597]: `b` does not live long enough - --> $DIR/ref-escapes-but-not-over-yield.rs:14:14 + --> $DIR/ref-escapes-but-not-over-yield.rs:11:14 | LL | a = &b; | ^ borrowed value does not live long enough diff --git a/src/test/ui/generator/sized-yield.rs b/src/test/ui/generator/sized-yield.rs index e34731a4406d9..f64849b3149b8 100644 --- a/src/test/ui/generator/sized-yield.rs +++ b/src/test/ui/generator/sized-yield.rs @@ -1,6 +1,7 @@ #![feature(generators, generator_trait)] use std::ops::Generator; +use std::pin::Pin; fn main() { let s = String::from("foo"); @@ -8,6 +9,6 @@ fn main() { //~^ ERROR the size for values of type yield s[..]; }; - unsafe { gen.resume(); } + Pin::new(&mut gen).resume(); //~^ ERROR the size for values of type } diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr index 4f59f2c1c6ab3..c98f42e62168e 100644 --- a/src/test/ui/generator/sized-yield.stderr +++ b/src/test/ui/generator/sized-yield.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/sized-yield.rs:7:26 + --> $DIR/sized-yield.rs:8:26 | LL | let mut gen = move || { | __________________________^ @@ -13,10 +13,10 @@ LL | | }; = note: the yield type of a generator must have a statically known size error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/sized-yield.rs:11:17 + --> $DIR/sized-yield.rs:12:23 | -LL | unsafe { gen.resume(); } - | ^^^^^^ doesn't have a size known at compile-time +LL | Pin::new(&mut gen).resume(); + | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `str` = note: to learn more, visit diff --git a/src/test/ui/generator/yield-while-iterating.nll.stderr b/src/test/ui/generator/yield-while-iterating.nll.stderr index bcbd68ab85d5c..2dc12f843b220 100644 --- a/src/test/ui/generator/yield-while-iterating.nll.stderr +++ b/src/test/ui/generator/yield-while-iterating.nll.stderr @@ -1,5 +1,5 @@ error[E0626]: borrow may still be in use when generator yields - --> $DIR/yield-while-iterating.rs:12:18 + --> $DIR/yield-while-iterating.rs:13:18 | LL | for p in &x { //~ ERROR | ^^ @@ -7,7 +7,7 @@ LL | yield(); | ------- possible yield occurs here error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/yield-while-iterating.rs:57:20 + --> $DIR/yield-while-iterating.rs:58:20 | LL | let mut b = || { | -- mutable borrow occurs here @@ -16,8 +16,8 @@ LL | for p in &mut x { ... LL | println!("{}", x[0]); //~ ERROR | ^ immutable borrow occurs here -LL | b.resume(); - | - mutable borrow later used here +LL | Pin::new(&mut b).resume(); + | ------ mutable borrow later used here error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/yield-while-iterating.rs b/src/test/ui/generator/yield-while-iterating.rs index b0966d2e921b7..e42781d1279e7 100644 --- a/src/test/ui/generator/yield-while-iterating.rs +++ b/src/test/ui/generator/yield-while-iterating.rs @@ -2,6 +2,7 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; +use std::pin::Pin; fn yield_during_iter_owned_data(x: Vec) { // The generator owns `x`, so we error out when yielding with a @@ -33,7 +34,7 @@ fn yield_during_iter_borrowed_slice_2() { println!("{:?}", x); } -unsafe fn yield_during_iter_borrowed_slice_3() { +fn yield_during_iter_borrowed_slice_3() { // OK to take a mutable ref to `x` and yield // up pointers from it: let mut x = vec![22_i32]; @@ -42,10 +43,10 @@ unsafe fn yield_during_iter_borrowed_slice_3() { yield p; } }; - b.resume(); + Pin::new(&mut b).resume(); } -unsafe fn yield_during_iter_borrowed_slice_4() { +fn yield_during_iter_borrowed_slice_4() { // ...but not OK to do that while reading // from `x` too let mut x = vec![22_i32]; @@ -55,10 +56,10 @@ unsafe fn yield_during_iter_borrowed_slice_4() { } }; println!("{}", x[0]); //~ ERROR - b.resume(); + Pin::new(&mut b).resume(); } -unsafe fn yield_during_range_iter() { +fn yield_during_range_iter() { // Should be OK. let mut b = || { let v = vec![1,2,3]; @@ -68,7 +69,7 @@ unsafe fn yield_during_range_iter() { yield x; } }; - b.resume(); + Pin::new(&mut b).resume(); } fn main() { } diff --git a/src/test/ui/generator/yield-while-iterating.stderr b/src/test/ui/generator/yield-while-iterating.stderr index aa66047feb227..1e3e31470e9d6 100644 --- a/src/test/ui/generator/yield-while-iterating.stderr +++ b/src/test/ui/generator/yield-while-iterating.stderr @@ -1,5 +1,5 @@ error[E0626]: borrow may still be in use when generator yields - --> $DIR/yield-while-iterating.rs:12:19 + --> $DIR/yield-while-iterating.rs:13:19 | LL | for p in &x { //~ ERROR | ^ @@ -7,7 +7,7 @@ LL | yield(); | ------- possible yield occurs here error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/yield-while-iterating.rs:57:20 + --> $DIR/yield-while-iterating.rs:58:20 | LL | let mut b = || { | -- mutable borrow occurs here @@ -16,7 +16,7 @@ LL | for p in &mut x { ... LL | println!("{}", x[0]); //~ ERROR | ^ immutable borrow occurs here -LL | b.resume(); +LL | Pin::new(&mut b).resume(); LL | } | - mutable borrow ends here diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs index a895f05b34cae..38061e71358c4 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.rs +++ b/src/test/ui/generator/yield-while-local-borrowed.rs @@ -4,8 +4,9 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; +use std::pin::Pin; -unsafe fn borrow_local_inline() { +fn borrow_local_inline() { // Not OK to yield with a borrow of a temporary. // // (This error occurs because the region shows up in the type of @@ -17,10 +18,10 @@ unsafe fn borrow_local_inline() { yield(); println!("{}", a); }; - b.resume(); + Pin::new(&mut b).resume(); } -unsafe fn borrow_local_inline_done() { +fn borrow_local_inline_done() { // No error here -- `a` is not in scope at the point of `yield`. let mut b = move || { { @@ -28,10 +29,10 @@ unsafe fn borrow_local_inline_done() { } yield(); }; - b.resume(); + Pin::new(&mut b).resume(); } -unsafe fn borrow_local() { +fn borrow_local() { // Not OK to yield with a borrow of a temporary. // // (This error occurs because the region shows up in the type of @@ -46,7 +47,7 @@ unsafe fn borrow_local() { println!("{}", b); } }; - b.resume(); + Pin::new(&mut b).resume(); } fn main() { } diff --git a/src/test/ui/generator/yield-while-local-borrowed.stderr b/src/test/ui/generator/yield-while-local-borrowed.stderr index 765267a58b4a7..56f425b7e70a0 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.stderr +++ b/src/test/ui/generator/yield-while-local-borrowed.stderr @@ -1,5 +1,5 @@ error[E0626]: borrow may still be in use when generator yields (Ast) - --> $DIR/yield-while-local-borrowed.rs:14:22 + --> $DIR/yield-while-local-borrowed.rs:15:22 | LL | let a = &mut 3; | ^ @@ -8,7 +8,7 @@ LL | yield(); | ------- possible yield occurs here error[E0626]: borrow may still be in use when generator yields (Ast) - --> $DIR/yield-while-local-borrowed.rs:42:22 + --> $DIR/yield-while-local-borrowed.rs:43:22 | LL | let b = &a; | ^ @@ -17,7 +17,7 @@ LL | yield(); | ------- possible yield occurs here error[E0626]: borrow may still be in use when generator yields (Mir) - --> $DIR/yield-while-local-borrowed.rs:14:17 + --> $DIR/yield-while-local-borrowed.rs:15:17 | LL | let a = &mut 3; | ^^^^^^ @@ -26,7 +26,7 @@ LL | yield(); | ------- possible yield occurs here error[E0626]: borrow may still be in use when generator yields (Mir) - --> $DIR/yield-while-local-borrowed.rs:42:21 + --> $DIR/yield-while-local-borrowed.rs:43:21 | LL | let b = &a; | ^^ diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr index 9a99b6ad02518..d0d6a98301e59 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr @@ -1,5 +1,5 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/yield-while-ref-reborrowed.rs:35:20 + --> $DIR/yield-while-ref-reborrowed.rs:36:20 | LL | let mut b = || { | -- generator construction occurs here @@ -8,8 +8,8 @@ LL | let a = &mut *x; ... LL | println!("{}", x); //~ ERROR | ^ second borrow occurs here -LL | b.resume(); - | - first borrow later used here +LL | Pin::new(&mut b).resume(); + | ------ first borrow later used here error: aborting due to previous error diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.rs b/src/test/ui/generator/yield-while-ref-reborrowed.rs index 540907a421dfb..f54a4f468f6a0 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.rs +++ b/src/test/ui/generator/yield-while-ref-reborrowed.rs @@ -2,8 +2,9 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; +use std::pin::Pin; -unsafe fn reborrow_shared_ref(x: &i32) { +fn reborrow_shared_ref(x: &i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the generator. let mut b = move || { @@ -11,10 +12,10 @@ unsafe fn reborrow_shared_ref(x: &i32) { yield(); println!("{}", a); }; - b.resume(); + Pin::new(&mut b).resume(); } -unsafe fn reborrow_mutable_ref(x: &mut i32) { +fn reborrow_mutable_ref(x: &mut i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the generator. let mut b = move || { @@ -22,10 +23,10 @@ unsafe fn reborrow_mutable_ref(x: &mut i32) { yield(); println!("{}", a); }; - b.resume(); + Pin::new(&mut b).resume(); } -unsafe fn reborrow_mutable_ref_2(x: &mut i32) { +fn reborrow_mutable_ref_2(x: &mut i32) { // ...but not OK to go on using `x`. let mut b = || { let a = &mut *x; @@ -33,7 +34,7 @@ unsafe fn reborrow_mutable_ref_2(x: &mut i32) { println!("{}", a); }; println!("{}", x); //~ ERROR - b.resume(); + Pin::new(&mut b).resume(); } fn main() { } diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.stderr index d70ef189ebc9a..5c9de279c02d8 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.stderr @@ -1,5 +1,5 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/yield-while-ref-reborrowed.rs:35:20 + --> $DIR/yield-while-ref-reborrowed.rs:36:20 | LL | let mut b = || { | -- closure construction occurs here @@ -8,7 +8,7 @@ LL | let a = &mut *x; ... LL | println!("{}", x); //~ ERROR | ^ borrow occurs here -LL | b.resume(); +LL | Pin::new(&mut b).resume(); LL | } | - borrow from closure ends here diff --git a/src/test/ui/nll/issue-55850.rs b/src/test/ui/nll/issue-55850.rs index eafbfd21700c8..8b5887224d19a 100644 --- a/src/test/ui/nll/issue-55850.rs +++ b/src/test/ui/nll/issue-55850.rs @@ -1,23 +1,23 @@ #![allow(unused_mut)] #![feature(generators, generator_trait)] +use std::marker::Unpin; use std::ops::Generator; use std::ops::GeneratorState::Yielded; +use std::pin::Pin; pub struct GenIter(G); impl Iterator for GenIter where - G: Generator, + G: Generator + Unpin, { type Item = G::Yield; fn next(&mut self) -> Option { - unsafe { - match self.0.resume() { - Yielded(y) => Some(y), - _ => None - } + match Pin::new(&mut self.0).resume() { + Yielded(y) => Some(y), + _ => None } } } From 730b18b6e5f49091878739498793676f0c0ca28b Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sun, 4 Nov 2018 22:07:55 +0100 Subject: [PATCH 0374/1064] Mark static generators as !Unpin --- src/libcore/marker.rs | 1 + src/librustc/middle/lang_items.rs | 1 + src/librustc/traits/select.rs | 6 ++++++ src/test/ui/generator/static-not-unpin.rs | 13 +++++++++++++ src/test/ui/generator/static-not-unpin.stderr | 15 +++++++++++++++ 5 files changed, 36 insertions(+) create mode 100644 src/test/ui/generator/static-not-unpin.rs create mode 100644 src/test/ui/generator/static-not-unpin.stderr diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 65752ba032104..457d556e4fa6d 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -627,6 +627,7 @@ unsafe impl Freeze for &mut T {} /// [`Pin`]: ../pin/struct.Pin.html /// [`pin module`]: ../../std/pin/index.html #[stable(feature = "pin", since = "1.33.0")] +#[cfg_attr(not(stage0), lang = "unpin")] pub auto trait Unpin {} /// A marker type which does not implement `Unpin`. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index c203ea96f3d64..e324bde1f17bf 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -299,6 +299,7 @@ language_item_table! { GeneratorStateLangItem, "generator_state", gen_state, Target::Enum; GeneratorTraitLangItem, "generator", gen_trait, Target::Trait; + UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait; EqTraitLangItem, "eq", eq_trait, Target::Trait; PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9a0610f45dec2..7a244b7e80e6a 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2017,6 +2017,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // the auto impl might apply, we don't know candidates.ambiguous = true; } + ty::Generator(_, _, hir::GeneratorMovability::Static) + if self.tcx().lang_items().unpin_trait() == Some(def_id) => + { + // Immovable generators are never `Unpin`, so suppress the + // normal auto-impl candidate for it. + } _ => candidates.vec.push(AutoImplCandidate(def_id.clone())), } } diff --git a/src/test/ui/generator/static-not-unpin.rs b/src/test/ui/generator/static-not-unpin.rs new file mode 100644 index 0000000000000..7586faf1842ba --- /dev/null +++ b/src/test/ui/generator/static-not-unpin.rs @@ -0,0 +1,13 @@ +#![feature(generators)] + +use std::marker::Unpin; + +fn assert_unpin(_: T) { +} + +fn main() { + let mut generator = static || { + yield; + }; + assert_unpin(generator); //~ ERROR std::marker::Unpin` is not satisfied +} diff --git a/src/test/ui/generator/static-not-unpin.stderr b/src/test/ui/generator/static-not-unpin.stderr new file mode 100644 index 0000000000000..7a1243f5783d4 --- /dev/null +++ b/src/test/ui/generator/static-not-unpin.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:9:25: 11:6 _]: std::marker::Unpin` is not satisfied + --> $DIR/static-not-unpin.rs:12:5 + | +LL | assert_unpin(generator); //~ ERROR std::marker::Unpin` is not satisfied + | ^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:9:25: 11:6 _]` + | +note: required by `assert_unpin` + --> $DIR/static-not-unpin.rs:5:1 + | +LL | fn assert_unpin(_: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 0c203965e2a5aca6750f90777003adad2b79849f Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Tue, 6 Nov 2018 19:47:18 +0100 Subject: [PATCH 0375/1064] impl Generator for Pin> --- src/liballoc/boxed.rs | 10 ++++++++++ src/test/run-pass/generator/pin-box-generator.rs | 13 +++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/test/run-pass/generator/pin-box-generator.rs diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 1fd8aa98cc355..14a1242e3e569 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -882,6 +882,16 @@ impl Generator for Box { } } +#[unstable(feature = "generator_trait", issue = "43122")] +impl Generator for Pin> { + type Yield = G::Yield; + type Return = G::Return; + + fn resume(mut self: Pin<&mut Self>) -> GeneratorState { + G::resume((*self).as_mut()) + } +} + #[unstable(feature = "futures_api", issue = "50547")] impl Future for Box { type Output = F::Output; diff --git a/src/test/run-pass/generator/pin-box-generator.rs b/src/test/run-pass/generator/pin-box-generator.rs new file mode 100644 index 0000000000000..c3136f5c0ec82 --- /dev/null +++ b/src/test/run-pass/generator/pin-box-generator.rs @@ -0,0 +1,13 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn assert_generator(_: G) { +} + +fn main() { + assert_generator(static || yield); + assert_generator(Box::pin(static || yield)); +} From be3989301aea41777bdbc65d5c3537b7036ec407 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Wed, 7 Nov 2018 00:11:58 +0100 Subject: [PATCH 0376/1064] Update generator transform and generated function signature --- src/libcore/pin.rs | 1 + src/librustc/middle/lang_items.rs | 1 + src/librustc/ty/instance.rs | 5 +++ src/librustc_mir/transform/generator.rs | 45 +++++++++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 7c09a36d89883..56a32c928fb3d 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -117,6 +117,7 @@ use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn}; // implementations, are allowed because they all only use `&P`, so they cannot move // the value behind `pointer`. #[stable(feature = "pin", since = "1.33.0")] +#[cfg_attr(not(stage0), lang = "pin")] #[fundamental] #[repr(transparent)] #[derive(Copy, Clone, Hash, Eq, Ord)] diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index e324bde1f17bf..87107f727a05d 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -300,6 +300,7 @@ language_item_table! { GeneratorStateLangItem, "generator_state", gen_state, Target::Enum; GeneratorTraitLangItem, "generator", gen_trait, Target::Trait; UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait; + PinTypeLangItem, "pin", pin_type, Target::Struct; EqTraitLangItem, "eq", eq_trait, Target::Trait; PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 78b6ffaa54e17..bc43fedef0f34 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -76,6 +76,11 @@ impl<'a, 'tcx> Instance<'tcx> { let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); + let pin_did = tcx.lang_items().pin_type().unwrap(); + let pin_adt_ref = tcx.adt_def(pin_did); + let pin_substs = tcx.intern_substs(&[env_ty.into()]); + let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); + sig.map_bound(|sig| { let state_did = tcx.lang_items().gen_state().unwrap(); let state_adt_ref = tcx.adt_def(state_did); diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index ec0c118634d0f..f5cc6a43e28b9 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -113,6 +113,33 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor { } } +struct PinArgVisitor<'tcx> { + ref_gen_ty: Ty<'tcx>, +} + +impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { + fn visit_local(&mut self, + local: &mut Local, + _: PlaceContext<'tcx>, + _: Location) { + assert_ne!(*local, self_arg()); + } + + fn visit_place(&mut self, + place: &mut Place<'tcx>, + context: PlaceContext<'tcx>, + location: Location) { + if *place == Place::Local(self_arg()) { + *place = Place::Projection(Box::new(Projection { + base: place.clone(), + elem: ProjectionElem::Field(Field::new(0), self.ref_gen_ty), + })); + } else { + self.super_place(place, context, location); + } + } +} + fn self_arg() -> Local { Local::new(1) } @@ -286,6 +313,23 @@ fn make_generator_state_argument_indirect<'a, 'tcx>( DerefArgVisitor.visit_mir(mir); } +fn make_generator_state_argument_pinned<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &mut Mir<'tcx>) { + let ref_gen_ty = mir.local_decls.raw[1].ty; + + let pin_did = tcx.lang_items().pin_type().unwrap(); + let pin_adt_ref = tcx.adt_def(pin_did); + let substs = tcx.intern_substs(&[ref_gen_ty.into()]); + let pin_ref_gen_ty = tcx.mk_adt(pin_adt_ref, substs); + + // Replace the by ref generator argument + mir.local_decls.raw[1].ty = pin_ref_gen_ty; + + // Add the Pin field access to accesses of the generator state + PinArgVisitor { ref_gen_ty }.visit_mir(mir); +} + fn replace_result_variable<'tcx>( ret_ty: Ty<'tcx>, mir: &mut Mir<'tcx>, @@ -741,6 +785,7 @@ fn create_generator_resume_function<'a, 'tcx>( insert_switch(tcx, mir, cases, &transform, TerminatorKind::Unreachable); make_generator_state_argument_indirect(tcx, def_id, mir); + make_generator_state_argument_pinned(tcx, mir); no_landing_pads(tcx, mir); From e7d66758cfce4dc2c87e3224b6ed47aee1fee257 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Wed, 7 Nov 2018 10:33:35 +0100 Subject: [PATCH 0377/1064] Update generator upvar debug info --- src/librustc_codegen_ssa/mir/mod.rs | 7 ++++++ src/test/debuginfo/generators.rs | 36 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/test/debuginfo/generators.rs diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 85a663dacdcc5..c7e2131eed5da 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -586,10 +586,17 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( return; } + let pin_did = tcx.lang_items().pin_type(); // Or is it the closure environment? let (closure_layout, env_ref) = match arg.layout.ty.sty { ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => (bx.layout_of(ty), true), + ty::Adt(def, substs) if Some(def.did) == pin_did => { + match substs.type_at(0).sty { + ty::Ref(_, ty, _) => (bx.layout_of(ty), true), + _ => (arg.layout, false), + } + } _ => (arg.layout, false) }; diff --git a/src/test/debuginfo/generators.rs b/src/test/debuginfo/generators.rs new file mode 100644 index 0000000000000..b56d222e0e01e --- /dev/null +++ b/src/test/debuginfo/generators.rs @@ -0,0 +1,36 @@ +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run +// gdb-command:print a +// gdb-check:$1 = 5 + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-command:print a +// lldbg-check:(int) $0 = 5 +// lldbr-check:(int) a = 5 + +#![feature(omit_gdb_pretty_printer_section, generators, generator_trait, pin)] +#![omit_gdb_pretty_printer_section] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut a = 5; + let mut b = || { + yield; + _zzz(); // #break + a = 6; + }; + Pin::new(&mut b).resume(); + Pin::new(&mut b).resume(); + _zzz(); // #break +} + +fn _zzz() {()} From c4bf5f9d63ea04b8907a3b41862f0372ed2afda8 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Wed, 7 Nov 2018 19:01:35 +0100 Subject: [PATCH 0378/1064] Temporary workaround for travis diagnostic difference --- src/test/ui/generator/static-not-unpin.rs | 2 ++ src/test/ui/generator/static-not-unpin.stderr | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/ui/generator/static-not-unpin.rs b/src/test/ui/generator/static-not-unpin.rs index 7586faf1842ba..b271e982fb420 100644 --- a/src/test/ui/generator/static-not-unpin.rs +++ b/src/test/ui/generator/static-not-unpin.rs @@ -1,5 +1,7 @@ #![feature(generators)] +// normalize-stderr-test "std::pin::Unpin" -> "std::marker::Unpin" + use std::marker::Unpin; fn assert_unpin(_: T) { diff --git a/src/test/ui/generator/static-not-unpin.stderr b/src/test/ui/generator/static-not-unpin.stderr index 7a1243f5783d4..caf92f0ec693e 100644 --- a/src/test/ui/generator/static-not-unpin.stderr +++ b/src/test/ui/generator/static-not-unpin.stderr @@ -1,11 +1,11 @@ -error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:9:25: 11:6 _]: std::marker::Unpin` is not satisfied - --> $DIR/static-not-unpin.rs:12:5 +error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]: std::marker::Unpin` is not satisfied + --> $DIR/static-not-unpin.rs:14:5 | LL | assert_unpin(generator); //~ ERROR std::marker::Unpin` is not satisfied - | ^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:9:25: 11:6 _]` + | ^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]` | note: required by `assert_unpin` - --> $DIR/static-not-unpin.rs:5:1 + --> $DIR/static-not-unpin.rs:7:1 | LL | fn assert_unpin(_: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From a21c95f08e37a2e609a0cb523eb9c132d8c341f3 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Wed, 21 Nov 2018 15:32:51 +0100 Subject: [PATCH 0379/1064] Mark non-static generators as always Unpin --- src/librustc/traits/select.rs | 18 +++++++++++++++--- .../run-pass/generator/auxiliary/xcrate.rs | 2 +- .../run-pass/generator/non-static-is-unpin.rs | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 src/test/run-pass/generator/non-static-is-unpin.rs diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7a244b7e80e6a..6fe4a7a52be86 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2017,12 +2017,24 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // the auto impl might apply, we don't know candidates.ambiguous = true; } - ty::Generator(_, _, hir::GeneratorMovability::Static) + ty::Generator(_, _, movability) if self.tcx().lang_items().unpin_trait() == Some(def_id) => { - // Immovable generators are never `Unpin`, so suppress the - // normal auto-impl candidate for it. + match movability { + hir::GeneratorMovability::Static => { + // Immovable generators are never `Unpin`, so + // suppress the normal auto-impl candidate for it. + } + hir::GeneratorMovability::Movable => { + // Movable generators are always `Unpin`, so add an + // unconditional builtin candidate. + candidates.vec.push(BuiltinCandidate { + has_nested: false, + }); + } + } } + _ => candidates.vec.push(AutoImplCandidate(def_id.clone())), } } diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/run-pass/generator/auxiliary/xcrate.rs index 831c248bf909c..613c495832f00 100644 --- a/src/test/run-pass/generator/auxiliary/xcrate.rs +++ b/src/test/run-pass/generator/auxiliary/xcrate.rs @@ -11,7 +11,7 @@ pub fn foo() -> impl Generator { } } -pub fn bar(t: T) -> Box + Unpin> { +pub fn bar(t: T) -> Box + Unpin> { Box::new(|| { yield t; }) diff --git a/src/test/run-pass/generator/non-static-is-unpin.rs b/src/test/run-pass/generator/non-static-is-unpin.rs new file mode 100644 index 0000000000000..96d0a8e283372 --- /dev/null +++ b/src/test/run-pass/generator/non-static-is-unpin.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::marker::{PhantomPinned, Unpin}; + +fn assert_unpin(_: G) { +} + +fn main() { + // Even though this generator holds a `PhantomPinned` in its environment, it + // remains `Unpin`. + assert_unpin(|| { + let pinned = PhantomPinned; + yield; + drop(pinned); + }); +} From ceacde31aeac4732a970ba253a99502b5d9f5280 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Sun, 27 Jan 2019 23:52:22 +0100 Subject: [PATCH 0380/1064] NVPTX: by-default use target cpu "sm_30" --- src/ci/docker/nvptx-cuda/Dockerfile | 2 +- src/librustc_target/spec/nvptx64_nvidia_cuda.rs | 6 +++--- src/test/run-make/nvptx-emit-asm/kernel.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ci/docker/nvptx-cuda/Dockerfile b/src/ci/docker/nvptx-cuda/Dockerfile index cdb1f565bd22e..b52865ced3e38 100644 --- a/src/ci/docker/nvptx-cuda/Dockerfile +++ b/src/ci/docker/nvptx-cuda/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get install -y --no-install-recommends \ g++ make file curl ca-certificates python git \ cmake sudo gdb -# TODO(denzp): setup `ptx-linker` CI for auttomatic binary releases. +# FIXME: setup `ptx-linker` CI for automatic binary releases. RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha/rust-ptx-linker.linux64.tar.gz | \ tar -xzvC /usr/bin diff --git a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs index ed5d0f2450623..e8512415e66a3 100644 --- a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs +++ b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs @@ -22,9 +22,9 @@ pub fn target() -> TargetResult { linker: Some("rust-ptx-linker".to_string()), // With `ptx-linker` approach, it can be later overriden via link flags. - cpu: "sm_20".to_string(), + cpu: "sm_30".to_string(), - // TODO(denzp): create tests for the atomics. + // FIXME: create tests for the atomics. max_atomic_width: Some(64), // Unwinding on CUDA is neither feasible nor useful. @@ -51,7 +51,7 @@ pub fn target() -> TargetResult { // This behavior is not supported by PTX ISA. merge_functions: MergeFunctions::Disabled, - // TODO(denzp): enable compilation tests for the target and + // FIXME: enable compilation tests for the target and // create the tests for this. abi_blacklist: vec![ Abi::Cdecl, diff --git a/src/test/run-make/nvptx-emit-asm/kernel.rs b/src/test/run-make/nvptx-emit-asm/kernel.rs index 070a6efd2d547..b71e18d910391 100644 --- a/src/test/run-make/nvptx-emit-asm/kernel.rs +++ b/src/test/run-make/nvptx-emit-asm/kernel.rs @@ -3,7 +3,7 @@ #![feature(abi_ptx)] // Verify the default CUDA arch. -// CHECK: .target sm_20 +// CHECK: .target sm_30 // CHECK: .address_size 64 // Verify function name doesn't contain unacceaptable characters. From 8d53c9247c23e36219102be68f887b0a39085a32 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Mon, 28 Jan 2019 01:16:59 +0100 Subject: [PATCH 0381/1064] SymbolPathBuffer shallow refactoring --- src/librustc_codegen_utils/symbol_names.rs | 156 ++++++++++----------- 1 file changed, 76 insertions(+), 80 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index f2014f7421289..3238a0b10bfd6 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance; use syntax_pos::symbol::Symbol; -use std::fmt::{self, Write}; +use std::fmt::Write; use std::mem::discriminant; pub fn provide(providers: &mut Providers) { @@ -339,28 +339,29 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance // // To be able to work on all platforms and get *some* reasonable output, we // use C++ name-mangling. -struct SymbolPathBuffer<'a, 'tcx> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, +#[derive(Debug)] +struct SymbolPathBuffer { result: String, temp_buf: String, + strict_naming: bool, } -impl SymbolPathBuffer<'a, 'tcx> { - fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { +impl SymbolPathBuffer { + fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - tcx, + strict_naming: tcx.has_strict_asm_symbol_naming(), }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { + fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - tcx, + strict_naming: tcx.has_strict_asm_symbol_naming(), }; result.result.push_str(&symbol.as_str()); result @@ -377,93 +378,88 @@ impl SymbolPathBuffer<'a, 'tcx> { let _ = write!(self.result, "17h{:016x}E", hash); self.result } -} -impl ItemPathBuffer for SymbolPathBuffer<'a, 'tcx> { - fn root_mode(&self) -> &RootMode { - const ABSOLUTE: &RootMode = &RootMode::Absolute; - ABSOLUTE - } - - fn push(&mut self, text: &str) { + // Name sanitation. LLVM will happily accept identifiers with weird names, but + // gas doesn't! + // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ + // NVPTX assembly has more strict naming rules than gas, so additionally, dots + // are replaced with '$' there. + fn sanitize_and_append(&mut self, s: &str) { self.temp_buf.clear(); - let need_underscore = sanitize(&mut self.temp_buf, text, self.tcx); + + for c in s.chars() { + match c { + // Escape these with $ sequences + '@' => self.temp_buf.push_str("$SP$"), + '*' => self.temp_buf.push_str("$BP$"), + '&' => self.temp_buf.push_str("$RF$"), + '<' => self.temp_buf.push_str("$LT$"), + '>' => self.temp_buf.push_str("$GT$"), + '(' => self.temp_buf.push_str("$LP$"), + ')' => self.temp_buf.push_str("$RP$"), + ',' => self.temp_buf.push_str("$C$"), + + '-' | ':' => if self.strict_naming { + // NVPTX doesn't support these characters in symbol names. + self.temp_buf.push('$') + } + else { + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + self.temp_buf.push('.') + }, + + '.' => if self.strict_naming { + self.temp_buf.push('$') + } + else { + self.temp_buf.push('.') + }, + + // These are legal symbols + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => self.temp_buf.push(c), + + _ => { + self.temp_buf.push('$'); + for c in c.escape_unicode().skip(1) { + match c { + '{' => {} + '}' => self.temp_buf.push('$'), + c => self.temp_buf.push(c), + } + } + } + } + } + + let need_underscore = { + // Underscore-qualify anything that didn't start as an ident. + !self.temp_buf.is_empty() + && self.temp_buf.as_bytes()[0] != '_' as u8 + && !(self.temp_buf.as_bytes()[0] as char).is_xid_start() + }; + let _ = write!( self.result, "{}", self.temp_buf.len() + (need_underscore as usize) ); + if need_underscore { self.result.push('_'); } + self.result.push_str(&self.temp_buf); } } -// Manual Debug implementation to omit non-Debug `tcx` field. -impl fmt::Debug for SymbolPathBuffer<'_, '_> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("SymbolPathBuffer") - .field("result", &self.result) - .field("temp_buf", &self.temp_buf) - .finish() +impl ItemPathBuffer for SymbolPathBuffer { + fn root_mode(&self) -> &RootMode { + const ABSOLUTE: &RootMode = &RootMode::Absolute; + ABSOLUTE } -} - -// Name sanitation. LLVM will happily accept identifiers with weird names, but -// gas doesn't! -// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ -// NVPTX assembly has more strict naming rules than gas, so additionally, dots -// are replaced with '$' there. -// -// returns true if an underscore must be added at the start -pub fn sanitize(result: &mut String, s: &str, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { - for c in s.chars() { - match c { - // Escape these with $ sequences - '@' => result.push_str("$SP$"), - '*' => result.push_str("$BP$"), - '&' => result.push_str("$RF$"), - '<' => result.push_str("$LT$"), - '>' => result.push_str("$GT$"), - '(' => result.push_str("$LP$"), - ')' => result.push_str("$RP$"), - ',' => result.push_str("$C$"), - - '-' | ':' => if tcx.has_strict_asm_symbol_naming() { - // NVPTX doesn't support these characters in symbol names. - result.push('$') - } - else { - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - result.push('.') - }, - - '.' => if tcx.has_strict_asm_symbol_naming() { - result.push('$') - } - else { - result.push('.') - }, - - // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => result.push(c), - _ => { - result.push('$'); - for c in c.escape_unicode().skip(1) { - match c { - '{' => {} - '}' => result.push('$'), - c => result.push(c), - } - } - } - } + fn push(&mut self, text: &str) { + self.sanitize_and_append(text); } - - // Underscore-qualify anything that didn't start as an ident. - !result.is_empty() && result.as_bytes()[0] != '_' as u8 - && !(result.as_bytes()[0] as char).is_xid_start() } From 5e6702117223b61057957ca2593f03e3f45ccd8a Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 25 Jan 2019 14:29:47 -0500 Subject: [PATCH 0382/1064] add typo suggestion to unknown attribute error --- src/librustc_resolve/macros.rs | 70 +++++++++++++++++-- src/test/ui/issues/issue-49074.stderr | 2 +- .../ui/macros/macro-reexport-removed.stderr | 2 +- .../ui/proc-macro/derive-still-gated.stderr | 2 +- src/test/ui/suggestions/attribute-typos.rs | 13 ++++ .../ui/suggestions/attribute-typos.stderr | 27 +++++++ 6 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/suggestions/attribute-typos.rs create mode 100644 src/test/ui/suggestions/attribute-typos.stderr diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fb5b6c97689d0..78b5518203084 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -19,7 +19,9 @@ use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue}; +use syntax::feature_gate::{ + feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES, +}; use syntax::symbol::{Symbol, keywords}; use syntax::visit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; @@ -310,15 +312,18 @@ impl<'a> Resolver<'a> { if !features.rustc_attrs { let msg = "unless otherwise specified, attributes with the prefix \ `rustc_` are reserved for internal compiler diagnostics"; - feature_err(&self.session.parse_sess, "rustc_attrs", path.span, - GateIssue::Language, &msg).emit(); + self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs"); } } else if !features.custom_attribute { let msg = format!("The attribute `{}` is currently unknown to the \ compiler and may have meaning added to it in the \ future", path); - feature_err(&self.session.parse_sess, "custom_attribute", path.span, - GateIssue::Language, &msg).emit(); + self.report_unknown_attribute( + path.span, + &name, + &msg, + "custom_attribute", + ); } } } else { @@ -339,6 +344,61 @@ impl<'a> Resolver<'a> { Ok((def, self.get_macro(def))) } + fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) { + let mut err = feature_err( + &self.session.parse_sess, + feature, + span, + GateIssue::Language, + &msg, + ); + + let features = self.session.features_untracked(); + + let attr_candidates = BUILTIN_ATTRIBUTES + .iter() + .filter_map(|(name, _, _, gate)| { + if name.starts_with("rustc_") && !features.rustc_attrs { + return None; + } + + match gate { + AttributeGate::Gated(Stability::Unstable, ..) + if self.session.opts.unstable_features.is_nightly_build() => + { + Some(name) + } + AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name), + AttributeGate::Ungated => Some(name), + _ => None, + } + }) + .map(|name| Symbol::intern(name)) + .chain( + // Add built-in macro attributes as well. + self.builtin_macros.iter().filter_map(|(name, binding)| { + match binding.macro_kind() { + Some(MacroKind::Attr) => Some(*name), + _ => None, + } + }), + ) + .collect::>(); + + let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None); + + if let Some(suggestion) = lev_suggestion { + err.span_suggestion( + span, + "a built-in attribute with a similar name exists", + suggestion.to_string(), + Applicability::MaybeIncorrect, + ); + } + + err.emit(); + } + pub fn resolve_macro_to_def_inner( &mut self, path: &ast::Path, diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr index d4648270f2d30..a25d8ee352686 100644 --- a/src/test/ui/issues/issue-49074.stderr +++ b/src/test/ui/issues/issue-49074.stderr @@ -2,7 +2,7 @@ error[E0658]: The attribute `marco_use` is currently unknown to the compiler and --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo - | ^^^^^^^^^ + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/macros/macro-reexport-removed.stderr b/src/test/ui/macros/macro-reexport-removed.stderr index 7c3555a92ed8b..6cfec3ee762dd 100644 --- a/src/test/ui/macros/macro-reexport-removed.stderr +++ b/src/test/ui/macros/macro-reexport-removed.stderr @@ -14,7 +14,7 @@ error[E0658]: The attribute `macro_reexport` is currently unknown to the compile --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr index d54a593f78311..ece1b6212914d 100644 --- a/src/test/ui/proc-macro/derive-still-gated.stderr +++ b/src/test/ui/proc-macro/derive-still-gated.stderr @@ -2,7 +2,7 @@ error[E0658]: The attribute `derive_A` is currently unknown to the compiler and --> $DIR/derive-still-gated.rs:8:3 | LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown - | ^^^^^^^^ + | ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs new file mode 100644 index 0000000000000..13c6308b97e85 --- /dev/null +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -0,0 +1,13 @@ +#[deprcated] //~ ERROR E0658 +fn foo() {} //~| HELP a built-in attribute with a similar name exists + //~| SUGGESTION deprecated + //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable + +#[tests] //~ ERROR E0658 +fn bar() {} //~| HELP a built-in attribute with a similar name exists + //~| SUGGESTION test + //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable + +#[rustc_err] //~ ERROR E0658 +fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable + // don't suggest rustc attributes diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr new file mode 100644 index 0000000000000..e40da787e96ca --- /dev/null +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -0,0 +1,27 @@ +error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642) + --> $DIR/attribute-typos.rs:11:3 + | +LL | #[rustc_err] //~ ERROR E0658 + | ^^^^^^^^^ + | + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/attribute-typos.rs:6:3 + | +LL | #[tests] //~ ERROR E0658 + | ^^^^^ help: a built-in attribute with a similar name exists: `test` + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/attribute-typos.rs:1:3 + | +LL | #[deprcated] //~ ERROR E0658 + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. From 1bdd2f699beb6249a97aac3e2007401b37b6f273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 17 Jan 2019 07:28:39 +0100 Subject: [PATCH 0383/1064] Conditionally skip two passes if their related attributes were not found --- Cargo.lock | 1 + src/librustc_driver/driver.rs | 31 +++++++++++++++------------ src/librustc_passes/Cargo.toml | 1 + src/librustc_passes/ast_validation.rs | 22 ++++++++++++++++--- src/librustc_passes/lib.rs | 1 + src/libsyntax_ext/proc_macro_decls.rs | 7 ++++-- 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cfe57da6974d..c34a325a47492 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2722,6 +2722,7 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_mir 0.0.0", "syntax 0.0.0", + "syntax_ext 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 88dac42997f36..f5e5f1f5c0b95 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1017,6 +1017,10 @@ where krate = ReplaceBodyWithLoop::new(sess).fold_crate(krate); } + let (has_proc_macro_decls, has_global_allocator) = time(sess, "AST validation", || { + ast_validation::check_crate(sess, &krate) + }); + // If we're in rustdoc we're always compiling as an rlib, but that'll trip a // bunch of checks in the `modify` function below. For now just skip this // step entirely if we're rustdoc as it's not too useful anyway. @@ -1031,6 +1035,7 @@ where &mut resolver, krate, is_proc_macro_crate, + has_proc_macro_decls, is_test_crate, num_crate_types, sess.diagnostic(), @@ -1038,16 +1043,18 @@ where }); } - // Expand global allocators, which are treated as an in-tree proc macro - krate = time(sess, "creating allocators", || { - allocator::expand::modify( - &sess.parse_sess, - &mut resolver, - krate, - crate_name.to_string(), - sess.diagnostic(), - ) - }); + if has_global_allocator { + // Expand global allocators, which are treated as an in-tree proc macro + krate = time(sess, "creating allocators", || { + allocator::expand::modify( + &sess.parse_sess, + &mut resolver, + krate, + crate_name.to_string(), + sess.diagnostic(), + ) + }); + } // Done with macro expansion! @@ -1065,10 +1072,6 @@ where println!("{}", json::as_json(&krate)); } - time(sess, "AST validation", || { - ast_validation::check_crate(sess, &krate) - }); - time(sess, "name resolution", || { resolver.resolve_crate(&krate); }); diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 2babb93eedbcf..f5154a033af8d 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -14,5 +14,6 @@ rustc = { path = "../librustc" } rustc_mir = { path = "../librustc_mir"} rustc_data_structures = { path = "../librustc_data_structures" } syntax = { path = "../libsyntax" } +syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 3b6328f320f78..3deb2ff8d8a0b 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -15,12 +15,15 @@ use syntax::source_map::Spanned; use syntax::symbol::keywords; use syntax::ptr::P; use syntax::visit::{self, Visitor}; +use syntax_ext::proc_macro_decls::is_proc_macro_attr; use syntax_pos::Span; use errors; use errors::Applicability; struct AstValidator<'a> { session: &'a Session, + has_proc_macro_decls: bool, + has_global_allocator: bool, // Used to ban nested `impl Trait`, e.g., `impl Into`. // Nested `impl Trait` _is_ allowed in associated type position, @@ -367,6 +370,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_item(&mut self, item: &'a Item) { + if item.attrs.iter().any(|attr| is_proc_macro_attr(attr) ) { + self.has_proc_macro_decls = true; + } + + if attr::contains_name(&item.attrs, "global_allocator") { + self.has_global_allocator = true; + } + match item.node { ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { self.invalid_visibility(&item.vis, None); @@ -590,10 +601,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -pub fn check_crate(session: &Session, krate: &Crate) { - visit::walk_crate(&mut AstValidator { +pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) { + let mut validator = AstValidator { session, + has_proc_macro_decls: false, + has_global_allocator: false, outer_impl_trait: None, is_impl_trait_banned: false, - }, krate) + }; + visit::walk_crate(&mut validator, krate); + + (validator.has_proc_macro_decls, validator.has_global_allocator) } diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index a181bc7e9b480..76605c58a7889 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -22,6 +22,7 @@ extern crate rustc_data_structures; extern crate log; #[macro_use] extern crate syntax; +extern crate syntax_ext; extern crate syntax_pos; extern crate rustc_errors as errors; diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 1d272712cacc8..46c502965eea8 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -48,6 +48,7 @@ pub fn modify(sess: &ParseSess, resolver: &mut dyn (::syntax::ext::base::Resolver), mut krate: ast::Crate, is_proc_macro_crate: bool, + has_proc_macro_decls: bool, is_test_crate: bool, num_crate_types: usize, handler: &errors::Handler) -> ast::Crate { @@ -64,7 +65,9 @@ pub fn modify(sess: &ParseSess, is_proc_macro_crate, is_test_crate, }; - visit::walk_crate(&mut collect, &krate); + if has_proc_macro_decls || is_proc_macro_crate { + visit::walk_crate(&mut collect, &krate); + } (collect.derives, collect.attr_macros, collect.bang_macros) }; @@ -85,7 +88,7 @@ pub fn modify(sess: &ParseSess, krate } -fn is_proc_macro_attr(attr: &ast::Attribute) -> bool { +pub fn is_proc_macro_attr(attr: &ast::Attribute) -> bool { PROC_MACRO_KINDS.iter().any(|kind| attr.check_name(kind)) } From c775c2fe969219b9631e295e6ef7d05a3ea07e65 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 20 Dec 2018 22:49:32 +0100 Subject: [PATCH 0384/1064] libcore: remove unneeded allow(deprecated) --- src/libcore/fmt/mod.rs | 2 +- src/libcore/fmt/num.rs | 2 -- src/libcore/hash/sip.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 935579f4943b6..530b2f52c0df2 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -2048,7 +2048,7 @@ macro_rules! tuple { ( $($name:ident,)+ ) => ( #[stable(feature = "rust1", since = "1.0.0")] impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { - #[allow(non_snake_case, unused_assignments, deprecated)] + #[allow(non_snake_case, unused_assignments)] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index c7c8fc50efaae..db3984f4a17e3 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -1,7 +1,5 @@ //! Integer and floating-point number formatting -#![allow(deprecated)] - use fmt; use ops::{Div, Rem, Sub}; diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 3377b831a9daa..18f09f4c5dda4 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -1,6 +1,6 @@ //! An implementation of SipHash. -#![allow(deprecated)] +#![allow(deprecated)] // the types in this module are deprecated use marker::PhantomData; use ptr; From c11e514e9dfd44eebe435408b32de4193d87860c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 20 Dec 2018 22:51:08 +0100 Subject: [PATCH 0385/1064] liballoc: remove unneeded allow(deprecated) --- src/liballoc/borrow.rs | 1 - src/liballoc/rc.rs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 603d73100a8b4..b47337e44b2fe 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -380,7 +380,6 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated)] impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { fn as_ref(&self) -> &T { self diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index d3a55c59ff69c..c0dc010fe59a5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - //! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference //! Counted'. //! From a88414e007d9740c1c3d483ff778f7f2d3f32749 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Dec 2018 11:08:26 +0100 Subject: [PATCH 0386/1064] libcore: avoid mem::uninitialized and raw ptr casts --- src/libcore/fmt/num.rs | 28 +++++++++++++++++++++------- src/libcore/lib.rs | 1 + src/libcore/mem.rs | 14 ++++++++++++++ src/libcore/slice/sort.rs | 19 +++++++++++++------ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index db3984f4a17e3..ff284d2978e70 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -6,7 +6,7 @@ use ops::{Div, Rem, Sub}; use str; use slice; use ptr; -use mem; +use mem::MaybeUninit; #[doc(hidden)] trait Int: PartialEq + PartialOrd + Div + Rem + @@ -51,7 +51,12 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf: [u8; 128] = unsafe { mem::uninitialized() }; + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + let mut buf: [MaybeUninit; 128] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -60,7 +65,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -72,7 +77,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -80,7 +85,11 @@ trait GenericRadix { }; } } - let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; + let buf = &buf[curr..]; + let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( + MaybeUninit::first_ptr(buf), + buf.len() + )) }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } } @@ -194,9 +203,14 @@ macro_rules! impl_Display { // convert the negative num to positive by summing 1 to it's 2 complement (!self.$conv_fn()).wrapping_add(1) }; - let mut buf: [u8; 39] = unsafe { mem::uninitialized() }; + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + let mut buf: [MaybeUninit; 39] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; let mut curr = buf.len() as isize; - let buf_ptr = buf.as_mut_ptr(); + let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 825e5148fd503..dbf0b15818909 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -60,6 +60,7 @@ test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] #![no_core] +#![warn(deprecated_in_future)] #![deny(missing_docs)] #![deny(intra_doc_link_resolution_failure)] #![deny(missing_debug_implementations)] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 0eeac5e1ea940..4631d32d186f6 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1148,4 +1148,18 @@ impl MaybeUninit { pub fn as_mut_ptr(&mut self) -> *mut T { unsafe { &mut *self.value as *mut T } } + + /// Get a pointer to the first contained values. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_ptr(this: &[MaybeUninit]) -> *const T { + this as *const [MaybeUninit] as *const T + } + + /// Get a mutable pointer to the first contained values. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { + this as *mut [MaybeUninit] as *mut T + } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index dd9b49fb7a002..8eb6a4d54c0f6 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,14 +216,21 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - let mut offsets_l = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + let mut offsets_l: [MaybeUninit; BLOCK] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + let mut offsets_r: [MaybeUninit; BLOCK] = unsafe { + MaybeUninit::uninitialized().into_inner() + }; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. @@ -262,8 +269,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = offsets_l.as_mut_ptr() as *mut u8; - end_l = offsets_l.as_mut_ptr() as *mut u8; + start_l = MaybeUninit::first_mut_ptr(&mut offsets_l); + end_l = MaybeUninit::first_mut_ptr(&mut offsets_l); let mut elem = l; for i in 0..block_l { @@ -278,8 +285,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = offsets_r.as_mut_ptr() as *mut u8; - end_r = offsets_r.as_mut_ptr() as *mut u8; + start_r = MaybeUninit::first_mut_ptr(&mut offsets_r); + end_r = MaybeUninit::first_mut_ptr(&mut offsets_r); let mut elem = r; for i in 0..block_r { From 5f021e0023b3b471c5c9c39e07f70d344cc604b0 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 25 Jan 2019 16:56:27 +0100 Subject: [PATCH 0387/1064] Unused variable suggestions on all patterns. This commit extends existing suggestions to prefix unused variable bindings in match arms with an underscore so that it applies to all patterns in a match arm. --- src/librustc/middle/liveness.rs | 84 +++++++++++-------- src/test/ui/issues/issue-17999.stderr | 4 +- src/test/ui/issues/issue-22599.stderr | 2 +- src/test/ui/issues/issue-56685.rs | 44 ++++++++++ src/test/ui/issues/issue-56685.stderr | 60 +++++++++++++ ...0-unused-variable-in-struct-pattern.stderr | 8 +- src/test/ui/lint/lint-removed-allow.stderr | 2 +- src/test/ui/lint/lint-removed-cmdline.stderr | 2 +- src/test/ui/lint/lint-removed.stderr | 2 +- src/test/ui/lint/lint-renamed-allow.stderr | 2 +- src/test/ui/lint/lint-renamed-cmdline.stderr | 2 +- src/test/ui/lint/lint-renamed.stderr | 2 +- .../ui/lint/lint-uppercase-variables.stderr | 2 +- src/test/ui/liveness/liveness-unused.stderr | 16 ++-- src/test/ui/never-assign-dead-code.stderr | 2 +- .../ui/proc-macro/attributes-included.stderr | 2 +- src/test/ui/span/issue-24690.stderr | 2 +- 17 files changed, 179 insertions(+), 59 deletions(-) create mode 100644 src/test/ui/issues/issue-56685.rs create mode 100644 src/test/ui/issues/issue-56685.stderr diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index cc0dd71738fce..4ef8e1a0cf95b 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -105,7 +105,7 @@ use lint; use errors::Applicability; use util::nodemap::{NodeMap, HirIdMap, HirIdSet}; -use std::collections::VecDeque; +use std::collections::{BTreeMap, VecDeque}; use std::{fmt, u32}; use std::io::prelude::*; use std::io; @@ -1446,7 +1446,7 @@ fn check_local<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, local: &'tcx hir::Local) None => { this.pat_bindings(&local.pat, |this, ln, var, sp, id| { let span = local.pat.simple_ident().map_or(sp, |ident| ident.span); - this.warn_about_unused(span, id, ln, var); + this.warn_about_unused(vec![span], id, ln, var); }) } } @@ -1455,12 +1455,29 @@ fn check_local<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, local: &'tcx hir::Local) } fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) { - // only consider the first pattern; any later patterns must have - // the same bindings, and we also consider the first pattern to be - // the "authoritative" set of ids - this.arm_pats_bindings(arm.pats.first().map(|p| &**p), |this, ln, var, sp, id| { - this.warn_about_unused(sp, id, ln, var); - }); + // Only consider the variable from the first pattern; any later patterns must have + // the same bindings, and we also consider the first pattern to be the "authoritative" set of + // ids. However, we should take the spans of variables with the same name from the later + // patterns so the suggestions to prefix with underscores will apply to those too. + let mut vars: BTreeMap)> = Default::default(); + + for pat in &arm.pats { + this.arm_pats_bindings(Some(&*pat), |this, ln, var, sp, id| { + let name = this.ir.variable_name(var); + vars.entry(name) + .and_modify(|(.., spans)| { + spans.push(sp); + }) + .or_insert_with(|| { + (ln, var, id, vec![sp]) + }); + }); + } + + for (_, (ln, var, id, spans)) in vars { + this.warn_about_unused(spans, id, ln, var); + } + intravisit::walk_arm(this, arm); } @@ -1551,7 +1568,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let var = self.variable(hir_id, sp); // Ignore unused self. if ident.name != keywords::SelfLower.name() { - if !self.warn_about_unused(sp, hir_id, entry_ln, var) { + if !self.warn_about_unused(vec![sp], hir_id, entry_ln, var) { if self.live_on_entry(entry_ln, var).is_none() { self.report_dead_assign(hir_id, sp, var, true); } @@ -1563,14 +1580,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &hir::Pat) { self.pat_bindings(pat, |this, ln, var, sp, id| { - if !this.warn_about_unused(sp, id, ln, var) { + if !this.warn_about_unused(vec![sp], id, ln, var) { this.warn_about_dead_assign(sp, id, ln, var); } }) } fn warn_about_unused(&self, - sp: Span, + spans: Vec, hir_id: HirId, ln: LiveNode, var: Variable) @@ -1587,33 +1604,36 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.assigned_on_exit(ln, var).is_some() }; - let suggest_underscore_msg = format!("consider using `_{}` instead", name); - if is_assigned { - self.ir.tcx - .lint_hir_note(lint::builtin::UNUSED_VARIABLES, hir_id, sp, - &format!("variable `{}` is assigned to, but never used", - name), - &suggest_underscore_msg); + self.ir.tcx.lint_hir_note( + lint::builtin::UNUSED_VARIABLES, + hir_id, + spans.clone(), + &format!("variable `{}` is assigned to, but never used", name), + &format!("consider using `_{}` instead", name), + ); } else if name != "self" { - let msg = format!("unused variable: `{}`", name); - let mut err = self.ir.tcx - .struct_span_lint_hir(lint::builtin::UNUSED_VARIABLES, hir_id, sp, &msg); + let mut err = self.ir.tcx.struct_span_lint_hir( + lint::builtin::UNUSED_VARIABLES, + hir_id, + spans.clone(), + &format!("unused variable: `{}`", name), + ); + if self.ir.variable_is_shorthand(var) { - err.span_suggestion( - sp, + err.multipart_suggestion( "try ignoring the field", - format!("{}: _", name), - Applicability::MachineApplicable, + spans.iter().map(|span| (*span, format!("{}: _", name))).collect(), + Applicability::MachineApplicable ); } else { - err.span_suggestion_short( - sp, - &suggest_underscore_msg, - format!("_{}", name), + err.multipart_suggestion( + "consider prefixing with an underscore", + spans.iter().map(|span| (*span, format!("_{}", name))).collect(), Applicability::MachineApplicable, ); } + err.emit() } } @@ -1623,11 +1643,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn warn_about_dead_assign(&self, - sp: Span, - hir_id: HirId, - ln: LiveNode, - var: Variable) { + fn warn_about_dead_assign(&self, sp: Span, hir_id: HirId, ln: LiveNode, var: Variable) { if self.live_on_exit(ln, var).is_none() { self.report_dead_assign(hir_id, sp, var, false); } diff --git a/src/test/ui/issues/issue-17999.stderr b/src/test/ui/issues/issue-17999.stderr index 3f32dc1540232..51c0c757a80c1 100644 --- a/src/test/ui/issues/issue-17999.stderr +++ b/src/test/ui/issues/issue-17999.stderr @@ -2,7 +2,7 @@ error: unused variable: `x` --> $DIR/issue-17999.rs:5:13 | LL | let x = (); //~ ERROR: unused variable: `x` - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` | note: lint level defined here --> $DIR/issue-17999.rs:1:9 @@ -14,7 +14,7 @@ error: unused variable: `a` --> $DIR/issue-17999.rs:7:13 | LL | a => {} //~ ERROR: unused variable: `a` - | ^ help: consider using `_a` instead + | ^ help: consider prefixing with an underscore: `_a` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-22599.stderr b/src/test/ui/issues/issue-22599.stderr index 5c2ed7455f132..bc4949da6f785 100644 --- a/src/test/ui/issues/issue-22599.stderr +++ b/src/test/ui/issues/issue-22599.stderr @@ -2,7 +2,7 @@ error: unused variable: `a` --> $DIR/issue-22599.rs:8:19 | LL | v = match 0 { a => 0 }; //~ ERROR: unused variable: `a` - | ^ help: consider using `_a` instead + | ^ help: consider prefixing with an underscore: `_a` | note: lint level defined here --> $DIR/issue-22599.rs:1:9 diff --git a/src/test/ui/issues/issue-56685.rs b/src/test/ui/issues/issue-56685.rs new file mode 100644 index 0000000000000..f320c99ed15d1 --- /dev/null +++ b/src/test/ui/issues/issue-56685.rs @@ -0,0 +1,44 @@ +#![allow(dead_code)] +#![deny(unused_variables)] + +// This test aims to check that unused variable suggestions update bindings in all +// match arms. + +fn main() { + enum E { + A(i32,), + B(i32,), + } + + match E::A(1) { + E::A(x) | E::B(x) => {} + //~^ ERROR unused variable: `x` + } + + enum F { + A(i32, i32,), + B(i32, i32,), + C(i32, i32,), + } + + let _ = match F::A(1, 2) { + F::A(x, y) | F::B(x, y) => { y }, + //~^ ERROR unused variable: `x` + F::C(a, b) => { 3 } + //~^ ERROR unused variable: `a` + //~^^ ERROR unused variable: `b` + }; + + let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + //~^ ERROR unused variable: `x` + y + } else { + 3 + }; + + while let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + //~^ ERROR unused variable: `x` + let _ = y; + break; + } +} diff --git a/src/test/ui/issues/issue-56685.stderr b/src/test/ui/issues/issue-56685.stderr new file mode 100644 index 0000000000000..4a461c72b2417 --- /dev/null +++ b/src/test/ui/issues/issue-56685.stderr @@ -0,0 +1,60 @@ +error: unused variable: `x` + --> $DIR/issue-56685.rs:14:14 + | +LL | E::A(x) | E::B(x) => {} + | ^ ^ + | +note: lint level defined here + --> $DIR/issue-56685.rs:2:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ +help: consider prefixing with an underscore + | +LL | E::A(_x) | E::B(_x) => {} + | ^^ ^^ + +error: unused variable: `x` + --> $DIR/issue-56685.rs:25:14 + | +LL | F::A(x, y) | F::B(x, y) => { y }, + | ^ ^ +help: consider prefixing with an underscore + | +LL | F::A(_x, y) | F::B(_x, y) => { y }, + | ^^ ^^ + +error: unused variable: `a` + --> $DIR/issue-56685.rs:27:14 + | +LL | F::C(a, b) => { 3 } + | ^ help: consider prefixing with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/issue-56685.rs:27:17 + | +LL | F::C(a, b) => { 3 } + | ^ help: consider prefixing with an underscore: `_b` + +error: unused variable: `x` + --> $DIR/issue-56685.rs:32:25 + | +LL | let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + | ^ ^ +help: consider prefixing with an underscore + | +LL | let _ = if let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) { + | ^^ ^^ + +error: unused variable: `x` + --> $DIR/issue-56685.rs:39:20 + | +LL | while let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + | ^ ^ +help: consider prefixing with an underscore + | +LL | while let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) { + | ^^ ^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index ab12aef2474f3..8fd98e0a3db2e 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -2,7 +2,7 @@ warning: unused variable: `i_think_continually` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9 | LL | let i_think_continually = 2; - | ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead + | ^^^^^^^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_i_think_continually` | note: lint level defined here --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 @@ -15,19 +15,19 @@ warning: unused variable: `mut_unused_var` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13 | LL | let mut mut_unused_var = 1; - | ^^^^^^^^^^^^^^ help: consider using `_mut_unused_var` instead + | ^^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_mut_unused_var` warning: unused variable: `var` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:14 | LL | let (mut var, unused_var) = (1, 2); - | ^^^ help: consider using `_var` instead + | ^^^ help: consider prefixing with an underscore: `_var` warning: unused variable: `unused_var` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:19 | LL | let (mut var, unused_var) = (1, 2); - | ^^^^^^^^^^ help: consider using `_unused_var` instead + | ^^^^^^^^^^ help: consider prefixing with an underscore: `_unused_var` warning: unused variable: `corridors_of_light` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:26 diff --git a/src/test/ui/lint/lint-removed-allow.stderr b/src/test/ui/lint/lint-removed-allow.stderr index 3af983165eb17..f796a14d63796 100644 --- a/src/test/ui/lint/lint-removed-allow.stderr +++ b/src/test/ui/lint/lint-removed-allow.stderr @@ -2,7 +2,7 @@ error: unused variable: `unused` --> $DIR/lint-removed-allow.rs:8:17 | LL | fn main() { let unused = (); } //~ ERROR unused - | ^^^^^^ help: consider using `_unused` instead + | ^^^^^^ help: consider prefixing with an underscore: `_unused` | note: lint level defined here --> $DIR/lint-removed-allow.rs:7:8 diff --git a/src/test/ui/lint/lint-removed-cmdline.stderr b/src/test/ui/lint/lint-removed-cmdline.stderr index 191509c5a180c..d46ef6b9237fd 100644 --- a/src/test/ui/lint/lint-removed-cmdline.stderr +++ b/src/test/ui/lint/lint-removed-cmdline.stderr @@ -6,7 +6,7 @@ error: unused variable: `unused` --> $DIR/lint-removed-cmdline.rs:12:17 | LL | fn main() { let unused = (); } - | ^^^^^^ help: consider using `_unused` instead + | ^^^^^^ help: consider prefixing with an underscore: `_unused` | note: lint level defined here --> $DIR/lint-removed-cmdline.rs:11:8 diff --git a/src/test/ui/lint/lint-removed.stderr b/src/test/ui/lint/lint-removed.stderr index 34fa85b0d8b9f..55f010348fe1e 100644 --- a/src/test/ui/lint/lint-removed.stderr +++ b/src/test/ui/lint/lint-removed.stderr @@ -10,7 +10,7 @@ error: unused variable: `unused` --> $DIR/lint-removed.rs:8:17 | LL | fn main() { let unused = (); } //~ ERROR unused - | ^^^^^^ help: consider using `_unused` instead + | ^^^^^^ help: consider prefixing with an underscore: `_unused` | note: lint level defined here --> $DIR/lint-removed.rs:7:8 diff --git a/src/test/ui/lint/lint-renamed-allow.stderr b/src/test/ui/lint/lint-renamed-allow.stderr index 390b4c3f38abd..b2eeeae8f8e6d 100644 --- a/src/test/ui/lint/lint-renamed-allow.stderr +++ b/src/test/ui/lint/lint-renamed-allow.stderr @@ -2,7 +2,7 @@ error: unused variable: `unused` --> $DIR/lint-renamed-allow.rs:8:17 | LL | fn main() { let unused = (); } //~ ERROR unused - | ^^^^^^ help: consider using `_unused` instead + | ^^^^^^ help: consider prefixing with an underscore: `_unused` | note: lint level defined here --> $DIR/lint-renamed-allow.rs:7:8 diff --git a/src/test/ui/lint/lint-renamed-cmdline.stderr b/src/test/ui/lint/lint-renamed-cmdline.stderr index 78a05bdc89f01..6247ee0aff833 100644 --- a/src/test/ui/lint/lint-renamed-cmdline.stderr +++ b/src/test/ui/lint/lint-renamed-cmdline.stderr @@ -6,7 +6,7 @@ error: unused variable: `unused` --> $DIR/lint-renamed-cmdline.rs:8:17 | LL | fn main() { let unused = (); } - | ^^^^^^ help: consider using `_unused` instead + | ^^^^^^ help: consider prefixing with an underscore: `_unused` | note: lint level defined here --> $DIR/lint-renamed-cmdline.rs:7:8 diff --git a/src/test/ui/lint/lint-renamed.stderr b/src/test/ui/lint/lint-renamed.stderr index 1296fef5a4c63..b140a93ab38bd 100644 --- a/src/test/ui/lint/lint-renamed.stderr +++ b/src/test/ui/lint/lint-renamed.stderr @@ -10,7 +10,7 @@ error: unused variable: `unused` --> $DIR/lint-renamed.rs:4:17 | LL | fn main() { let unused = (); } //~ ERROR unused - | ^^^^^^ help: consider using `_unused` instead + | ^^^^^^ help: consider prefixing with an underscore: `_unused` | note: lint level defined here --> $DIR/lint-renamed.rs:3:8 diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index 0741179c4a4dd..f2267f351ddda 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -8,7 +8,7 @@ warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:22:9 | LL | Foo => {} - | ^^^ help: consider using `_Foo` instead + | ^^^ help: consider prefixing with an underscore: `_Foo` | note: lint level defined here --> $DIR/lint-uppercase-variables.rs:1:9 diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr index 17cdacb859f02..49795faa59c8d 100644 --- a/src/test/ui/liveness/liveness-unused.stderr +++ b/src/test/ui/liveness/liveness-unused.stderr @@ -15,7 +15,7 @@ error: unused variable: `x` --> $DIR/liveness-unused.rs:8:7 | LL | fn f1(x: isize) { - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` | note: lint level defined here --> $DIR/liveness-unused.rs:2:9 @@ -27,19 +27,19 @@ error: unused variable: `x` --> $DIR/liveness-unused.rs:12:8 | LL | fn f1b(x: &mut isize) { - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` error: unused variable: `x` --> $DIR/liveness-unused.rs:20:9 | LL | let x: isize; - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` error: unused variable: `x` --> $DIR/liveness-unused.rs:25:9 | LL | let x = 3; - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` error: variable `x` is assigned to, but never used --> $DIR/liveness-unused.rs:30:13 @@ -74,25 +74,25 @@ error: unused variable: `i` --> $DIR/liveness-unused.rs:59:12 | LL | Some(i) => { - | ^ help: consider using `_i` instead + | ^ help: consider prefixing with an underscore: `_i` error: unused variable: `x` --> $DIR/liveness-unused.rs:79:9 | LL | for x in 1..10 { } - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` error: unused variable: `x` --> $DIR/liveness-unused.rs:84:10 | LL | for (x, _) in [1, 2, 3].iter().enumerate() { } - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` error: unused variable: `x` --> $DIR/liveness-unused.rs:89:13 | LL | for (_, x) in [1, 2, 3].iter().enumerate() { - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` error: variable `x` is assigned to, but never used --> $DIR/liveness-unused.rs:112:9 diff --git a/src/test/ui/never-assign-dead-code.stderr b/src/test/ui/never-assign-dead-code.stderr index c59fd938e8326..bcc20a0d703c0 100644 --- a/src/test/ui/never-assign-dead-code.stderr +++ b/src/test/ui/never-assign-dead-code.stderr @@ -21,7 +21,7 @@ warning: unused variable: `x` --> $DIR/never-assign-dead-code.rs:9:9 | LL | let x: ! = panic!("aah"); //~ WARN unused - | ^ help: consider using `_x` instead + | ^ help: consider prefixing with an underscore: `_x` | note: lint level defined here --> $DIR/never-assign-dead-code.rs:5:9 diff --git a/src/test/ui/proc-macro/attributes-included.stderr b/src/test/ui/proc-macro/attributes-included.stderr index ea5be5a3be0e5..87b6fb9539fb4 100644 --- a/src/test/ui/proc-macro/attributes-included.stderr +++ b/src/test/ui/proc-macro/attributes-included.stderr @@ -2,7 +2,7 @@ warning: unused variable: `a` --> $DIR/attributes-included.rs:17:9 | LL | let a: i32 = "foo"; //~ WARN: unused variable - | ^ help: consider using `_a` instead + | ^ help: consider prefixing with an underscore: `_a` | note: lint level defined here --> $DIR/attributes-included.rs:4:9 diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index f052f866c901b..964e323b83ed4 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -2,7 +2,7 @@ warning: unused variable: `theOtherTwo` --> $DIR/issue-24690.rs:13:9 | LL | let theOtherTwo = 2; //~ WARN should have a snake case name - | ^^^^^^^^^^^ help: consider using `_theOtherTwo` instead + | ^^^^^^^^^^^ help: consider prefixing with an underscore: `_theOtherTwo` | note: lint level defined here --> $DIR/issue-24690.rs:8:9 From 7dbb70eea3aaef916ca3fd794e02f9f408bdf821 Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Mon, 28 Jan 2019 11:46:41 +0200 Subject: [PATCH 0388/1064] Build the standard library for thumbv7neon-unknown-linux-gnueabihf in CI Closes #57030. --- src/ci/docker/dist-various-1/Dockerfile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 76cdd367987b2..ab2dd5a399280 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -116,13 +116,17 @@ ENV TARGETS=$TARGETS,armebv7r-none-eabi ENV TARGETS=$TARGETS,armebv7r-none-eabihf ENV TARGETS=$TARGETS,armv7r-none-eabi ENV TARGETS=$TARGETS,armv7r-none-eabihf +ENV TARGETS=$TARGETS,thumbv7neon-unknown-linux-gnueabihf ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \ CC_sparc64_unknown_linux_gnu=sparc64-linux-gnu-gcc \ CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc \ - CC_armebv7r_none_eabi=arm-none-eabi-gcc - + CC_armebv7r_none_eabi=arm-none-eabi-gcc \ + CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ + AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ + CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ + ENV RUST_CONFIGURE_ARGS \ --musl-root-armv5te=/musl-armv5te \ --musl-root-arm=/musl-arm \ From ffd73df7559be73398679d7f09447379dd0c2098 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Dec 2018 11:22:18 +0100 Subject: [PATCH 0389/1064] avoid mem::uninitialized in BTreeMap --- src/liballoc/collections/btree/node.rs | 25 ++++++++++++++++--------- src/liballoc/lib.rs | 1 + src/libcore/lib.rs | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index f9a21aa95db71..cc46bae01cb99 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -145,7 +145,7 @@ struct InternalNode { /// The pointers to the children of this node. `len + 1` of these are considered /// initialized and valid. - edges: [BoxedNode; 2 * B], + edges: [MaybeUninit>; 2 * B], } impl InternalNode { @@ -159,7 +159,10 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - edges: mem::uninitialized() + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + edges: MaybeUninit::uninitialized().into_inner(), } } } @@ -261,7 +264,7 @@ impl Root { -> NodeRef { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); - new_node.edges[0] = unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }; + new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); self.node = BoxedNode::from_internal(new_node); self.height += 1; @@ -718,7 +721,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { unsafe { ptr::write(self.keys_mut().get_unchecked_mut(idx), key); ptr::write(self.vals_mut().get_unchecked_mut(idx), val); - ptr::write(self.as_internal_mut().edges.get_unchecked_mut(idx + 1), edge.node); + self.as_internal_mut().edges.get_unchecked_mut(idx + 1).set(edge.node); (*self.as_leaf_mut()).len += 1; @@ -749,7 +752,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { slice_insert(self.vals_mut(), 0, val); slice_insert( slice::from_raw_parts_mut( - self.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_mut_ptr(&mut self.as_internal_mut().edges), self.len()+1 ), 0, @@ -778,7 +781,9 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(internal) => { - let edge = ptr::read(internal.as_internal().edges.get_unchecked(idx + 1)); + let edge = ptr::read( + internal.as_internal().edges.get_unchecked(idx + 1).as_ptr() + ); let mut new_root = Root { node: edge, height: internal.height - 1 }; (*new_root.as_mut().as_leaf_mut()).parent = ptr::null(); Some(new_root) @@ -806,7 +811,7 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { ForceResult::Internal(mut internal) => { let edge = slice_remove( slice::from_raw_parts_mut( - internal.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_mut_ptr(&mut internal.as_internal_mut().edges), old_len+1 ), 0 @@ -1085,7 +1090,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: slice_insert( slice::from_raw_parts_mut( - self.node.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_mut_ptr(&mut self.node.as_internal_mut().edges), self.node.len() ), self.idx + 1, @@ -1140,7 +1145,9 @@ impl pub fn descend(self) -> NodeRef { NodeRef { height: self.node.height - 1, - node: unsafe { self.node.as_internal().edges.get_unchecked(self.idx).as_ptr() }, + node: unsafe { + self.node.as_internal().edges.get_unchecked(self.idx).get_ref().as_ptr() + }, root: self.node.root, _marker: PhantomData } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3050a93ef39a0..cf9d89ee05adf 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -63,6 +63,7 @@ #![no_std] #![needs_allocator] +#![warn(deprecated_in_future)] #![deny(intra_doc_link_resolution_failure)] #![deny(missing_debug_implementations)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index dbf0b15818909..4d7da3692fd84 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -58,8 +58,8 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] - #![no_core] + #![warn(deprecated_in_future)] #![deny(missing_docs)] #![deny(intra_doc_link_resolution_failure)] From 630aaa4e801393c55c8327f642aec2349adfaee3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Dec 2018 15:10:19 +0100 Subject: [PATCH 0390/1064] avoid some raw ptr casts in BTreeMap --- src/liballoc/collections/btree/node.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index cc46bae01cb99..8dd4aec136aa8 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -95,8 +95,8 @@ struct LeafNode { /// The arrays storing the actual data of the node. Only the first `len` elements of each /// array are initialized and valid. - keys: MaybeUninit<[K; CAPACITY]>, - vals: MaybeUninit<[V; CAPACITY]>, + keys: [MaybeUninit; CAPACITY], + vals: [MaybeUninit; CAPACITY], } impl LeafNode { @@ -106,8 +106,11 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - keys: MaybeUninit::uninitialized(), - vals: MaybeUninit::uninitialized(), + // Creating a `[MaybeUninit; N]` array by first creating a + // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner + // array does not require initialization. + keys: MaybeUninit::uninitialized().into_inner(), + vals: MaybeUninit::uninitialized().into_inner(), parent: ptr::null(), parent_idx: MaybeUninit::uninitialized(), len: 0 @@ -626,7 +629,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { // We cannot be the root, so `as_leaf` is okay unsafe { slice::from_raw_parts( - self.as_leaf().vals.as_ptr() as *const V, + MaybeUninit::first_ptr(&self.as_leaf().vals), self.len() ) } @@ -653,7 +656,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } else { unsafe { slice::from_raw_parts_mut( - (*self.as_leaf_mut()).keys.as_mut_ptr() as *mut K, + MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).keys), self.len() ) } @@ -664,7 +667,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { debug_assert!(!self.is_shared_root()); unsafe { slice::from_raw_parts_mut( - (*self.as_leaf_mut()).vals.as_mut_ptr() as *mut V, + MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).vals), self.len() ) } From 22a947f3aa4b990efa135e3593fe7365bc7c36b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 22 Dec 2018 11:02:06 +0100 Subject: [PATCH 0391/1064] add macro for creating uninitialized array --- src/liballoc/collections/btree/node.rs | 12 +++--------- src/libcore/fmt/num.rs | 14 ++------------ src/libcore/lib.rs | 1 + src/libcore/macros.rs | 17 +++++++++++++++++ src/libcore/slice/sort.rs | 11 ++--------- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 8dd4aec136aa8..25810d680fa4b 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -106,11 +106,8 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - keys: MaybeUninit::uninitialized().into_inner(), - vals: MaybeUninit::uninitialized().into_inner(), + keys: uninitialized_array![_; CAPACITY], + vals: uninitialized_array![_; CAPACITY], parent: ptr::null(), parent_idx: MaybeUninit::uninitialized(), len: 0 @@ -162,10 +159,7 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - edges: MaybeUninit::uninitialized().into_inner(), + edges: uninitialized_array![_; 2*B], } } } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index ff284d2978e70..5283c6d7ef347 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -51,12 +51,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - let mut buf: [MaybeUninit; 128] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut buf = uninitialized_array![u8; 128]; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -203,12 +198,7 @@ macro_rules! impl_Display { // convert the negative num to positive by summing 1 to it's 2 complement (!self.$conv_fn()).wrapping_add(1) }; - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - let mut buf: [MaybeUninit; 39] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut buf = uninitialized_array![u8; 39]; let mut curr = buf.len() as isize; let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4d7da3692fd84..1295acb44a543 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -123,6 +123,7 @@ #![feature(structural_match)] #![feature(abi_unadjusted)] #![feature(adx_target_feature)] +#![feature(maybe_uninit)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 2f350df2f5c18..12b7adb8a9d26 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -547,6 +547,23 @@ macro_rules! unimplemented { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } +/// A macro to create an array of [`MaybeUninit`] +/// +/// This macro constructs and uninitialized array of the type `[MaybeUninit; N]`. +/// +/// [`MaybeUninit`]: mem/union.MaybeUninit.html +#[macro_export] +#[unstable(feature = "maybe_uninit", issue = "53491")] +macro_rules! uninitialized_array { + // This `into_inner` is safe because an array of `MaybeUninit` does not + // require initialization. + // FIXME(#49147): Could be replaced by an array initializer, once those can + // be any const expression. + ($t:ty; $size:expr) => (unsafe { + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_inner() + }); +} + /// Built-in macros to the compiler itself. /// /// These macros do not have any corresponding definition with a `macro_rules!` diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index 8eb6a4d54c0f6..2ff67a4934f74 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,21 +216,14 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - // Creating a `[MaybeUninit; N]` array by first creating a - // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner - // array does not require initialization. - let mut offsets_l: [MaybeUninit; BLOCK] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut offsets_l: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r: [MaybeUninit; BLOCK] = unsafe { - MaybeUninit::uninitialized().into_inner() - }; + let mut offsets_r: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. From 0e8fb93249ee63edba83cd7f2f5f1b09819efa15 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 10:49:11 +0100 Subject: [PATCH 0392/1064] Use warn() for extra diagnostics; with -D warnings this leads to errors This is needed to properly respect "deny_warnings = false" in config.toml --- src/liballoc/lib.rs | 4 ++-- src/libcore/lib.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index cf9d89ee05adf..d2ff1bae63561 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -64,8 +64,8 @@ #![needs_allocator] #![warn(deprecated_in_future)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![cfg_attr(not(test), feature(fn_traits))] #![cfg_attr(not(test), feature(generator_trait))] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1295acb44a543..1ef21832592ca 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -61,9 +61,9 @@ #![no_core] #![warn(deprecated_in_future)] -#![deny(missing_docs)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] +#![warn(missing_docs)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] From 33a969d9faa6d935895a82cbe6e96ee83ba36b88 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 11:04:30 +0100 Subject: [PATCH 0393/1064] fix typos, improve docs --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 4631d32d186f6..fdee86064e620 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1149,14 +1149,14 @@ impl MaybeUninit { unsafe { &mut *self.value as *mut T } } - /// Get a pointer to the first contained values. + /// Get a pointer to the first element of the array. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub fn first_ptr(this: &[MaybeUninit]) -> *const T { this as *const [MaybeUninit] as *const T } - /// Get a mutable pointer to the first contained values. + /// Get a mutable pointer to the first element of the array. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub fn first_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { From 6a52ca3fb465544f62cee70bec9499b967939cc9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 12:37:29 +0100 Subject: [PATCH 0394/1064] rename first_mut_ptr -> first_ptr_mut --- src/liballoc/collections/btree/node.rs | 10 +++++----- src/libcore/fmt/num.rs | 2 +- src/libcore/mem.rs | 2 +- src/libcore/slice/sort.rs | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 25810d680fa4b..e969e119dbe88 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -650,7 +650,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } else { unsafe { slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).keys), + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys), self.len() ) } @@ -661,7 +661,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { debug_assert!(!self.is_shared_root()); unsafe { slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut (*self.as_leaf_mut()).vals), + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals), self.len() ) } @@ -749,7 +749,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { slice_insert(self.vals_mut(), 0, val); slice_insert( slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut self.as_internal_mut().edges), + MaybeUninit::first_ptr_mut(&mut self.as_internal_mut().edges), self.len()+1 ), 0, @@ -808,7 +808,7 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { ForceResult::Internal(mut internal) => { let edge = slice_remove( slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut internal.as_internal_mut().edges), + MaybeUninit::first_ptr_mut(&mut internal.as_internal_mut().edges), old_len+1 ), 0 @@ -1087,7 +1087,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: slice_insert( slice::from_raw_parts_mut( - MaybeUninit::first_mut_ptr(&mut self.node.as_internal_mut().edges), + MaybeUninit::first_ptr_mut(&mut self.node.as_internal_mut().edges), self.node.len() ), self.idx + 1, diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 5283c6d7ef347..3a812337bb111 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -200,7 +200,7 @@ macro_rules! impl_Display { }; let mut buf = uninitialized_array![u8; 39]; let mut curr = buf.len() as isize; - let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf); + let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index fdee86064e620..8b6d9d882b5ad 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1159,7 +1159,7 @@ impl MaybeUninit { /// Get a mutable pointer to the first element of the array. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub fn first_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { + pub fn first_ptr_mut(this: &mut [MaybeUninit]) -> *mut T { this as *mut [MaybeUninit] as *mut T } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index 2ff67a4934f74..3f84faa049939 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -262,8 +262,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = MaybeUninit::first_mut_ptr(&mut offsets_l); - end_l = MaybeUninit::first_mut_ptr(&mut offsets_l); + start_l = MaybeUninit::first_ptr_mut(&mut offsets_l); + end_l = MaybeUninit::first_ptr_mut(&mut offsets_l); let mut elem = l; for i in 0..block_l { @@ -278,8 +278,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = MaybeUninit::first_mut_ptr(&mut offsets_r); - end_r = MaybeUninit::first_mut_ptr(&mut offsets_r); + start_r = MaybeUninit::first_ptr_mut(&mut offsets_r); + end_r = MaybeUninit::first_ptr_mut(&mut offsets_r); let mut elem = r; for i in 0..block_r { From 975eb312eff3f8e3453e1836995e485b5086515d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 28 Jan 2019 15:51:47 +0100 Subject: [PATCH 0395/1064] Use multiple threads by default. Limits tests to one thread. Do some renaming. --- Cargo.lock | 1 + config.toml.example | 2 +- src/bootstrap/bin/rustc.rs | 4 +-- src/bootstrap/compile.rs | 4 +-- src/bootstrap/config.rs | 6 ++-- src/librustc/Cargo.toml | 1 + src/librustc/dep_graph/graph.rs | 8 ++--- src/librustc/lib.rs | 1 + src/librustc/session/config.rs | 12 ++++---- src/librustc/session/mod.rs | 12 ++++---- src/librustc/ty/context.rs | 14 ++++----- src/librustc/ty/query/job.rs | 42 +++++++++++++------------- src/librustc/ty/query/mod.rs | 2 +- src/librustc/ty/query/plumbing.rs | 8 ++--- src/librustc_data_structures/sync.rs | 44 ++++++++++++++-------------- src/librustc_driver/driver.rs | 6 ++-- src/libsyntax_pos/lib.rs | 4 +-- src/libsyntax_pos/symbol.rs | 4 +-- src/tools/compiletest/src/runtest.rs | 3 ++ 19 files changed, 92 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c34a325a47492..18f05658a17ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2234,6 +2234,7 @@ dependencies = [ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/config.toml.example b/config.toml.example index 24293fc864c5f..183d61a43e342 100644 --- a/config.toml.example +++ b/config.toml.example @@ -318,7 +318,7 @@ #incremental = false # Build rustc with experimental parallelization -#experimental-parallel-queries = false +#parallel-compiler = false # The default linker that will be hard-coded into the generated compiler for # targets that don't specify linker explicitly in their target specifications. diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index a0c75cd9e9476..7a765973e20f8 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -284,8 +284,8 @@ fn main() { } } - if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() { - cmd.arg("--cfg").arg("parallel_queries"); + if env::var_os("RUSTC_PARALLEL_COMPILER").is_some() { + cmd.arg("--cfg").arg("parallel_compiler"); } if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none() diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index ec04dee6c32f0..ddae3cb0d60ce 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -554,8 +554,8 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) { if let Some(ref s) = builder.config.rustc_default_linker { cargo.env("CFG_DEFAULT_LINKER", s); } - if builder.config.rustc_parallel_queries { - cargo.env("RUSTC_PARALLEL_QUERIES", "1"); + if builder.config.rustc_parallel { + cargo.env("RUSTC_PARALLEL_COMPILER", "1"); } if builder.config.rust_verify_llvm_ir { cargo.env("RUSTC_VERIFY_LLVM_IR", "1"); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index a2989f0cffa6e..ba339c50fc304 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -97,7 +97,7 @@ pub struct Config { pub rust_debuginfo_only_std: bool, pub rust_debuginfo_tools: bool, pub rust_rpath: bool, - pub rustc_parallel_queries: bool, + pub rustc_parallel: bool, pub rustc_default_linker: Option, pub rust_optimize_tests: bool, pub rust_debuginfo_tests: bool, @@ -298,7 +298,7 @@ struct Rust { debuginfo_lines: Option, debuginfo_only_std: Option, debuginfo_tools: Option, - experimental_parallel_queries: Option, + parallel_compiler: Option, backtrace: Option, default_linker: Option, channel: Option, @@ -557,7 +557,7 @@ impl Config { set(&mut config.lld_enabled, rust.lld); set(&mut config.lldb_enabled, rust.lldb); set(&mut config.llvm_tools_enabled, rust.llvm_tools); - config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false); + config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); config.rustc_default_linker = rust.default_linker.clone(); config.musl_root = rust.musl_root.clone().map(PathBuf::from); config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from); diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 504e016e5b803..a5521effc7d8d 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -15,6 +15,7 @@ fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } jobserver = "0.1" lazy_static = "1.0.0" +num_cpus = "1.0" scoped-tls = { version = "0.1.1", features = ["nightly"] } log = { version = "0.4", features = ["release_max_level_info", "std"] } polonius-engine = "0.6.2" diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 63857d6c9189a..c9353a451e2cd 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -580,7 +580,7 @@ impl DepGraph { ) -> Option { debug!("try_mark_previous_green({:?}) - BEGIN", dep_node); - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] { debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node)); debug_assert!(data.colors.get(prev_dep_node_index).is_none()); @@ -743,7 +743,7 @@ impl DepGraph { // ... and finally storing a "Green" entry in the color map. // Multiple threads can all write the same color here - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] debug_assert!(data.colors.get(prev_dep_node_index).is_none(), "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ insertion for {:?}", dep_node); @@ -766,7 +766,7 @@ impl DepGraph { did_allocation: bool, diagnostics: Vec, ) { - if did_allocation || !cfg!(parallel_queries) { + if did_allocation || !cfg!(parallel_compiler) { // Only the thread which did the allocation emits the error messages let handle = tcx.sess.diagnostic(); @@ -778,7 +778,7 @@ impl DepGraph { DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit(); } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] { // Mark the diagnostics and emitted and wake up waiters data.emitted_diagnostics.lock().insert(dep_node_index); diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 7ecec0b9a69ac..f886e50246ac0 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -70,6 +70,7 @@ extern crate core; extern crate fmt_macros; extern crate getopts; extern crate graphviz; +extern crate num_cpus; #[macro_use] extern crate lazy_static; #[macro_use] extern crate scoped_tls; #[cfg(windows)] diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index e2f4049b1db28..4b1aefb2216fb 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1194,8 +1194,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "prints the llvm optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), - query_threads: Option = (None, parse_opt_uint, [UNTRACKED], - "execute queries on a thread pool with N threads"), + threads: Option = (None, parse_opt_uint, [UNTRACKED], + "use a thread pool with N threads"), ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], "print the pre-expansion AST as JSON and halt"), ls: bool = (false, parse_bool, [UNTRACKED], @@ -1986,17 +1986,17 @@ pub fn build_session_options_and_crate_config( } } - if debugging_opts.query_threads == Some(0) { + if debugging_opts.threads == Some(0) { early_error( error_format, - "Value for query threads must be a positive nonzero integer", + "Value for threads must be a positive nonzero integer", ); } - if debugging_opts.query_threads.unwrap_or(1) > 1 && debugging_opts.fuel.is_some() { + if debugging_opts.threads.unwrap_or(1) > 1 && debugging_opts.fuel.is_some() { early_error( error_format, - "Optimization fuel is incompatible with multiple query threads", + "Optimization fuel is incompatible with multiple threads", ); } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 875021e20d420..c5034415d6ffb 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -877,7 +877,7 @@ impl Session { let mut ret = true; if let Some(ref c) = self.optimization_fuel_crate { if c == crate_name { - assert_eq!(self.query_threads(), 1); + assert_eq!(self.threads(), 1); let mut fuel = self.optimization_fuel.lock(); ret = fuel.remaining != 0; if fuel.remaining == 0 && !fuel.out_of_fuel { @@ -890,7 +890,7 @@ impl Session { } if let Some(ref c) = self.print_fuel_crate { if c == crate_name { - assert_eq!(self.query_threads(), 1); + assert_eq!(self.threads(), 1); self.print_fuel.fetch_add(1, SeqCst); } } @@ -899,14 +899,14 @@ impl Session { /// Returns the number of query threads that should be used for this /// compilation - pub fn query_threads_from_opts(opts: &config::Options) -> usize { - opts.debugging_opts.query_threads.unwrap_or(1) + pub fn threads_from_opts(opts: &config::Options) -> usize { + opts.debugging_opts.threads.unwrap_or(::num_cpus::get()) } /// Returns the number of query threads that should be used for this /// compilation - pub fn query_threads(&self) -> usize { - Self::query_threads_from_opts(&self.opts) + pub fn threads(&self) -> usize { + Self::threads_from_opts(&self.opts) } /// Returns the number of codegen units that should be used for this diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a0da7cf2137d0..881c0d4e6d239 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1823,10 +1823,10 @@ pub mod tls { use rustc_data_structures::thin_vec::ThinVec; use dep_graph::TaskDeps; - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] use std::cell::Cell; - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] use rayon_core; /// This is the implicit state of rustc. It contains the current @@ -1859,7 +1859,7 @@ pub mod tls { /// Sets Rayon's thread local variable which is preserved for Rayon jobs /// to `value` during the call to `f`. It is restored to its previous value after. /// This is used to set the pointer to the new ImplicitCtxt. - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline] fn set_tlv R, R>(value: usize, f: F) -> R { rayon_core::tlv::with(value, f) @@ -1867,20 +1867,20 @@ pub mod tls { /// Gets Rayon's thread local variable which is preserved for Rayon jobs. /// This is used to get the pointer to the current ImplicitCtxt. - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline] fn get_tlv() -> usize { rayon_core::tlv::get() } /// A thread local variable which stores a pointer to the current ImplicitCtxt - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] thread_local!(static TLV: Cell = Cell::new(0)); /// Sets TLV to `value` during the call to `f`. /// It is restored to its previous value after. /// This is used to set the pointer to the new ImplicitCtxt. - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline] fn set_tlv R, R>(value: usize, f: F) -> R { let old = get_tlv(); @@ -1890,7 +1890,7 @@ pub mod tls { } /// This is used to get the pointer to the current ImplicitCtxt. - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] fn get_tlv() -> usize { TLV.with(|tlv| tlv.get()) } diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index d794429a8a706..abbf74a7761ef 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -8,7 +8,7 @@ use syntax_pos::Span; use ty::tls; use ty::query::Query; use ty::query::plumbing::CycleError; -#[cfg(not(parallel_queries))] +#[cfg(not(parallel_compiler))] use ty::query::{ plumbing::TryGetJob, config::QueryDescription, @@ -17,7 +17,7 @@ use ty::context::TyCtxt; use std::process; use std::{fmt, ptr}; -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] use { rayon_core, parking_lot::{Mutex, Condvar}, @@ -54,7 +54,7 @@ pub struct QueryJob<'tcx> { pub parent: Option>>, /// The latch which is used to wait on this job - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] latch: QueryLatch<'tcx>, } @@ -64,7 +64,7 @@ impl<'tcx> QueryJob<'tcx> { QueryJob { info, parent, - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] latch: QueryLatch::new(), } } @@ -73,7 +73,7 @@ impl<'tcx> QueryJob<'tcx> { /// /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any /// query that means that there is a query cycle, thus this always running a cycle error. - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline(never)] #[cold] pub(super) fn cycle_error<'lcx, 'a, D: QueryDescription<'tcx>>( @@ -88,7 +88,7 @@ impl<'tcx> QueryJob<'tcx> { /// /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any /// query that means that there is a query cycle, thus this always running a cycle error. - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] pub(super) fn await<'lcx>( &self, tcx: TyCtxt<'_, 'tcx, 'lcx>, @@ -113,7 +113,7 @@ impl<'tcx> QueryJob<'tcx> { }) } - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] fn find_cycle_in_stack<'lcx>( &self, tcx: TyCtxt<'_, 'tcx, 'lcx>, @@ -152,7 +152,7 @@ impl<'tcx> QueryJob<'tcx> { /// This does nothing for single threaded rustc, /// as there are no concurrent jobs which could be waiting on us pub fn signal_complete(&self) { - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] self.latch.set(); } @@ -161,7 +161,7 @@ impl<'tcx> QueryJob<'tcx> { } } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] struct QueryWaiter<'tcx> { query: Option>>, condvar: Condvar, @@ -169,7 +169,7 @@ struct QueryWaiter<'tcx> { cycle: Lock>>, } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] impl<'tcx> QueryWaiter<'tcx> { fn notify(&self, registry: &rayon_core::Registry) { rayon_core::mark_unblocked(registry); @@ -177,18 +177,18 @@ impl<'tcx> QueryWaiter<'tcx> { } } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] struct QueryLatchInfo<'tcx> { complete: bool, waiters: Vec>>, } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] struct QueryLatch<'tcx> { info: Mutex>, } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] impl<'tcx> QueryLatch<'tcx> { fn new() -> Self { QueryLatch { @@ -242,7 +242,7 @@ impl<'tcx> QueryLatch<'tcx> { } /// A resumable waiter of a query. The usize is the index into waiters in the query's latch -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] type Waiter<'tcx> = (Lrc>, usize); /// Visits all the non-resumable and resumable waiters of a query. @@ -254,7 +254,7 @@ type Waiter<'tcx> = (Lrc>, usize); /// For visits of resumable waiters it returns Some(Some(Waiter)) which has the /// required information to resume the waiter. /// If all `visit` calls returns None, this function also returns None. -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] fn visit_waiters<'tcx, F>(query: Lrc>, mut visit: F) -> Option>> where F: FnMut(Span, Lrc>) -> Option>> @@ -282,7 +282,7 @@ where /// `span` is the reason for the `query` to execute. This is initially DUMMY_SP. /// If a cycle is detected, this initial value is replaced with the span causing /// the cycle. -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] fn cycle_check<'tcx>(query: Lrc>, span: Span, stack: &mut Vec<(Span, Lrc>)>, @@ -321,7 +321,7 @@ fn cycle_check<'tcx>(query: Lrc>, /// Finds out if there's a path to the compiler root (aka. code which isn't in a query) /// from `query` without going through any of the queries in `visited`. /// This is achieved with a depth first search. -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] fn connected_to_root<'tcx>( query: Lrc>, visited: &mut FxHashSet<*const QueryJob<'tcx>> @@ -346,7 +346,7 @@ fn connected_to_root<'tcx>( } // Deterministically pick an query from a list -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc>)>( tcx: TyCtxt<'_, 'tcx, '_>, queries: &'a [T], @@ -372,7 +372,7 @@ fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc>)>( /// the function return true. /// If a cycle was not found, the starting query is removed from `jobs` and /// the function returns false. -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] fn remove_cycle<'tcx>( jobs: &mut Vec>>, wakelist: &mut Vec>>, @@ -475,7 +475,7 @@ fn remove_cycle<'tcx>( /// Creates a new thread and forwards information in thread locals to it. /// The new thread runs the deadlock handler. /// Must only be called when a deadlock is about to happen. -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] pub unsafe fn handle_deadlock() { use syntax; use syntax_pos; @@ -514,7 +514,7 @@ pub unsafe fn handle_deadlock() { /// uses a query latch and then resuming that waiter. /// There may be multiple cycles involved in a deadlock, so this searches /// all active queries for cycles before finally resuming all the waiters at once. -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) { let on_panic = OnDrop(|| { eprintln!("deadlock handler panicked, aborting process"); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index ec1103b0ae588..195bec11ee570 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -69,7 +69,7 @@ pub use self::plumbing::{force_from_dep_node, CycleError}; mod job; pub use self::job::{QueryJob, QueryInfo}; -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] pub use self::job::handle_deadlock; mod keys; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 541f5b75aa5c7..e777c883c3787 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -153,12 +153,12 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { // If we are single-threaded we know that we have cycle error, // so we just turn the errror - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] return job.cycle_error(tcx, span); // With parallel queries we might just have to wait on some other // thread - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] { if let Err(cycle) = job.await(tcx, span) { return TryGetJob::JobCompleted(Err(cycle)); @@ -695,7 +695,7 @@ macro_rules! define_queries_inner { [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => { use std::mem; - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] use ty::query::job::QueryResult; use rustc_data_structures::sync::Lock; use { @@ -736,7 +736,7 @@ macro_rules! define_queries_inner { }); } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] pub fn collect_active_jobs(&self) -> Vec>> { let mut jobs = Vec::new(); diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 0253eef4dfa3a..cae3087fe586c 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -1,21 +1,21 @@ -//! This module defines types which are thread safe if cfg!(parallel_queries) is true. +//! This module defines types which are thread safe if cfg!(parallel_compiler) is true. //! //! `Lrc` is an alias of either Rc or Arc. //! //! `Lock` is a mutex. -//! It internally uses `parking_lot::Mutex` if cfg!(parallel_queries) is true, +//! It internally uses `parking_lot::Mutex` if cfg!(parallel_compiler) is true, //! `RefCell` otherwise. //! //! `RwLock` is a read-write lock. -//! It internally uses `parking_lot::RwLock` if cfg!(parallel_queries) is true, +//! It internally uses `parking_lot::RwLock` if cfg!(parallel_compiler) is true, //! `RefCell` otherwise. //! -//! `MTLock` is a mutex which disappears if cfg!(parallel_queries) is false. +//! `MTLock` is a mutex which disappears if cfg!(parallel_compiler) is false. //! -//! `MTRef` is a immutable reference if cfg!(parallel_queries), and an mutable reference otherwise. +//! `MTRef` is a immutable reference if cfg!(parallel_compiler), and an mutable reference otherwise. //! //! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync -//! depending on the value of cfg!(parallel_queries). +//! depending on the value of cfg!(parallel_compiler). use std::collections::HashMap; use std::hash::{Hash, BuildHasher}; @@ -50,7 +50,7 @@ pub use std::sync::atomic::Ordering::SeqCst; pub use std::sync::atomic::Ordering; cfg_if! { - if #[cfg(not(parallel_queries))] { + if #[cfg(not(parallel_compiler))] { pub auto trait Send {} pub auto trait Sync {} @@ -461,19 +461,19 @@ impl Lock { self.0.get_mut() } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline(always)] pub fn try_lock(&self) -> Option> { self.0.try_lock() } - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn try_lock(&self) -> Option> { self.0.try_borrow_mut().ok() } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline(always)] pub fn lock(&self) -> LockGuard { if ERROR_CHECKING { @@ -483,7 +483,7 @@ impl Lock { } } - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn lock(&self) -> LockGuard { self.0.borrow_mut() @@ -539,13 +539,13 @@ impl RwLock { self.0.get_mut() } - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn read(&self) -> ReadGuard { self.0.borrow() } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline(always)] pub fn read(&self) -> ReadGuard { if ERROR_CHECKING { @@ -560,25 +560,25 @@ impl RwLock { f(&*self.read()) } - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn try_write(&self) -> Result, ()> { self.0.try_borrow_mut().map_err(|_| ()) } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline(always)] pub fn try_write(&self) -> Result, ()> { self.0.try_write().ok_or(()) } - #[cfg(not(parallel_queries))] + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn write(&self) -> WriteGuard { self.0.borrow_mut() } - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] #[inline(always)] pub fn write(&self) -> WriteGuard { if ERROR_CHECKING { @@ -616,27 +616,27 @@ impl Clone for RwLock { /// It will panic if it is used on multiple threads. #[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)] pub struct OneThread { - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] thread: thread::ThreadId, inner: T, } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] unsafe impl std::marker::Sync for OneThread {} -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] unsafe impl std::marker::Send for OneThread {} impl OneThread { #[inline(always)] fn check(&self) { - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] assert_eq!(thread::current().id(), self.thread); } #[inline(always)] pub fn new(inner: T) -> Self { OneThread { - #[cfg(parallel_queries)] + #[cfg(parallel_compiler)] thread: thread::current().id(), inner, } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f5e5f1f5c0b95..c586c705676f4 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -56,7 +56,7 @@ use proc_macro_decls; use profile; use super::Compilation; -#[cfg(not(parallel_queries))] +#[cfg(not(parallel_compiler))] pub fn spawn_thread_pool R + sync::Send, R: sync::Send>( opts: config::Options, f: F @@ -66,7 +66,7 @@ pub fn spawn_thread_pool R + sync::Send, R: sync:: }) } -#[cfg(parallel_queries)] +#[cfg(parallel_compiler)] pub fn spawn_thread_pool R + sync::Send, R: sync::Send>( opts: config::Options, f: F @@ -78,7 +78,7 @@ pub fn spawn_thread_pool R + sync::Send, R: sync:: let gcx_ptr = &Lock::new(0); let config = ThreadPoolBuilder::new() - .num_threads(Session::query_threads_from_opts(&opts)) + .num_threads(Session::threads_from_opts(&opts)) .deadlock_handler(|| unsafe { ty::query::handle_deadlock() }) .stack_size(::STACK_SIZE); diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index d9d7f9b0cb492..2a85779239689 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -238,9 +238,9 @@ impl SpanData { // The interner is pointed to by a thread local value which is only set on the main thread // with parallelization is disabled. So we don't allow `Span` to transfer between threads // to avoid panics and other errors, even though it would be memory safe to do so. -#[cfg(not(parallel_queries))] +#[cfg(not(parallel_compiler))] impl !Send for Span {} -#[cfg(not(parallel_queries))] +#[cfg(not(parallel_compiler))] impl !Sync for Span {} impl PartialOrd for Span { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index e741b79bd4c45..7097f332b8b8f 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -150,9 +150,9 @@ newtype_index! { // The interner is pointed to by a thread local value which is only set on the main thread // with parallelization is disabled. So we don't allow `Symbol` to transfer between threads // to avoid panics and other errors, even though it would be memory safe to do so. -#[cfg(not(parallel_queries))] +#[cfg(not(parallel_compiler))] impl !Send for Symbol { } -#[cfg(not(parallel_queries))] +#[cfg(not(parallel_compiler))] impl !Sync for Symbol { } impl Symbol { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index fc4f7654bd1a1..3581c4cfbcb84 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1727,6 +1727,9 @@ impl<'test> TestCx<'test> { // FIXME Why is -L here? rustc.arg(input_file); //.arg("-L").arg(&self.config.build_base); + // Use a single thread for efficiency and a deterministic error message order + rustc.arg("-Zthreads=1"); + // Optionally prevent default --target if specified in test compile-flags. let custom_target = self .props From a2b75eda955a46ec643b8277b1fb41c4fed94f4e Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 28 Jan 2019 09:30:43 -0600 Subject: [PATCH 0396/1064] review comments --- src/librustc/diagnostics.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index dd5144b1568fb..21aa4d7d15061 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -363,7 +363,7 @@ struct Foo1 { x: &bool } struct Foo2<'a> { x: &'a bool } // correct impl Foo2 {} - // ^ expected lifetime parameter + // ^^^^ expected lifetime parameter impl<'a> Foo2<'a> {} // correct struct Bar1 { x: Foo2 } @@ -770,40 +770,40 @@ struct Foo { These can be fixed by declaring lifetime parameters: ``` -fn foo<'a>(x: &'a str) {} - struct Foo<'a> { x: &'a str, } + +fn foo<'a>(x: &'a str) {} ``` Impl blocks declare lifetime parameters separately. You need to add lifetime parameters to an impl block if you're implementing a type that has a lifetime parameter of its own. For example: - + ```compile_fail,E0261 +struct Foo<'a> { + x: &'a str, +} + // error, use of undeclared lifetime name `'a` impl Foo<'a> { fn foo<'a>(x: &'a str) {} } - -struct Foo<'a> { - x: &'a str, -} ``` -This is fixed by declaring impl block like this: +This is fixed by declaring the impl block like this: ``` +struct Foo<'a> { + x: &'a str, +} + // correct impl<'a> Foo<'a> { fn foo(x: &'a str) {} } - -struct Foo<'a> { - x: &'a str, -} ``` "##, From 489a79247ddf5da8090019ff4da4b688ad55afa7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Jan 2019 17:33:29 +0100 Subject: [PATCH 0397/1064] fix gdb debug printing --- src/etc/gdb_rust_pretty_printing.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index b9413563fd9ff..a6b09722e1c94 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -330,19 +330,20 @@ def children_of_node(boxed_node, height, want_values): leaf = node_ptr['data'] else: leaf = node_ptr.dereference() - keys = leaf['keys']['value']['value'] + keys = leaf['keys'] if want_values: - values = leaf['vals']['value']['value'] + values = leaf['vals'] length = int(leaf['len']) for i in xrange(0, length + 1): if height > 0: - for child in children_of_node(node_ptr['edges'][i], height - 1, want_values): + child_ptr = node_ptr['edges'][i]['value']['value'] + for child in children_of_node(child_ptr, height - 1, want_values): yield child if i < length: if want_values: - yield (keys[i], values[i]) + yield (keys[i]['value']['value'], values[i]['value']['value']) else: - yield keys[i] + yield keys[i]['value']['value'] class RustStdBTreeSetPrinter(object): def __init__(self, val): From 30b1c35f030ae746bf08784dea65fc20f47dc9f8 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Mon, 28 Jan 2019 13:04:05 -0500 Subject: [PATCH 0398/1064] rustdoc: remove blank unstable spans --- src/librustdoc/html/render.rs | 4 ---- src/test/rustdoc/stability.rs | 12 ++++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 src/test/rustdoc/stability.rs diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..83302892c1c96 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3483,10 +3483,6 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, ns_id = ns_id, name = field.name.as_ref().unwrap(), ty = ty)?; - if let Some(stability_class) = field.stability_class() { - write!(w, "", - stab = stability_class)?; - } document(w, cx, field)?; } } diff --git a/src/test/rustdoc/stability.rs b/src/test/rustdoc/stability.rs new file mode 100644 index 0000000000000..18a21603493c2 --- /dev/null +++ b/src/test/rustdoc/stability.rs @@ -0,0 +1,12 @@ +#![feature(staged_api)] + +#![unstable(feature = "test", issue = "0")] + +pub struct Unstable { + // @has stability/struct.Unstable.html \ + // '//div[@class="stability"]//div[@class="stab unstable"]' \ + // 'This is a nightly-only experimental API' + // @count stability/struct.Unstable.html '//span[@class="stab unstable"]' 0 + pub foo: u32, + pub bar: u32, +} From a015f7f61ffba8ef2ea53320de8f3a6cd53561fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 28 Jan 2019 19:22:55 +0100 Subject: [PATCH 0399/1064] Fix CI --- src/bootstrap/configure.py | 2 +- src/ci/run.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 7b70236dfe8e6..b2d8f2d8ebfcf 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -35,7 +35,7 @@ def v(*args): o("docs", "build.docs", "build standard library documentation") o("compiler-docs", "build.compiler-docs", "build compiler documentation") o("optimize-tests", "rust.optimize-tests", "build tests with optimizations") -o("experimental-parallel-queries", "rust.experimental-parallel-queries", "build rustc with experimental parallelization") +o("parallel-compiler", "rust.parallel-compiler", "build a multi-threaded rustc") o("test-miri", "rust.test-miri", "run miri's test suite") o("debuginfo-tests", "rust.debuginfo-tests", "build tests with debugger metadata") o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests") diff --git a/src/ci/run.sh b/src/ci/run.sh index b0e1b1651055f..42d0d7db5964c 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -82,7 +82,7 @@ fi SCCACHE_IDLE_TIMEOUT=10800 sccache --start-server || true if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then - $SRC/configure --enable-experimental-parallel-queries + $SRC/configure --enable-parallel-compiler CARGO_INCREMENTAL=0 python2.7 ../x.py check rm -f config.toml rm -rf build From fd9d9ee3a293bab88fd4dfb69f28d5ccb92e292c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 28 Jan 2019 19:24:07 +0100 Subject: [PATCH 0400/1064] Fix a comment --- config.toml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.toml.example b/config.toml.example index 183d61a43e342..69a38ec877381 100644 --- a/config.toml.example +++ b/config.toml.example @@ -317,7 +317,7 @@ # Whether to always use incremental compilation when building rustc #incremental = false -# Build rustc with experimental parallelization +# Build a multi-threaded rustc #parallel-compiler = false # The default linker that will be hard-coded into the generated compiler for From 99d00c86f85e8c1a7a1ba4cbe23d2e6b0ce85271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Mon, 28 Jan 2019 18:40:47 +0100 Subject: [PATCH 0401/1064] bootstrap: set toolchain variables on per target basis Using CC, CFLAGS, CXX, CXXFLAGS, AR and RANLIB breaks cross compilation because host is built first and has correct values. The same values are incorrect for the target however. --- src/bootstrap/builder.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index f742bce180c05..716774632a01c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1051,29 +1051,24 @@ impl<'a> Builder<'a> { } }; let cc = ccacheify(&self.cc(target)); - cargo.env(format!("CC_{}", target), &cc).env("CC", &cc); + cargo.env(format!("CC_{}", target), &cc); let cflags = self.cflags(target, GitRepo::Rustc).join(" "); cargo - .env(format!("CFLAGS_{}", target), cflags.clone()) - .env("CFLAGS", cflags.clone()); + .env(format!("CFLAGS_{}", target), cflags.clone()); if let Some(ar) = self.ar(target) { let ranlib = format!("{} s", ar.display()); cargo .env(format!("AR_{}", target), ar) - .env("AR", ar) - .env(format!("RANLIB_{}", target), ranlib.clone()) - .env("RANLIB", ranlib); + .env(format!("RANLIB_{}", target), ranlib); } if let Ok(cxx) = self.cxx(target) { let cxx = ccacheify(&cxx); cargo .env(format!("CXX_{}", target), &cxx) - .env("CXX", &cxx) - .env(format!("CXXFLAGS_{}", target), cflags.clone()) - .env("CXXFLAGS", cflags); + .env(format!("CXXFLAGS_{}", target), cflags); } } From c97d13545290c559ac93442ea6dc6a93545302fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81my=20Rakic?= Date: Mon, 28 Jan 2019 23:12:13 +0100 Subject: [PATCH 0402/1064] Refer to synthetically named lifetimes as "some specific lifetime" rather than "the specific lifetime" --- .../nice_region_error/placeholder_error.rs | 4 ++-- .../ui/associated-types/associated-types-eq-hr.stderr | 6 +++--- .../associated-types/higher-ranked-projection.bad.stderr | 2 +- src/test/ui/generator/auto-trait-regions.stderr | 4 ++-- src/test/ui/hrtb/hrtb-cache-issue-54302.stderr | 2 +- src/test/ui/hrtb/hrtb-conflate-regions.stderr | 2 +- .../ui/hrtb/hrtb-exists-forall-trait-invariant.stderr | 2 +- src/test/ui/hrtb/hrtb-just-for-static.stderr | 4 ++-- src/test/ui/hrtb/hrtb-perfect-forwarding.stderr | 2 +- src/test/ui/issues/issue-54302-cases.stderr | 8 ++++---- src/test/ui/issues/issue-54302.stderr | 2 +- src/test/ui/issues/issue-57362-2.stderr | 2 +- src/test/ui/where-clauses/where-for-self-2.stderr | 2 +- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 98458796ef4d6..ebac5a0c2a69e 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -416,14 +416,14 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { if any_self_ty_has_vid { err.note(&format!( "but `{}` is actually implemented for the type `{}`, \ - for the specific lifetime `'{}`", + for some specific lifetime `'{}`", actual_trait_ref, actual_trait_ref.self_ty(), n )); } else { err.note(&format!( - "but `{}` actually implements `{}`, for some lifetime `'{}`", + "but `{}` actually implements `{}`, for some specific lifetime `'{}`", actual_trait_ref.self_ty(), actual_trait_ref, n diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index 5a074fe345734..5299ebbb1ba8a 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -42,7 +42,7 @@ LL | tuple_one::(); | = note: Due to a where-clause on `tuple_one`, = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2` + = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` error: implementation of `TheTrait` is not general enough --> $DIR/associated-types-eq-hr.rs:96:5 @@ -52,7 +52,7 @@ LL | tuple_two::(); | = note: Due to a where-clause on `tuple_two`, = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2` + = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` error: implementation of `TheTrait` is not general enough --> $DIR/associated-types-eq-hr.rs:105:5 @@ -62,7 +62,7 @@ LL | tuple_four::(); | = note: Due to a where-clause on `tuple_four`, = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2` + = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` error: aborting due to 5 previous errors diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index 69fa1ce30aa8f..3bbf48cb37f58 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -6,7 +6,7 @@ LL | foo(()); | = note: Due to a where-clause on `foo`, = note: `Mirror` would have to be implemented for the type `&'0 ()`, for any lifetime `'0` - = note: but `Mirror` is actually implemented for the type `&'1 ()`, for the specific lifetime `'1` + = note: but `Mirror` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index 680a7bbc50e5e..92f92e2a32a36 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -5,7 +5,7 @@ LL | assert_foo(gen); | ^^^^^^^^^^ | = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0` - = note: but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for the specific lifetime `'1` + = note: but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:48:5 @@ -14,7 +14,7 @@ LL | assert_foo(gen); | ^^^^^^^^^^ | = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1` - = note: but `Foo` is actually implemented for the type `A<'_, '2>`, for the specific lifetime `'2` + = note: but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr index d0bcebeac4f70..21d154eb2316c 100644 --- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr +++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr @@ -5,7 +5,7 @@ LL | assert_deserialize_owned::<&'static str>(); //~ ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0` - = note: but `&str` actually implements `Deserialize<'1>`, for some lifetime `'1` + = note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr index aa91314b350a1..630dda2694fde 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr @@ -6,7 +6,7 @@ LL | fn b() { want_foo2::(); } //~ ERROR | = note: Due to a where-clause on `want_foo2`, = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some lifetime `'2` + = note: but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr index 91b5db6cd664f..a44837a1e26fd 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr @@ -6,7 +6,7 @@ LL | foo::<()>(); //~ ERROR not general enough | = note: Due to a where-clause on `foo`, = note: `()` must implement `Trait fn(std::cell::Cell<&'b u32>)>` - = note: but `()` actually implements `Trait)>`, for some lifetime `'0` + = note: but `()` actually implements `Trait)>`, for some specific lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr index 24edcd910764e..99c87f13672b1 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr @@ -6,7 +6,7 @@ LL | want_hrtb::() //~ ERROR | = note: Due to a where-clause on `want_hrtb`, = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0` - = note: but `StaticInt` actually implements `Foo<&'1 isize>`, for some lifetime `'1` + = note: but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/hrtb-just-for-static.rs:30:5 @@ -16,7 +16,7 @@ LL | want_hrtb::<&'a u32>() //~ ERROR | = note: Due to a where-clause on `want_hrtb`, = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0` - = note: but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for the specific lifetime `'1` + = note: but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index a87fa6d3012da..c7be3790aa1c8 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -6,7 +6,7 @@ LL | foo_hrtb_bar_not(&mut t); //~ ERROR not general enough | = note: Due to a where-clause on `foo_hrtb_bar_not`, = note: `&mut T` must implement `Foo<&'0 isize>`, for any lifetime `'0` - = note: but `&mut T` actually implements `Foo<&'1 isize>`, for some lifetime `'1` + = note: but `&mut T` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-54302-cases.stderr b/src/test/ui/issues/issue-54302-cases.stderr index 377bac3b24524..98637611b79fe 100644 --- a/src/test/ui/issues/issue-54302-cases.stderr +++ b/src/test/ui/issues/issue-54302-cases.stderr @@ -5,7 +5,7 @@ LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` - = note: but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for the specific lifetime `'1` + = note: but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:69:5 @@ -14,7 +14,7 @@ LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0` - = note: but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for the specific lifetime `'1` + = note: but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:75:5 @@ -23,7 +23,7 @@ LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0` - = note: but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for the specific lifetime `'1` + = note: but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:81:5 @@ -32,7 +32,7 @@ LL | >::ref_foo(a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0` - = note: but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for the specific lifetime `'1` + = note: but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr index 442d32eb9f1e9..c6d0805f3ab2a 100644 --- a/src/test/ui/issues/issue-54302.stderr +++ b/src/test/ui/issues/issue-54302.stderr @@ -5,7 +5,7 @@ LL | assert_deserialize_owned::<&'static str>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0` - = note: but `&str` actually implements `Deserialize<'1>`, for some lifetime `'1` + = note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr index 782c78da3a22c..14b7f52bb8799 100644 --- a/src/test/ui/issues/issue-57362-2.stderr +++ b/src/test/ui/issues/issue-57362-2.stderr @@ -5,7 +5,7 @@ LL | let x = ::make_g(); //~ ERROR not general enough | ^^^^^^^^^^^^^^^^^^ | = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())` - = note: but `X` is actually implemented for the type `fn(&'0 ())`, for the specific lifetime `'0` + = note: but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` error: aborting due to previous error diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr index 4d827e6ce4fd6..342cabfd6bf0a 100644 --- a/src/test/ui/where-clauses/where-for-self-2.stderr +++ b/src/test/ui/where-clauses/where-for-self-2.stderr @@ -6,7 +6,7 @@ LL | foo(&X); //~ ERROR implementation of `Bar` is not general enough | = note: Due to a where-clause on `foo`, = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` - = note: but `Bar` is actually implemented for the type `&'1 u32`, for the specific lifetime `'1` + = note: but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` error: aborting due to previous error From 1e577269da046b5e2b862830b72210c855fca123 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 27 Jan 2019 17:03:03 +0000 Subject: [PATCH 0403/1064] Introduce into_raw_non_null on Rc and Arc --- src/liballoc/rc.rs | 21 +++++++++++++++++++++ src/liballoc/sync.rs | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index d3a55c59ff69c..456f7cd5e2ff1 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -435,6 +435,27 @@ impl Rc { } } + /// Consumes the `Rc`, returning the wrapped pointer as `NonNull`. + /// + /// # Examples + /// + /// ``` + /// #![feature(rc_into_raw_non_null)] + /// + /// use std::rc::Rc; + /// + /// let x = Rc::new(10); + /// let ptr = Rc::into_raw_non_null(x); + /// let deref = unsafe { *ptr.as_ref() }; + /// assert_eq!(deref, 10); + /// ``` + #[unstable(feature = "rc_into_raw_non_null", issue = "47336")] + #[inline] + pub fn into_raw_non_null(this: Self) -> NonNull { + // safe because Rc guarantees its pointer is non-null + unsafe { NonNull::new_unchecked(Rc::into_raw(this) as *mut _) } + } + /// Creates a new [`Weak`][weak] pointer to this value. /// /// [weak]: struct.Weak.html diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 390a079165054..5cffa93db11d4 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -413,6 +413,27 @@ impl Arc { } } + /// Consumes the `Arc`, returning the wrapped pointer as `NonNull`. + /// + /// # Examples + /// + /// ``` + /// #![feature(rc_into_raw_non_null)] + /// + /// use std::sync::Arc; + /// + /// let x = Arc::new(10); + /// let ptr = Arc::into_raw_non_null(x); + /// let deref = unsafe { *ptr.as_ref() }; + /// assert_eq!(deref, 10); + /// ``` + #[unstable(feature = "rc_into_raw_non_null", issue = "47336")] + #[inline] + pub fn into_raw_non_null(this: Self) -> NonNull { + // safe because Arc guarantees its pointer is non-null + unsafe { NonNull::new_unchecked(Arc::into_raw(this) as *mut _) } + } + /// Creates a new [`Weak`][weak] pointer to this value. /// /// [weak]: struct.Weak.html From 6f86a70ea13cbe8b32c6e6ed76b8f57be4d70c68 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Mon, 28 Jan 2019 23:56:37 +0100 Subject: [PATCH 0404/1064] Adjust PTXLinker LTO logic and CLI --- src/ci/docker/nvptx-cuda/Dockerfile | 2 +- src/librustc_codegen_ssa/back/linker.rs | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ci/docker/nvptx-cuda/Dockerfile b/src/ci/docker/nvptx-cuda/Dockerfile index b52865ced3e38..c7c3ca6bc5417 100644 --- a/src/ci/docker/nvptx-cuda/Dockerfile +++ b/src/ci/docker/nvptx-cuda/Dockerfile @@ -6,7 +6,7 @@ RUN apt-get install -y --no-install-recommends \ cmake sudo gdb # FIXME: setup `ptx-linker` CI for automatic binary releases. -RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha/rust-ptx-linker.linux64.tar.gz | \ +RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.1/rust-ptx-linker.linux64.tar.gz | \ tar -xzvC /usr/bin COPY scripts/sccache.sh /scripts/ diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 5e9aeed7107ac..55b02ebe6c4d5 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -13,7 +13,7 @@ use rustc::hir::def_id::{LOCAL_CRATE, CrateNum}; use rustc::middle::dependency_format::Linkage; use rustc::session::Session; use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, - CrossLangLto}; + CrossLangLto, Lto}; use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; use serialize::{json, Encoder}; @@ -1118,14 +1118,13 @@ impl<'a> Linker for PtxLinker<'a> { } fn optimize(&mut self) { - self.cmd.arg(match self.sess.opts.optimize { - OptLevel::No => "-O0", - OptLevel::Less => "-O1", - OptLevel::Default => "-O2", - OptLevel::Aggressive => "-O3", - OptLevel::Size => "-Os", - OptLevel::SizeMin => "-Os" - }); + match self.sess.lto() { + Lto::Thin | Lto::Fat | Lto::ThinLocal => { + self.cmd.arg("-Olto"); + }, + + Lto::No => { }, + }; } fn output_filename(&mut self, path: &Path) { From 8d26c7504365127c143d540094516f0a2dd67442 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 29 Jan 2019 00:59:13 +0200 Subject: [PATCH 0405/1064] add some comments to method::probe::Candidate --- src/librustc_typeck/check/method/probe.rs | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index b849be52a9223..03a0f6233a75e 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -85,6 +85,37 @@ impl<'a, 'gcx, 'tcx> Deref for ProbeContext<'a, 'gcx, 'tcx> { #[derive(Debug)] struct Candidate<'tcx> { + // Candidates are (I'm not quite sure, but they are mostly) basically + // some metadata on top of a `ty::AssociatedItem` (without substs). + // + // However, method probing wants to be able to evaluate the predicates + // for a function with the substs applied - for example, if a function + // has `where Self: Sized`, we don't want to consider it unless `Self` + // is actually `Sized`, and similarly, return-type suggestions want + // to consider the "actual" return type. + // + // The way this is handled is through `xform_self_ty`. It contains + // the receiver type of this candidate, but `xform_self_ty`, + // `xform_ret_ty` and `kind` (which contains the predicates) have the + // generic parameters of this candidate substituted with the *same set* + // of inference variables, which acts as some weird sort of "query". + // + // When we check out a candidate, we require `xform_self_ty` to be + // a subtype of the passed-in self-type, and this equates the type + // variables in the rest of the fields. + // + // For example, if we have this candidate: + // ``` + // trait Foo { + // fn foo(&self) where Self: Sized; + // } + // ``` + // + // Then `xform_self_ty` will be `&'erased ?X` and `kind` will contain + // the predicate `?X: Sized`, so if we are evaluating `Foo` for a + // the receiver `&T`, we'll do the subtyping which will make `?X` + // get the right value, then when we evaluate the predicate we'll check + // if `T: Sized`. xform_self_ty: Ty<'tcx>, xform_ret_ty: Option>, item: ty::AssociatedItem, From 0ceb30de6d5bb82b14159f37dd66a3fd6bcd756c Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 29 Jan 2019 00:59:30 +0200 Subject: [PATCH 0406/1064] add tests to a few edge cases in method lookup These aren't fixed by this PR, but were broken in a few older attempts at it. Make sure they don't regress. --- ...-same-trait-object-with-separate-params.rs | 177 ++++++++++++++++++ ...e-trait-object-with-separate-params.stderr | 72 +++++++ .../methods/method-trait-object-with-hrtb.rs | 41 ++++ 3 files changed, 290 insertions(+) create mode 100644 src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs create mode 100644 src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr create mode 100644 src/test/ui/methods/method-trait-object-with-hrtb.rs diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs new file mode 100644 index 0000000000000..a5dae1c71cdaa --- /dev/null +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs @@ -0,0 +1,177 @@ +#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize, unsized_locals)] + +// This tests a few edge-cases around `arbitrary_self_types`. Most specifically, +// it checks that the `ObjectCandidate` you get from method matching can't +// match a trait with the same DefId as a supertrait but a bad type parameter. + +use std::marker::PhantomData; + +mod internal { + use std::ops::{CoerceUnsized, Deref, DispatchFromDyn}; + use std::marker::{PhantomData, Unsize}; + + pub struct Smaht(pub Box, pub PhantomData); + + impl Deref for Smaht { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl, U: ?Sized, MISC> CoerceUnsized> + for Smaht + {} + impl, U: ?Sized, MISC> DispatchFromDyn> + for Smaht + {} + + pub trait Foo: X {} + pub trait X { + fn foo(self: Smaht) -> T; + } + + impl X for () { + fn foo(self: Smaht) -> u32 { + 0 + } + } + + pub trait Marker {} + impl Marker for dyn Foo {} + impl X for T { + fn foo(self: Smaht) -> u64 { + 1 + } + } + + impl Deref for dyn Foo { + type Target = (); + fn deref(&self) -> &() { &() } + } + + impl Foo for () {} +} + +pub trait FinalFoo { + fn foo(&self) -> u8; +} + +impl FinalFoo for () { + fn foo(&self) -> u8 { 0 } +} + +mod nuisance_foo { + pub trait NuisanceFoo { + fn foo(self); + } + + impl NuisanceFoo for T { + fn foo(self) {} + } +} + + +fn objectcandidate_impl() { + let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This picks `>::foo` via `ObjectCandidate`. + // + // The `TraitCandidate` is not relevant because `X` is not in scope. + let z = x.foo(); + + // Observe the type of `z` is `u32` + let _seetype: () = z; //~ ERROR mismatched types + //~| expected (), found u32 +} + +fn traitcandidate_impl() { + use internal::X; + + let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This picks `>::foo` via `TraitCandidate`. + // + // The `ObjectCandidate` does not apply, as it only applies to + // `X` (and not `X`). + let z = x.foo(); + + // Observe the type of `z` is `u64` + let _seetype: () = z; //~ ERROR mismatched types + //~| expected (), found u64 +} + +fn traitcandidate_impl_with_nuisance() { + use internal::X; + use nuisance_foo::NuisanceFoo; + + let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This picks `>::foo` via `TraitCandidate`. + // + // The `ObjectCandidate` does not apply, as it only applies to + // `X` (and not `X`). + // + // The NuisanceFoo impl has the same priority as the `X` impl, + // so we get a conflict. + let z = x.foo(); //~ ERROR multiple applicable items in scope +} + + +fn neither_impl() { + let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This can't pick the `TraitCandidate` impl, because `Foo` is not + // imported. However, this also can't pick the `ObjectCandidate` + // impl, because it only applies to `X` (and not `X`). + // + // Therefore, neither of the candidates is applicable, and we pick + // the `FinalFoo` impl after another deref, which will return `u8`. + let z = x.foo(); + + // Observe the type of `z` is `u8` + let _seetype: () = z; //~ ERROR mismatched types + //~| expected (), found u8 +} + +fn both_impls() { + use internal::X; + + let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This can pick both the `TraitCandidate` and the `ObjectCandidate` impl. + // + // However, the `ObjectCandidate` is considered an "inherent candidate", + // and therefore has priority over both the `TraitCandidate` as well as + // any other "nuisance" candidate" (if present). + let z = x.foo(); + + // Observe the type of `z` is `u32` + let _seetype: () = z; //~ ERROR mismatched types + //~| expected (), found u32 +} + + +fn both_impls_with_nuisance() { + // Similar to the `both_impls` example, except with a nuisance impl to + // make sure the `ObjectCandidate` indeed has a higher priority. + + use internal::X; + use nuisance_foo::NuisanceFoo; + + let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + let z = x.foo(); + + // Observe the type of `z` is `u32` + let _seetype: () = z; //~ ERROR mismatched types + //~| expected (), found u32 +} + +fn main() { +} diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr new file mode 100644 index 0000000000000..2d8449b96de41 --- /dev/null +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -0,0 +1,72 @@ +error[E0308]: mismatched types + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:85:24 + | +LL | let _seetype: () = z; //~ ERROR mismatched types + | ^ expected (), found u32 + | + = note: expected type `()` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:102:24 + | +LL | let _seetype: () = z; //~ ERROR mismatched types + | ^ expected (), found u64 + | + = note: expected type `()` + found type `u64` + +error[E0034]: multiple applicable items in scope + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:120:15 + | +LL | let z = x.foo(); //~ ERROR multiple applicable items in scope + | ^^^ multiple `foo` found + | +note: candidate #1 is defined in an impl of the trait `internal::X` for the type `_` + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:43:9 + | +LL | fn foo(self: Smaht) -> u64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_` + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^ +note: candidate #3 is defined in the trait `FinalFoo` + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:57:5 + | +LL | fn foo(&self) -> u8; + | ^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `FinalFoo::foo(x)` instead + +error[E0308]: mismatched types + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:137:24 + | +LL | let _seetype: () = z; //~ ERROR mismatched types + | ^ expected (), found u8 + | + = note: expected type `()` + found type `u8` + +error[E0308]: mismatched types + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:155:24 + | +LL | let _seetype: () = z; //~ ERROR mismatched types + | ^ expected (), found u32 + | + = note: expected type `()` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:172:24 + | +LL | let _seetype: () = z; //~ ERROR mismatched types + | ^ expected (), found u32 + | + = note: expected type `()` + found type `u32` + +error: aborting due to 6 previous errors + +Some errors occurred: E0034, E0308. +For more information about an error, try `rustc --explain E0034`. diff --git a/src/test/ui/methods/method-trait-object-with-hrtb.rs b/src/test/ui/methods/method-trait-object-with-hrtb.rs new file mode 100644 index 0000000000000..da2f13f5a2f8a --- /dev/null +++ b/src/test/ui/methods/method-trait-object-with-hrtb.rs @@ -0,0 +1,41 @@ +// compile-pass + +// Check that method probing ObjectCandidate works in the presence of +// auto traits and/or HRTBs. + +mod internal { + pub trait MyObject<'a> { + type Output; + + fn foo(&self) -> Self::Output; + } + + impl<'a> MyObject<'a> for () { + type Output = &'a u32; + + fn foo(&self) -> Self::Output { &4 } + } +} + +fn t1(d: &dyn for<'a> internal::MyObject<'a, Output=&'a u32>) { + d.foo(); +} + +fn t2(d: &dyn internal::MyObject<'static, Output=&'static u32>) { + d.foo(); +} + +fn t3(d: &(dyn for<'a> internal::MyObject<'a, Output=&'a u32> + Sync)) { + d.foo(); +} + +fn t4(d: &(dyn internal::MyObject<'static, Output=&'static u32> + Sync)) { + d.foo(); +} + +fn main() { + t1(&()); + t2(&()); + t3(&()); + t4(&()); +} From 927d01fdb9adb7ee716af987f7074d5af5426a5d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 29 Jan 2019 01:00:42 +0200 Subject: [PATCH 0407/1064] avoid committing to autoderef in object method probing --- src/librustc_typeck/check/method/probe.rs | 29 ++++++--- .../method-probe-no-guessing-dyn-trait.rs | 59 +++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 03a0f6233a75e..be6a2ffa3eb7f 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -537,13 +537,28 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { match self_ty.value.value.sty { ty::Dynamic(ref data, ..) => { if let Some(p) = data.principal() { - let InferOk { value: instantiated_self_ty, obligations: _ } = - self.fcx.probe_instantiate_query_response( - self.span, &self.orig_steps_var_values, self_ty) - .unwrap_or_else(|_| { - span_bug!(self.span, "{:?} was applicable but now isn't?", self_ty) - }); - self.assemble_inherent_candidates_from_object(instantiated_self_ty); + // Subtle: we can't use `instantiate_query_response` here: using it will + // commit to all of the type equalities assumed by inference going through + // autoderef (see the `method-probe-no-guessing` test). + // + // However, in this code, it is OK if we end up with an object type that is + // "more general" than the object type that we are evaluating. For *every* + // object type `MY_OBJECT`, a function call that goes through a trait-ref + // of the form `::func` is a valid + // `ObjectCandidate`, and it should be discoverable "exactly" through one + // of the iterations in the autoderef loop, so there is no problem with it + // being discoverable in another one of these iterations. + // + // Using `instantiate_canonical_with_fresh_inference_vars` on our + // `Canonical>>` and then *throwing away* the + // `CanonicalVarValues` will exactly give us such a generalization - it + // will still match the original object type, but it won't pollute our + // type variables in any form, so just do that! + let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) = + self.fcx.instantiate_canonical_with_fresh_inference_vars( + self.span, &self_ty); + + self.assemble_inherent_candidates_from_object(generalized_self_ty); self.assemble_inherent_impl_candidates_for_type(p.def_id()); } } diff --git a/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs b/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs new file mode 100644 index 0000000000000..8c8165a100449 --- /dev/null +++ b/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs @@ -0,0 +1,59 @@ +// Check that method matching does not make "guesses" depending on +// Deref impls that don't eventually end up being picked. + +use std::ops::Deref; + +// An impl with less derefs will get called over an impl with more derefs, +// so `(t: Foo<_>).my_fn()` will use ` as MyTrait1>::my_fn(t)`, +// and does *not* force the `_` to equal `()`, because the Deref impl +// was *not* used. + +trait MyTrait1 { + fn my_fn(&self) {} +} + +impl MyTrait1 for Foo {} + +struct Foo(T); + +impl Deref for Foo<()> { + type Target = dyn MyTrait1 + 'static; + fn deref(&self) -> &(dyn MyTrait1 + 'static) { + panic!() + } +} + +// ...but if there is no impl with less derefs, the "guess" will be +// forced, so `(t: Bar<_>).my_fn2()` is `::my_fn2(*t)`, +// and because the deref impl is used, the `_` is forced to equal `u8`. + +trait MyTrait2 { + fn my_fn2(&self) {} +} + +impl MyTrait2 for u32 {} +struct Bar(T, u32); +impl Deref for Bar { + type Target = dyn MyTrait2 + 'static; + fn deref(&self) -> &(dyn MyTrait2 + 'static) { + &self.1 + } +} + +// actually invoke things + +fn main() { + let mut foo: Option> = None; + let mut bar: Option> = None; + let mut first_iter = true; + loop { + if !first_iter { + foo.as_ref().unwrap().my_fn(); + bar.as_ref().unwrap().my_fn2(); + break; + } + foo = Some(Foo(0)); + bar = Some(Bar(Default::default(), 0)); + first_iter = false; + } +} From 938a814e87878e2ff718935f5c7a12f120758c05 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 21 Jan 2019 18:42:04 +0100 Subject: [PATCH 0408/1064] Update stdsimd --- src/libcore/lib.rs | 17 ++--- src/libstd/lib.rs | 30 ++++----- src/libstd/tests/run-time-detect.rs | 100 ++++++++++++++++++++++++++++ src/stdsimd | 2 +- src/tools/tidy/src/pal.rs | 2 + 5 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 src/libstd/tests/run-time-detect.rs diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 825e5148fd503..b9f97155a0d91 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -219,11 +219,12 @@ pub mod alloc; mod tuple; mod unit; -// Pull in the `coresimd` crate directly into libcore. This is where all the -// architecture-specific (and vendor-specific) intrinsics are defined. AKA -// things like SIMD and such. Note that the actual source for all this lies in a -// different repository, rust-lang-nursery/stdsimd. That's why the setup here is -// a bit wonky. +// Pull in the `core_arch` crate directly into libcore. The contents of +// `core_arch` are in a different repository: rust-lang-nursery/stdsimd. +// +// `core_arch` depends on libcore, but the contents of this module are +// set up in such a way that directly pulling it here works such that the +// crate uses the this crate as its libcore. #[allow(unused_macros)] macro_rules! test_v16 { ($item:item) => {}; } #[allow(unused_macros)] @@ -238,10 +239,10 @@ macro_rules! test_v256 { ($item:item) => {}; } macro_rules! test_v512 { ($item:item) => {}; } #[allow(unused_macros)] macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } } -#[path = "../stdsimd/coresimd/mod.rs"] +#[path = "../stdsimd/crates/core_arch/src/mod.rs"] #[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)] #[unstable(feature = "stdsimd", issue = "48556")] -mod coresimd; +mod core_arch; #[stable(feature = "simd_arch", since = "1.27.0")] -pub use coresimd::arch; +pub use core_arch::arch; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index c94a33da03790..244caf28ec7cd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -358,6 +358,9 @@ pub mod prelude; // Public module declarations and re-exports #[stable(feature = "rust1", since = "1.0.0")] pub use core::any; +#[stable(feature = "simd_arch", since = "1.27.0")] +#[doc(no_inline)] +pub use core::arch; #[stable(feature = "rust1", since = "1.0.0")] pub use core::cell; #[stable(feature = "rust1", since = "1.0.0")] @@ -489,29 +492,22 @@ mod memchr; // compiler pub mod rt; -// Pull in the `stdsimd` crate directly into libstd. This is the same as -// libcore's arch/simd modules where the source of truth here is in a different -// repository, but we pull things in here manually to get it into libstd. +// Pull in the `std_detect` crate directly into libstd. The contents of +// `std_detect` are in a different repository: rust-lang-nursery/stdsimd. // -// Note that the #[cfg] here is intended to do two things. First it allows us to -// change the rustc implementation of intrinsics in stage0 by not compiling simd -// intrinsics in stage0. Next it doesn't compile anything in test mode as -// stdsimd has tons of its own tests which we don't want to run. -#[path = "../stdsimd/stdsimd/mod.rs"] +// `std_detect` depends on libstd, but the contents of this module are +// set up in such a way that directly pulling it here works such that the +// crate uses the this crate as its libstd. +#[path = "../stdsimd/crates/std_detect/src/mod.rs"] #[allow(missing_debug_implementations, missing_docs, dead_code)] #[unstable(feature = "stdsimd", issue = "48556")] #[cfg(not(test))] -mod stdsimd; - -// A "fake" module needed by the `stdsimd` module to compile, not actually -// exported though. -mod coresimd { - pub use core::arch; -} +mod std_detect; -#[stable(feature = "simd_arch", since = "1.27.0")] +#[doc(hidden)] +#[unstable(feature = "stdsimd", issue = "48556")] #[cfg(not(test))] -pub use stdsimd::arch; +pub use std_detect::detect; // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` diff --git a/src/libstd/tests/run-time-detect.rs b/src/libstd/tests/run-time-detect.rs new file mode 100644 index 0000000000000..eacce1e568211 --- /dev/null +++ b/src/libstd/tests/run-time-detect.rs @@ -0,0 +1,100 @@ +//! These tests just check that the macros are available in libstd. + +#![cfg_attr( + any( + all(target_arch = "arm", any(target_os = "linux", target_os = "android")), + all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")), + all(target_arch = "powerpc", target_os = "linux"), + all(target_arch = "powerpc64", target_os = "linux"), + ), + feature(stdsimd) +)] + +#[test] +#[cfg(all(target_arch = "arm", + any(target_os = "linux", target_os = "android")))] +fn arm_linux() { + println!("neon: {}", is_arm_feature_detected!("neon")); + println!("pmull: {}", is_arm_feature_detected!("pmull")); +} + +#[test] +#[cfg(all( + target_arch = "aarch64", + any(target_os = "linux", target_os = "android") +))] +fn aarch64_linux() { + println!("fp: {}", is_aarch64_feature_detected!("fp")); + println!("fp16: {}", is_aarch64_feature_detected!("fp16")); + println!("neon: {}", is_aarch64_feature_detected!("neon")); + println!("asimd: {}", is_aarch64_feature_detected!("asimd")); + println!("sve: {}", is_aarch64_feature_detected!("sve")); + println!("crc: {}", is_aarch64_feature_detected!("crc")); + println!("crypto: {}", is_aarch64_feature_detected!("crypto")); + println!("lse: {}", is_aarch64_feature_detected!("lse")); + println!("rdm: {}", is_aarch64_feature_detected!("rdm")); + println!("rcpc: {}", is_aarch64_feature_detected!("rcpc")); + println!("dotprod: {}", is_aarch64_feature_detected!("dotprod")); +} + +#[test] +#[cfg(all(target_arch = "powerpc", target_os = "linux"))] +fn powerpc_linux() { + println!("altivec: {}", is_powerpc_feature_detected!("altivec")); + println!("vsx: {}", is_powerpc_feature_detected!("vsx")); + println!("power8: {}", is_powerpc_feature_detected!("power8")); +} + +#[test] +#[cfg(all(target_arch = "powerpc64", target_os = "linux"))] +fn powerpc64_linux() { + println!("altivec: {}", is_powerpc64_feature_detected!("altivec")); + println!("vsx: {}", is_powerpc64_feature_detected!("vsx")); + println!("power8: {}", is_powerpc64_feature_detected!("power8")); +} + +#[test] +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn x86_all() { + println!("aes: {:?}", is_x86_feature_detected!("aes")); + println!("pcmulqdq: {:?}", is_x86_feature_detected!("pclmulqdq")); + println!("rdrand: {:?}", is_x86_feature_detected!("rdrand")); + println!("rdseed: {:?}", is_x86_feature_detected!("rdseed")); + println!("tsc: {:?}", is_x86_feature_detected!("tsc")); + println!("mmx: {:?}", is_x86_feature_detected!("mmx")); + println!("sse: {:?}", is_x86_feature_detected!("sse")); + println!("sse2: {:?}", is_x86_feature_detected!("sse2")); + println!("sse3: {:?}", is_x86_feature_detected!("sse3")); + println!("ssse3: {:?}", is_x86_feature_detected!("ssse3")); + println!("sse4.1: {:?}", is_x86_feature_detected!("sse4.1")); + println!("sse4.2: {:?}", is_x86_feature_detected!("sse4.2")); + println!("sse4a: {:?}", is_x86_feature_detected!("sse4a")); + println!("sha: {:?}", is_x86_feature_detected!("sha")); + println!("avx: {:?}", is_x86_feature_detected!("avx")); + println!("avx2: {:?}", is_x86_feature_detected!("avx2")); + println!("avx512f {:?}", is_x86_feature_detected!("avx512f")); + println!("avx512cd {:?}", is_x86_feature_detected!("avx512cd")); + println!("avx512er {:?}", is_x86_feature_detected!("avx512er")); + println!("avx512pf {:?}", is_x86_feature_detected!("avx512pf")); + println!("avx512bw {:?}", is_x86_feature_detected!("avx512bw")); + println!("avx512dq {:?}", is_x86_feature_detected!("avx512dq")); + println!("avx512vl {:?}", is_x86_feature_detected!("avx512vl")); + println!("avx512_ifma {:?}", is_x86_feature_detected!("avx512ifma")); + println!("avx512_vbmi {:?}", is_x86_feature_detected!("avx512vbmi")); + println!( + "avx512_vpopcntdq {:?}", + is_x86_feature_detected!("avx512vpopcntdq") + ); + println!("fma: {:?}", is_x86_feature_detected!("fma")); + println!("bmi1: {:?}", is_x86_feature_detected!("bmi1")); + println!("bmi2: {:?}", is_x86_feature_detected!("bmi2")); + println!("abm: {:?}", is_x86_feature_detected!("abm")); + println!("lzcnt: {:?}", is_x86_feature_detected!("lzcnt")); + println!("tbm: {:?}", is_x86_feature_detected!("tbm")); + println!("popcnt: {:?}", is_x86_feature_detected!("popcnt")); + println!("fxsr: {:?}", is_x86_feature_detected!("fxsr")); + println!("xsave: {:?}", is_x86_feature_detected!("xsave")); + println!("xsaveopt: {:?}", is_x86_feature_detected!("xsaveopt")); + println!("xsaves: {:?}", is_x86_feature_detected!("xsaves")); + println!("xsavec: {:?}", is_x86_feature_detected!("xsavec")); +} diff --git a/src/stdsimd b/src/stdsimd index 269d0ba959f70..b23541340b594 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 269d0ba959f70e9b692e528311c78b8f9601d4af +Subproject commit b23541340b5941749e5fbb1930e666bbd1375244 diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index ce5e15af2f97c..0f722945c49e6 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -52,6 +52,8 @@ const EXCEPTION_PATHS: &[&str] = &[ "src/libstd/path.rs", "src/libstd/f32.rs", "src/libstd/f64.rs", + // Integration test for platform-specific run-time feature detection: + "src/libstd/tests/run-time-detect.rs" , "src/libstd/sys_common/mod.rs", "src/libstd/sys_common/net.rs", "src/libterm", // Not sure how to make this crate portable, but test crate needs it. From a75ae00c63ad2859351e9682026462048f1cf83e Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 29 Jan 2019 17:10:22 +0530 Subject: [PATCH 0409/1064] SGX target: improve panic & exit handling --- src/libstd/sys/sgx/abi/entry.S | 20 ++++++++--------- src/libstd/sys/sgx/abi/panic.rs | 30 ++++++++++++++++--------- src/libstd/sys/sgx/abi/usercalls/mod.rs | 2 +- src/libstd/sys/sgx/mod.rs | 2 +- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index ac7f95d4eae80..9b46c2180d9a2 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -66,7 +66,7 @@ IMAGE_BASE: globvar EH_FRM_HDR_SIZE 8 .Lreentry_panic_msg: - .asciz "Re-entered panicked enclave!" + .asciz "Re-entered aborted enclave!" .Lreentry_panic_msg_end: .Lusercall_panic_msg: @@ -80,7 +80,7 @@ IMAGE_BASE: .org .+48 /* reserved bits */ .data -.Lpanicked: +.Laborted: .byte 0 /* TCS local storage section */ @@ -134,6 +134,9 @@ sgx_entry: jz .Lskip_debug_init mov %r10,%gs:tcsls_debug_panic_buf_ptr .Lskip_debug_init: +/* check for abort */ + bt $0,.Laborted(%rip) + jc .Lreentry_panic /* check if returning from usercall */ mov %gs:tcsls_last_rsp,%r11 test %r11,%r11 @@ -164,9 +167,6 @@ sgx_entry: mov %r14,%r8 mov %r15,%r9 .Lskip_init: -/* check for panic */ - bt $0,.Lpanicked(%rip) - jc .Lreentry_panic /* call into main entry point */ load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */ call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */ @@ -237,18 +237,18 @@ sgx_entry: stmxcsr (%rsp) .endm -.global panic_exit -panic_exit: +.global usercall_exit +usercall_exit: /* save registers in DEBUG mode, so that debugger can reconstruct the stack */ testb $0xff,DEBUG(%rip) jz .Lskip_save_registers push_callee_saved_registers movq %rsp,%gs:tcsls_panic_last_rsp .Lskip_save_registers: -/* set panicked bit */ - movb $1,.Lpanicked(%rip) +/* set aborted bit */ + movb $1,.Laborted(%rip) /* call usercall exit(true) */ - mov $1,%esi /* RSI = usercall() argument: panic = true */ + /* NOP: mov %rsi,%rsi */ /* RSI = usercall() argument: panic */ xor %rdx,%rdx /* RDX cleared */ movq $usercall_nr_exit,%rdi /* RDI = usercall exit */ jmp .Lexit diff --git a/src/libstd/sys/sgx/abi/panic.rs b/src/libstd/sys/sgx/abi/panic.rs index 5ace7fb3368b6..d23fa9a9ec6f9 100644 --- a/src/libstd/sys/sgx/abi/panic.rs +++ b/src/libstd/sys/sgx/abi/panic.rs @@ -1,12 +1,18 @@ +use super::usercalls::alloc::UserRef; +use cmp; use io::{self, Write}; -use slice::from_raw_parts_mut; +use mem; extern "C" { fn take_debug_panic_buf_ptr() -> *mut u8; static DEBUG: u8; } -pub(crate) struct SgxPanicOutput(Option<&'static mut [u8]>); +pub(crate) struct SgxPanicOutput(Option<&'static mut UserRef<[u8]>>); + +fn empty_user_slice() -> &'static mut UserRef<[u8]> { + unsafe { UserRef::from_raw_parts_mut(1 as *mut u8, 0) } +} impl SgxPanicOutput { pub(crate) fn new() -> Option { @@ -17,32 +23,36 @@ impl SgxPanicOutput { } } - fn init(&mut self) -> &mut &'static mut [u8] { + fn init(&mut self) -> &mut &'static mut UserRef<[u8]> { self.0.get_or_insert_with(|| unsafe { let ptr = take_debug_panic_buf_ptr(); if ptr.is_null() { - &mut [] + empty_user_slice() } else { - from_raw_parts_mut(ptr, 1024) + UserRef::from_raw_parts_mut(ptr, 1024) } }) } } impl Write for SgxPanicOutput { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.init().write(buf) + fn write(&mut self, src: &[u8]) -> io::Result { + let dst = mem::replace(self.init(), empty_user_slice()); + let written = cmp::min(src.len(), dst.len()); + dst[..written].copy_from_enclave(&src[..written]); + self.0 = Some(&mut dst[written..]); + Ok(written) } fn flush(&mut self) -> io::Result<()> { - self.init().flush() + Ok(()) } } #[no_mangle] pub extern "C" fn panic_msg(msg: &str) -> ! { let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes())); - unsafe { panic_exit(); } + unsafe { usercall_exit(true); } } -extern "C" { pub fn panic_exit() -> !; } +extern "C" { pub fn usercall_exit(panic: bool) -> !; } diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index 58903761ebe40..4e889c172ef38 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -119,7 +119,7 @@ pub unsafe fn launch_thread() -> IoResult<()> { /// Usercall `exit`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn exit(panic: bool) -> ! { - unsafe { raw::exit(panic) } + unsafe { super::panic::usercall_exit(panic) } } /// Usercall `wait`. See the ABI documentation for more information. diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index 7f8550490a199..f2593c35bed14 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -125,7 +125,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize { } pub unsafe fn abort_internal() -> ! { - abi::panic::panic_exit() + abi::panic::usercall_exit(true) } pub fn hashmap_random_keys() -> (u64, u64) { From ce279a8e53a315622d5b6b4f3332692b903c6655 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 29 Jan 2019 07:45:54 -0800 Subject: [PATCH 0410/1064] Attempt to debug 259 exit code on AppVeyor Let's try to dig in a bit more and see where this is coming from, it looks like AppVeyor is also unsure where this is coming from! --- src/ci/run.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ci/run.sh b/src/ci/run.sh index b0e1b1651055f..13c7604e5c3a1 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -121,7 +121,14 @@ fi travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then + # This `set +e` followed by capturing the return value is a temporary measure + # to help debug "error with exit 259" on AppVeyor temporarily, otherwise all + # that's needed here is the `sh` + set +e sh -x -c "$SCRIPT" + ret=$? + echo "script exited with $ret" + exit $ret else do_make() { travis_fold start "make-$1" From 899d936dee555ef2ac67e68a5017ccb0d1e9a697 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Tue, 29 Jan 2019 19:06:42 +0100 Subject: [PATCH 0411/1064] Merge NVPTX and WASM test images into `test-various` --- .../Dockerfile | 19 ++++++++++++++----- src/test/run-make/nvptx-dylib-crate/kernel.rs | 12 ++---------- 2 files changed, 16 insertions(+), 15 deletions(-) rename src/ci/docker/{wasm32-unknown => test-various}/Dockerfile (63%) diff --git a/src/ci/docker/wasm32-unknown/Dockerfile b/src/ci/docker/test-various/Dockerfile similarity index 63% rename from src/ci/docker/wasm32-unknown/Dockerfile rename to src/ci/docker/test-various/Dockerfile index 161f0c0062fa0..a5ae94262c1ca 100644 --- a/src/ci/docker/wasm32-unknown/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -13,14 +13,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ gdb \ xz-utils +# FIXME: build the `ptx-linker` instead. +RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.1/rust-ptx-linker.linux64.tar.gz | \ + tar -xzvC /usr/bin + RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \ - tar -xJ + tar -xJ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV TARGETS=wasm32-unknown-unknown - ENV RUST_CONFIGURE_ARGS \ --set build.nodejs=/node-v9.2.0-linux-x64/bin/node \ --set rust.lld @@ -31,11 +33,18 @@ ENV RUST_CONFIGURE_ARGS \ # other contexts as well ENV NO_DEBUG_ASSERTIONS=1 -ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \ +ENV WASM_TARGETS=wasm32-unknown-unknown +ENV WASM_SCRIPT python2.7 /checkout/x.py test --target $WASM_TARGETS \ src/test/run-make \ src/test/ui \ src/test/run-pass \ src/test/compile-fail \ src/test/mir-opt \ src/test/codegen-units \ - src/libcore \ + src/libcore + +ENV NVPTX_TARGETS=nvptx64-nvidia-cuda +ENV NVPTX_SCRIPT python2.7 /checkout/x.py test --target $NVPTX_TARGETS \ + src/test/run-make + +ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT diff --git a/src/test/run-make/nvptx-dylib-crate/kernel.rs b/src/test/run-make/nvptx-dylib-crate/kernel.rs index a889e23018d81..5e65cca9140b7 100644 --- a/src/test/run-make/nvptx-dylib-crate/kernel.rs +++ b/src/test/run-make/nvptx-dylib-crate/kernel.rs @@ -12,7 +12,6 @@ extern crate dep; // CHECK: .func (.param .b32 func_retval0) wrapping_external_fn // CHECK: .func (.param .b32 func_retval0) panicking_external_fn // CHECK: .func [[PANIC_HANDLER:_ZN4core9panicking5panic[a-zA-Z0-9]+]] -// CHECK: .func [[PANIC_FMT:_ZN4core9panicking9panic_fmt[a-zA-Z0-9]+]] // CHECK-LABEL: .visible .entry top_kernel( #[no_mangle] @@ -47,15 +46,8 @@ pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) { // CHECK: [[PANIC_HANDLER]] // CHECK: } -// Verify whether panic handler is present. -// CHECK: .func [[PANIC_HANDLER]]() -// CHECK: { -// CHECK: call.uni -// CHECK: [[PANIC_FMT]] -// CHECK: } - -// And finally, check the dummy panic formatter. -// CHECK: .func [[PANIC_FMT]]() +// Verify whether out dummy panic formatter has a correct body. +// CHECK: .func [[PANIC_FMT:_ZN4core9panicking9panic_fmt[a-zA-Z0-9]+]]() // CHECK: { // CHECK: trap; // CHECK: } From 3f624456e6e284f918d4e189e766e357911b49e2 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Tue, 29 Jan 2019 20:54:23 +0100 Subject: [PATCH 0412/1064] Provide PTXLinker with fallback to internal `target-cpu` --- src/ci/docker/test-various/Dockerfile | 2 +- src/librustc_codegen_ssa/back/linker.rs | 6 ++++++ src/test/run-make/nvptx-binary-crate/Makefile | 7 +++++-- src/test/run-make/nvptx-dylib-crate/kernel.rs | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile index a5ae94262c1ca..6c419e13c9f05 100644 --- a/src/ci/docker/test-various/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ xz-utils # FIXME: build the `ptx-linker` instead. -RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.1/rust-ptx-linker.linux64.tar.gz | \ +RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.2/rust-ptx-linker.linux64.tar.gz | \ tar -xzvC /usr/bin RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \ diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 55b02ebe6c4d5..249715a7b6e26 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -1132,6 +1132,12 @@ impl<'a> Linker for PtxLinker<'a> { } fn finalize(&mut self) -> Command { + // Provide the linker with fallback to internal `target-cpu`. + self.cmd.arg("--fallback-arch").arg(match self.sess.opts.cg.target_cpu { + Some(ref s) => s, + None => &self.sess.target.target.options.cpu + }); + ::std::mem::replace(&mut self.cmd, Command::new("")) } diff --git a/src/test/run-make/nvptx-binary-crate/Makefile b/src/test/run-make/nvptx-binary-crate/Makefile index 4c22dae265c14..2c211b5c78507 100644 --- a/src/test/run-make/nvptx-binary-crate/Makefile +++ b/src/test/run-make/nvptx-binary-crate/Makefile @@ -2,8 +2,11 @@ ifeq ($(TARGET),nvptx64-nvidia-cuda) all: - $(RUSTC) main.rs -Clink-arg=--arch=sm_60 --crate-type="bin" -O --target $(TARGET) - FileCheck main.rs --input-file $(TMPDIR)/main.ptx + $(RUSTC) main.rs --crate-type="bin" --target $(TARGET) -O -C link-arg=--arch=sm_60 -o $(TMPDIR)/main.link_arg.ptx + $(RUSTC) main.rs --crate-type="bin" --target $(TARGET) -O -C target-cpu=sm_60 -o $(TMPDIR)/main.target_cpu.ptx + + FileCheck main.rs --input-file $(TMPDIR)/main.link_arg.ptx + FileCheck main.rs --input-file $(TMPDIR)/main.target_cpu.ptx else all: endif diff --git a/src/test/run-make/nvptx-dylib-crate/kernel.rs b/src/test/run-make/nvptx-dylib-crate/kernel.rs index 5e65cca9140b7..63fd6b063dd8c 100644 --- a/src/test/run-make/nvptx-dylib-crate/kernel.rs +++ b/src/test/run-make/nvptx-dylib-crate/kernel.rs @@ -5,7 +5,7 @@ extern crate dep; // Verify the default CUDA arch. -// CHECK: .target sm_20 +// CHECK: .target sm_30 // CHECK: .address_size 64 // Make sure declarations are there. From 49931fda56dc6268ba3c104b64768f551cfc4636 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Tue, 29 Jan 2019 21:00:07 +0100 Subject: [PATCH 0413/1064] Use correct CI test image for WASM and NVPTX --- .travis.yml | 4 +--- src/ci/docker/nvptx-cuda/Dockerfile | 18 ------------------ 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 src/ci/docker/nvptx-cuda/Dockerfile diff --git a/.travis.yml b/.travis.yml index a8e1bfbbfa93a..7985b6c0e191f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -168,7 +168,7 @@ matrix: if: branch = auto - env: IMAGE=i686-gnu-nopt if: branch = auto - - env: IMAGE=wasm32-unknown + - env: IMAGE=test-various if: branch = auto - env: IMAGE=x86_64-gnu if: branch = auto @@ -186,8 +186,6 @@ matrix: if: branch = auto - env: IMAGE=mingw-check if: type = pull_request OR branch = auto - - env: IMAGE=nvptx-cuda - if: branch = auto - stage: publish toolstate if: branch = master AND type = push diff --git a/src/ci/docker/nvptx-cuda/Dockerfile b/src/ci/docker/nvptx-cuda/Dockerfile deleted file mode 100644 index c7c3ca6bc5417..0000000000000 --- a/src/ci/docker/nvptx-cuda/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update -RUN apt-get install -y --no-install-recommends \ - g++ make file curl ca-certificates python git \ - cmake sudo gdb - -# FIXME: setup `ptx-linker` CI for automatic binary releases. -RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.1/rust-ptx-linker.linux64.tar.gz | \ - tar -xzvC /usr/bin - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -ENV TARGETS=nvptx64-nvidia-cuda - -ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \ - src/test/run-make From 2fe3b3b486b3b5e1ec1e6ad259d8840b88b7c77a Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 11 Dec 2018 00:40:39 +0100 Subject: [PATCH 0414/1064] Implement Weak::{strong_count, weak_count} --- src/liballoc/rc.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++ src/liballoc/sync.rs | 19 ++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index c0dc010fe59a5..7ee05eaff91a0 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1284,6 +1284,40 @@ impl Weak { } } + /// Gets the number of strong (`Rc`) pointers pointing to this value. + /// + /// If `self` was created using [`Weak::new`], this will return 0. + /// + /// [`Weak::new`]: #method.new + #[unstable(feature = "weak_counts", issue = "0")] + pub fn strong_count(&self) -> usize { + if let Some(inner) = self.inner() { + inner.strong() + } else { + 0 + } + } + + /// Gets the number of `Weak` pointers pointing to this value. + /// + /// If `self` was created using [`Weak::new`], this will return 0. If not, + /// the returned value is at least 1, since `self` still points to the + /// value. + /// + /// [`Weak::new`]: #method.new + #[unstable(feature = "weak_counts", issue = "0")] + pub fn weak_count(&self) -> usize { + if let Some(inner) = self.inner() { + if inner.strong() > 0 { + inner.weak() - 1 // subtract the implicit weak ptr + } else { + inner.weak() + } + } else { + 0 + } + } + /// Return `None` when the pointer is dangling and there is no allocated `RcBox`, /// i.e., this `Weak` was created by `Weak::new` #[inline] @@ -1622,6 +1656,33 @@ mod tests { drop(c); } + #[test] + fn weak_counts() { + assert_eq!(Weak::weak_count(&Weak::::new()), 0); + assert_eq!(Weak::strong_count(&Weak::::new()), 0); + + let a = Rc::new(0); + let w = Rc::downgrade(&a); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), 1); + let w2 = w.clone(); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), 2); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), 2); + drop(w); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), 1); + let a2 = a.clone(); + assert_eq!(Weak::strong_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), 1); + drop(a2); + drop(a); + assert_eq!(Weak::strong_count(&w2), 0); + assert_eq!(Weak::weak_count(&w2), 1); + drop(w2); + } + #[test] fn try_unwrap() { let x = Rc::new(3); diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 390a079165054..fd3519dee18cf 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1117,6 +1117,25 @@ impl Weak { } } + /// Gets the number of strong (`Arc`) pointers pointing to this value. + /// + /// If `self` was created using [`Weak::new`], this will return 0. + /// + /// [`Weak::new`]: #method.new + #[unstable(feature = "weak_counts", issue = "0")] + pub fn strong_count(&self) -> usize { + if let Some(inner) = self.inner() { + inner.strong.load(SeqCst) + } else { + 0 + } + } + + // Due to the implicit weak pointer added when any strong pointers are + // around, we cannot implement `weak_count` correctly since it necessarily + // requires accessing the strong count and weak count in an unsynchronized + // fashion. + /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`, /// i.e., this `Weak` was created by `Weak::new` #[inline] From 7e0edb39baa02c58c373f05014ffd8e3058c93ad Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Jan 2019 23:35:52 +0100 Subject: [PATCH 0415/1064] Implement a slightly racy `sync::Weak::weak_count` --- src/liballoc/sync.rs | 75 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index fd3519dee18cf..b065bd60c60a7 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -11,7 +11,7 @@ use core::sync::atomic; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; use core::borrow; use core::fmt; -use core::cmp::Ordering; +use core::cmp::{self, Ordering}; use core::intrinsics::abort; use core::mem::{self, align_of_val, size_of_val}; use core::ops::{Deref, Receiver}; @@ -1131,10 +1131,48 @@ impl Weak { } } - // Due to the implicit weak pointer added when any strong pointers are - // around, we cannot implement `weak_count` correctly since it necessarily - // requires accessing the strong count and weak count in an unsynchronized - // fashion. + /// Gets an approximation of the number of `Weak` pointers pointing to this + /// value. + /// + /// If `self` was created using [`Weak::new`], this will return 0. If not, + /// the returned value is at least 1, since `self` still points to the + /// value. + /// + /// # Accuracy + /// + /// Due to implementation details, the returned value can be off by 1 in + /// either direction when other threads are manipulating any `Arc`s or + /// `Weak`s pointing to the same value. + /// + /// [`Weak::new`]: #method.new + #[unstable(feature = "weak_counts", issue = "0")] + pub fn weak_count(&self) -> usize { + // Due to the implicit weak pointer added when any strong pointers are + // around, we cannot implement `weak_count` correctly since it + // necessarily requires accessing the strong count and weak count in an + // unsynchronized fashion. So this version is a bit racy. + if let Some(inner) = self.inner() { + let strong = inner.strong.load(SeqCst); + let weak = inner.weak.load(SeqCst); + if strong == 0 { + // If the last `Arc` has *just* been dropped, it might not yet + // have removed the implicit weak count, so the value we get + // here might be 1 too high. + weak + } else { + // As long as there's still at least 1 `Arc` around, subtract + // the implicit weak pointer. + // Note that the last `Arc` might get dropped between the 2 + // loads we do above, removing the implicit weak pointer. This + // means that the value might be 1 too low here. In order to not + // return 0 here (which would happen if we're the only weak + // pointer), we guard against that specifically. + cmp::max(1, weak - 1) + } + } else { + 0 + } + } /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`, /// i.e., this `Weak` was created by `Weak::new` @@ -1655,6 +1693,33 @@ mod tests { assert!(Arc::get_mut(&mut x).is_none()); } + #[test] + fn weak_counts() { + assert_eq!(Weak::weak_count(&Weak::::new()), 0); + assert_eq!(Weak::strong_count(&Weak::::new()), 0); + + let a = Arc::new(0); + let w = Arc::downgrade(&a); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), 1); + let w2 = w.clone(); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), 2); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), 2); + drop(w); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), 1); + let a2 = a.clone(); + assert_eq!(Weak::strong_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), 1); + drop(a2); + drop(a); + assert_eq!(Weak::strong_count(&w2), 0); + assert_eq!(Weak::weak_count(&w2), 1); + drop(w2); + } + #[test] fn try_unwrap() { let x = Arc::new(3); From 0c2bf6fe2a0257712ea52a17e396b00cfd92b25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 11:47:56 +0100 Subject: [PATCH 0416/1064] Add an ensure() method to TyCtxt used to ensure queries are run --- src/librustc/hir/check_attr.rs | 3 +-- src/librustc/middle/intrinsicck.rs | 4 ++-- src/librustc/middle/liveness.rs | 4 ++-- src/librustc/middle/stability.rs | 3 +-- src/librustc/ty/query/plumbing.rs | 33 +++++++++++++++++---------- src/librustc/ty/util.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_passes/loops.rs | 3 +-- src/librustc_privacy/lib.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 5 ++-- src/librustc_typeck/coherence/mod.rs | 6 ++--- src/librustc_typeck/collect.rs | 3 +-- 12 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index df111b2be319f..a2947fa0d8c1f 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -7,7 +7,6 @@ use ty::TyCtxt; use ty::query::Providers; -use ty::query::queries; use hir; use hir::def_id::DefId; @@ -355,7 +354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_attrs::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index a0f7954eb0c55..29d3713900ad9 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -2,7 +2,7 @@ use hir::def::Def; use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; -use ty::query::{Providers, queries}; +use ty::query::Providers; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_data_structures::indexed_vec::Idx; @@ -12,7 +12,7 @@ use hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_intrinsics::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 4ef8e1a0cf95b..0724d3a262d28 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -100,7 +100,7 @@ use self::VarKind::*; use hir::def::*; use hir::Node; use ty::{self, TyCtxt}; -use ty::query::{Providers, queries}; +use ty::query::Providers; use lint; use errors::Applicability; use util::nodemap::{NodeMap, HirIdMap, HirIdSet}; @@ -187,7 +187,7 @@ fn check_mod_liveness<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_liveness::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_liveness(tcx.hir().local_def_id(module)); } tcx.sess.abort_if_errors(); } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 918e286c435bc..8b8318db20597 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -9,7 +9,6 @@ use hir::def::Def; use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use ty::query::Providers; -use ty::query::queries; use middle::privacy::AccessLevels; use session::{DiagnosticMessageId, Session}; use syntax::symbol::Symbol; @@ -458,7 +457,7 @@ impl<'a, 'tcx> Index<'tcx> { pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_unstable_api_usage::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_unstable_api_usage(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e777c883c3787..783a4646540a0 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -969,20 +969,20 @@ macro_rules! define_queries_inner { fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value { handle_cycle_error!([$($modifiers)*][tcx]) } + })* + + #[derive(Copy, Clone)] + pub struct TyCtxtEnsure<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { + pub tcx: TyCtxt<'a, 'gcx, 'tcx>, } - impl<'a, $tcx, 'lcx> queries::$name<$tcx> { - /// Ensure that either this query has all green inputs or been executed. - /// Executing query::ensure(D) is considered a read of the dep-node D. - /// - /// This function is particularly useful when executing passes for their - /// side-effects -- e.g., in order to report errors for erroneous programs. - /// - /// Note: The optimization is only available during incr. comp. - pub fn ensure(tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> () { - tcx.ensure_query::>(key); - } - })* + impl<'a, $tcx, 'lcx> TyCtxtEnsure<'a, $tcx, 'lcx> { + $($(#[$attr])* + #[inline(always)] + pub fn $name(self, key: $K) { + self.tcx.ensure_query::>(key) + })* + } #[derive(Copy, Clone)] pub struct TyCtxtAt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { @@ -999,6 +999,15 @@ macro_rules! define_queries_inner { } impl<'a, $tcx, 'lcx> TyCtxt<'a, $tcx, 'lcx> { + /// Return a transparent wrapper for `TyCtxt` which ensures queries + /// are executed instead of returing their result + #[inline(always)] + pub fn ensure(self) -> TyCtxtEnsure<'a, $tcx, 'lcx> { + TyCtxtEnsure { + tcx: self, + } + } + /// Return a transparent wrapper for `TyCtxt` which uses /// `span` as the location of queries performed through it. #[inline(always)] diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 75fc0f716a2f6..2fe47b2f032f8 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -402,7 +402,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return None; }; - ty::query::queries::coherent_trait::ensure(self, drop_trait); + self.ensure().coherent_trait(drop_trait); let mut dtor_did = None; let ty = self.type_of(adt_did); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 5c11d622d0a8a..f177f3661accb 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -121,7 +121,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // Note that `mir_validated` is a "stealable" result; the // thief, `optimized_mir()`, forces borrowck, so we know that // is not yet stolen. - ty::query::queries::mir_validated::ensure(tcx, owner_def_id); + tcx.ensure().mir_validated(owner_def_id); // option dance because you can't capture an uninitialized variable // by mut-ref. diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 0dcfc72d10bc0..f05a7be7d7513 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -3,7 +3,6 @@ use self::Context::*; use rustc::session::Session; use rustc::ty::query::Providers; -use rustc::ty::query::queries; use rustc::ty::TyCtxt; use rustc::hir::def_id::DefId; use rustc::hir::map::Map; @@ -48,7 +47,7 @@ struct CheckLoopVisitor<'a, 'hir: 'a> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_loops::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_loops(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index dcbb9ff4a7576..7f2b82f7e0155 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -22,7 +22,7 @@ use rustc::lint; use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::ty::{self, TyCtxt, Ty, TraitRef, TypeFoldable, GenericParamDefKind}; use rustc::ty::fold::TypeVisitor; -use rustc::ty::query::{Providers, queries}; +use rustc::ty::query::Providers; use rustc::ty::subst::Substs; use rustc::util::nodemap::NodeSet; use rustc_data_structures::fx::FxHashSet; @@ -1722,7 +1722,7 @@ fn privacy_access_levels<'tcx>( let krate = tcx.hir().krate(); for &module in krate.modules.keys() { - queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); } // Build up a set of all exported items in the AST. This is a set of all diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c94713980d8c0..85bed301d1be8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -109,7 +109,6 @@ use rustc::ty::{ use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::fold::TypeFoldable; use rustc::ty::query::Providers; -use rustc::ty::query::queries; use rustc::ty::subst::{UnpackedKind, Subst, Substs, UserSelfTy, UserSubsts}; use rustc::ty::util::{Representability, IntTypeExt, Discr}; use rustc::ty::layout::VariantIdx; @@ -703,7 +702,7 @@ pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorRe pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { for &module in tcx.hir().krate().modules.keys() { - queries::check_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module)); } }) } @@ -722,7 +721,7 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum debug_assert!(crate_num == LOCAL_CRATE); Ok(tcx.sess.track_errors(|| { tcx.par_body_owners(|body_owner_def_id| { - ty::query::queries::typeck_tables_of::ensure(tcx, body_owner_def_id); + tcx.ensure().typeck_tables_of(body_owner_def_id); }); })?) } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 8053ed130e91b..13d24026ba3bc 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -137,15 +137,15 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &trait_def_id in tcx.hir().krate().trait_impls.keys() { - ty::query::queries::coherent_trait::ensure(tcx, trait_def_id); + tcx.ensure().coherent_trait(trait_def_id); } unsafety::check(tcx); orphan::check(tcx); // these queries are executed for side-effects (error reporting): - ty::query::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE); - ty::query::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE); + tcx.ensure().crate_inherent_impls(LOCAL_CRATE); + tcx.ensure().crate_inherent_impls_overlap_check(LOCAL_CRATE); } /// Overlap: No two impls for the same trait are implemented for the diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ade84faae8dbd..6cfb1ceaa12ae 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -23,7 +23,6 @@ use middle::resolve_lifetime as rl; use middle::weak_lang_items; use rustc::mir::mono::Linkage; use rustc::ty::query::Providers; -use rustc::ty::query::queries; use rustc::ty::subst::Substs; use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; @@ -58,7 +57,7 @@ struct OnlySelfBounds(bool); pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { - queries::collect_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module)); + tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module)); } } From 73b8f1d90ce75bea8e89b3572ff1e9943efcf436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 11:53:42 +0100 Subject: [PATCH 0417/1064] Optimize match checking --- src/librustc_mir/hair/pattern/check_match.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 10a4575d81220..8d10227cd5901 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -28,22 +28,10 @@ use syntax::ast; use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } - -impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.hir()) - } - - fn visit_body(&mut self, body: &'tcx hir::Body) { - intravisit::walk_body(self, body); - let def_id = self.tcx.hir().body_owner_def_id(body.id()); - let _ = self.tcx.check_match(def_id); - } -} - pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir().krate().visit_all_item_likes(&mut OuterVisitor { tcx }.as_deep_visitor()); + for def_id in tcx.body_owners() { + tcx.ensure().check_match(def_id); + } tcx.sess.abort_if_errors(); } From 2a4eeba70f6c9017cf34936f9a49e05c31b575b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 12:18:32 +0100 Subject: [PATCH 0418/1064] Make impl_wf_check incremental --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/query/config.rs | 9 +++++++++ src/librustc/ty/query/mod.rs | 2 ++ src/librustc/ty/query/plumbing.rs | 1 + src/librustc_typeck/impl_wf_check.rs | 19 ++++++++++++++++++- src/librustc_typeck/lib.rs | 1 + 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 05f331145afe2..cda469657ed87 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -479,6 +479,7 @@ define_dep_nodes!( <'tcx> [] CheckModPrivacy(DefId), [] CheckModIntrinsics(DefId), [] CheckModLiveness(DefId), + [] CheckModImplWf(DefId), [] CollectModItemTypes(DefId), [] Reachability, diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index c4757574ffe4d..68dd5d533c8d2 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -136,6 +136,15 @@ impl<'tcx> QueryDescription<'tcx> for queries::check_mod_liveness<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::check_mod_impl_wf<'tcx> { + fn describe( + tcx: TyCtxt<'_, '_, '_>, + key: DefId, + ) -> Cow<'static, str> { + format!("checking that impls are well-formed in {}", key.describe_as_module(tcx)).into() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::collect_mod_item_types<'tcx> { fn describe( tcx: TyCtxt<'_, '_, '_>, diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 195bec11ee570..d4884e712b860 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -270,6 +270,8 @@ define_queries! { <'tcx> [] fn check_mod_liveness: CheckModLiveness(DefId) -> (), + [] fn check_mod_impl_wf: CheckModImplWf(DefId) -> (), + [] fn collect_mod_item_types: CollectModItemTypes(DefId) -> (), /// Caches CoerceUnsized kinds for impls on custom types. diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 783a4646540a0..26762f5d1f783 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1260,6 +1260,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CheckModPrivacy => { force!(check_mod_privacy, def_id!()); } DepKind::CheckModIntrinsics => { force!(check_mod_intrinsics, def_id!()); } DepKind::CheckModLiveness => { force!(check_mod_liveness, def_id!()); } + DepKind::CheckModImplWf => { force!(check_mod_impl_wf, def_id!()); } DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); } DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); } DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); } diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index d5e15b28fb04b..07f5fca6fe68e 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -13,6 +13,7 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; +use rustc::ty::query::Providers; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -52,7 +53,23 @@ pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. - tcx.hir().krate().visit_all_item_likes(&mut ImplWfCheck { tcx }); + for &module in tcx.hir().krate().modules.keys() { + tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id(module)); + } +} + +fn check_mod_impl_wf<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { + tcx.hir().visit_item_likes_in_module( + module_def_id, + &mut ImplWfCheck { tcx } + ); +} + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + check_mod_impl_wf, + ..*providers + }; } struct ImplWfCheck<'a, 'tcx: 'a> { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 5149f460baca0..b51c290039938 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -318,6 +318,7 @@ pub fn provide(providers: &mut Providers) { check::provide(providers); variance::provide(providers); outlives::provide(providers); + impl_wf_check::provide(providers); } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) From eb8fb5342528907222edbf6fcb06dd624a395ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 12:19:03 +0100 Subject: [PATCH 0419/1064] Use an ItemLikeVisitor for CheckTypeWellFormedVisitor --- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 23 ++++++++--------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 85bed301d1be8..48475b3dcb802 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -695,7 +695,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); - tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor()); + tcx.hir().krate().visit_all_item_likes(&mut visit); }) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 6cae8d6fc5b94..97881708b0a07 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -14,7 +14,7 @@ use syntax::feature_gate::{self, GateIssue}; use syntax_pos::Span; use errors::{DiagnosticBuilder, DiagnosticId}; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; /// Helper type of a temporary returned by `.for_item(...)`. @@ -1015,30 +1015,23 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { - NestedVisitorMap::None - } - - fn visit_item(&mut self, i: &hir::Item) { +impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'a, 'tcx> { + fn visit_item(&mut self, i: &'tcx hir::Item) { debug!("visit_item: {:?}", i); let def_id = self.tcx.hir().local_def_id(i.id); - ty::query::queries::check_item_well_formed::ensure(self.tcx, def_id); - intravisit::walk_item(self, i); + self.tcx.ensure().check_item_well_formed(def_id); } - fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { debug!("visit_trait_item: {:?}", trait_item); let def_id = self.tcx.hir().local_def_id(trait_item.id); - ty::query::queries::check_trait_item_well_formed::ensure(self.tcx, def_id); - intravisit::walk_trait_item(self, trait_item) + self.tcx.ensure().check_trait_item_well_formed(def_id); } - fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) { + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { debug!("visit_impl_item: {:?}", impl_item); let def_id = self.tcx.hir().local_def_id(impl_item.id); - ty::query::queries::check_impl_item_well_formed::ensure(self.tcx, def_id); - intravisit::walk_impl_item(self, impl_item) + self.tcx.ensure().check_impl_item_well_formed(def_id); } } From 8d7606078501d4827f39a9b1f9a00536e7fe1f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 15:06:51 +0100 Subject: [PATCH 0420/1064] Add some time statements --- src/librustc_typeck/coherence/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 13d24026ba3bc..853c4c85d3f3b 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -9,6 +9,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::traits; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::ty::query::Providers; +use rustc::util::common::time; use syntax::ast; @@ -132,7 +133,9 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { for &impl_id in impls { check_impl_overlap(tcx, impl_id); } - builtin::check_trait(tcx, def_id); + use rustc::util::common::time; + time(tcx.sess, "builtin::check_trait checking", || + builtin::check_trait(tcx, def_id)); } pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { @@ -140,8 +143,8 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.ensure().coherent_trait(trait_def_id); } - unsafety::check(tcx); - orphan::check(tcx); + time(tcx.sess, "unsafety checking", || unsafety::check(tcx)); + time(tcx.sess, "orphan checking", || orphan::check(tcx)); // these queries are executed for side-effects (error reporting): tcx.ensure().crate_inherent_impls(LOCAL_CRATE); From edf0cac94ba9f192acecd5ba3316a048342847a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 15:07:02 +0100 Subject: [PATCH 0421/1064] Use ensure for borrowck --- src/librustc_borrowck/borrowck/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index f177f3661accb..e40c2b4508922 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -57,7 +57,7 @@ pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.par_body_owners(|body_owner_def_id| { - tcx.borrowck(body_owner_def_id); + tcx.ensure().borrowck(body_owner_def_id); }); } From 219f818c1be77801f8c1f2e0c9fc74d4ab64be0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 15:26:49 +0100 Subject: [PATCH 0422/1064] Skip some test passes --- src/librustc_typeck/lib.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b51c290039938..d5e870bb28d75 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -334,10 +334,12 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) })?; - tcx.sess.track_errors(|| { - time(tcx.sess, "outlives testing", || - outlives::test::test_inferred_outlives(tcx)); - })?; + if tcx.features().rustc_attrs { + tcx.sess.track_errors(|| { + time(tcx.sess, "outlives testing", || + outlives::test::test_inferred_outlives(tcx)); + })?; + } tcx.sess.track_errors(|| { time(tcx.sess, "impl wf inference", || @@ -349,10 +351,12 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) coherence::check_coherence(tcx)); })?; - tcx.sess.track_errors(|| { - time(tcx.sess, "variance testing", || - variance::test::test_variance(tcx)); - })?; + if tcx.features().rustc_attrs { + tcx.sess.track_errors(|| { + time(tcx.sess, "variance testing", || + variance::test::test_variance(tcx)); + })?; + } time(tcx.sess, "wf checking", || check::check_wf_new(tcx))?; From 9bdf054dc8c6ef9069a42791915e7f230246b4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 15:58:39 +0100 Subject: [PATCH 0423/1064] Only store the result of mir_borrowck for closures --- src/librustc/ty/query/config.rs | 47 ++++++++++++++------------ src/librustc/ty/query/on_disk_cache.rs | 4 +-- src/librustc/ty/query/plumbing.rs | 4 +-- src/librustc_mir/transform/mod.rs | 4 +-- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 68dd5d533c8d2..495cce4d2feac 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -51,7 +51,7 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> Cow<'static, str>; #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { false } @@ -387,7 +387,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { } #[inline] - fn cache_on_disk(_key: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _key: Self::Key) -> bool { true } @@ -407,7 +407,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> { } #[inline] - fn cache_on_disk(_key: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _key: Self::Key) -> bool { true } @@ -431,7 +431,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> { } #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { true } @@ -505,7 +505,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta } #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { true } @@ -539,7 +539,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> } #[inline] - fn cache_on_disk(_: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, _: Self::Key) -> bool { true } @@ -877,7 +877,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { #[inline] - fn cache_on_disk(def_id: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { def_id.is_local() } @@ -894,7 +894,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { #[inline] - fn cache_on_disk(def_id: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { def_id.is_local() } @@ -933,7 +933,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> { #[inline] - fn cache_on_disk(def_id: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { def_id.is_local() } @@ -983,10 +983,10 @@ impl<'tcx> QueryDescription<'tcx> for queries::backend_optimization_level<'tcx> } macro_rules! impl_disk_cacheable_query( - ($query_name:ident, |$key:tt| $cond:expr) => { + ($query_name:ident, |$tcx:tt, $key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { #[inline] - fn cache_on_disk($key: Self::Key) -> bool { + fn cache_on_disk($tcx: TyCtxt<'_, 'tcx, 'tcx>, $key: Self::Key) -> bool { $cond } @@ -1000,14 +1000,17 @@ macro_rules! impl_disk_cacheable_query( } ); -impl_disk_cacheable_query!(unsafety_check_result, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(def_symbol_name, |_| true); -impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local()); -impl_disk_cacheable_query!(codegen_fn_attrs, |_| true); -impl_disk_cacheable_query!(specialization_graph_of, |_| true); +impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| { + def_id.is_local() && tcx.is_closure(def_id) +}); + +impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(mir_const_qualif, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(def_symbol_name, |_, _| true); +impl_disk_cacheable_query!(type_of, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local()); +impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true); +impl_disk_cacheable_query!(specialization_graph_of, |_, _| true); diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index a674e942b3893..a3f49de0d078b 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -230,7 +230,7 @@ impl<'sess> OnDiskCache<'sess> { assert!(cache.active.is_empty()); for (key, entry) in cache.results.iter() { use ty::query::config::QueryDescription; - if const_eval::cache_on_disk(key.clone()) { + if const_eval::cache_on_disk(tcx, key.clone()) { if let Ok(ref value) = entry.value { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); @@ -1086,7 +1086,7 @@ fn encode_query_results<'enc, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let map = Q::query_cache(tcx).borrow(); assert!(map.active.is_empty()); for (key, entry) in map.results.iter() { - if Q::cache_on_disk(key.clone()) { + if Q::cache_on_disk(tcx, key.clone()) { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); // Record position of the cache entry diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 26762f5d1f783..69bff8d25b024 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -434,7 +434,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug_assert!(self.dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache - let result = if Q::cache_on_disk(key.clone()) && + let result = if Q::cache_on_disk(self.global_tcx(), key.clone()) && self.sess.opts.debugging_opts.incremental_queries { let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index); @@ -1443,7 +1443,7 @@ macro_rules! impl_load_from_cache { match self.kind { $(DepKind::$dep_kind => { let def_id = self.extract_def_id(tcx).unwrap(); - queries::$query_name::cache_on_disk(def_id) + queries::$query_name::cache_on_disk(tcx.global_tcx(), def_id) })* _ => false } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 5a80a5fdab501..6ba35052c8aad 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -228,10 +228,10 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> { // (Mir-)Borrowck uses `mir_validated`, so we have to force it to // execute before we can steal. - let _ = tcx.mir_borrowck(def_id); + tcx.ensure().mir_borrowck(def_id); if tcx.use_ast_borrowck() { - let _ = tcx.borrowck(def_id); + tcx.ensure().borrowck(def_id); } let mut mir = tcx.mir_validated(def_id).steal(); From 0e2ad51e3653269ecadecaa73e31df62b7936f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 28 Jan 2019 22:28:44 +0100 Subject: [PATCH 0424/1064] Fix tests --- .../ui/feature-gates/feature-gate-rustc-attrs-1.rs | 2 +- .../feature-gates/feature-gate-rustc-attrs-1.stderr | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs index 2b23388fdc96d..f7ff3eb3ac9ff 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs @@ -5,4 +5,4 @@ #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable -fn main() {} //~ ERROR [] +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr index 31e24f5b99f1e..2b90699384b48 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr @@ -14,13 +14,6 @@ LL | #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for ru | = help: add #![feature(rustc_attrs)] to the crate attributes to enable -error[E0208]: [] - --> $DIR/feature-gate-rustc-attrs-1.rs:8:1 - | -LL | fn main() {} //~ ERROR [] - | ^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0208, E0658. -For more information about an error, try `rustc --explain E0208`. +For more information about this error, try `rustc --explain E0658`. From b664341d917cafade5a2470579a4c122fdcf941b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 29 Jan 2019 21:58:17 +0100 Subject: [PATCH 0425/1064] Make weak_count return an Option --- src/liballoc/rc.rs | 26 ++++++++++++-------------- src/liballoc/sync.rs | 22 ++++++++++------------ 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 7ee05eaff91a0..72b43b5d6adff 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1300,22 +1300,20 @@ impl Weak { /// Gets the number of `Weak` pointers pointing to this value. /// - /// If `self` was created using [`Weak::new`], this will return 0. If not, - /// the returned value is at least 1, since `self` still points to the + /// If `self` was created using [`Weak::new`], this will return `None`. If + /// not, the returned value is at least 1, since `self` still points to the /// value. /// /// [`Weak::new`]: #method.new #[unstable(feature = "weak_counts", issue = "0")] - pub fn weak_count(&self) -> usize { - if let Some(inner) = self.inner() { + pub fn weak_count(&self) -> Option { + self.inner().map(|inner| { if inner.strong() > 0 { inner.weak() - 1 // subtract the implicit weak ptr } else { inner.weak() } - } else { - 0 - } + }) } /// Return `None` when the pointer is dangling and there is no allocated `RcBox`, @@ -1658,28 +1656,28 @@ mod tests { #[test] fn weak_counts() { - assert_eq!(Weak::weak_count(&Weak::::new()), 0); + assert_eq!(Weak::weak_count(&Weak::::new()), None); assert_eq!(Weak::strong_count(&Weak::::new()), 0); let a = Rc::new(0); let w = Rc::downgrade(&a); assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(1)); let w2 = w.clone(); assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), 2); + assert_eq!(Weak::weak_count(&w), Some(2)); assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), Some(2)); drop(w); assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); let a2 = a.clone(); assert_eq!(Weak::strong_count(&w2), 2); - assert_eq!(Weak::weak_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); drop(a2); drop(a); assert_eq!(Weak::strong_count(&w2), 0); - assert_eq!(Weak::weak_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); drop(w2); } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index b065bd60c60a7..777851e192501 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1146,12 +1146,12 @@ impl Weak { /// /// [`Weak::new`]: #method.new #[unstable(feature = "weak_counts", issue = "0")] - pub fn weak_count(&self) -> usize { + pub fn weak_count(&self) -> Option { // Due to the implicit weak pointer added when any strong pointers are // around, we cannot implement `weak_count` correctly since it // necessarily requires accessing the strong count and weak count in an // unsynchronized fashion. So this version is a bit racy. - if let Some(inner) = self.inner() { + self.inner().map(|inner| { let strong = inner.strong.load(SeqCst); let weak = inner.weak.load(SeqCst); if strong == 0 { @@ -1169,9 +1169,7 @@ impl Weak { // pointer), we guard against that specifically. cmp::max(1, weak - 1) } - } else { - 0 - } + }) } /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`, @@ -1695,28 +1693,28 @@ mod tests { #[test] fn weak_counts() { - assert_eq!(Weak::weak_count(&Weak::::new()), 0); + assert_eq!(Weak::weak_count(&Weak::::new()), None); assert_eq!(Weak::strong_count(&Weak::::new()), 0); let a = Arc::new(0); let w = Arc::downgrade(&a); assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(1)); let w2 = w.clone(); assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), 2); + assert_eq!(Weak::weak_count(&w), Some(2)); assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), Some(2)); drop(w); assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); let a2 = a.clone(); assert_eq!(Weak::strong_count(&w2), 2); - assert_eq!(Weak::weak_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); drop(a2); drop(a); assert_eq!(Weak::strong_count(&w2), 0); - assert_eq!(Weak::weak_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); drop(w2); } From 4a4186e4d1168f9faf3df019596bcf87f0a4dc2b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 29 Jan 2019 22:16:43 +0100 Subject: [PATCH 0426/1064] Use LLVM intrinsics for saturating add/sub --- src/libcore/intrinsics.rs | 13 ++++++++ src/libcore/num/mod.rs | 20 ++++++++++++ src/librustc_codegen_llvm/context.rs | 24 ++++++++++++++ src/librustc_codegen_llvm/intrinsic.rs | 44 ++++++++++++++++++++++++-- src/librustc_typeck/check/intrinsic.rs | 3 ++ 5 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index e66a846537043..e927ed40d7fb7 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1493,6 +1493,19 @@ extern "rust-intrinsic" { /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul) pub fn overflowing_mul(a: T, b: T) -> T; + /// Computes `a + b`, while saturating at numeric bounds. + /// The stabilized versions of this intrinsic are available on the integer + /// primitives via the `saturating_add` method. For example, + /// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add) + #[cfg(not(stage0))] + pub fn saturating_add(a: T, b: T) -> T; + /// Computes `a - b`, while saturating at numeric bounds. + /// The stabilized versions of this intrinsic are available on the integer + /// primitives via the `saturating_sub` method. For example, + /// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub) + #[cfg(not(stage0))] + pub fn saturating_sub(a: T, b: T) -> T; + /// Returns the value of the discriminant for the variant in 'v', /// cast to a `u64`; if `T` has no discriminant, returns 0. pub fn discriminant_value(v: &T) -> u64; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7cf2317f4b37f..f80f839282781 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -883,11 +883,16 @@ $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_add(self, rhs: Self) -> Self { + #[cfg(stage0)] match self.checked_add(rhs) { Some(x) => x, None if rhs >= 0 => Self::max_value(), None => Self::min_value(), } + #[cfg(not(stage0))] + { + intrinsics::saturating_add(self, rhs) + } } } @@ -908,11 +913,16 @@ $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_sub(self, rhs: Self) -> Self { + #[cfg(stage0)] match self.checked_sub(rhs) { Some(x) => x, None if rhs >= 0 => Self::min_value(), None => Self::max_value(), } + #[cfg(not(stage0))] + { + intrinsics::saturating_sub(self, rhs) + } } } @@ -2744,10 +2754,15 @@ assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_add(self, rhs: Self) -> Self { + #[cfg(stage0)] match self.checked_add(rhs) { Some(x) => x, None => Self::max_value(), } + #[cfg(not(stage0))] + { + intrinsics::saturating_add(self, rhs) + } } } @@ -2766,10 +2781,15 @@ assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_sub(self, rhs: Self) -> Self { + #[cfg(stage0)] match self.checked_sub(rhs) { Some(x) => x, None => Self::min_value(), } + #[cfg(not(stage0))] + { + intrinsics::saturating_sub(self, rhs) + } } } diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 1d7f14b02e199..f679558844198 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -757,6 +757,30 @@ impl CodegenCx<'b, 'tcx> { ifn!("llvm.umul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); ifn!("llvm.umul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); + ifn!("llvm.sadd.sat.i8", fn(t_i8, t_i8) -> t_i8); + ifn!("llvm.sadd.sat.i16", fn(t_i16, t_i16) -> t_i16); + ifn!("llvm.sadd.sat.i32", fn(t_i32, t_i32) -> t_i32); + ifn!("llvm.sadd.sat.i64", fn(t_i64, t_i64) -> t_i64); + ifn!("llvm.sadd.sat.i128", fn(t_i128, t_i128) -> t_i128); + + ifn!("llvm.uadd.sat.i8", fn(t_i8, t_i8) -> t_i8); + ifn!("llvm.uadd.sat.i16", fn(t_i16, t_i16) -> t_i16); + ifn!("llvm.uadd.sat.i32", fn(t_i32, t_i32) -> t_i32); + ifn!("llvm.uadd.sat.i64", fn(t_i64, t_i64) -> t_i64); + ifn!("llvm.uadd.sat.i128", fn(t_i128, t_i128) -> t_i128); + + ifn!("llvm.ssub.sat.i8", fn(t_i8, t_i8) -> t_i8); + ifn!("llvm.ssub.sat.i16", fn(t_i16, t_i16) -> t_i16); + ifn!("llvm.ssub.sat.i32", fn(t_i32, t_i32) -> t_i32); + ifn!("llvm.ssub.sat.i64", fn(t_i64, t_i64) -> t_i64); + ifn!("llvm.ssub.sat.i128", fn(t_i128, t_i128) -> t_i128); + + ifn!("llvm.usub.sat.i8", fn(t_i8, t_i8) -> t_i8); + ifn!("llvm.usub.sat.i16", fn(t_i16, t_i16) -> t_i16); + ifn!("llvm.usub.sat.i32", fn(t_i32, t_i32) -> t_i32); + ifn!("llvm.usub.sat.i64", fn(t_i64, t_i64) -> t_i64); + ifn!("llvm.usub.sat.i128", fn(t_i128, t_i128) -> t_i128); + ifn!("llvm.lifetime.start", fn(t_i64,i8p) -> void); ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void); diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 201b1684fb9b2..58b466dbe6faa 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -14,7 +14,7 @@ use type_::Type; use type_of::LayoutLlvmExt; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive}; -use rustc_codegen_ssa::common::TypeKind; +use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc::hir; use syntax::ast::{self, FloatTy}; use syntax::symbol::Symbol; @@ -28,7 +28,7 @@ use rustc::session::Session; use syntax_pos::Span; use std::cmp::Ordering; -use std::iter; +use std::{iter, i128, u128}; fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { let llvm_name = match name { @@ -342,7 +342,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { "bitreverse" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" | "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" | - "rotate_left" | "rotate_right" => { + "rotate_left" | "rotate_right" | "saturating_add" | "saturating_sub" => { let ty = arg_tys[0]; match int_type_width_signed(ty, self) { Some((width, signed)) => @@ -468,6 +468,44 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.or(shift1, shift2) } }, + "saturating_add" | "saturating_sub" => { + let is_add = name == "saturating_add"; + let lhs = args[0].immediate(); + let rhs = args[1].immediate(); + if llvm_util::get_major_version() >= 8 { + let llvm_name = &format!("llvm.{}{}.sat.i{}", + if signed { 's' } else { 'u' }, + if is_add { "add" } else { "sub" }, + width); + let llfn = self.get_intrinsic(llvm_name); + self.call(llfn, &[lhs, rhs], None) + } else { + let llvm_name = &format!("llvm.{}{}.with.overflow.i{}", + if signed { 's' } else { 'u' }, + if is_add { "add" } else { "sub" }, + width); + let llfn = self.get_intrinsic(llvm_name); + let pair = self.call(llfn, &[lhs, rhs], None); + let val = self.extract_value(pair, 0); + let overflow = self.extract_value(pair, 1); + let llty = self.type_ix(width); + + let limit = if signed { + let limit_lo = self.const_uint_big( + llty, (i128::MIN >> (128 - width)) as u128); + let limit_hi = self.const_uint_big( + llty, (i128::MAX >> (128 - width)) as u128); + let neg = self.icmp( + IntPredicate::IntSLT, val, self.const_uint(llty, 0)); + self.select(neg, limit_hi, limit_lo) + } else if is_add { + self.const_uint_big(llty, u128::MAX >> (128 - width)) + } else { + self.const_uint(llty, 0) + }; + self.select(overflow, limit, val) + } + }, _ => bug!(), }, None => { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 96e271f0cde10..82d4300d99687 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -68,6 +68,7 @@ pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { "size_of" | "min_align_of" | "needs_drop" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" | + "saturating_add" | "saturating_sub" | "rotate_left" | "rotate_right" | "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" => hir::Unsafety::Normal, @@ -307,6 +308,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "overflowing_add" | "overflowing_sub" | "overflowing_mul" => (1, vec![param(0), param(0)], param(0)), + "saturating_add" | "saturating_sub" => + (1, vec![param(0), param(0)], param(0)), "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => (1, vec![param(0), param(0)], param(0)), From 0d314f08af086afd7a67131a621f861b2633d6d3 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 29 Jan 2019 22:34:35 +0100 Subject: [PATCH 0427/1064] Add tracking issue to unstable attribute --- src/liballoc/rc.rs | 4 ++-- src/liballoc/sync.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 72b43b5d6adff..235a89c9e9db4 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1289,7 +1289,7 @@ impl Weak { /// If `self` was created using [`Weak::new`], this will return 0. /// /// [`Weak::new`]: #method.new - #[unstable(feature = "weak_counts", issue = "0")] + #[unstable(feature = "weak_counts", issue = "57977")] pub fn strong_count(&self) -> usize { if let Some(inner) = self.inner() { inner.strong() @@ -1305,7 +1305,7 @@ impl Weak { /// value. /// /// [`Weak::new`]: #method.new - #[unstable(feature = "weak_counts", issue = "0")] + #[unstable(feature = "weak_counts", issue = "57977")] pub fn weak_count(&self) -> Option { self.inner().map(|inner| { if inner.strong() > 0 { diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 777851e192501..d08aaa38a4c0a 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1122,7 +1122,7 @@ impl Weak { /// If `self` was created using [`Weak::new`], this will return 0. /// /// [`Weak::new`]: #method.new - #[unstable(feature = "weak_counts", issue = "0")] + #[unstable(feature = "weak_counts", issue = "57977")] pub fn strong_count(&self) -> usize { if let Some(inner) = self.inner() { inner.strong.load(SeqCst) @@ -1145,7 +1145,7 @@ impl Weak { /// `Weak`s pointing to the same value. /// /// [`Weak::new`]: #method.new - #[unstable(feature = "weak_counts", issue = "0")] + #[unstable(feature = "weak_counts", issue = "57977")] pub fn weak_count(&self) -> Option { // Due to the implicit weak pointer added when any strong pointers are // around, we cannot implement `weak_count` correctly since it From 84a89aa666db1a144f7bd44e535f19ac81dfaae5 Mon Sep 17 00:00:00 2001 From: Siddhartha Sahu Date: Tue, 29 Jan 2019 17:30:49 -0500 Subject: [PATCH 0428/1064] Add link to the edition guide. --- src/doc/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/index.md b/src/doc/index.md index 55897e5a3e906..7bd1854d86f40 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -71,6 +71,10 @@ accomplishing various tasks. +## The Edition Guide + +[The Edition Guide](edition-guide/index.html) describes the Rust editions. + ## The Rustc Book [The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`. From a27cf8a2817d641644ca3cbc32cacc66eef696d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 30 Jan 2019 01:24:37 +0100 Subject: [PATCH 0429/1064] submodules: update clippy from f1753522 to 6ce78d12 Changes: ```` wildcard_match_arm: Update lint count. wildcard_match_arm: add nesting issue to known. wildcard_match_arm: lint only enum matches. wildcard_match_arm: update ui test stderr wildcard_match_arm: format test. wilcard_match_arm: run rustfmt. wildcard_match_arm: add lint properly. wildcard_match_arm: rename function. wildcard_match_arm: add simple ui test. wildcard_match_arm: expand lint scope. Change match_wild lint name to WILDCARD_MATCH_ARM. Add match_wild lint (#3649). fetch_prs_between: add .sh file ending cargo fmt Update various docs Use built-in entry_fn detection over self-built cargo fmt Reorganize conditionals: Run faster checks first Maybe fix ICE? Add initial version of const_fn lint Fix `unit_arg` false positive Rustfmt Check hypothetically failing conversion Remove tests for deprecated items Update more changed iterator paths Atomics constants are now handled by the deprecation lint Update changed iterator paths Update const slice processing update test stderr run cargo fmt rustup https://github.com/rust-lang/rust/pull/57907/ Fix documentation for `slow_vector_initialization` rustup https://github.com/rust-lang/rust/pull/57726 Remove unsafe_vector_initialization from added lints Prevent incorrect cast_lossless suggestion in const_fn Incorporate review suggestions Fix dogfood tests on Appveyor test(versioncheck): Use .no_deps() test(versioncheck): Fix version equality check chore(cargo/dependencies/cargo-metadata): Upgrade to 0.7.1 dependencies: update itertools from 0.7 to 0.8 Add script to fetch GitHub PRs between two commits gitattributes: Treat .fixed files as rust files Update changelog with all changes since 0.0.212 Fix `expect_fun_call` lint suggestions ```` --- Cargo.lock | 27 ++++++++++++++++++++------- src/tools/clippy | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18f05658a17ba..442652911925d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,6 +272,18 @@ dependencies = [ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cargo_metadata" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -332,7 +344,7 @@ dependencies = [ name = "clippy" version = "0.0.212" dependencies = [ - "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "clippy-mini-macro-test 0.2.0", "clippy_dev 0.0.1", "clippy_lints 0.0.212", @@ -356,7 +368,7 @@ name = "clippy_dev" version = "0.0.1" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -366,9 +378,9 @@ dependencies = [ name = "clippy_lints" version = "0.0.212" dependencies = [ - "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1969,7 +1981,7 @@ name = "rand_chacha" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1991,7 +2003,7 @@ name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2016,7 +2028,7 @@ name = "rand_xorshift" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3782,6 +3794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" "checksum cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8dfe3adeb30f7938e6c1dd5327f29235d8ada3e898aeb08c343005ec2915a2" +"checksum cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "585784cac9b05c93a53b17a0b24a5cdd1dfdda5256f030e089b549d2390cc720" "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17ec698a6f053a23bfbe646d9f2fde4b02abc19125595270a99e6f44ae0bdd1a" diff --git a/src/tools/clippy b/src/tools/clippy index f1753522d8f3b..6ce78d1257ac6 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit f1753522d8f3bb2d218266b4760f7a99f027f5ca +Subproject commit 6ce78d1257ac6fd77f245730fcfbadd536a173eb From 62867b499291a69f5df16a60228c6bcedc5e4225 Mon Sep 17 00:00:00 2001 From: Knium_ Date: Wed, 30 Jan 2019 13:50:44 +0900 Subject: [PATCH 0430/1064] Suggest to add each of `|` and `()` when unexpected `,` is found in pattern --- src/libsyntax/parse/parser.rs | 7 ++- ...92-tuple-destructure-missing-parens.stderr | 60 +++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 65572102c5981..514b2952c5036 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4381,9 +4381,14 @@ impl<'a> Parser<'a> { if let Ok(seq_snippet) = self.sess.source_map().span_to_snippet(seq_span) { err.span_suggestion( seq_span, - "try adding parentheses", + "try adding parentheses to match on a tuple..", format!("({})", seq_snippet), Applicability::MachineApplicable + ).span_suggestion( + seq_span, + "..or a vertical bar to match on multiple alternatives", + format!("{}", seq_snippet.replace(",", " |")), + Applicability::MachineApplicable ); } return Err(err); diff --git a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr index 9df881e8e26d9..8099c3c0584fc 100644 --- a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr +++ b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr @@ -2,37 +2,85 @@ error: unexpected `,` in pattern --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:38:17 | LL | while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") { - | --^------- help: try adding parentheses: `(b1, b2, b3)` + | ^ +help: try adding parentheses to match on a tuple.. + | +LL | while let (b1, b2, b3) = reading_frame.next().expect("there should be a start codon") { + | ^^^^^^^^^^^^ +help: ..or a vertical bar to match on multiple alternatives + | +LL | while let b1 | b2 | b3 = reading_frame.next().expect("there should be a start codon") { + | ^^^^^^^^^^^^ error: unexpected `,` in pattern --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:49:14 | LL | if let b1, b2, b3 = reading_frame.next().unwrap() { - | --^------- help: try adding parentheses: `(b1, b2, b3)` + | ^ +help: try adding parentheses to match on a tuple.. + | +LL | if let (b1, b2, b3) = reading_frame.next().unwrap() { + | ^^^^^^^^^^^^ +help: ..or a vertical bar to match on multiple alternatives + | +LL | if let b1 | b2 | b3 = reading_frame.next().unwrap() { + | ^^^^^^^^^^^^ error: unexpected `,` in pattern --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:59:28 | LL | Nucleotide::Adenine, Nucleotide::Cytosine, _ => true - | -------------------^------------------------ help: try adding parentheses: `(Nucleotide::Adenine, Nucleotide::Cytosine, _)` + | ^ +help: try adding parentheses to match on a tuple.. + | +LL | (Nucleotide::Adenine, Nucleotide::Cytosine, _) => true + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: ..or a vertical bar to match on multiple alternatives + | +LL | Nucleotide::Adenine | Nucleotide::Cytosine | _ => true + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unexpected `,` in pattern --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:67:10 | LL | for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { - | -^----------- help: try adding parentheses: `(x, _barr_body)` + | ^ +help: try adding parentheses to match on a tuple.. + | +LL | for (x, _barr_body) in women.iter().map(|woman| woman.allosomes.clone()) { + | ^^^^^^^^^^^^^^^ +help: ..or a vertical bar to match on multiple alternatives + | +LL | for x | _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { + | ^^^^^^^^^^^^^^ error: unexpected `,` in pattern --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:75:10 | LL | for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { - | -^------------------- help: try adding parentheses: `(x, y @ Allosome::Y(_))` + | ^ +help: try adding parentheses to match on a tuple.. + | +LL | for (x, y @ Allosome::Y(_)) in men.iter().map(|man| man.allosomes.clone()) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: ..or a vertical bar to match on multiple alternatives + | +LL | for x | y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { + | ^^^^^^^^^^^^^^^^^^^^^^ error: unexpected `,` in pattern --> $DIR/issue-48492-tuple-destructure-missing-parens.rs:84:14 | LL | let women, men: (Vec, Vec) = genomes.iter().cloned() - | -----^---- help: try adding parentheses: `(women, men)` + | ^ +help: try adding parentheses to match on a tuple.. + | +LL | let (women, men): (Vec, Vec) = genomes.iter().cloned() + | ^^^^^^^^^^^^ +help: ..or a vertical bar to match on multiple alternatives + | +LL | let women | men: (Vec, Vec) = genomes.iter().cloned() + | ^^^^^^^^^^^ error: aborting due to 6 previous errors From b062b75559c1e6300324193873631e5e7beccfd7 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 29 Jan 2019 16:15:02 +0100 Subject: [PATCH 0431/1064] override `VecDeque`'s `Iter::try_fold` --- src/liballoc/collections/vec_deque.rs | 10 +++++++- src/liballoc/lib.rs | 1 + src/liballoc/tests/vec_deque.rs | 37 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index b3f7ef5fd6ecc..579d7de96e6da 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -12,7 +12,7 @@ use core::fmt; use core::iter::{repeat_with, FromIterator, FusedIterator}; use core::mem; use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{Index, IndexMut, RangeBounds}; +use core::ops::{Index, IndexMut, RangeBounds, Try}; use core::ptr; use core::ptr::NonNull; use core::slice; @@ -2172,6 +2172,14 @@ impl<'a, T> Iterator for Iter<'a, T> { accum = front.iter().fold(accum, &mut f); back.iter().fold(accum, &mut f) } + + fn try_fold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); + let accum = front.iter().try_fold(init, &mut f)?; + back.iter().try_fold(accum, &mut f) + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d2ff1bae63561..5165a7ca5a8f3 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -113,6 +113,7 @@ #![feature(slice_partition_dedup)] #![feature(maybe_uninit)] #![feature(alloc_layout_extra)] +#![feature(try_trait)] // Allow testing this library diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 76831ba65e3b8..c9d16a06b4773 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1433,3 +1433,40 @@ fn test_rotate_right_random() { } } } + +#[test] +fn test_try_fold_empty() { + assert_eq!(Some(0), VecDeque::::new().iter().try_fold(0, |_, _| None)); +} + +#[test] +fn test_try_fold_none() { + let v: VecDeque = (0..12).collect(); + assert_eq!(None, v.into_iter().try_fold(0, |a, b| + if b < 11 { Some(a + b) } else { None })); +} + +#[test] +fn test_try_fold_ok() { + let v: VecDeque = (0..12).collect(); + assert_eq!(Ok::<_, ()>(66), v.into_iter().try_fold(0, |a, b| Ok(a + b))); +} + +#[test] +fn test_try_fold_unit() { + let v: VecDeque<()> = std::iter::repeat(()).take(42).collect(); + assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(()))); +} + +#[test] +fn test_try_fold_rotated() { + let mut v: VecDeque<_> = (0..12).collect(); + for n in 0..10 { + if n & 1 == 0 { + v.rotate_left(n); + } else { + v.rotate_right(n); + } + assert_eq!(Ok::<_, ()>(66), v.iter().try_fold(0, |a, b| Ok(a + b))); + } +} From c397ba0420562c227230a1d8fbe3bc2966608691 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 30 Jan 2019 09:25:19 +0100 Subject: [PATCH 0432/1064] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 1cd85d2a2767b..a9505a8fb89ec 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 1cd85d2a2767b37f9869b719a74e3da99087c31a +Subproject commit a9505a8fb89ece7fa514cf3c70f1ada3e39baeec From c6f6101180f8f18008b819b4e438824048b90925 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 30 Jan 2019 14:14:16 +0100 Subject: [PATCH 0433/1064] Allow #[repr(align(x))] on enums (#57996) --- .../src/language-features/repr-align-enum.md | 26 +++++++++++++++++++ src/librustc/hir/check_attr.rs | 12 ++------- src/libsyntax/feature_gate.rs | 14 ++++++++++ src/test/run-pass/structs-enums/align-enum.rs | 17 ++++++++++++ src/test/ui/attr-usage-repr.rs | 3 ++- src/test/ui/attr-usage-repr.stderr | 18 ++++--------- .../feature-gate-repr_align_enum.rs | 10 +++++++ .../feature-gate-repr_align_enum.stderr | 11 ++++++++ 8 files changed, 87 insertions(+), 24 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/repr-align-enum.md create mode 100644 src/test/run-pass/structs-enums/align-enum.rs create mode 100644 src/test/ui/feature-gates/feature-gate-repr_align_enum.rs create mode 100644 src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr diff --git a/src/doc/unstable-book/src/language-features/repr-align-enum.md b/src/doc/unstable-book/src/language-features/repr-align-enum.md new file mode 100644 index 0000000000000..1fd9bd20f3f0d --- /dev/null +++ b/src/doc/unstable-book/src/language-features/repr-align-enum.md @@ -0,0 +1,26 @@ +# `repr_align_enum` + +The tracking issue for this feature is: [#57996] + +[#57996]: https://github.com/rust-lang/rust/issues/57996 + +------------------------ + +The `repr_align_enum` feature allows using the `#[repr(align(x))]` attribute +on enums, similarly to structs. + +# Examples + +```rust +#![feature(repr_align_enum)] + +#[repr(align(8))] +enum Aligned { + Foo, + Bar { value: u32 }, +} + +fn main() { + assert_eq!(std::mem::align_of::(), 8); +} +``` diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index df111b2be319f..9fac88fbbe9ab 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -187,8 +187,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { }; let (article, allowed_targets) = match &*name.as_str() { - "C" => { - is_c = true; + "C" | "align" => { + is_c |= name == "C"; if target != Target::Struct && target != Target::Union && target != Target::Enum { @@ -213,14 +213,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue } } - "align" => { - if target != Target::Struct && - target != Target::Union { - ("a", "struct or union") - } else { - continue - } - } "transparent" => { is_transparent = true; if target != Target::Struct { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2820924824697..218a3f52ee0b2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -461,6 +461,9 @@ declare_features! ( // #[optimize(X)] (active, optimize_attribute, "1.34.0", Some(54882), None), + + // #[repr(align(X))] on enums + (active, repr_align_enum, "1.34.0", Some(57996), None), ); declare_features! ( @@ -1697,6 +1700,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + ast::ItemKind::Enum(..) => { + for attr in attr::filter_by_name(&i.attrs[..], "repr") { + for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + if item.check_name("align") { + gate_feature_post!(&self, repr_align_enum, attr.span, + "`#[repr(align(x))]` on enums is experimental"); + } + } + } + } + ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => { if polarity == ast::ImplPolarity::Negative { gate_feature_post!(&self, optin_builtin_traits, diff --git a/src/test/run-pass/structs-enums/align-enum.rs b/src/test/run-pass/structs-enums/align-enum.rs new file mode 100644 index 0000000000000..265bae89b80c9 --- /dev/null +++ b/src/test/run-pass/structs-enums/align-enum.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +#![feature(repr_align_enum)] + +use std::mem; + +// Raising alignment +#[repr(align(8))] +enum Align8 { + Foo { foo: u32 }, + Bar { bar: u32 }, +} + +fn main() { + assert_eq!(mem::align_of::(), 8); + assert_eq!(mem::size_of::(), 8); +} diff --git a/src/test/ui/attr-usage-repr.rs b/src/test/ui/attr-usage-repr.rs index 498bf4d284a73..1df2947cbe2dd 100644 --- a/src/test/ui/attr-usage-repr.rs +++ b/src/test/ui/attr-usage-repr.rs @@ -1,4 +1,5 @@ #![feature(repr_simd)] +#![feature(repr_align_enum)] #[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union fn f() {} @@ -18,7 +19,7 @@ struct SInt(f64, f64); #[repr(C)] enum EExtern { A, B } -#[repr(align(8))] //~ ERROR: attribute should be applied to struct +#[repr(align(8))] enum EAlign { A, B } #[repr(packed)] //~ ERROR: attribute should be applied to struct diff --git a/src/test/ui/attr-usage-repr.stderr b/src/test/ui/attr-usage-repr.stderr index 990984bbb2b3d..abb8685e4cef0 100644 --- a/src/test/ui/attr-usage-repr.stderr +++ b/src/test/ui/attr-usage-repr.stderr @@ -1,5 +1,5 @@ error[E0517]: attribute should be applied to struct, enum or union - --> $DIR/attr-usage-repr.rs:3:8 + --> $DIR/attr-usage-repr.rs:4:8 | LL | #[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union | ^ @@ -7,7 +7,7 @@ LL | fn f() {} | --------- not a struct, enum or union error[E0517]: attribute should be applied to enum - --> $DIR/attr-usage-repr.rs:15:8 + --> $DIR/attr-usage-repr.rs:16:8 | LL | #[repr(i8)] //~ ERROR: attribute should be applied to enum | ^^ @@ -15,15 +15,7 @@ LL | struct SInt(f64, f64); | ---------------------- not an enum error[E0517]: attribute should be applied to struct or union - --> $DIR/attr-usage-repr.rs:21:8 - | -LL | #[repr(align(8))] //~ ERROR: attribute should be applied to struct - | ^^^^^^^^ -LL | enum EAlign { A, B } - | -------------------- not a struct or union - -error[E0517]: attribute should be applied to struct or union - --> $DIR/attr-usage-repr.rs:24:8 + --> $DIR/attr-usage-repr.rs:25:8 | LL | #[repr(packed)] //~ ERROR: attribute should be applied to struct | ^^^^^^ @@ -31,13 +23,13 @@ LL | enum EPacked { A, B } | --------------------- not a struct or union error[E0517]: attribute should be applied to struct - --> $DIR/attr-usage-repr.rs:27:8 + --> $DIR/attr-usage-repr.rs:28:8 | LL | #[repr(simd)] //~ ERROR: attribute should be applied to struct | ^^^^ LL | enum ESimd { A, B } | ------------------- not a struct -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0517`. diff --git a/src/test/ui/feature-gates/feature-gate-repr_align_enum.rs b/src/test/ui/feature-gates/feature-gate-repr_align_enum.rs new file mode 100644 index 0000000000000..f8e68a9de015b --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-repr_align_enum.rs @@ -0,0 +1,10 @@ +#[repr(align(16))] +struct Foo(u64); + +#[repr(align(8))] //~ ERROR `#[repr(align(x))]` on enums is experimental (see issue #57996) +enum Bar { + Foo { foo: Foo }, + Baz, +} + +fn main() { } diff --git a/src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr b/src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr new file mode 100644 index 0000000000000..6def25f965118 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr @@ -0,0 +1,11 @@ +error[E0658]: `#[repr(align(x))]` on enums is experimental (see issue #57996) + --> $DIR/feature-gate-repr_align_enum.rs:4:1 + | +LL | #[repr(align(8))] //~ ERROR `#[repr(align(x))]` on enums is experimental (see issue #57996) + | ^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(repr_align_enum)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From 7cfb05fd23b5ecc6a13f4629844ff81ac758497c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 14:16:18 +0100 Subject: [PATCH 0434/1064] Merge `locals` and `local_layouts` fields --- src/librustc_mir/interpret/eval_context.rs | 70 ++++++++++++---------- src/librustc_mir/interpret/mod.rs | 2 +- src/librustc_mir/interpret/snapshot.rs | 35 ++++++++--- 3 files changed, 68 insertions(+), 39 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 34443bb353e0e..d2cabde986345 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -76,8 +76,7 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=(), Extra=()> { /// The locals are stored as `Option`s. /// `None` represents a local that is currently dead, while a live local /// can either directly contain `Scalar` or refer to some part of an `Allocation`. - pub locals: IndexVec>, - pub local_layouts: IndexVec>>>, + pub locals: IndexVec>, //////////////////////////////////////////////////////////////////////////////// // Current position within the function @@ -106,9 +105,17 @@ pub enum StackPopCleanup { None { cleanup: bool }, } -// State of a local variable +/// State of a local variable including a memoized layout +#[derive(Clone, PartialEq, Eq)] +pub struct LocalValue<'tcx, Tag=(), Id=AllocId> { + pub state: LocalState, + /// Don't modify if `Some`, this is only used to prevent computing the layout twice + pub layout: Cell>>, +} + +/// State of a local variable #[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub enum LocalValue { +pub enum LocalState { Dead, // Mostly for convenience, we re-use the `Operand` type here. // This is an optimization over just always having a pointer here; @@ -117,18 +124,18 @@ pub enum LocalValue { Live(Operand), } -impl<'tcx, Tag> LocalValue { +impl<'tcx, Tag> LocalValue<'tcx, Tag> { pub fn access(&self) -> EvalResult<'tcx, &Operand> { - match self { - LocalValue::Dead => err!(DeadLocal), - LocalValue::Live(ref val) => Ok(val), + match self.state { + LocalState::Dead => err!(DeadLocal), + LocalState::Live(ref val) => Ok(val), } } pub fn access_mut(&mut self) -> EvalResult<'tcx, &mut Operand> { - match self { - LocalValue::Dead => err!(DeadLocal), - LocalValue::Live(ref mut val) => Ok(val), + match self.state { + LocalState::Dead => err!(DeadLocal), + LocalState::Live(ref mut val) => Ok(val), } } } @@ -312,7 +319,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, local: mir::Local ) -> EvalResult<'tcx, TyLayout<'tcx>> { - let cell = &frame.local_layouts[local]; + let cell = &frame.locals[local].layout; if cell.get().is_none() { let local_ty = frame.mir.local_decls[local].ty; let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); @@ -454,7 +461,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // empty local array, we fill it in below, after we are inside the stack frame and // all methods actually know about the frame locals: IndexVec::new(), - local_layouts: IndexVec::from_elem_n(Default::default(), mir.local_decls.len()), span, instance, stmt: 0, @@ -464,14 +470,18 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // don't allocate at all for trivial constants if mir.local_decls.len() > 1 { // We put some marker immediate into the locals that we later want to initialize. - // This can be anything except for LocalValue::Dead -- because *that* is the + // This can be anything except for LocalState::Dead -- because *that* is the // value we use for things that we know are initially dead. - let dummy = - LocalValue::Live(Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))); + let dummy = LocalValue { + state: LocalState::Live(Operand::Immediate(Immediate::Scalar( + ScalarMaybeUndef::Undef, + ))), + layout: Cell::new(None), + }; let mut locals = IndexVec::from_elem(dummy, &mir.local_decls); // Return place is handled specially by the `eval_place` functions, and the // entry in `locals` should never be used. Make it dead, to be sure. - locals[mir::RETURN_PLACE] = LocalValue::Dead; + locals[mir::RETURN_PLACE].state = LocalState::Dead; // Now mark those locals as dead that we do not want to initialize match self.tcx.describe_def(instance.def_id()) { // statics and constants don't have `Storage*` statements, no need to look for them @@ -484,7 +494,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc match stmt.kind { StorageLive(local) | StorageDead(local) => { - locals[local] = LocalValue::Dead; + locals[local].state = LocalState::Dead; } _ => {} } @@ -494,13 +504,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } // Finally, properly initialize all those that still have the dummy value for (idx, local) in locals.iter_enumerated_mut() { - match *local { - LocalValue::Live(_) => { + match local.state { + LocalState::Live(_) => { // This needs to be peoperly initialized. let layout = self.layout_of_local(self.frame(), idx)?; - *local = LocalValue::Live(self.uninit_operand(layout)?); + local.state = LocalState::Live(self.uninit_operand(layout)?); } - LocalValue::Dead => { + LocalState::Dead => { // Nothing to do } } @@ -543,7 +553,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } // Deallocate all locals that are backed by an allocation. for local in frame.locals { - self.deallocate_local(local)?; + self.deallocate_local(local.state)?; } // Validate the return value. Do this after deallocating so that we catch dangling // references. @@ -587,31 +597,31 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc pub fn storage_live( &mut self, local: mir::Local - ) -> EvalResult<'tcx, LocalValue> { + ) -> EvalResult<'tcx, LocalState> { assert!(local != mir::RETURN_PLACE, "Cannot make return place live"); trace!("{:?} is now live", local); let layout = self.layout_of_local(self.frame(), local)?; - let init = LocalValue::Live(self.uninit_operand(layout)?); + let init = LocalState::Live(self.uninit_operand(layout)?); // StorageLive *always* kills the value that's currently stored - Ok(mem::replace(&mut self.frame_mut().locals[local], init)) + Ok(mem::replace(&mut self.frame_mut().locals[local].state, init)) } /// Returns the old value of the local. /// Remember to deallocate that! - pub fn storage_dead(&mut self, local: mir::Local) -> LocalValue { + pub fn storage_dead(&mut self, local: mir::Local) -> LocalState { assert!(local != mir::RETURN_PLACE, "Cannot make return place dead"); trace!("{:?} is now dead", local); - mem::replace(&mut self.frame_mut().locals[local], LocalValue::Dead) + mem::replace(&mut self.frame_mut().locals[local].state, LocalState::Dead) } pub(super) fn deallocate_local( &mut self, - local: LocalValue, + local: LocalState, ) -> EvalResult<'tcx> { // FIXME: should we tell the user that there was a local which was never written to? - if let LocalValue::Live(Operand::Indirect(MemPlace { ptr, .. })) = local { + if let LocalState::Live(Operand::Indirect(MemPlace { ptr, .. })) = local { trace!("deallocating local"); let ptr = ptr.to_ptr()?; self.memory.dump_alloc(ptr.alloc_id); diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index e3ab90a602040..6ee7d3309f464 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -18,7 +18,7 @@ mod visitor; pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here pub use self::eval_context::{ - EvalContext, Frame, StackPopCleanup, LocalValue, + EvalContext, Frame, StackPopCleanup, LocalValue, LocalState, }; pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy}; diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 53105266b3928..0b5dc9446921a 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -7,7 +7,7 @@ use std::hash::{Hash, Hasher}; -use rustc::ich::StableHashingContextProvider; +use rustc::ich::{StableHashingContextProvider, StableHashingContext}; use rustc::mir; use rustc::mir::interpret::{ AllocId, Pointer, Scalar, @@ -19,12 +19,12 @@ use rustc::ty::{self, TyCtxt}; use rustc::ty::layout::Align; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use syntax::ast::Mutability; use syntax::source_map::Span; use super::eval_context::{LocalValue, StackPopCleanup}; -use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef}; +use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef, LocalState}; use const_eval::CompileTimeInterpreter; #[derive(Default)] @@ -250,11 +250,11 @@ impl_snapshot_for!(enum Operand { Indirect(m), }); -impl_stable_hash_for!(enum ::interpret::LocalValue { +impl_stable_hash_for!(enum ::interpret::LocalState { Dead, Live(x), }); -impl_snapshot_for!(enum LocalValue { +impl_snapshot_for!(enum LocalState { Live(v), Dead, }); @@ -309,7 +309,7 @@ struct FrameSnapshot<'a, 'tcx: 'a> { span: &'a Span, return_to_block: &'a StackPopCleanup, return_place: Option>>, - locals: IndexVec>>, + locals: IndexVec>>, block: &'a mir::BasicBlock, stmt: usize, } @@ -321,7 +321,6 @@ impl_stable_hash_for!(impl<'mir, 'tcx: 'mir> for struct Frame<'mir, 'tcx> { return_to_block, return_place -> (return_place.as_ref().map(|r| &**r)), locals, - local_layouts -> _, block, stmt, extra, @@ -340,7 +339,6 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> return_to_block, return_place, locals, - local_layouts: _, block, stmt, extra: _, @@ -358,6 +356,27 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> } } +impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalValue<'tcx> + where Ctx: SnapshotContext<'a>, +{ + type Item = LocalState<(), AllocIdSnapshot<'a>>; + + fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { + self.state.snapshot(ctx) + } +} + + +impl<'a, 'gcx> HashStable> for LocalValue<'gcx> { + fn hash_stable( + &self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher, + ) { + self.state.hash_stable(hcx, hasher); + } +} + impl<'a, 'b, 'mir, 'tcx: 'a+'mir> SnapshotContext<'b> for Memory<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>> { From bc528d93ec27758af5e61c21c3e05d8da077a9ce Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 14:55:31 +0100 Subject: [PATCH 0435/1064] Allow `layout_of_local` to also use cached layouts --- src/librustc_mir/interpret/eval_context.rs | 11 +++++++---- src/librustc_mir/interpret/operand.rs | 12 +++++++----- src/librustc_mir/interpret/place.rs | 6 +++--- src/librustc_mir/interpret/terminator.rs | 4 ++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d2cabde986345..d890e2fbe46da 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -317,13 +317,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc pub fn layout_of_local( &self, frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, - local: mir::Local + local: mir::Local, + layout: Option>, ) -> EvalResult<'tcx, TyLayout<'tcx>> { let cell = &frame.locals[local].layout; if cell.get().is_none() { + let layout = ::interpret::operand::from_known_layout(layout, || { let local_ty = frame.mir.local_decls[local].ty; let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); - let layout = self.layout_of(local_ty)?; + self.layout_of(local_ty) + })?; cell.set(Some(layout)); } @@ -507,7 +510,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc match local.state { LocalState::Live(_) => { // This needs to be peoperly initialized. - let layout = self.layout_of_local(self.frame(), idx)?; + let layout = self.layout_of_local(self.frame(), idx, None)?; local.state = LocalState::Live(self.uninit_operand(layout)?); } LocalState::Dead => { @@ -601,7 +604,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc assert!(local != mir::RETURN_PLACE, "Cannot make return place live"); trace!("{:?} is now live", local); - let layout = self.layout_of_local(self.frame(), local)?; + let layout = self.layout_of_local(self.frame(), local, None)?; let init = LocalState::Live(self.uninit_operand(layout)?); // StorageLive *always* kills the value that's currently stored Ok(mem::replace(&mut self.frame_mut().locals[local].state, init)) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index e4bee24c88cfa..a7e92d5679409 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -227,7 +227,7 @@ impl<'tcx, Tag> OpTy<'tcx, Tag> // Use the existing layout if given (but sanity check in debug mode), // or compute the layout. #[inline(always)] -fn from_known_layout<'tcx>( +pub(super) fn from_known_layout<'tcx>( layout: Option>, compute: impl FnOnce() -> EvalResult<'tcx, TyLayout<'tcx>> ) -> EvalResult<'tcx, TyLayout<'tcx>> { @@ -461,10 +461,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> &self, frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, local: mir::Local, + layout: Option>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { assert_ne!(local, mir::RETURN_PLACE); let op = *frame.locals[local].access()?; - let layout = self.layout_of_local(frame, local)?; + let layout = self.layout_of_local(frame, local, layout)?; Ok(OpTy { op, layout }) } @@ -473,14 +474,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> fn eval_place_to_op( &self, mir_place: &mir::Place<'tcx>, + layout: Option>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { use rustc::mir::Place::*; let op = match *mir_place { Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), - Local(local) => self.access_local(self.frame(), local)?, + Local(local) => self.access_local(self.frame(), local, layout)?, Projection(ref proj) => { - let op = self.eval_place_to_op(&proj.base)?; + let op = self.eval_place_to_op(&proj.base, None)?; self.operand_projection(op, &proj.elem)? } @@ -504,7 +506,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // FIXME: do some more logic on `move` to invalidate the old location Copy(ref place) | Move(ref place) => - self.eval_place_to_op(place)?, + self.eval_place_to_op(place, layout)?, Constant(ref constant) => { let layout = from_known_layout(layout, || { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index f3a948a6ca3e7..ffb8ec899a07d 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -624,7 +624,7 @@ where // their layout on return. PlaceTy { place: *return_place, - layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE)?, + layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?, }, None => return err!(InvalidNullPointerUsage), }, @@ -633,7 +633,7 @@ where frame: self.cur_frame(), local, }, - layout: self.layout_of_local(self.frame(), local)?, + layout: self.layout_of_local(self.frame(), local, None)?, }, Projection(ref proj) => { @@ -901,7 +901,7 @@ where // We need the layout of the local. We can NOT use the layout we got, // that might e.g., be an inner field of a struct with `Scalar` layout, // that has different alignment than the outer field. - let local_layout = self.layout_of_local(&self.stack[frame], local)?; + let local_layout = self.layout_of_local(&self.stack[frame], local, None)?; let ptr = self.allocate(local_layout, MemoryKind::Stack); // We don't have to validate as we can assume the local // was already valid for its type. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 951e9fabe5932..7e823524c180c 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -309,7 +309,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> mir.spread_arg, mir.args_iter() .map(|local| - (local, self.layout_of_local(self.frame(), local).unwrap().ty) + (local, self.layout_of_local(self.frame(), local, None).unwrap().ty) ) .collect::>() ); @@ -383,7 +383,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } } else { let callee_layout = - self.layout_of_local(self.frame(), mir::RETURN_PLACE)?; + self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?; if !callee_layout.abi.is_uninhabited() { return err!(FunctionRetMismatch( self.tcx.types.never, callee_layout.ty From 154c54c875fe8892cacc2d8bc0275ecc27b4baaf Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 15:01:42 +0100 Subject: [PATCH 0436/1064] Make priroda happy again --- src/librustc_mir/interpret/operand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index a7e92d5679409..37e421c2e7339 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -457,7 +457,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local - fn access_local( + pub fn access_local( &self, frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, local: mir::Local, From 4165c890ed573cc801a27483935ccdbc01fcd75b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 15:05:50 +0100 Subject: [PATCH 0437/1064] Can't use `layout_of_local` for the frame currently being created --- src/librustc_mir/interpret/eval_context.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d890e2fbe46da..bb4f5c131d628 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -509,9 +509,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc for (idx, local) in locals.iter_enumerated_mut() { match local.state { LocalState::Live(_) => { - // This needs to be peoperly initialized. - let layout = self.layout_of_local(self.frame(), idx, None)?; + // This needs to be properly initialized. + let layout = self.layout_of(mir.local_decls[idx].ty)?; local.state = LocalState::Live(self.uninit_operand(layout)?); + local.layout = Cell::new(Some(layout)); } LocalState::Dead => { // Nothing to do From ab708f5c6f7077ccf0b30baeb9395d372f5dbcce Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 15:08:59 +0100 Subject: [PATCH 0438/1064] The return place's layout is only used once per frame, so caching doesn't help --- src/librustc_mir/interpret/place.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index ffb8ec899a07d..ba1960300a85c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -624,7 +624,7 @@ where // their layout on return. PlaceTy { place: *return_place, - layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?, + layout: self.layout_of(self.frame().mir.return_ty())?, }, None => return err!(InvalidNullPointerUsage), }, From 1a183368082ad357b1fef0f55038becc9ac14b7b Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 30 Jan 2019 15:12:41 +0100 Subject: [PATCH 0439/1064] proc_macro: make `TokenStream::from_streams` pre-allocate its vector. This requires a pre-pass over the input streams. But that is cheap compared to the quadratic blowup associated with reallocating the accumulating vector on-the-fly. --- src/libsyntax/tokenstream.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index f5d2d6f18ee87..7d6ffceb2c0d4 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -255,7 +255,13 @@ impl TokenStream { 0 => TokenStream::empty(), 1 => streams.pop().unwrap(), _ => { - let mut vec = vec![]; + // rust-lang/rust#57735: pre-allocate vector to avoid + // quadratic blow-up due to on-the-fly reallocations. + let tree_count = streams.iter() + .map(|ts| match &ts.0 { None => 0, Some(s) => s.len() }) + .sum(); + let mut vec = Vec::with_capacity(tree_count); + for stream in streams { match stream.0 { None => {}, From 7389f97cde3da06fd7025e3eb93f4ab3c10c7d40 Mon Sep 17 00:00:00 2001 From: James Munns Date: Thu, 10 Jan 2019 20:37:51 +0100 Subject: [PATCH 0440/1064] Only the compatibility items from the embedded book PR PR: https://github.com/rust-lang/rust/pull/56291 --- src/bootstrap/doc.rs | 41 +++++++++++++++---- src/tools/rustbook/Cargo.toml | 12 +++++- src/tools/rustbook/src/main.rs | 72 ++++++++++++++++++++++++++-------- 3 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index eec193c21f5db..c428f29d70684 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -23,7 +23,7 @@ use crate::cache::{INTERNER, Interned}; use crate::config::Config; macro_rules! book { - ($($name:ident, $path:expr, $book_name:expr;)+) => { + ($($name:ident, $path:expr, $book_name:expr, $book_ver:expr;)+) => { $( #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct $name { @@ -49,6 +49,7 @@ macro_rules! book { builder.ensure(Rustbook { target: self.target, name: INTERNER.intern_str($book_name), + version: $book_ver, }) } } @@ -56,19 +57,28 @@ macro_rules! book { } } +// NOTE: When adding a book here, make sure to ALSO build the book by +// adding a build step in `src/bootstrap/builder.rs`! book!( - Nomicon, "src/doc/nomicon", "nomicon"; - Reference, "src/doc/reference", "reference"; - EditionGuide, "src/doc/edition-guide", "edition-guide"; - RustdocBook, "src/doc/rustdoc", "rustdoc"; - RustcBook, "src/doc/rustc", "rustc"; - RustByExample, "src/doc/rust-by-example", "rust-by-example"; + EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::MdBook1; + Nomicon, "src/doc/nomicon", "nomicon", RustbookVersion::MdBook1; + Reference, "src/doc/reference", "reference", RustbookVersion::MdBook1; + RustByExample, "src/doc/rust-by-example", "rust-by-example", RustbookVersion::MdBook1; + RustcBook, "src/doc/rustc", "rustc", RustbookVersion::MdBook1; + RustdocBook, "src/doc/rustdoc", "rustdoc", RustbookVersion::MdBook1; ); +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +enum RustbookVersion { + MdBook1, + MdBook2, +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] struct Rustbook { target: Interned, name: Interned, + version: RustbookVersion, } impl Step for Rustbook { @@ -90,6 +100,7 @@ impl Step for Rustbook { target: self.target, name: self.name, src: INTERNER.intern_path(src), + version: self.version, }); } } @@ -122,6 +133,7 @@ impl Step for UnstableBook { target: self.target, name: INTERNER.intern_str("unstable-book"), src: builder.md_doc_out(self.target), + version: RustbookVersion::MdBook1, }) } } @@ -175,6 +187,7 @@ struct RustbookSrc { target: Interned, name: Interned, src: Interned, + version: RustbookVersion, } impl Step for RustbookSrc { @@ -205,11 +218,19 @@ impl Step for RustbookSrc { } builder.info(&format!("Rustbook ({}) - {}", target, name)); let _ = fs::remove_dir_all(&out); + + let vers = match self.version { + RustbookVersion::MdBook1 => "1", + RustbookVersion::MdBook2 => "2", + }; + builder.run(rustbook_cmd .arg("build") .arg(&src) .arg("-d") - .arg(out)); + .arg(out) + .arg("-m") + .arg(vers)); } } @@ -255,6 +276,7 @@ impl Step for TheBook { builder.ensure(Rustbook { target, name: INTERNER.intern_string(name.to_string()), + version: RustbookVersion::MdBook1, }); // building older edition redirects @@ -263,18 +285,21 @@ impl Step for TheBook { builder.ensure(Rustbook { target, name: INTERNER.intern_string(source_name), + version: RustbookVersion::MdBook1, }); let source_name = format!("{}/second-edition", name); builder.ensure(Rustbook { target, name: INTERNER.intern_string(source_name), + version: RustbookVersion::MdBook1, }); let source_name = format!("{}/2018-edition", name); builder.ensure(Rustbook { target, name: INTERNER.intern_string(source_name), + version: RustbookVersion::MdBook1, }); // build the version info page and CSS diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 5e11646ee4c19..27454431228a8 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -1,13 +1,23 @@ +cargo-features = ["rename-dependency"] + [package] authors = ["The Rust Project Developers"] name = "rustbook" version = "0.1.0" license = "MIT/Apache-2.0" +edition = "2018" [dependencies] clap = "2.25.0" -[dependencies.mdbook] +[dependencies.mdbook_2] +package = "mdbook" +version = "0.2.2" +default-features = false +features = ["search"] + +[dependencies.mdbook_1] +package = "mdbook" version = "0.1.7" default-features = false features = ["search"] diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 80a85dc2ac0e3..5a6246347cc03 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -1,21 +1,24 @@ // -extern crate mdbook; -#[macro_use] -extern crate clap; +use clap::{crate_version}; use std::env; use std::path::{Path, PathBuf}; use clap::{App, ArgMatches, SubCommand, AppSettings}; -use mdbook::MDBook; -use mdbook::errors::Result; +use mdbook_1::{MDBook as MDBook1}; +use mdbook_1::errors::{Result as Result1}; + +use mdbook_2::{MDBook as MDBook2}; +use mdbook_2::errors::{Result as Result2}; fn main() { let d_message = "-d, --dest-dir=[dest-dir] 'The output directory for your book{n}(Defaults to ./book when omitted)'"; let dir_message = "[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'"; + let vers_message = "-m, --mdbook-vers=[md-version] +'The version of mdbook to use for your book{n}(Defaults to 1 when omitted)'"; let matches = App::new("rustbook") .about("Build a book with mdBook") @@ -25,29 +28,66 @@ fn main() { .subcommand(SubCommand::with_name("build") .about("Build the book from the markdown files") .arg_from_usage(d_message) - .arg_from_usage(dir_message)) + .arg_from_usage(dir_message) + .arg_from_usage(vers_message)) .get_matches(); // Check which subcomamnd the user ran... - let res = match matches.subcommand() { - ("build", Some(sub_matches)) => build(sub_matches), + match matches.subcommand() { + ("build", Some(sub_matches)) => { + match sub_matches.value_of("mdbook-vers") { + None | Some("1") => { + if let Err(e) = build_1(sub_matches) { + eprintln!("Error: {}", e); + + for cause in e.iter().skip(1) { + eprintln!("\tCaused By: {}", cause); + } + + ::std::process::exit(101); + } + } + Some("2") => { + if let Err(e) = build_2(sub_matches) { + eprintln!("Error: {}", e); + + for cause in e.iter().skip(1) { + eprintln!("\tCaused By: {}", cause); + } + + ::std::process::exit(101); + } + } + _ => { + panic!("Invalid mdBook version! Select '1' or '2'"); + } + }; + }, (_, _) => unreachable!(), }; +} - if let Err(e) = res { - eprintln!("Error: {}", e); +// Build command implementation +pub fn build_1(args: &ArgMatches) -> Result1<()> { + let book_dir = get_book_dir(args); + let mut book = MDBook1::load(&book_dir)?; - for cause in e.iter().skip(1) { - eprintln!("\tCaused By: {}", cause); - } + // Set this to allow us to catch bugs in advance. + book.config.build.create_missing = false; - ::std::process::exit(101); + if let Some(dest_dir) = args.value_of("dest-dir") { + book.config.build.build_dir = PathBuf::from(dest_dir); } + + book.build()?; + + Ok(()) } + // Build command implementation -pub fn build(args: &ArgMatches) -> Result<()> { +pub fn build_2(args: &ArgMatches) -> Result2<()> { let book_dir = get_book_dir(args); - let mut book = MDBook::load(&book_dir)?; + let mut book = MDBook2::load(&book_dir)?; // Set this to allow us to catch bugs in advance. book.config.build.create_missing = false; From b98a1e17102630c03051b8fd20b4c6ea4b3185ed Mon Sep 17 00:00:00 2001 From: James Munns Date: Thu, 10 Jan 2019 21:18:13 +0100 Subject: [PATCH 0441/1064] No consumers of MdBook2 yet --- src/bootstrap/doc.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index c428f29d70684..08e97396fd68b 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -71,6 +71,10 @@ book!( #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] enum RustbookVersion { MdBook1, + + /// Note: Currently no books use mdBook v2, but we want the option + /// to be available + #[allow(dead_code)] MdBook2, } From 9004b44b99c3de4277f9212e5a574e21572451b6 Mon Sep 17 00:00:00 2001 From: James Munns Date: Thu, 10 Jan 2019 21:22:33 +0100 Subject: [PATCH 0442/1064] Remove stable feature --- src/tools/rustbook/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 27454431228a8..4b465d72338c3 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -1,5 +1,3 @@ -cargo-features = ["rename-dependency"] - [package] authors = ["The Rust Project Developers"] name = "rustbook" From 7017927aaf5ba14cec6c28b1079a93abfc715985 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 15:24:41 +0100 Subject: [PATCH 0443/1064] Indent fixup --- src/librustc_mir/interpret/eval_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index bb4f5c131d628..3382288b99a25 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -323,8 +323,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc let cell = &frame.locals[local].layout; if cell.get().is_none() { let layout = ::interpret::operand::from_known_layout(layout, || { - let local_ty = frame.mir.local_decls[local].ty; - let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); + let local_ty = frame.mir.local_decls[local].ty; + let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); self.layout_of(local_ty) })?; cell.set(Some(layout)); From de76369f93537fb9978dd0626296643764dee868 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sat, 19 Jan 2019 03:39:37 +0100 Subject: [PATCH 0444/1064] Update to newer version of mdbook(2) --- Cargo.lock | 167 ++++++++++++++++++++++++++++++++++ src/tools/rustbook/Cargo.toml | 2 +- 2 files changed, 168 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 442652911925d..058f1b1e716a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,6 +54,11 @@ dependencies = [ "rustc_data_structures 0.0.0", ] +[[package]] +name = "arrayref" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayvec" version = "0.4.7" @@ -131,6 +136,15 @@ name = "bitflags" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "block-buffer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bootstrap" version = "0.0.0" @@ -175,6 +189,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "build_helper" version = "0.1.0" +[[package]] +name = "byte-tools" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bytecount" version = "0.4.0" @@ -714,6 +733,14 @@ name = "difference" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "digest" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "directories" version = "1.0.2" @@ -832,6 +859,11 @@ dependencies = [ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "filetime" version = "0.2.4" @@ -949,6 +981,14 @@ dependencies = [ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "generic-array" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "getopts" version = "0.2.17" @@ -1015,6 +1055,22 @@ dependencies = [ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "handlebars" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "heck" version = "0.3.0" @@ -1393,6 +1449,34 @@ dependencies = [ "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mdbook" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "toml-query 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "memchr" version = "2.1.1" @@ -1733,6 +1817,14 @@ name = "pest" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pest" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pest_derive" version = "1.0.8" @@ -1743,6 +1835,37 @@ dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pest_generator" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pest_meta" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "petgraph" version = "0.4.13" @@ -2229,6 +2352,7 @@ version = "0.1.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mdbook 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3025,6 +3149,17 @@ dependencies = [ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha-1" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "shell-escape" version = "0.1.4" @@ -3551,11 +3686,28 @@ dependencies = [ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "toml-query" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "typenum" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ucd-trie" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ucd-util" version = "0.1.3" @@ -3778,6 +3930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" +"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" @@ -3787,8 +3940,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" "checksum bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" +"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" @@ -3830,6 +3985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72d337a64190607d4fcca2cb78982c5dd57f4916e19696b48a575fa746b6cb0f" "checksum dlmalloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d56ad71b31043818d0ee10a7fb9664882f8e45849c81647585e6a3124f185517" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" @@ -3842,6 +3998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" +"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4" @@ -3857,12 +4014,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" "checksum fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34dd4c507af68d37ffef962063dfa1944ce0dd4d5b82043dbab1dabe088610c3" +"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0" "checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" +"checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff" @@ -3902,6 +4061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f" +"checksum mdbook 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba0d44cb4089c741b9a91f3e5218298a40699c2f3a070a85014eed290c60819" "checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" @@ -3937,7 +4097,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" +"checksum pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3" "checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" +"checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +"checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" +"checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" @@ -4013,6 +4177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" "checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" +"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f272d1b7586bec132ed427f532dd418d8beca1ca7f2caf7df35569b1415a4b4" @@ -4056,7 +4221,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" +"checksum toml-query 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab234a943a2363ad774020e2f9474a38a85bc4396bace01a96380144aef17db3" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 4b465d72338c3..5bf1553b22711 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -10,7 +10,7 @@ clap = "2.25.0" [dependencies.mdbook_2] package = "mdbook" -version = "0.2.2" +version = "0.2.3" default-features = false features = ["search"] From f8a9a28421f76b84f45694cf668cfd4c0c3aa40b Mon Sep 17 00:00:00 2001 From: James Munns Date: Sat, 19 Jan 2019 05:15:25 +0100 Subject: [PATCH 0445/1064] Add exception for new dependency in license checker --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index f1bfb6efc2f07..17c36b80f3a7c 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -26,6 +26,7 @@ const EXCEPTIONS: &[&str] = &[ "mdbook", // MPL2, mdbook "openssl", // BSD+advertising clause, cargo, mdbook "pest", // MPL2, mdbook via handlebars + "arrayref", // BSD-2-Clause, mdbook via handlebars via pest "thread-id", // Apache-2.0, mdbook "toml-query", // MPL-2.0, mdbook "is-match", // MPL-2.0, mdbook From 4e0af1fee19c2ff056e20a55464c233dc30e5c92 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 15:42:00 +0100 Subject: [PATCH 0446/1064] Monomorphize types when not going through `layout_of_local` --- src/librustc_mir/interpret/eval_context.rs | 3 ++- src/librustc_mir/interpret/place.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 3382288b99a25..4bf84cb465f77 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -510,7 +510,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc match local.state { LocalState::Live(_) => { // This needs to be properly initialized. - let layout = self.layout_of(mir.local_decls[idx].ty)?; + let ty = self.monomorphize(mir.local_decls[idx].ty)?; + let layout = self.layout_of(ty)?; local.state = LocalState::Live(self.uninit_operand(layout)?); local.layout = Cell::new(Some(layout)); } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index ba1960300a85c..9ca7f9d8e27ff 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -624,7 +624,7 @@ where // their layout on return. PlaceTy { place: *return_place, - layout: self.layout_of(self.frame().mir.return_ty())?, + layout: self.layout_of(self.monomorphize(self.frame().mir.return_ty())?)?, }, None => return err!(InvalidNullPointerUsage), }, From 5aa713e1c39b0e84ae9c96f99514f4981d3cea30 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 15:51:20 +0100 Subject: [PATCH 0447/1064] Eliminate an unwrap --- src/librustc_mir/interpret/eval_context.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 4bf84cb465f77..4e66d21214b29 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -320,17 +320,18 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc local: mir::Local, layout: Option>, ) -> EvalResult<'tcx, TyLayout<'tcx>> { - let cell = &frame.locals[local].layout; - if cell.get().is_none() { - let layout = ::interpret::operand::from_known_layout(layout, || { - let local_ty = frame.mir.local_decls[local].ty; - let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); - self.layout_of(local_ty) - })?; - cell.set(Some(layout)); + match frame.locals[local].layout.get() { + None => { + let layout = ::interpret::operand::from_known_layout(layout, || { + let local_ty = frame.mir.local_decls[local].ty; + let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); + self.layout_of(local_ty) + })?; + frame.locals[local].layout.set(Some(layout)); + Ok(layout) + } + Some(layout) => Ok(layout), } - - Ok(cell.get().unwrap()) } pub fn str_to_immediate(&mut self, s: &str) -> EvalResult<'tcx, Immediate> { From 4460e7c919921ee0fbfd4804d2df33996f404581 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 24 Jan 2019 14:08:39 +0100 Subject: [PATCH 0448/1064] Add missing packages. --- src/ci/docker/x86_64-gnu-debug/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index 241c25aaa050b..1f2cdf36d156f 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -8,6 +8,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ python2.7 \ python2.7-dev \ + libxml2-dev \ + libncurses-dev \ + libedit-dev \ + swig \ + doxygen \ git \ cmake \ sudo \ From 9c29517af9cc44683fabcdf8c4b9b9c650e33ca6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 25 Jan 2019 12:34:59 +0100 Subject: [PATCH 0449/1064] bootstrap: Make LLD available to run-make tests. --- src/bootstrap/tool.rs | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 9f6db73e6f713..cd3afc59e560c 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -1,6 +1,5 @@ use std::fs; use std::env; -use std::iter; use std::path::PathBuf; use std::process::{Command, exit}; use std::collections::HashSet; @@ -666,19 +665,33 @@ impl<'a> Builder<'a> { // Add the llvm/bin directory to PATH since it contains lots of // useful, platform-independent tools - if tool.uses_llvm_tools() { + if tool.uses_llvm_tools() && !self.config.dry_run { + let mut additional_paths = vec![]; + if let Some(llvm_bin_path) = self.llvm_bin_path() { - if host.contains("windows") { - // On Windows, PATH and the dynamic library path are the same, - // so we just add the LLVM bin path to lib_path - lib_paths.push(llvm_bin_path); - } else { - let old_path = env::var_os("PATH").unwrap_or_default(); - let new_path = env::join_paths(iter::once(llvm_bin_path) - .chain(env::split_paths(&old_path))) - .expect("Could not add LLVM bin path to PATH"); - cmd.env("PATH", new_path); - } + additional_paths.push(llvm_bin_path); + } + + // If LLD is available, add that too. + if self.config.lld_enabled { + let lld_install_root = self.ensure(native::Lld { + target: self.config.build, + }); + + let lld_bin_path = lld_install_root.join("bin"); + additional_paths.push(lld_bin_path); + } + + if host.contains("windows") { + // On Windows, PATH and the dynamic library path are the same, + // so we just add the LLVM bin path to lib_path + lib_paths.extend(additional_paths); + } else { + let old_path = env::var_os("PATH").unwrap_or_default(); + let new_path = env::join_paths(additional_paths.into_iter() + .chain(env::split_paths(&old_path))) + .expect("Could not add LLVM bin path to PATH"); + cmd.env("PATH", new_path); } } @@ -686,7 +699,7 @@ impl<'a> Builder<'a> { } fn llvm_bin_path(&self) -> Option { - if self.config.llvm_enabled && !self.config.dry_run { + if self.config.llvm_enabled { let llvm_config = self.ensure(native::Llvm { target: self.config.build, emscripten: false, From 4f534ffbdb9bb9897ea6a1f7290e5e6fb4d86f02 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 28 Jan 2019 15:16:29 +0100 Subject: [PATCH 0450/1064] ci: Use clang as the C++ compiler for x86_64-gnu-debug. --- src/ci/docker/x86_64-gnu-debug/Dockerfile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index 1f2cdf36d156f..10d92256dccca 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.10 RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ @@ -17,7 +17,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ - xz-utils + xz-utils \ + lld \ + clang COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh @@ -30,7 +32,11 @@ ENV RUST_CONFIGURE_ARGS \ --enable-debug \ --enable-lld \ --enable-lldb \ - --enable-optimize + --enable-optimize \ + --set target.x86_64-unknown-linux-gnu.linker=clang \ + --set target.x86_64-unknown-linux-gnu.cc=clang \ + --set target.x86_64-unknown-linux-gnu.cxx=clang++ + ENV SCRIPT \ python2.7 ../x.py build && \ python2.7 ../x.py test src/test/run-make-fulldeps --test-args clang From dc20c8cc25a6d1bc9baaa4cc3a879a9c0f9f6657 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 Jan 2019 13:27:12 +0100 Subject: [PATCH 0451/1064] bootstrap: Expose LLVM_USE_LINKER cmake option to config.toml. --- config.toml.example | 4 ++++ src/bootstrap/config.rs | 3 +++ src/bootstrap/native.rs | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/config.toml.example b/config.toml.example index 23943d34b7ca8..548aa691633db 100644 --- a/config.toml.example +++ b/config.toml.example @@ -96,6 +96,10 @@ # that your host compiler ships with libc++. #use-libcxx = true +# The value specified here will be passed as `-DLLVM_USE_LINKER` to CMake. +#use-linker = "lld" + + # ============================================================================= # General build configuration options # ============================================================================= diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9421817ae6d8e..2871db2c9a2d1 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -77,6 +77,7 @@ pub struct Config { pub llvm_experimental_targets: String, pub llvm_link_jobs: Option, pub llvm_version_suffix: Option, + pub llvm_use_linker: Option, pub lld_enabled: bool, pub lldb_enabled: bool, @@ -255,6 +256,7 @@ struct Llvm { version_suffix: Option, clang_cl: Option, use_libcxx: Option, + use_linker: Option, } #[derive(Deserialize, Default, Clone)] @@ -517,6 +519,7 @@ impl Config { config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); set(&mut config.llvm_use_libcxx, llvm.use_libcxx); + config.llvm_use_linker = llvm.use_linker.clone(); } if let Some(ref rust) = toml.rust { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index cb9c86df55080..e4325179f63a5 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -231,6 +231,10 @@ impl Step for Llvm { cfg.define("LLVM_VERSION_SUFFIX", suffix); } + if let Some(ref linker) = builder.config.llvm_use_linker { + cfg.define("LLVM_USE_LINKER", linker); + } + if let Some(ref python) = builder.config.python { cfg.define("PYTHON_EXECUTABLE", python); } From b17c10de46b021cb25855d440b6a0c270d4d1f4e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 Jan 2019 13:28:46 +0100 Subject: [PATCH 0452/1064] CI: Use lld for linking LLVM in the x86_64-gnu-debug image. --- src/ci/docker/x86_64-gnu-debug/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index 10d92256dccca..1c7eff68adc15 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -33,6 +33,7 @@ ENV RUST_CONFIGURE_ARGS \ --enable-lld \ --enable-lldb \ --enable-optimize \ + --set llvm.use-linker=lld \ --set target.x86_64-unknown-linux-gnu.linker=clang \ --set target.x86_64-unknown-linux-gnu.cc=clang \ --set target.x86_64-unknown-linux-gnu.cxx=clang++ From a3f0af2e672055cddef1e87b56caff763322e6d9 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 30 Jan 2019 18:57:55 +0530 Subject: [PATCH 0453/1064] Add MOVBE feature --- src/librustc_codegen_llvm/llvm_util.rs | 1 + src/librustc_typeck/collect.rs | 1 + src/libsyntax/feature_gate.rs | 1 + src/test/ui/target-feature-gate.rs | 1 + src/test/ui/target-feature-gate.stderr | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index e2d0e558d3b78..b46e6ef84b98b 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -147,6 +147,7 @@ const X86_WHITELIST: &[(&str, Option<&str>)] = &[ ("fxsr", None), ("lzcnt", None), ("mmx", Some("mmx_target_feature")), + ("movbe", Some("movbe_target_feature")), ("pclmulqdq", None), ("popcnt", None), ("rdrand", None), diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ade84faae8dbd..393f3066c62e3 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2205,6 +2205,7 @@ fn from_target_feature( Some("wasm_target_feature") => rust_features.wasm_target_feature, Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature, Some("adx_target_feature") => rust_features.adx_target_feature, + Some("movbe_target_feature") => rust_features.movbe_target_feature, Some(name) => bug!("unknown target feature gate {}", name), None => true, }; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2820924824697..9dd17b420aa44 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -394,6 +394,7 @@ declare_features! ( (active, wasm_target_feature, "1.30.0", Some(44839), None), (active, adx_target_feature, "1.32.0", Some(44839), None), (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None), + (active, movbe_target_feature, "1.34.0", Some(44839), None), // Allows macro invocations on modules expressions and statements and // procedural macros to expand to non-items. diff --git a/src/test/ui/target-feature-gate.rs b/src/test/ui/target-feature-gate.rs index 30fb534dbb591..84300301b7629 100644 --- a/src/test/ui/target-feature-gate.rs +++ b/src/test/ui/target-feature-gate.rs @@ -22,6 +22,7 @@ // gate-test-wasm_target_feature // gate-test-adx_target_feature // gate-test-cmpxchg16b_target_feature +// gate-test-movbe_target_feature // min-llvm-version 6.0 #[target_feature(enable = "avx512bw")] diff --git a/src/test/ui/target-feature-gate.stderr b/src/test/ui/target-feature-gate.stderr index 8dfb4f65f98c4..24141d0064fb0 100644 --- a/src/test/ui/target-feature-gate.stderr +++ b/src/test/ui/target-feature-gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `avx512bw` is currently unstable (see issue #44839) - --> $DIR/target-feature-gate.rs:27:18 + --> $DIR/target-feature-gate.rs:28:18 | LL | #[target_feature(enable = "avx512bw")] | ^^^^^^^^^^^^^^^^^^^ From 4056b575e2f7d6fe88b0c72714f3bd044d1dadb6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 17:47:36 +0100 Subject: [PATCH 0454/1064] Add suggestions to deprecation lints --- src/libcore/lib.rs | 1 + src/libcore/sync/atomic.rs | 33 +++++++++- src/librustc/ich/impls_syntax.rs | 2 +- src/librustc/middle/stability.rs | 62 ++++++++++++------- src/libsyntax/attr/builtin.rs | 5 +- .../ui/deprecation/atomic_initializers.fixed | 11 ++++ .../ui/deprecation/atomic_initializers.rs | 11 ++++ .../ui/deprecation/atomic_initializers.stderr | 12 ++++ 8 files changed, 111 insertions(+), 26 deletions(-) create mode 100644 src/test/ui/deprecation/atomic_initializers.fixed create mode 100644 src/test/ui/deprecation/atomic_initializers.rs create mode 100644 src/test/ui/deprecation/atomic_initializers.stderr diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 6f364eb970965..7180a813a3e47 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -124,6 +124,7 @@ #![feature(abi_unadjusted)] #![feature(adx_target_feature)] #![feature(maybe_uninit)] +#![feature(unrestricted_attribute_tokens)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index bcedff5abc70c..8c5dde7dc271b 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -290,7 +290,15 @@ pub enum Ordering { /// [`AtomicBool`]: struct.AtomicBool.html #[cfg(target_has_atomic = "8")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_deprecated(since = "1.34.0", reason = "the `new` function is now preferred")] +#[cfg_attr(not(stage0), rustc_deprecated( + since = "1.34.0", + reason = "the `new` function is now preferred", + suggestion = "AtomicBool::new(false)", +))] +#[cfg_attr(stage0, rustc_deprecated( + since = "1.34.0", + reason = "the `new` function is now preferred", +))] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); #[cfg(target_has_atomic = "8")] @@ -1127,6 +1135,7 @@ macro_rules! atomic_int { $extra_feature:expr, $min_fn:ident, $max_fn:ident, $align:expr, + $atomic_new:expr, $int_type:ident $atomic_type:ident $atomic_init:ident) => { /// An integer type which can be safely shared between threads. /// @@ -1148,7 +1157,15 @@ macro_rules! atomic_int { /// An atomic integer initialized to `0`. #[$stable] - #[rustc_deprecated(since = "1.34.0", reason = "the `new` function is now preferred")] + #[cfg_attr(stage0, rustc_deprecated( + since = "1.34.0", + reason = "the `new` function is now preferred", + ))] + #[cfg_attr(not(stage0), rustc_deprecated( + since = "1.34.0", + reason = "the `new` function is now preferred", + suggestion = $atomic_new, + ))] pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] @@ -1878,6 +1895,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, 1, + "AtomicI8::new(0)", i8 AtomicI8 ATOMIC_I8_INIT } #[cfg(target_has_atomic = "8")] @@ -1892,6 +1910,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, 1, + "AtomicU8::new(0)", u8 AtomicU8 ATOMIC_U8_INIT } #[cfg(target_has_atomic = "16")] @@ -1906,6 +1925,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, 2, + "AtomicI16::new(0)", i16 AtomicI16 ATOMIC_I16_INIT } #[cfg(target_has_atomic = "16")] @@ -1920,6 +1940,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, 2, + "AtomicU16::new(0)", u16 AtomicU16 ATOMIC_U16_INIT } #[cfg(target_has_atomic = "32")] @@ -1934,6 +1955,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, 4, + "AtomicI32::new(0)", i32 AtomicI32 ATOMIC_I32_INIT } #[cfg(target_has_atomic = "32")] @@ -1948,6 +1970,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, 4, + "AtomicU32::new(0)", u32 AtomicU32 ATOMIC_U32_INIT } #[cfg(target_has_atomic = "64")] @@ -1962,6 +1985,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, 8, + "AtomicI64::new(0)", i64 AtomicI64 ATOMIC_I64_INIT } #[cfg(target_has_atomic = "64")] @@ -1976,6 +2000,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, 8, + "AtomicU64::new(0)", u64 AtomicU64 ATOMIC_U64_INIT } #[cfg(target_has_atomic = "128")] @@ -1990,6 +2015,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, 16, + "AtomicI128::new(0)", i128 AtomicI128 ATOMIC_I128_INIT } #[cfg(target_has_atomic = "128")] @@ -2004,6 +2030,7 @@ atomic_int! { "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, 16, + "AtomicU128::new(0)", u128 AtomicU128 ATOMIC_U128_INIT } #[cfg(target_pointer_width = "16")] @@ -2030,6 +2057,7 @@ atomic_int!{ "", atomic_min, atomic_max, ptr_width!(), + "AtomicIsize::new(0)", isize AtomicIsize ATOMIC_ISIZE_INIT } #[cfg(target_has_atomic = "ptr")] @@ -2044,6 +2072,7 @@ atomic_int!{ "", atomic_umin, atomic_umax, ptr_width!(), + "AtomicUsize::new(0)", usize AtomicUsize ATOMIC_USIZE_INIT } diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 7e48554067a95..e10359636f749 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -147,7 +147,7 @@ for ::syntax::attr::StabilityLevel { } } -impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason }); +impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion }); impl_stable_hash_for!(enum ::syntax::attr::IntType { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 918e286c435bc..a9193e06d89e9 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -16,6 +16,7 @@ use syntax::symbol::Symbol; use syntax_pos::{Span, MultiSpan}; use syntax::ast; use syntax::ast::{NodeId, Attribute}; +use syntax::errors::Applicability; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::attr::{self, Stability, Deprecation}; use ty::{self, TyCtxt}; @@ -569,6 +570,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let lint_deprecated = |def_id: DefId, id: NodeId, note: Option, + suggestion: Option, message: &str, lint: &'static Lint| { let msg = if let Some(note) = note { @@ -577,7 +579,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { format!("{}", message) }; - self.lint_node(lint, id, span, &msg); + let mut diag = self.struct_span_lint_node(lint, id, span, &msg); + if let Some(suggestion) = suggestion { + if let hir::Node::Expr(_) = self.hir().get(id) { + diag.span_suggestion( + span, + &msg, + suggestion.to_string(), + Applicability::MachineApplicable, + ); + } + } + diag.emit(); if id == ast::DUMMY_NODE_ID { span_bug!(span, "emitted a {} lint with dummy node id: {:?}", lint.name, def_id); } @@ -613,6 +626,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { lint_deprecated(def_id, id, depr_entry.attr.note, + None, &message, lint::builtin::DEPRECATED_IN_FUTURE); } else if !skip { @@ -621,6 +635,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { lint_deprecated(def_id, id, depr_entry.attr.note, + None, &message, lint::builtin::DEPRECATED); } @@ -639,27 +654,30 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("stability: \ inspecting def_id={:?} span={:?} of stability={:?}", def_id, span, stability); - if let Some(&Stability{rustc_depr: Some(attr::RustcDeprecation { reason, since }), ..}) - = stability { - if let Some(id) = id { - let path = self.item_path_str(def_id); - if deprecation_in_effect(&since.as_str()) { - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - Some(reason), - &message, - lint::builtin::DEPRECATED); - } else { - let message = format!("use of item '{}' \ - that will be deprecated in future version {}", - path, - since); - lint_deprecated(def_id, - id, - Some(reason), - &message, - lint::builtin::DEPRECATED_IN_FUTURE); + if let Some(id) = id { + if let Some(stability) = stability { + if let Some(depr) = &stability.rustc_depr { + let path = self.item_path_str(def_id); + if deprecation_in_effect(&depr.since.as_str()) { + let message = format!("use of deprecated item '{}'", path); + lint_deprecated(def_id, + id, + Some(depr.reason), + depr.suggestion, + &message, + lint::builtin::DEPRECATED); + } else { + let message = format!("use of item '{}' \ + that will be deprecated in future version {}", + path, + depr.since); + lint_deprecated(def_id, + id, + Some(depr.reason), + depr.suggestion, + &message, + lint::builtin::DEPRECATED_IN_FUTURE); + } } } } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 08c7c617a7bef..7fe6f4a231689 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -158,6 +158,8 @@ impl StabilityLevel { pub struct RustcDeprecation { pub since: Symbol, pub reason: Symbol, + /// A text snippet used to completely replace any use of the deprecated item in an expression. + pub suggestion: Option, } /// Check if `attrs` contains an attribute like `#![feature(feature_name)]`. @@ -274,13 +276,14 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, continue 'outer } - get_meta!(since, reason); + get_meta!(since, reason, suggestion); match (since, reason) { (Some(since), Some(reason)) => { rustc_depr = Some(RustcDeprecation { since, reason, + suggestion, }) } (None, _) => { diff --git a/src/test/ui/deprecation/atomic_initializers.fixed b/src/test/ui/deprecation/atomic_initializers.fixed new file mode 100644 index 0000000000000..dee1d979cff1d --- /dev/null +++ b/src/test/ui/deprecation/atomic_initializers.fixed @@ -0,0 +1,11 @@ +// run-rustfix +// compile-pass + +#[allow(deprecated, unused_imports)] +use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; + +#[allow(dead_code)] +static FOO: AtomicIsize = AtomicIsize::new(0); +//~^ WARN use of deprecated item + +fn main() {} diff --git a/src/test/ui/deprecation/atomic_initializers.rs b/src/test/ui/deprecation/atomic_initializers.rs new file mode 100644 index 0000000000000..b9e25e817bce4 --- /dev/null +++ b/src/test/ui/deprecation/atomic_initializers.rs @@ -0,0 +1,11 @@ +// run-rustfix +// compile-pass + +#[allow(deprecated, unused_imports)] +use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; + +#[allow(dead_code)] +static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; +//~^ WARN use of deprecated item + +fn main() {} diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr new file mode 100644 index 0000000000000..77c370814f7af --- /dev/null +++ b/src/test/ui/deprecation/atomic_initializers.stderr @@ -0,0 +1,12 @@ +warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred + --> $DIR/atomic_initializers.rs:8:27 + | +LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; + | ^^^^^^^^^^^^^^^^^ + | + = note: #[warn(deprecated)] on by default +help: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred + | +LL | static FOO: AtomicIsize = AtomicIsize::new(0); + | ^^^^^^^^^^^^^^^^^^^ + From a7a5cb620feab14defb633af4ebf8d0671c22441 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 17:50:46 +0100 Subject: [PATCH 0455/1064] Prefer macro over manual implementation --- src/librustc_mir/interpret/snapshot.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 0b5dc9446921a..c9fe673c847d1 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -7,7 +7,7 @@ use std::hash::{Hash, Hasher}; -use rustc::ich::{StableHashingContextProvider, StableHashingContext}; +use rustc::ich::StableHashingContextProvider; use rustc::mir; use rustc::mir::interpret::{ AllocId, Pointer, Scalar, @@ -19,7 +19,7 @@ use rustc::ty::{self, TyCtxt}; use rustc::ty::layout::Align; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use syntax::ast::Mutability; use syntax::source_map::Span; @@ -366,16 +366,10 @@ impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalValue<'tcx> } } - -impl<'a, 'gcx> HashStable> for LocalValue<'gcx> { - fn hash_stable( - &self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher, - ) { - self.state.hash_stable(hcx, hasher); - } -} +impl_stable_hash_for!(struct LocalValue<'tcx> { + state, + layout -> _, +}); impl<'a, 'b, 'mir, 'tcx: 'a+'mir> SnapshotContext<'b> for Memory<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>> From 765fa81a6e8d063db60be20e710e51d8ca995fbd Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 17:51:59 +0100 Subject: [PATCH 0456/1064] Swap the names of `LocalValue` and `LocalState` --- src/librustc/mir/interpret/value.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 46 +++++++++++----------- src/librustc_mir/interpret/mod.rs | 2 +- src/librustc_mir/interpret/snapshot.rs | 16 ++++---- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 4ac84bcfd1903..1328a1aeeab96 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -14,7 +14,7 @@ pub struct RawConst<'tcx> { } /// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which -/// matches the LocalValue optimizations for easy conversions between Value and ConstValue. +/// matches the LocalState optimizations for easy conversions between Value and ConstValue. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)] pub enum ConstValue<'tcx> { /// Used only for types with layout::abi::Scalar ABI and ZSTs diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 4e66d21214b29..1b976d822ebff 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -76,7 +76,7 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=(), Extra=()> { /// The locals are stored as `Option`s. /// `None` represents a local that is currently dead, while a live local /// can either directly contain `Scalar` or refer to some part of an `Allocation`. - pub locals: IndexVec>, + pub locals: IndexVec>, //////////////////////////////////////////////////////////////////////////////// // Current position within the function @@ -107,15 +107,15 @@ pub enum StackPopCleanup { /// State of a local variable including a memoized layout #[derive(Clone, PartialEq, Eq)] -pub struct LocalValue<'tcx, Tag=(), Id=AllocId> { - pub state: LocalState, +pub struct LocalState<'tcx, Tag=(), Id=AllocId> { + pub state: LocalValue, /// Don't modify if `Some`, this is only used to prevent computing the layout twice pub layout: Cell>>, } /// State of a local variable #[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub enum LocalState { +pub enum LocalValue { Dead, // Mostly for convenience, we re-use the `Operand` type here. // This is an optimization over just always having a pointer here; @@ -124,18 +124,18 @@ pub enum LocalState { Live(Operand), } -impl<'tcx, Tag> LocalValue<'tcx, Tag> { +impl<'tcx, Tag> LocalState<'tcx, Tag> { pub fn access(&self) -> EvalResult<'tcx, &Operand> { match self.state { - LocalState::Dead => err!(DeadLocal), - LocalState::Live(ref val) => Ok(val), + LocalValue::Dead => err!(DeadLocal), + LocalValue::Live(ref val) => Ok(val), } } pub fn access_mut(&mut self) -> EvalResult<'tcx, &mut Operand> { match self.state { - LocalState::Dead => err!(DeadLocal), - LocalState::Live(ref mut val) => Ok(val), + LocalValue::Dead => err!(DeadLocal), + LocalValue::Live(ref mut val) => Ok(val), } } } @@ -474,10 +474,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // don't allocate at all for trivial constants if mir.local_decls.len() > 1 { // We put some marker immediate into the locals that we later want to initialize. - // This can be anything except for LocalState::Dead -- because *that* is the + // This can be anything except for LocalValue::Dead -- because *that* is the // value we use for things that we know are initially dead. - let dummy = LocalValue { - state: LocalState::Live(Operand::Immediate(Immediate::Scalar( + let dummy = LocalState { + state: LocalValue::Live(Operand::Immediate(Immediate::Scalar( ScalarMaybeUndef::Undef, ))), layout: Cell::new(None), @@ -485,7 +485,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc let mut locals = IndexVec::from_elem(dummy, &mir.local_decls); // Return place is handled specially by the `eval_place` functions, and the // entry in `locals` should never be used. Make it dead, to be sure. - locals[mir::RETURN_PLACE].state = LocalState::Dead; + locals[mir::RETURN_PLACE].state = LocalValue::Dead; // Now mark those locals as dead that we do not want to initialize match self.tcx.describe_def(instance.def_id()) { // statics and constants don't have `Storage*` statements, no need to look for them @@ -498,7 +498,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc match stmt.kind { StorageLive(local) | StorageDead(local) => { - locals[local].state = LocalState::Dead; + locals[local].state = LocalValue::Dead; } _ => {} } @@ -509,14 +509,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // Finally, properly initialize all those that still have the dummy value for (idx, local) in locals.iter_enumerated_mut() { match local.state { - LocalState::Live(_) => { + LocalValue::Live(_) => { // This needs to be properly initialized. let ty = self.monomorphize(mir.local_decls[idx].ty)?; let layout = self.layout_of(ty)?; - local.state = LocalState::Live(self.uninit_operand(layout)?); + local.state = LocalValue::Live(self.uninit_operand(layout)?); local.layout = Cell::new(Some(layout)); } - LocalState::Dead => { + LocalValue::Dead => { // Nothing to do } } @@ -603,31 +603,31 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc pub fn storage_live( &mut self, local: mir::Local - ) -> EvalResult<'tcx, LocalState> { + ) -> EvalResult<'tcx, LocalValue> { assert!(local != mir::RETURN_PLACE, "Cannot make return place live"); trace!("{:?} is now live", local); let layout = self.layout_of_local(self.frame(), local, None)?; - let init = LocalState::Live(self.uninit_operand(layout)?); + let init = LocalValue::Live(self.uninit_operand(layout)?); // StorageLive *always* kills the value that's currently stored Ok(mem::replace(&mut self.frame_mut().locals[local].state, init)) } /// Returns the old value of the local. /// Remember to deallocate that! - pub fn storage_dead(&mut self, local: mir::Local) -> LocalState { + pub fn storage_dead(&mut self, local: mir::Local) -> LocalValue { assert!(local != mir::RETURN_PLACE, "Cannot make return place dead"); trace!("{:?} is now dead", local); - mem::replace(&mut self.frame_mut().locals[local].state, LocalState::Dead) + mem::replace(&mut self.frame_mut().locals[local].state, LocalValue::Dead) } pub(super) fn deallocate_local( &mut self, - local: LocalState, + local: LocalValue, ) -> EvalResult<'tcx> { // FIXME: should we tell the user that there was a local which was never written to? - if let LocalState::Live(Operand::Indirect(MemPlace { ptr, .. })) = local { + if let LocalValue::Live(Operand::Indirect(MemPlace { ptr, .. })) = local { trace!("deallocating local"); let ptr = ptr.to_ptr()?; self.memory.dump_alloc(ptr.alloc_id); diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 6ee7d3309f464..d2ab3fcb7a30a 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -18,7 +18,7 @@ mod visitor; pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here pub use self::eval_context::{ - EvalContext, Frame, StackPopCleanup, LocalValue, LocalState, + EvalContext, Frame, StackPopCleanup, LocalState, LocalValue, }; pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy}; diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index c9fe673c847d1..c4b56f571db9c 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -23,8 +23,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use syntax::ast::Mutability; use syntax::source_map::Span; -use super::eval_context::{LocalValue, StackPopCleanup}; -use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef, LocalState}; +use super::eval_context::{LocalState, StackPopCleanup}; +use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef, LocalValue}; use const_eval::CompileTimeInterpreter; #[derive(Default)] @@ -250,11 +250,11 @@ impl_snapshot_for!(enum Operand { Indirect(m), }); -impl_stable_hash_for!(enum ::interpret::LocalState { +impl_stable_hash_for!(enum ::interpret::LocalValue { Dead, Live(x), }); -impl_snapshot_for!(enum LocalState { +impl_snapshot_for!(enum LocalValue { Live(v), Dead, }); @@ -309,7 +309,7 @@ struct FrameSnapshot<'a, 'tcx: 'a> { span: &'a Span, return_to_block: &'a StackPopCleanup, return_place: Option>>, - locals: IndexVec>>, + locals: IndexVec>>, block: &'a mir::BasicBlock, stmt: usize, } @@ -356,17 +356,17 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> } } -impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalValue<'tcx> +impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalState<'tcx> where Ctx: SnapshotContext<'a>, { - type Item = LocalState<(), AllocIdSnapshot<'a>>; + type Item = LocalValue<(), AllocIdSnapshot<'a>>; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { self.state.snapshot(ctx) } } -impl_stable_hash_for!(struct LocalValue<'tcx> { +impl_stable_hash_for!(struct LocalState<'tcx> { state, layout -> _, }); From 4a3caca978042b3d1f6700a5dce757414992a714 Mon Sep 17 00:00:00 2001 From: Rett Berg Date: Wed, 30 Jan 2019 09:14:28 -0800 Subject: [PATCH 0457/1064] fix #57686: update docs for fix_start/end_matches --- src/libcore/str/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ac92018563654..a47ea8d2a4609 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3774,10 +3774,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. 'Left' in this context means the first - /// position of that byte string; for a language like Arabic or Hebrew - /// which are 'right to left' rather than 'left to right', this will be - /// the _right_ side, not the left. + /// A string is a sequence of bytes. `start` in this context means the first + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be left side; and for right-to-left languages like + /// like Arabic or Hebrew, this will be the right side. /// /// # Examples /// @@ -3806,10 +3806,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. 'Right' in this context means the last - /// position of that byte string; for a language like Arabic or Hebrew - /// which are 'right to left' rather than 'left to right', this will be - /// the _left_ side, not the right. + /// A string is a sequence of bytes. `end` in this context means the last + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be right side; and for right-to-left languages like + /// like Arabic or Hebrew, this will be the left side. /// /// # Examples /// From 037fdb8213da90f3fe26f78b1e415b86f59b0185 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Wed, 30 Jan 2019 07:30:39 +0100 Subject: [PATCH 0458/1064] Improve bug message in check_ty This branch was hit in Clippy and I think it would be nice to show the thing that was unexpected in the bug message. It's also in line with the other `bug!` messages in `check_ty`. --- src/librustc_typeck/collect.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ade84faae8dbd..120467cbd13a0 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1303,12 +1303,12 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> { } }, - Node::GenericParam(param) => match param.kind { + Node::GenericParam(param) => match ¶m.kind { hir::GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty), - _ => bug!("unexpected non-type NodeGenericParam"), + x => bug!("unexpected non-type Node::GenericParam: {:?}", x), }, x => { From 8c26c590b4b22066f4ae5ac245dfa7c2e5ae4044 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 30 Jan 2019 19:29:10 +0100 Subject: [PATCH 0459/1064] Failure resistent trait implementing --- src/librustc_mir/interpret/snapshot.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index c4b56f571db9c..5fae461bdc203 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -362,7 +362,8 @@ impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalState<'tcx> type Item = LocalValue<(), AllocIdSnapshot<'a>>; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { - self.state.snapshot(ctx) + let LocalState { state, layout: _ } = self; + state.snapshot(ctx) } } From 74675fed682d02282419e840b88a501bc0b909e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 30 Jan 2019 11:39:56 -0800 Subject: [PATCH 0460/1064] Don't panic when accessing enum variant ctor using `Self` in match --- src/librustc_typeck/check/_match.rs | 3 ++- src/test/ui/issues/issue-58006.rs | 15 +++++++++++++++ src/test/ui/issues/issue-58006.stderr | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-58006.rs create mode 100644 src/test/ui/issues/issue-58006.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 141b8222b1f33..4203c71a00a41 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -784,7 +784,8 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); report_unexpected_variant_def(tcx, &def, pat.span, qpath); return tcx.types.err; } - Def::VariantCtor(_, CtorKind::Fictive) => { + Def::VariantCtor(_, CtorKind::Fictive) | + Def::VariantCtor(_, CtorKind::Fn) => { report_unexpected_variant_def(tcx, &def, pat.span, qpath); return tcx.types.err; } diff --git a/src/test/ui/issues/issue-58006.rs b/src/test/ui/issues/issue-58006.rs new file mode 100644 index 0000000000000..1fb5fefa7596d --- /dev/null +++ b/src/test/ui/issues/issue-58006.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_enum_variants)] +pub enum Enum { + A(usize), +} + +impl Enum { + fn foo(&self) -> () { + match self { + Self::A => (), + //~^ ERROR expected unit struct/variant or constant, found tuple variant + } + } +} + +fn main() {} diff --git a/src/test/ui/issues/issue-58006.stderr b/src/test/ui/issues/issue-58006.stderr new file mode 100644 index 0000000000000..c65e3e2777fae --- /dev/null +++ b/src/test/ui/issues/issue-58006.stderr @@ -0,0 +1,9 @@ +error[E0533]: expected unit struct/variant or constant, found tuple variant `::A` + --> $DIR/issue-58006.rs:9:13 + | +LL | Self::A => (), + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0533`. From 6fe370c7ceef08dbbaed6a502b0dde0ee0614db9 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 30 Jan 2019 19:49:31 +0000 Subject: [PATCH 0461/1064] Pass correct arguments to places_conflict The borrow place *must* be a place that we track borrows for, otherwise we will likely ICE. --- src/librustc_mir/dataflow/impls/borrows.rs | 2 +- src/test/ui/nll/issue-57989.rs | 12 +++++++++++ src/test/ui/nll/issue-57989.stderr | 24 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/nll/issue-57989.rs create mode 100644 src/test/ui/nll/issue-57989.stderr diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 0ceff4aa04898..72218e29cfd20 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -215,8 +215,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { if places_conflict::places_conflict( self.tcx, self.mir, - place, &borrow_data.borrowed_place, + place, places_conflict::PlaceConflictBias::NoOverlap, ) { debug!( diff --git a/src/test/ui/nll/issue-57989.rs b/src/test/ui/nll/issue-57989.rs new file mode 100644 index 0000000000000..4f21cca97cc09 --- /dev/null +++ b/src/test/ui/nll/issue-57989.rs @@ -0,0 +1,12 @@ +// Test for ICE from issue 57989 + +#![feature(nll)] + +fn f(x: &i32) { + let g = &x; + *x = 0; //~ ERROR cannot assign to `*x` which is behind a `&` reference + //~| ERROR cannot assign to `*x` because it is borrowed + g; +} + +fn main() {} diff --git a/src/test/ui/nll/issue-57989.stderr b/src/test/ui/nll/issue-57989.stderr new file mode 100644 index 0000000000000..4561c99096f14 --- /dev/null +++ b/src/test/ui/nll/issue-57989.stderr @@ -0,0 +1,24 @@ +error[E0594]: cannot assign to `*x` which is behind a `&` reference + --> $DIR/issue-57989.rs:7:5 + | +LL | fn f(x: &i32) { + | ---- help: consider changing this to be a mutable reference: `&mut i32` +LL | let g = &x; +LL | *x = 0; //~ ERROR cannot assign to `*x` which is behind a `&` reference + | ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-57989.rs:7:5 + | +LL | let g = &x; + | -- borrow of `*x` occurs here +LL | *x = 0; //~ ERROR cannot assign to `*x` which is behind a `&` reference + | ^^^^^^ assignment to borrowed `*x` occurs here +LL | //~| ERROR cannot assign to `*x` because it is borrowed +LL | g; + | - borrow later used here + +error: aborting due to 2 previous errors + +Some errors occurred: E0506, E0594. +For more information about an error, try `rustc --explain E0506`. From 38bcd4b42a1d0a5546122e78efb266161aa4c731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 29 Jan 2019 16:47:30 +0100 Subject: [PATCH 0462/1064] Move privacy checking later in the pipeline and make some passes run in parallel --- src/librustc/hir/mod.rs | 26 ++--- src/librustc/middle/liveness.rs | 1 - src/librustc/session/mod.rs | 4 +- src/librustc_data_structures/sync.rs | 27 +++++ src/librustc_driver/driver.rs | 102 ++++++++++-------- src/librustc_driver/lib.rs | 1 + src/librustc_passes/rvalue_promotion.rs | 1 - src/test/ui/error-codes/E0446.rs | 2 +- src/test/ui/error-codes/E0446.stderr | 4 +- src/test/ui/error-codes/E0451.rs | 8 +- src/test/ui/error-codes/E0451.stderr | 12 +-- ...nctional-struct-update-respects-privacy.rs | 4 +- src/test/ui/privacy/private-in-public-warn.rs | 2 + .../ui/privacy/private-in-public-warn.stderr | 65 ++++++----- src/test/ui/privacy/private-inferred-type.rs | 2 +- 15 files changed, 157 insertions(+), 104 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 657e6e5dcde35..841124bb4a60a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -30,7 +30,7 @@ use syntax::util::parser::ExprPrecedence; use ty::AdtKind; use ty::query::Providers; -use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope}; +use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync}; use rustc_data_structures::thin_vec::ThinVec; use serialize::{self, Encoder, Encodable, Decoder, Decodable}; @@ -754,23 +754,17 @@ impl Crate { pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V) where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send { - scope(|s| { - s.spawn(|_| { - par_iter(&self.items).for_each(|(_, item)| { - visitor.visit_item(item); - }); + parallel!({ + par_iter(&self.items).for_each(|(_, item)| { + visitor.visit_item(item); }); - - s.spawn(|_| { - par_iter(&self.trait_items).for_each(|(_, trait_item)| { - visitor.visit_trait_item(trait_item); - }); + }, { + par_iter(&self.trait_items).for_each(|(_, trait_item)| { + visitor.visit_trait_item(trait_item); }); - - s.spawn(|_| { - par_iter(&self.impl_items).for_each(|(_, impl_item)| { - visitor.visit_impl_item(impl_item); - }); + }, { + par_iter(&self.impl_items).for_each(|(_, impl_item)| { + visitor.visit_impl_item(impl_item); }); }); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 4ef8e1a0cf95b..841a93cae1b62 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -189,7 +189,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { queries::check_mod_liveness::ensure(tcx, tcx.hir().local_def_id(module)); } - tcx.sess.abort_if_errors(); } pub fn provide(providers: &mut Providers<'_>) { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index c5034415d6ffb..b273c73332c67 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -85,7 +85,7 @@ pub struct Session { /// in order to avoid redundantly verbose output (Issue #24690, #44953). pub one_time_diagnostics: Lock, String)>>, pub plugin_llvm_passes: OneThread>>, - pub plugin_attributes: OneThread>>, + pub plugin_attributes: Lock>, pub crate_types: Once>, pub dependency_formats: Once, /// The crate_disambiguator is constructed out of all the `-C metadata` @@ -1178,7 +1178,7 @@ pub fn build_session_( buffered_lints: Lock::new(Some(Default::default())), one_time_diagnostics: Default::default(), plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), - plugin_attributes: OneThread::new(RefCell::new(Vec::new())), + plugin_attributes: Lock::new(Vec::new()), crate_types: Once::new(), dependency_formats: Once::new(), crate_disambiguator: Once::new(), diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index cae3087fe586c..7fef1f374d6fd 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -127,6 +127,13 @@ cfg_if! { pub use self::serial_join as join; pub use self::serial_scope as scope; + #[macro_export] + macro_rules! parallel { + ($($blocks:tt),*) => { + $($blocks)*; + } + } + pub use std::iter::Iterator as ParallelIterator; pub fn par_iter(t: T) -> T::IntoIter { @@ -271,6 +278,26 @@ cfg_if! { use std::thread; pub use rayon::{join, scope}; + #[macro_export] + macro_rules! parallel { + (impl [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { + parallel!(impl [$block, $($c,)*] [$($rest),*]) + }; + (impl [$($blocks:tt,)*] []) => { + ::rustc_data_structures::sync::scope(|s| { + $( + s.spawn(|_| $blocks); + )* + }) + }; + ($($blocks:tt),*) => { + // Reverse the order of the blocks since Rayon executes them in reverse order + // when using a single thread. This ensures the execution order matches that + // of a single threaded rustc + parallel!(impl [] [$($blocks),*]); + }; + } + pub use rayon_core::WorkerLocal; pub use rayon::iter::ParallelIterator; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c586c705676f4..a3fa55931f02e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1222,26 +1222,28 @@ where // tcx available. time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); - time(sess, "looking for entry point", || { - middle::entry::find_entry_point(tcx) - }); - - time(sess, "looking for plugin registrar", || { - plugin::build::find_plugin_registrar(tcx) - }); - - time(sess, "looking for derive registrar", || { - proc_macro_decls::find(tcx) - }); - - time(sess, "loop checking", || loops::check_crate(tcx)); + parallel!({ + time(sess, "looking for entry point", || { + middle::entry::find_entry_point(tcx) + }); - time(sess, "attribute checking", || { - hir::check_attr::check_crate(tcx) - }); + time(sess, "looking for plugin registrar", || { + plugin::build::find_plugin_registrar(tcx) + }); - time(sess, "stability checking", || { - stability::check_unstable_api_usage(tcx) + time(sess, "looking for derive registrar", || { + proc_macro_decls::find(tcx) + }); + }, { + time(sess, "loop checking", || loops::check_crate(tcx)); + }, { + time(sess, "attribute checking", || { + hir::check_attr::check_crate(tcx) + }); + }, { + time(sess, "stability checking", || { + stability::check_unstable_api_usage(tcx) + }); }); // passes are timed inside typeck @@ -1253,27 +1255,31 @@ where } } - time(sess, "rvalue promotion", || { - rvalue_promotion::check_crate(tcx) - }); - - time(sess, "privacy checking", || { - rustc_privacy::check_crate(tcx) - }); - - time(sess, "intrinsic checking", || { - middle::intrinsicck::check_crate(tcx) + time(sess, "misc checking", || { + parallel!({ + time(sess, "rvalue promotion", || { + rvalue_promotion::check_crate(tcx) + }); + }, { + time(sess, "intrinsic checking", || { + middle::intrinsicck::check_crate(tcx) + }); + }, { + time(sess, "match checking", || mir::matchck_crate(tcx)); + }, { + // this must run before MIR dump, because + // "not all control paths return a value" is reported here. + // + // maybe move the check to a MIR pass? + time(sess, "liveness checking", || { + middle::liveness::check_crate(tcx) + }); + }); }); - time(sess, "match checking", || mir::matchck_crate(tcx)); - - // this must run before MIR dump, because - // "not all control paths return a value" is reported here. - // - // maybe move the check to a MIR pass? - time(sess, "liveness checking", || { - middle::liveness::check_crate(tcx) - }); + // Abort so we don't try to construct MIR with liveness errors. + // We also won't want to continue with errors from rvalue promotion + tcx.sess.abort_if_errors(); time(sess, "borrow checking", || { if tcx.use_ast_borrowck() { @@ -1297,7 +1303,7 @@ where time(sess, "layout testing", || layout_test::test_layout(tcx)); - // Avoid overwhelming user with errors if type checking failed. + // Avoid overwhelming user with errors if borrow checking failed. // I'm not sure how helpful this is, to be honest, but it avoids // a // lot of annoying errors in the compile-fail tests (basically, @@ -1307,14 +1313,22 @@ where return Ok(f(tcx, rx, sess.compile_status())); } - time(sess, "death checking", || middle::dead::check_crate(tcx)); - - time(sess, "unused lib feature checking", || { - stability::check_unused_or_stable_features(tcx) + time(sess, "misc checking", || { + parallel!({ + time(sess, "privacy checking", || { + rustc_privacy::check_crate(tcx) + }); + }, { + time(sess, "death checking", || middle::dead::check_crate(tcx)); + }, { + time(sess, "unused lib feature checking", || { + stability::check_unused_or_stable_features(tcx) + }); + }, { + time(sess, "lint checking", || lint::check_crate(tcx)); + }); }); - time(sess, "lint checking", || lint::check_crate(tcx)); - return Ok(f(tcx, rx, tcx.sess.compile_status())); }, ) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a95ce810ffaeb..5f98ea29d2e76 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -30,6 +30,7 @@ extern crate rustc; extern crate rustc_allocator; extern crate rustc_target; extern crate rustc_borrowck; +#[macro_use] extern crate rustc_data_structures; extern crate rustc_errors as errors; extern crate rustc_passes; diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index c11b1af97766d..739c96934e6ab 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -44,7 +44,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let def_id = tcx.hir().body_owner_def_id(body_id); tcx.const_is_rvalue_promotable_to_static(def_id); } - tcx.sess.abort_if_errors(); } fn const_is_rvalue_promotable_to_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/test/ui/error-codes/E0446.rs b/src/test/ui/error-codes/E0446.rs index 33bd6144716c8..f61c7e5461662 100644 --- a/src/test/ui/error-codes/E0446.rs +++ b/src/test/ui/error-codes/E0446.rs @@ -1,4 +1,4 @@ -mod Foo { +mod foo { struct Bar(u32); pub fn bar() -> Bar { //~ ERROR E0446 diff --git a/src/test/ui/error-codes/E0446.stderr b/src/test/ui/error-codes/E0446.stderr index 8f381320cf99e..9c7399515f439 100644 --- a/src/test/ui/error-codes/E0446.stderr +++ b/src/test/ui/error-codes/E0446.stderr @@ -1,8 +1,8 @@ -error[E0446]: private type `Foo::Bar` in public interface +error[E0446]: private type `foo::Bar` in public interface --> $DIR/E0446.rs:4:5 | LL | struct Bar(u32); - | - `Foo::Bar` declared as private + | - `foo::Bar` declared as private LL | LL | / pub fn bar() -> Bar { //~ ERROR E0446 LL | | Bar(0) diff --git a/src/test/ui/error-codes/E0451.rs b/src/test/ui/error-codes/E0451.rs index 7c1c326fb5bec..aa8f051afa777 100644 --- a/src/test/ui/error-codes/E0451.rs +++ b/src/test/ui/error-codes/E0451.rs @@ -1,4 +1,4 @@ -mod Bar { +mod bar { pub struct Foo { pub a: isize, b: isize, @@ -10,10 +10,10 @@ mod Bar { ); } -fn pat_match(foo: Bar::Foo) { - let Bar::Foo{a:a, b:b} = foo; //~ ERROR E0451 +fn pat_match(foo: bar::Foo) { + let bar::Foo{a, b} = foo; //~ ERROR E0451 } fn main() { - let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451 + let f = bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451 } diff --git a/src/test/ui/error-codes/E0451.stderr b/src/test/ui/error-codes/E0451.stderr index 11bc7e31803a7..11f0867724627 100644 --- a/src/test/ui/error-codes/E0451.stderr +++ b/src/test/ui/error-codes/E0451.stderr @@ -1,13 +1,13 @@ -error[E0451]: field `b` of struct `Bar::Foo` is private - --> $DIR/E0451.rs:14:23 +error[E0451]: field `b` of struct `bar::Foo` is private + --> $DIR/E0451.rs:14:21 | -LL | let Bar::Foo{a:a, b:b} = foo; //~ ERROR E0451 - | ^^^ field `b` is private +LL | let bar::Foo{a, b} = foo; //~ ERROR E0451 + | ^ field `b` is private -error[E0451]: field `b` of struct `Bar::Foo` is private +error[E0451]: field `b` of struct `bar::Foo` is private --> $DIR/E0451.rs:18:29 | -LL | let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451 +LL | let f = bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451 | ^^^^ field `b` is private error: aborting due to 2 previous errors diff --git a/src/test/ui/functional-struct-update/functional-struct-update-respects-privacy.rs b/src/test/ui/functional-struct-update/functional-struct-update-respects-privacy.rs index 00606af904835..7ae53020fe011 100644 --- a/src/test/ui/functional-struct-update/functional-struct-update-respects-privacy.rs +++ b/src/test/ui/functional-struct-update/functional-struct-update-respects-privacy.rs @@ -6,12 +6,12 @@ use self::foo::S; mod foo { use std::cell::{UnsafeCell}; - static mut count : UnsafeCell = UnsafeCell::new(1); + static mut COUNT : UnsafeCell = UnsafeCell::new(1); pub struct S { pub a: u8, pub b: String, secret_uid: u64 } pub fn make_secrets(a: u8, b: String) -> S { - let val = unsafe { let p = count.get(); let val = *p; *p = val + 1; val }; + let val = unsafe { let p = COUNT.get(); let val = *p; *p = val + 1; val }; println!("creating {}, uid {}", b, val); S { a: a, b: b, secret_uid: val } } diff --git a/src/test/ui/privacy/private-in-public-warn.rs b/src/test/ui/privacy/private-in-public-warn.rs index 29f365b69be4d..467b83746702b 100644 --- a/src/test/ui/privacy/private-in-public-warn.rs +++ b/src/test/ui/privacy/private-in-public-warn.rs @@ -49,6 +49,7 @@ mod traits { pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface //~| WARNING hard error + //~| WARNING bounds on generic parameters are not enforced in type aliases pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error pub trait Tr2 {} //~ ERROR private trait `traits::PrivTr` in public interface @@ -74,6 +75,7 @@ mod traits_where { pub type Alias where T: PrivTr = T; //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error + //~| WARNING where clauses are not enforced in type aliases pub trait Tr2 where T: PrivTr {} //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error diff --git a/src/test/ui/privacy/private-in-public-warn.stderr b/src/test/ui/privacy/private-in-public-warn.stderr index 8f9e7cd74f992..621d9a57fa076 100644 --- a/src/test/ui/privacy/private-in-public-warn.stderr +++ b/src/test/ui/privacy/private-in-public-warn.stderr @@ -112,7 +112,7 @@ LL | pub type Alias = T; //~ ERROR private trait `traits::PrivTr` = note: for more information, see issue #34537 error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:52:5 + --> $DIR/private-in-public-warn.rs:53:5 | LL | pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in pu = note: for more information, see issue #34537 error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:54:5 + --> $DIR/private-in-public-warn.rs:55:5 | LL | pub trait Tr2 {} //~ ERROR private trait `traits::PrivTr` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | pub trait Tr2 {} //~ ERROR private trait `traits::PrivTr` in = note: for more information, see issue #34537 error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:56:5 + --> $DIR/private-in-public-warn.rs:57:5 | LL | / pub trait Tr3 { LL | | //~^ ERROR private trait `traits::PrivTr` in public interface @@ -145,7 +145,7 @@ LL | | } = note: for more information, see issue #34537 error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:60:9 + --> $DIR/private-in-public-warn.rs:61:9 | LL | fn f(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | fn f(arg: T) {} //~ ERROR private trait `traits::PrivTr` = note: for more information, see issue #34537 error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:63:5 + --> $DIR/private-in-public-warn.rs:64:5 | LL | impl Pub {} //~ ERROR private trait `traits::PrivTr` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | impl Pub {} //~ ERROR private trait `traits::PrivTr` in p = note: for more information, see issue #34537 error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:65:5 + --> $DIR/private-in-public-warn.rs:66:5 | LL | impl PubTr for Pub {} //~ ERROR private trait `traits::PrivTr` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | impl PubTr for Pub {} //~ ERROR private trait `traits::Pr = note: for more information, see issue #34537 error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:74:5 + --> $DIR/private-in-public-warn.rs:75:5 | LL | pub type Alias where T: PrivTr = T; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | pub type Alias where T: PrivTr = T; = note: for more information, see issue #34537 error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:77:5 + --> $DIR/private-in-public-warn.rs:79:5 | LL | pub trait Tr2 where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,7 +190,7 @@ LL | pub trait Tr2 where T: PrivTr {} = note: for more information, see issue #34537 error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:81:9 + --> $DIR/private-in-public-warn.rs:83:9 | LL | fn f(arg: T) where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | fn f(arg: T) where T: PrivTr {} = note: for more information, see issue #34537 error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:85:5 + --> $DIR/private-in-public-warn.rs:87:5 | LL | impl Pub where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -208,7 +208,7 @@ LL | impl Pub where T: PrivTr {} = note: for more information, see issue #34537 error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:88:5 + --> $DIR/private-in-public-warn.rs:90:5 | LL | impl PubTr for Pub where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | impl PubTr for Pub where T: PrivTr {} = note: for more information, see issue #34537 error: private trait `generics::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:99:5 + --> $DIR/private-in-public-warn.rs:101:5 | LL | pub trait Tr1: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +226,7 @@ LL | pub trait Tr1: PrivTr {} = note: for more information, see issue #34537 error: private type `generics::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:102:5 + --> $DIR/private-in-public-warn.rs:104:5 | LL | pub trait Tr2: PubTr {} //~ ERROR private type `generics::Priv` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -235,7 +235,7 @@ LL | pub trait Tr2: PubTr {} //~ ERROR private type `generics::Priv` i = note: for more information, see issue #34537 error: private type `generics::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:104:5 + --> $DIR/private-in-public-warn.rs:106:5 | LL | pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Priv` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Pr = note: for more information, see issue #34537 error: private type `generics::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:106:5 + --> $DIR/private-in-public-warn.rs:108:5 | LL | pub trait Tr4: PubTr> {} //~ ERROR private type `generics::Priv` in public interface | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | pub trait Tr4: PubTr> {} //~ ERROR private type `generics::Pr = note: for more information, see issue #34537 error[E0446]: private type `impls::Priv` in public interface - --> $DIR/private-in-public-warn.rs:133:9 + --> $DIR/private-in-public-warn.rs:135:9 | LL | struct Priv; | - `impls::Priv` declared as private @@ -262,7 +262,7 @@ LL | type Alias = Priv; //~ ERROR private type `impls::Priv` in public i | ^^^^^^^^^^^^^^^^^^ can't leak private type error: private type `aliases_pub::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:204:9 + --> $DIR/private-in-public-warn.rs:206:9 | LL | pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface | ^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` i = note: for more information, see issue #34537 error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:208:9 + --> $DIR/private-in-public-warn.rs:210:9 | LL | struct Priv; | - `aliases_pub::Priv` declared as private @@ -280,7 +280,7 @@ LL | type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in pu | ^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:211:9 + --> $DIR/private-in-public-warn.rs:213:9 | LL | struct Priv; | - `aliases_pub::Priv` declared as private @@ -289,7 +289,7 @@ LL | type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in pu | ^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:214:9 + --> $DIR/private-in-public-warn.rs:216:9 | LL | struct Priv; | - `aliases_pub::Priv` declared as private @@ -298,7 +298,7 @@ LL | type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in pu | ^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:217:9 + --> $DIR/private-in-public-warn.rs:219:9 | LL | struct Priv; | - `aliases_pub::Priv` declared as private @@ -307,7 +307,7 @@ LL | type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in pu | ^^^^^^^^^^^^^^^^^^ can't leak private type error: private trait `aliases_priv::PrivTr1` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:247:5 + --> $DIR/private-in-public-warn.rs:249:5 | LL | pub trait Tr1: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -316,7 +316,7 @@ LL | pub trait Tr1: PrivUseAliasTr {} = note: for more information, see issue #34537 error: private trait `aliases_priv::PrivTr1` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:250:5 + --> $DIR/private-in-public-warn.rs:252:5 | LL | pub trait Tr2: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | pub trait Tr2: PrivUseAliasTr {} = note: for more information, see issue #34537 error: private type `aliases_priv::Priv2` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:250:5 + --> $DIR/private-in-public-warn.rs:252:5 | LL | pub trait Tr2: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -333,6 +333,23 @@ LL | pub trait Tr2: PrivUseAliasTr {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/private-in-public-warn.rs:50:23 + | +LL | pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface + | ^^^^^^ + | + = note: #[warn(type_alias_bounds)] on by default + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/private-in-public-warn.rs:75:29 + | +LL | pub type Alias where T: PrivTr = T; + | ^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0446`. diff --git a/src/test/ui/privacy/private-inferred-type.rs b/src/test/ui/privacy/private-inferred-type.rs index 69b60a56c67f1..d98cf5991efeb 100644 --- a/src/test/ui/privacy/private-inferred-type.rs +++ b/src/test/ui/privacy/private-inferred-type.rs @@ -1,4 +1,3 @@ -#![feature(associated_consts)] #![feature(decl_macro)] #![allow(private_in_public)] @@ -15,6 +14,7 @@ mod m { pub struct PubTupleStruct(u8); impl PubTupleStruct { fn method() {} } + #[derive(Clone, Copy)] struct Priv; pub type Alias = Priv; pub struct Pub(pub T); From e6d5f251f11f4ac74f23748b665a29f0ceddfdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 30 Jan 2019 00:50:27 +0100 Subject: [PATCH 0463/1064] Fix #57730 --- src/librustc_passes/ast_validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 3deb2ff8d8a0b..bad1367a89af4 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -519,7 +519,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let Some(ref type_) = data.output { // `-> Foo` syntax is essentially an associated type binding, // so it is also allowed to contain nested `impl Trait`. - self.with_impl_trait(None, |this| visit::walk_ty(this, type_)); + self.with_impl_trait(None, |this| this.visit_ty(type_)); } } } From 1595163356546e8a4db55784bcc591e2c5cea26c Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 29 Jan 2019 13:34:40 +0100 Subject: [PATCH 0464/1064] Add suggestion for duplicated import. This commit adds a suggestion when a import is duplicated (ie. the same name is used twice trying to import the same thing) to remove the second import. --- src/librustc_resolve/build_reduced_graph.rs | 9 + src/librustc_resolve/lib.rs | 275 +++++++++++++++--- src/librustc_resolve/resolve_imports.rs | 28 +- src/libsyntax/ast.rs | 7 + src/test/ui/double-type-import.stderr | 9 +- src/test/ui/error-codes/E0430.stderr | 10 +- src/test/ui/imports/duplicate.stderr | 9 +- src/test/ui/issues/auxiliary/issue-52891.rs | 33 +++ src/test/ui/issues/issue-26886.stderr | 18 +- .../ui/issues/issue-45829/import-twice.stderr | 10 +- src/test/ui/issues/issue-52891.fixed | 37 +++ src/test/ui/issues/issue-52891.rs | 38 +++ src/test/ui/issues/issue-52891.stderr | 145 +++++++++ src/test/ui/proc-macro/shadow.stderr | 17 +- .../resolve-conflict-import-vs-import.stderr | 9 +- .../unresolved-extern-mod-suggestion.stderr | 9 +- src/test/ui/use/use-mod.stderr | 9 +- src/test/ui/use/use-paths-as-items.stderr | 9 +- 18 files changed, 570 insertions(+), 111 deletions(-) create mode 100644 src/test/ui/issues/auxiliary/issue-52891.rs create mode 100644 src/test/ui/issues/issue-52891.fixed create mode 100644 src/test/ui/issues/issue-52891.rs create mode 100644 src/test/ui/issues/issue-52891.stderr diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3752d953f8afa..c5401ac3f5560 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -238,12 +238,14 @@ impl<'a> Resolver<'a> { macro_ns: Cell::new(None), }, type_ns_only, + nested, }; self.add_import_directive( module_path, subclass, use_tree.span, id, + item, root_span, item.id, vis, @@ -260,6 +262,7 @@ impl<'a> Resolver<'a> { subclass, use_tree.span, id, + item, root_span, item.id, vis, @@ -379,6 +382,9 @@ impl<'a> Resolver<'a> { source: orig_name, target: ident, }, + has_attributes: !item.attrs.is_empty(), + use_span_with_attributes: item.span_with_attributes(), + use_span: item.span, root_span: item.span, span: item.span, module_path: Vec::new(), @@ -824,6 +830,9 @@ impl<'a> Resolver<'a> { parent_scope: parent_scope.clone(), imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::MacroUse, + use_span_with_attributes: item.span_with_attributes(), + has_attributes: !item.attrs.is_empty(), + use_span: item.span, root_span: span, span, module_path: Vec::new(), diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 55d5cdedd6ddd..3973bc2ad62de 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -63,7 +63,7 @@ use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path}; use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind}; use syntax::ptr::P; -use syntax_pos::{Span, DUMMY_SP, MultiSpan}; +use syntax_pos::{BytePos, Span, DUMMY_SP, MultiSpan}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use std::cell::{Cell, RefCell}; @@ -1228,6 +1228,16 @@ enum NameBindingKind<'a> { }, } +impl<'a> NameBindingKind<'a> { + /// Is this a name binding of a import? + fn is_import(&self) -> bool { + match *self { + NameBindingKind::Import { .. } => true, + _ => false, + } + } +} + struct PrivacyError<'a>(Span, Ident, &'a NameBinding<'a>); struct UseError<'a> { @@ -5134,64 +5144,235 @@ impl<'a> Resolver<'a> { ); // See https://github.com/rust-lang/rust/issues/32354 + use NameBindingKind::Import; let directive = match (&new_binding.kind, &old_binding.kind) { - (NameBindingKind::Import { directive, .. }, _) if !new_binding.span.is_dummy() => - Some((directive, new_binding.span)), - (_, NameBindingKind::Import { directive, .. }) if !old_binding.span.is_dummy() => - Some((directive, old_binding.span)), + // If there are two imports where one or both have attributes then prefer removing the + // import without attributes. + (Import { directive: new, .. }, Import { directive: old, .. }) if { + !new_binding.span.is_dummy() && !old_binding.span.is_dummy() && + (new.has_attributes || old.has_attributes) + } => { + if old.has_attributes { + Some((new, new_binding.span, true)) + } else { + Some((old, old_binding.span, true)) + } + }, + // Otherwise prioritize the new binding. + (Import { directive, .. }, other) if !new_binding.span.is_dummy() => + Some((directive, new_binding.span, other.is_import())), + (other, Import { directive, .. }) if !old_binding.span.is_dummy() => + Some((directive, old_binding.span, other.is_import())), _ => None, }; - if let Some((directive, binding_span)) = directive { - let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { - format!("Other{}", name) - } else { - format!("other_{}", name) - }; - let mut suggestion = None; - match directive.subclass { - ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => - suggestion = Some(format!("self as {}", suggested_name)), - ImportDirectiveSubclass::SingleImport { source, .. } => { - if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0) - .map(|pos| pos as usize) { - if let Ok(snippet) = self.session.source_map() - .span_to_snippet(binding_span) { - if pos <= snippet.len() { - suggestion = Some(format!( - "{} as {}{}", - &snippet[..pos], - suggested_name, - if snippet.ends_with(";") { ";" } else { "" } - )) - } + // Check if the target of the use for both bindings is the same. + let duplicate = new_binding.def().opt_def_id() == old_binding.def().opt_def_id(); + let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy(); + let from_item = self.extern_prelude.get(&ident) + .map(|entry| entry.introduced_by_item) + .unwrap_or(true); + // Only suggest removing an import if both bindings are to the same def, if both spans + // aren't dummy spans. Further, if both bindings are imports, then the ident must have + // been introduced by a item. + let should_remove_import = duplicate && !has_dummy_span && + ((new_binding.is_extern_crate() || old_binding.is_extern_crate()) || from_item); + + match directive { + Some((directive, span, true)) if should_remove_import && directive.is_nested() => + self.add_suggestion_for_duplicate_nested_use(&mut err, directive, span), + Some((directive, _, true)) if should_remove_import && !directive.is_glob() => { + // Simple case - remove the entire import. Due to the above match arm, this can + // only be a single use so just remove it entirely. + err.span_suggestion( + directive.use_span_with_attributes, + "remove unnecessary import", + String::new(), + Applicability::MaybeIncorrect, + ); + }, + Some((directive, span, _)) => + self.add_suggestion_for_rename_of_use(&mut err, name, directive, span), + _ => {}, + } + + err.emit(); + self.name_already_seen.insert(name, span); + } + + /// This function adds a suggestion to change the binding name of a new import that conflicts + /// with an existing import. + /// + /// ```ignore (diagnostic) + /// help: you can use `as` to change the binding name of the import + /// | + /// LL | use foo::bar as other_bar; + /// | ^^^^^^^^^^^^^^^^^^^^^ + /// ``` + fn add_suggestion_for_rename_of_use( + &self, + err: &mut DiagnosticBuilder<'_>, + name: Symbol, + directive: &ImportDirective<'_>, + binding_span: Span, + ) { + let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { + format!("Other{}", name) + } else { + format!("other_{}", name) + }; + + let mut suggestion = None; + match directive.subclass { + ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => + suggestion = Some(format!("self as {}", suggested_name)), + ImportDirectiveSubclass::SingleImport { source, .. } => { + if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0) + .map(|pos| pos as usize) { + if let Ok(snippet) = self.session.source_map() + .span_to_snippet(binding_span) { + if pos <= snippet.len() { + suggestion = Some(format!( + "{} as {}{}", + &snippet[..pos], + suggested_name, + if snippet.ends_with(";") { ";" } else { "" } + )) } } } - ImportDirectiveSubclass::ExternCrate { source, target, .. } => - suggestion = Some(format!( - "extern crate {} as {};", - source.unwrap_or(target.name), - suggested_name, - )), - _ => unreachable!(), } + ImportDirectiveSubclass::ExternCrate { source, target, .. } => + suggestion = Some(format!( + "extern crate {} as {};", + source.unwrap_or(target.name), + suggested_name, + )), + _ => unreachable!(), + } + + let rename_msg = "you can use `as` to change the binding name of the import"; + if let Some(suggestion) = suggestion { + err.span_suggestion( + binding_span, + rename_msg, + suggestion, + Applicability::MaybeIncorrect, + ); + } else { + err.span_label(binding_span, rename_msg); + } + } - let rename_msg = "you can use `as` to change the binding name of the import"; - if let Some(suggestion) = suggestion { - err.span_suggestion( - binding_span, - rename_msg, - suggestion, - Applicability::MaybeIncorrect, - ); - } else { - err.span_label(binding_span, rename_msg); + /// This function adds a suggestion to remove a unnecessary binding from an import that is + /// nested. In the following example, this function will be invoked to remove the `a` binding + /// in the second use statement: + /// + /// ```ignore (diagnostic) + /// use issue_52891::a; + /// use issue_52891::{d, a, e}; + /// ``` + /// + /// The following suggestion will be added: + /// + /// ```ignore (diagnostic) + /// use issue_52891::{d, a, e}; + /// ^-- help: remove unnecessary import + /// ``` + /// + /// If the nested use contains only one import then the suggestion will remove the entire + /// line. + /// + /// It is expected that the directive provided is a nested import - this isn't checked by the + /// function. If this invariant is not upheld, this function's behaviour will be unexpected + /// as characters expected by span manipulations won't be present. + fn add_suggestion_for_duplicate_nested_use( + &self, + err: &mut DiagnosticBuilder<'_>, + directive: &ImportDirective<'_>, + binding_span: Span, + ) { + assert!(directive.is_nested()); + let message = "remove unnecessary import"; + let source_map = self.session.source_map(); + + // Two examples will be used to illustrate the span manipulations we're doing: + // + // - Given `use issue_52891::{d, a, e};` where `a` is a duplicate then `binding_span` is + // `a` and `directive.use_span` is `issue_52891::{d, a, e};`. + // - Given `use issue_52891::{d, e, a};` where `a` is a duplicate then `binding_span` is + // `a` and `directive.use_span` is `issue_52891::{d, e, a};`. + + // Find the span of everything after the binding. + // ie. `a, e};` or `a};` + let binding_until_end = binding_span.with_hi(directive.use_span.hi()); + + // Find everything after the binding but not including the binding. + // ie. `, e};` or `};` + let after_binding_until_end = binding_until_end.with_lo(binding_span.hi()); + + // Keep characters in the span until we encounter something that isn't a comma or + // whitespace. + // ie. `, ` or ``. + // + // Also note whether a closing brace character was encountered. If there + // was, then later go backwards to remove any trailing commas that are left. + let mut found_closing_brace = false; + let after_binding_until_next_binding = source_map.span_take_while( + after_binding_until_end, + |&ch| { + if ch == '}' { found_closing_brace = true; } + ch == ' ' || ch == ',' + } + ); + + // Combine the two spans. + // ie. `a, ` or `a`. + // + // Removing these would leave `issue_52891::{d, e};` or `issue_52891::{d, e, };` + let span = binding_span.with_hi(after_binding_until_next_binding.hi()); + + // If there was a closing brace then identify the span to remove any trailing commas from + // previous imports. + if found_closing_brace { + if let Ok(prev_source) = source_map.span_to_prev_source(span) { + // `prev_source` will contain all of the source that came before the span. + // Then split based on a command and take the first (ie. closest to our span) + // snippet. In the example, this is a space. + let prev_comma = prev_source.rsplit(',').collect::>(); + let prev_starting_brace = prev_source.rsplit('{').collect::>(); + if prev_comma.len() > 1 && prev_starting_brace.len() > 1 { + let prev_comma = prev_comma.first().unwrap(); + let prev_starting_brace = prev_starting_brace.first().unwrap(); + + // If the amount of source code before the comma is greater than + // the amount of source code before the starting brace then we've only + // got one item in the nested item (eg. `issue_52891::{self}`). + if prev_comma.len() > prev_starting_brace.len() { + // So just remove the entire line... + err.span_suggestion( + directive.use_span_with_attributes, + message, + String::new(), + Applicability::MaybeIncorrect, + ); + return; + } + + let span = span.with_lo(BytePos( + // Take away the number of bytes for the characters we've found and an + // extra for the comma. + span.lo().0 - (prev_comma.as_bytes().len() as u32) - 1 + )); + err.span_suggestion( + span, message, String::new(), Applicability::MaybeIncorrect, + ); + return; + } } } - err.emit(); - self.name_already_seen.insert(name, span); + err.span_suggestion(span, message, String::new(), Applicability::MachineApplicable); } fn extern_prelude_get(&mut self, ident: Ident, speculative: bool) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index fd55897522bf7..5105c80fcbc87 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -18,7 +18,7 @@ use rustc::hir::def::*; use rustc::session::DiagnosticMessageId; use rustc::util::nodemap::FxHashSet; -use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID}; +use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::hygiene::Mark; use syntax::symbol::keywords; @@ -42,6 +42,8 @@ pub enum ImportDirectiveSubclass<'a> { target_bindings: PerNS>>>, /// `true` for `...::{self [as target]}` imports, `false` otherwise. type_ns_only: bool, + /// Did this import result from a nested import? ie. `use foo::{bar, baz};` + nested: bool, }, GlobImport { is_prelude: bool, @@ -78,6 +80,15 @@ crate struct ImportDirective<'a> { /// `UseTree` node. pub root_id: NodeId, + /// Span of the entire use statement. + pub use_span: Span, + + /// Span of the entire use statement with attributes. + pub use_span_with_attributes: Span, + + /// Did the use statement have any attributes? + pub has_attributes: bool, + /// Span of this use tree. pub span: Span, @@ -98,6 +109,13 @@ impl<'a> ImportDirective<'a> { match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false } } + pub fn is_nested(&self) -> bool { + match self.subclass { + ImportDirectiveSubclass::SingleImport { nested, .. } => nested, + _ => false + } + } + crate fn crate_lint(&self) -> CrateLint { CrateLint::UsePath { root_id: self.root_id, root_span: self.root_span } } @@ -390,6 +408,7 @@ impl<'a> Resolver<'a> { subclass: ImportDirectiveSubclass<'a>, span: Span, id: NodeId, + item: &ast::Item, root_span: Span, root_id: NodeId, vis: ty::Visibility, @@ -402,6 +421,9 @@ impl<'a> Resolver<'a> { subclass, span, id, + use_span: item.span, + use_span_with_attributes: item.span_with_attributes(), + has_attributes: !item.attrs.is_empty(), root_span, root_id, vis: Cell::new(vis), @@ -787,7 +809,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { let (source, target, source_bindings, target_bindings, type_ns_only) = match directive.subclass { SingleImport { source, target, ref source_bindings, - ref target_bindings, type_ns_only } => + ref target_bindings, type_ns_only, .. } => (source, target, source_bindings, target_bindings, type_ns_only), GlobImport { .. } => { self.resolve_glob_import(directive); @@ -908,7 +930,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { let (ident, target, source_bindings, target_bindings, type_ns_only) = match directive.subclass { SingleImport { source, target, ref source_bindings, - ref target_bindings, type_ns_only } => + ref target_bindings, type_ns_only, .. } => (source, target, source_bindings, target_bindings, type_ns_only), GlobImport { is_prelude, ref max_vis } => { if directive.module_path.len() <= 1 { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index af521848e9057..4f3f5631cc39c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2164,6 +2164,13 @@ pub struct Item { pub tokens: Option, } +impl Item { + /// Return the span that encompasses the attributes. + pub fn span_with_attributes(&self) -> Span { + self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span())) + } +} + /// A function header. /// /// All the information between the visibility and the name of the function is diff --git a/src/test/ui/double-type-import.stderr b/src/test/ui/double-type-import.stderr index 4bdee0c4c9f6c..c7288af13c278 100644 --- a/src/test/ui/double-type-import.stderr +++ b/src/test/ui/double-type-import.stderr @@ -4,13 +4,12 @@ error[E0252]: the name `X` is defined multiple times LL | pub use self::bar::X; | ------------ previous import of the type `X` here LL | use self::bar::X; - | ^^^^^^^^^^^^ `X` reimported here + | ----^^^^^^^^^^^^- + | | | + | | `X` reimported here + | help: remove unnecessary import | = note: `X` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use self::bar::X as OtherX; - | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0430.stderr b/src/test/ui/error-codes/E0430.stderr index 0151cde887f1d..78e4e43ac2f3d 100644 --- a/src/test/ui/error-codes/E0430.stderr +++ b/src/test/ui/error-codes/E0430.stderr @@ -10,15 +10,13 @@ error[E0252]: the name `fmt` is defined multiple times --> $DIR/E0430.rs:1:22 | LL | use std::fmt::{self, self}; //~ ERROR E0430 - | ---- ^^^^ `fmt` reimported here - | | + | ------^^^^ + | | | | + | | | `fmt` reimported here + | | help: remove unnecessary import | previous import of the module `fmt` here | = note: `fmt` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use std::fmt::{self, self as other_fmt}; //~ ERROR E0430 - | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index acd66826fdfb7..29660d908e485 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -4,13 +4,12 @@ error[E0252]: the name `foo` is defined multiple times LL | use a::foo; | ------ previous import of the value `foo` here LL | use a::foo; //~ ERROR the name `foo` is defined multiple times - | ^^^^^^ `foo` reimported here + | ----^^^^^^- + | | | + | | `foo` reimported here + | help: remove unnecessary import | = note: `foo` must be defined only once in the value namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^ error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module) --> $DIR/duplicate.rs:46:15 diff --git a/src/test/ui/issues/auxiliary/issue-52891.rs b/src/test/ui/issues/auxiliary/issue-52891.rs new file mode 100644 index 0000000000000..0759811832242 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-52891.rs @@ -0,0 +1,33 @@ +pub mod a { + pub mod inner { + } +} + +pub mod b { + pub mod inner { + } +} + +pub mod c {} + +pub mod d {} + +pub mod e {} + +pub mod f {} + +pub mod g {} + +pub mod h {} + +pub mod i {} + +pub mod j {} + +pub mod k {} + +pub mod l {} + +pub mod m {} + +pub mod n {} diff --git a/src/test/ui/issues/issue-26886.stderr b/src/test/ui/issues/issue-26886.stderr index 08faa9c9ca2c2..70dacb353fe07 100644 --- a/src/test/ui/issues/issue-26886.stderr +++ b/src/test/ui/issues/issue-26886.stderr @@ -4,13 +4,12 @@ error[E0252]: the name `Arc` is defined multiple times LL | use std::sync::{self, Arc}; | --- previous import of the type `Arc` here LL | use std::sync::Arc; //~ ERROR the name `Arc` is defined multiple times - | ^^^^^^^^^^^^^^ `Arc` reimported here + | ----^^^^^^^^^^^^^^- + | | | + | | `Arc` reimported here + | help: remove unnecessary import | = note: `Arc` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use std::sync::Arc as OtherArc; //~ ERROR the name `Arc` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0252]: the name `sync` is defined multiple times --> $DIR/issue-26886.rs:4:5 @@ -19,13 +18,12 @@ LL | use std::sync::{self, Arc}; | ---- previous import of the module `sync` here ... LL | use std::sync; //~ ERROR the name `sync` is defined multiple times - | ^^^^^^^^^ `sync` reimported here + | ----^^^^^^^^^- + | | | + | | `sync` reimported here + | help: remove unnecessary import | = note: `sync` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use std::sync as other_sync; //~ ERROR the name `sync` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-45829/import-twice.stderr b/src/test/ui/issues/issue-45829/import-twice.stderr index 374b809647e7a..2a1ac57651138 100644 --- a/src/test/ui/issues/issue-45829/import-twice.stderr +++ b/src/test/ui/issues/issue-45829/import-twice.stderr @@ -2,15 +2,13 @@ error[E0252]: the name `A` is defined multiple times --> $DIR/import-twice.rs:6:14 | LL | use foo::{A, A}; - | - ^ `A` reimported here - | | + | ---^ + | || | + | || `A` reimported here + | |help: remove unnecessary import | previous import of the type `A` here | = note: `A` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use foo::{A, A as OtherA}; - | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-52891.fixed b/src/test/ui/issues/issue-52891.fixed new file mode 100644 index 0000000000000..e694b5c9b154f --- /dev/null +++ b/src/test/ui/issues/issue-52891.fixed @@ -0,0 +1,37 @@ +// aux-build:issue-52891.rs +// run-rustfix + +#![allow(warnings)] + +extern crate issue_52891; + +// Check that we don't suggest renaming duplicate imports but instead +// suggest removing one. + +use issue_52891::a; + //~ ERROR `a` is defined multiple times + +use issue_52891::{b, c}; //~ ERROR `a` is defined multiple times +use issue_52891::{d, e}; //~ ERROR `a` is defined multiple times +use issue_52891::{f, g}; //~ ERROR `a` is defined multiple times + +use issue_52891::{//~ ERROR `a` is defined multiple times + h, + i}; +use issue_52891::{j, + //~ ERROR `a` is defined multiple times + k}; +use issue_52891::{l, + m}; //~ ERROR `a` is defined multiple times + +use issue_52891::a::inner; +use issue_52891::b::inner as other_inner; //~ ERROR `inner` is defined multiple times + + +//~^ ERROR `issue_52891` is defined multiple times + + +#[macro_use] +use issue_52891::n; //~ ERROR `n` is defined multiple times + +fn main() {} diff --git a/src/test/ui/issues/issue-52891.rs b/src/test/ui/issues/issue-52891.rs new file mode 100644 index 0000000000000..cd4b40629ab7f --- /dev/null +++ b/src/test/ui/issues/issue-52891.rs @@ -0,0 +1,38 @@ +// aux-build:issue-52891.rs +// run-rustfix + +#![allow(warnings)] + +extern crate issue_52891; + +// Check that we don't suggest renaming duplicate imports but instead +// suggest removing one. + +use issue_52891::a; +use issue_52891::a; //~ ERROR `a` is defined multiple times + +use issue_52891::{a, b, c}; //~ ERROR `a` is defined multiple times +use issue_52891::{d, a, e}; //~ ERROR `a` is defined multiple times +use issue_52891::{f, g, a}; //~ ERROR `a` is defined multiple times + +use issue_52891::{a, //~ ERROR `a` is defined multiple times + h, + i}; +use issue_52891::{j, + a, //~ ERROR `a` is defined multiple times + k}; +use issue_52891::{l, + m, + a}; //~ ERROR `a` is defined multiple times + +use issue_52891::a::inner; +use issue_52891::b::inner; //~ ERROR `inner` is defined multiple times + +use issue_52891::{self}; +//~^ ERROR `issue_52891` is defined multiple times + +use issue_52891::n; +#[macro_use] +use issue_52891::n; //~ ERROR `n` is defined multiple times + +fn main() {} diff --git a/src/test/ui/issues/issue-52891.stderr b/src/test/ui/issues/issue-52891.stderr new file mode 100644 index 0000000000000..55d611070d9dc --- /dev/null +++ b/src/test/ui/issues/issue-52891.stderr @@ -0,0 +1,145 @@ +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:12:5 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +LL | use issue_52891::a; //~ ERROR `a` is defined multiple times + | ----^^^^^^^^^^^^^^- + | | | + | | `a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:14:19 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +... +LL | use issue_52891::{a, b, c}; //~ ERROR `a` is defined multiple times + | ^-- + | | + | `a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:15:22 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +... +LL | use issue_52891::{d, a, e}; //~ ERROR `a` is defined multiple times + | ^-- + | | + | `a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:16:25 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +... +LL | use issue_52891::{f, g, a}; //~ ERROR `a` is defined multiple times + | --^ + | | | + | | `a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:18:19 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +... +LL | use issue_52891::{a, //~ ERROR `a` is defined multiple times + | ^-- + | | + | `a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:22:5 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +... +LL | a, //~ ERROR `a` is defined multiple times + | ^-- + | | + | `a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `a` is defined multiple times + --> $DIR/issue-52891.rs:26:5 + | +LL | use issue_52891::a; + | -------------- previous import of the module `a` here +... +LL | m, + | ______- +LL | | a}; //~ ERROR `a` is defined multiple times + | | - + | | | + | |_____`a` reimported here + | help: remove unnecessary import + | + = note: `a` must be defined only once in the type namespace of this module + +error[E0252]: the name `inner` is defined multiple times + --> $DIR/issue-52891.rs:29:5 + | +LL | use issue_52891::a::inner; + | --------------------- previous import of the module `inner` here +LL | use issue_52891::b::inner; //~ ERROR `inner` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^^^ `inner` reimported here + | + = note: `inner` must be defined only once in the type namespace of this module +help: you can use `as` to change the binding name of the import + | +LL | use issue_52891::b::inner as other_inner; //~ ERROR `inner` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0254]: the name `issue_52891` is defined multiple times + --> $DIR/issue-52891.rs:31:19 + | +LL | extern crate issue_52891; + | ------------------------- previous import of the extern crate `issue_52891` here +... +LL | use issue_52891::{self}; + | ------------------^^^^-- + | | | + | | `issue_52891` reimported here + | help: remove unnecessary import + | + = note: `issue_52891` must be defined only once in the type namespace of this module + +error[E0252]: the name `n` is defined multiple times + --> $DIR/issue-52891.rs:36:5 + | +LL | use issue_52891::n; + | ------------------- + | | | + | | previous import of the module `n` here + | help: remove unnecessary import +LL | #[macro_use] +LL | use issue_52891::n; //~ ERROR `n` is defined multiple times + | ^^^^^^^^^^^^^^ `n` reimported here + | + = note: `n` must be defined only once in the type namespace of this module + +error: aborting due to 10 previous errors + +Some errors occurred: E0252, E0254. +For more information about an error, try `rustc --explain E0252`. diff --git a/src/test/ui/proc-macro/shadow.stderr b/src/test/ui/proc-macro/shadow.stderr index 103c78126a838..2dfe2a94c88e1 100644 --- a/src/test/ui/proc-macro/shadow.stderr +++ b/src/test/ui/proc-macro/shadow.stderr @@ -1,17 +1,16 @@ error[E0259]: the name `derive_a` is defined multiple times --> $DIR/shadow.rs:6:1 | -LL | extern crate derive_a; - | ---------------------- previous import of the extern crate `derive_a` here -LL | #[macro_use] -LL | extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^ `derive_a` reimported here +LL | extern crate derive_a; + | ---------------------- previous import of the extern crate `derive_a` here +LL | / #[macro_use] +LL | | extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times + | | ^^^^^^^^^^^^^^^^^^^^^- + | |_|____________________| + | | help: remove unnecessary import + | `derive_a` reimported here | = note: `derive_a` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | extern crate derive_a as other_derive_a; //~ ERROR the name `derive_a` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr b/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr index 2852d122e5e4a..1b4b058b783ad 100644 --- a/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr +++ b/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr @@ -4,13 +4,12 @@ error[E0252]: the name `transmute` is defined multiple times LL | use std::mem::transmute; | ------------------- previous import of the value `transmute` here LL | use std::mem::transmute; - | ^^^^^^^^^^^^^^^^^^^ `transmute` reimported here + | ----^^^^^^^^^^^^^^^^^^^- + | | | + | | `transmute` reimported here + | help: remove unnecessary import | = note: `transmute` must be defined only once in the value namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use std::mem::transmute as other_transmute; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/unresolved/unresolved-extern-mod-suggestion.stderr b/src/test/ui/unresolved/unresolved-extern-mod-suggestion.stderr index 012d3c3a7510f..e8679a3726d30 100644 --- a/src/test/ui/unresolved/unresolved-extern-mod-suggestion.stderr +++ b/src/test/ui/unresolved/unresolved-extern-mod-suggestion.stderr @@ -4,13 +4,12 @@ error[E0254]: the name `core` is defined multiple times LL | extern crate core; | ------------------ previous import of the extern crate `core` here LL | use core; - | ^^^^ `core` reimported here + | ----^^^^- + | | | + | | `core` reimported here + | help: remove unnecessary import | = note: `core` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use core as other_core; - | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/use/use-mod.stderr b/src/test/ui/use/use-mod.stderr index 9ab873b35989c..c23ab34eae678 100644 --- a/src/test/ui/use/use-mod.stderr +++ b/src/test/ui/use/use-mod.stderr @@ -20,13 +20,12 @@ LL | self, | ---- previous import of the module `bar` here ... LL | self - | ^^^^ `bar` reimported here + | ^^^^ + | | + | `bar` reimported here + | help: remove unnecessary import | = note: `bar` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | self as other_bar - | error: aborting due to 3 previous errors diff --git a/src/test/ui/use/use-paths-as-items.stderr b/src/test/ui/use/use-paths-as-items.stderr index 5bcdf937d5698..00f468cdf316b 100644 --- a/src/test/ui/use/use-paths-as-items.stderr +++ b/src/test/ui/use/use-paths-as-items.stderr @@ -4,13 +4,12 @@ error[E0252]: the name `mem` is defined multiple times LL | use std::{mem, ptr}; | --- previous import of the module `mem` here LL | use std::mem; //~ ERROR the name `mem` is defined multiple times - | ^^^^^^^^ `mem` reimported here + | ----^^^^^^^^- + | | | + | | `mem` reimported here + | help: remove unnecessary import | = note: `mem` must be defined only once in the type namespace of this module -help: you can use `as` to change the binding name of the import - | -LL | use std::mem as other_mem; //~ ERROR the name `mem` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error From b025557e9703f2e8a52789ea50bcb7fe060fac54 Mon Sep 17 00:00:00 2001 From: Vardhan Thigle Date: Thu, 31 Jan 2019 17:01:16 +0530 Subject: [PATCH 0465/1064] Updated commit id for building libunwind. --- src/ci/docker/dist-various-2/Dockerfile | 2 +- .../build-x86_64-fortanix-unknown-sgx-toolchain.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 1d33fd0f7f4cf..97892405b8eb4 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -32,7 +32,7 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc COPY dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/ # We pass the commit id of the port of LLVM's libunwind to the build script. # Any update to the commit id here, should cause the container image to be re-built from this point on. -RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "75628849f538a62712353ac6e4c9e789da90923e" +RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "53b586346f2c7870e20b170decdc30729d97c42b" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh index f94cd36e8d6ec..725ec341b9497 100755 --- a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh @@ -49,4 +49,4 @@ build_unwind() { set -x hide_output install_prereq -hide_output build_unwind +build_unwind From d0129a613c3bd4581826bb838eea1ab96c2cd5c7 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 21 Nov 2018 10:54:46 +0100 Subject: [PATCH 0466/1064] Add a forever unstable opt-out of const qualification checks --- src/librustc/session/config.rs | 2 ++ src/librustc_mir/transform/qualify_consts.rs | 29 ++++++++++++++++-- .../ui/consts/miri_unleashed/assoc_const.rs | 30 +++++++++++++++++++ .../consts/miri_unleashed/assoc_const.stderr | 15 ++++++++++ .../ui/consts/miri_unleashed/assoc_const_2.rs | 28 +++++++++++++++++ .../miri_unleashed/assoc_const_2.stderr | 9 ++++++ ...ure-gate-unleash_the_miri_inside_of_you.rs | 27 +++++++++++++++++ ...gate-unleash_the_miri_inside_of_you.stderr | 17 +++++++++++ 8 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/consts/miri_unleashed/assoc_const.rs create mode 100644 src/test/ui/consts/miri_unleashed/assoc_const.stderr create mode 100644 src/test/ui/consts/miri_unleashed/assoc_const_2.rs create mode 100644 src/test/ui/consts/miri_unleashed/assoc_const_2.stderr create mode 100644 src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs create mode 100644 src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 4b1aefb2216fb..577246783a178 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1300,6 +1300,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "print some statistics about AST and HIR"), always_encode_mir: bool = (false, parse_bool, [TRACKED], "encode MIR of all functions into the crate metadata"), + unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED], + "take the breaks off const evaluation. NOTE: this is unsound"), osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], "pass `-install_name @rpath/...` to the macOS linker"), sanitizer: Option = (None, parse_sanitizer, [TRACKED], diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2d941902debc3..7d1943e21b90d 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -108,6 +108,15 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { promotion_candidates: Vec } +macro_rules! unleash_miri { + ($this:expr) => {{ + if $this.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + $this.tcx.sess.span_warn($this.span, "skipping const checks"); + return; + } + }} +} + impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, @@ -147,6 +156,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { // categories, but enabling full miri would make that // slightly pointless (even with feature-gating). fn not_const(&mut self) { + unleash_miri!(self); self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { let mut err = struct_span_err!( @@ -419,6 +429,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } return; } + unleash_miri!(self); self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { @@ -618,6 +629,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } if forbidden_mut { + unleash_miri!(self); self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { let mut err = struct_span_err!(self.tcx.sess, self.span, E0017, @@ -660,6 +672,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { debug!("visit_rvalue: forbidden_mut={:?}", forbidden_mut); if forbidden_mut { + unleash_miri!(self); self.add(Qualif::NOT_CONST); } else { // We might have a candidate for promotion. @@ -700,6 +713,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { match (cast_in, cast_out) { (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { + unleash_miri!(self); if let Mode::Fn = self.mode { // in normal functions, mark such casts as not promotable self.add(Qualif::NOT_CONST); @@ -727,6 +741,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { op == BinOp::Ge || op == BinOp::Gt || op == BinOp::Offset); + unleash_miri!(self); if let Mode::Fn = self.mode { // raw pointer operations are not allowed inside promoteds self.add(Qualif::NOT_CONST); @@ -745,6 +760,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } Rvalue::NullaryOp(NullOp::Box, _) => { + unleash_miri!(self); self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { let mut err = struct_span_err!(self.tcx.sess, self.span, E0010, @@ -861,7 +877,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } else { // stable const fns or unstable const fns with their feature gate // active - if self.tcx.is_const_fn(def_id) { + let unleash_miri = self + .tcx + .sess + .opts + .debugging_opts + .unleash_the_miri_inside_of_you; + if self.tcx.is_const_fn(def_id) || unleash_miri { is_const_fn = true; } else if self.is_const_panic_fn(def_id) { // Check the const_panic feature gate. @@ -1030,6 +1052,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // Deny *any* live drops anywhere other than functions. if self.mode != Mode::Fn { + unleash_miri!(self); // HACK(eddyb): emulate a bit of dataflow analysis, // conservatively, that drop elaboration will do. let needs_drop = if let Place::Local(local) = *place { @@ -1175,7 +1198,9 @@ impl MirPass for QualifyAndPromoteConstants { let (temps, candidates) = { let mut qualifier = Qualifier::new(tcx, def_id, mir, mode); if mode == Mode::ConstFn { - if tcx.is_min_const_fn(def_id) { + if tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + qualifier.qualify_const(); + } else if tcx.is_min_const_fn(def_id) { // enforce `min_const_fn` for stable const fns use super::qualify_min_const_fn::is_min_const_fn; if let Err((span, err)) = is_min_const_fn(tcx, def_id, mir) { diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.rs b/src/test/ui/consts/miri_unleashed/assoc_const.rs new file mode 100644 index 0000000000000..b8959667cc215 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/assoc_const.rs @@ -0,0 +1,30 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![allow(const_err)] + +// a test demonstrating why we do need to run static const qualification on associated constants +// instead of just checking the final constant + +trait Foo { + const X: T; +} + +trait Bar> { + const F: u32 = (U::X, 42).1; //~ WARN skipping const checks +} + +impl Foo for () { + const X: u32 = 42; +} +impl Foo> for String { + const X: Vec = Vec::new(); +} + +impl Bar for () {} +impl Bar, String> for String {} + +fn main() { + // this is fine, but would have been forbidden by the static checks on `F` + let x = <() as Bar>::F; + // this test only causes errors due to the line below, so post-monomorphization + let y = , String>>::F; //~ ERROR erroneous constant +} diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr new file mode 100644 index 0000000000000..a40f8d46d0aa7 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr @@ -0,0 +1,15 @@ +warning: skipping const checks + --> $DIR/assoc_const.rs:12:31 + | +LL | const F: u32 = (U::X, 42).1; //~ WARN skipping const checks + | ^ + +error[E0080]: erroneous constant used + --> $DIR/assoc_const.rs:29:13 + | +LL | let y = , String>>::F; //~ ERROR erroneous constant + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.rs b/src/test/ui/consts/miri_unleashed/assoc_const_2.rs new file mode 100644 index 0000000000000..c87b6389848f4 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.rs @@ -0,0 +1,28 @@ +#![allow(const_err)] + +// a test demonstrating that const qualification cannot prevent monomorphization time errors + +trait Foo { + const X: u32; +} + +trait Bar { + const F: u32 = 100 / U::X; +} + +impl Foo for () { + const X: u32 = 42; +} + +impl Foo for String { + const X: u32 = 0; +} + +impl Bar<()> for () {} +impl Bar for String {} + +fn main() { + let x = <() as Bar<()>>::F; + // this test only causes errors due to the line below, so post-monomorphization + let y = >::F; //~ ERROR erroneous constant +} diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr new file mode 100644 index 0000000000000..77aab31d26ec3 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -0,0 +1,9 @@ +error[E0080]: erroneous constant used + --> $DIR/assoc_const_2.rs:27:13 + | +LL | let y = >::F; //~ ERROR erroneous constant + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs new file mode 100644 index 0000000000000..5fb92535502a5 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs @@ -0,0 +1,27 @@ +#![allow(const_err)] + +// a test demonstrating why we do need to run static const qualification on associated constants +// instead of just checking the final constant + +trait Foo { + const X: T; +} + +trait Bar> { + const F: u32 = (U::X, 42).1; //~ ERROR destructors cannot be evaluated at compile-time +} + +impl Foo for () { + const X: u32 = 42; +} +impl Foo> for String { + const X: Vec = Vec::new(); //~ ERROR not yet stable as a const fn +} + +impl Bar for () {} +impl Bar, String> for String {} + +fn main() { + let x = <() as Bar>::F; + let y = , String>>::F; +} diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr new file mode 100644 index 0000000000000..e23ed1c620639 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr @@ -0,0 +1,17 @@ +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:11:20 + | +LL | const F: u32 = (U::X, 42).1; //~ ERROR destructors cannot be evaluated at compile-time + | ^^^^^^^^^^ constants cannot evaluate destructors + +error: `>::new` is not yet stable as a const fn + --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25 + | +LL | const X: Vec = Vec::new(); //~ ERROR not yet stable as a const fn + | ^^^^^^^^^^ + | + = help: add `#![feature(const_vec_new)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0493`. From 73bf0703a70098cdeebfb29709f74f101ab3e6b1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 31 Jan 2019 14:18:31 +0100 Subject: [PATCH 0467/1064] Add more tests for #[repr(align(x))] on enums --- src/test/run-pass/structs-enums/align-enum.rs | 46 +++++++++++++++++-- src/test/ui/repr/repr-align.rs | 4 ++ src/test/ui/repr/repr-align.stderr | 14 ++++-- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/test/run-pass/structs-enums/align-enum.rs b/src/test/run-pass/structs-enums/align-enum.rs index 265bae89b80c9..8d72b1f6f0d24 100644 --- a/src/test/run-pass/structs-enums/align-enum.rs +++ b/src/test/run-pass/structs-enums/align-enum.rs @@ -5,13 +5,51 @@ use std::mem; // Raising alignment -#[repr(align(8))] -enum Align8 { +#[repr(align(16))] +enum Align16 { Foo { foo: u32 }, Bar { bar: u32 }, } +// Raise alignment by maximum +#[repr(align(1), align(16))] +#[repr(align(32))] +#[repr(align(4))] +enum Align32 { + Foo, + Bar, +} + +// Not reducing alignment +#[repr(align(4))] +enum AlsoAlign16 { + Foo { limb_with_align16: Align16 }, + Bar, +} + +// No niche for discriminant when used as limb +#[repr(align(16))] +struct NoNiche16(u64, u64); + +// Discriminant will require extra space, but enum needs to stay compatible +// with alignment 16 +#[repr(align(1))] +enum AnotherAlign16 { + Foo { limb_with_noniche16: NoNiche16 }, + Bar, + Baz, +} + fn main() { - assert_eq!(mem::align_of::(), 8); - assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + + assert_eq!(mem::align_of::(), 32); + assert_eq!(mem::size_of::(), 32); + + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 32); } diff --git a/src/test/ui/repr/repr-align.rs b/src/test/ui/repr/repr-align.rs index 78ed6c7e1c417..9ce89e82ca225 100644 --- a/src/test/ui/repr/repr-align.rs +++ b/src/test/ui/repr/repr-align.rs @@ -1,3 +1,4 @@ +#![feature(repr_align_enum)] #![allow(dead_code)] #[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer @@ -12,4 +13,7 @@ struct C(i32); #[repr(align(536870912))] // ok: this is the largest accepted alignment struct D(i32); +#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two +enum E { Left, Right } + fn main() {} diff --git a/src/test/ui/repr/repr-align.stderr b/src/test/ui/repr/repr-align.stderr index e8dbf74232bfa..f1a5d88ace1fd 100644 --- a/src/test/ui/repr/repr-align.stderr +++ b/src/test/ui/repr/repr-align.stderr @@ -1,21 +1,27 @@ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/repr-align.rs:3:8 + --> $DIR/repr-align.rs:4:8 | LL | #[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer | ^^^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/repr-align.rs:6:8 + --> $DIR/repr-align.rs:7:8 | LL | #[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two | ^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:9:8 + --> $DIR/repr-align.rs:10:8 | LL | #[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29 | ^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:16:8 + | +LL | #[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two + | ^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0589`. From ee229f7fd060b9ff3cd5df4556dd550a3df0b62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 31 Jan 2019 17:47:33 +0100 Subject: [PATCH 0468/1064] Use ensure for mir_borrowck --- src/librustc_driver/driver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c586c705676f4..d3412ec2dd93d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1283,7 +1283,7 @@ where time(sess, "MIR borrow checking", - || tcx.par_body_owners(|def_id| { tcx.mir_borrowck(def_id); })); + || tcx.par_body_owners(|def_id| { tcx.ensure().mir_borrowck(def_id); })); time(sess, "dumping chalk-like clauses", || { rustc_traits::lowering::dump_program_clauses(tcx); From f841ff4a7b8227f17e0fa056c6a73ba549f2872e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Thu, 31 Jan 2019 20:46:11 +0100 Subject: [PATCH 0469/1064] Stabilize the time_checked_add feature --- src/libstd/time.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 23924559fcc24..6685ee202658a 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -245,7 +245,7 @@ impl Instant { /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option { self.0.checked_add_duration(&duration).map(|t| Instant(t)) } @@ -253,7 +253,7 @@ impl Instant { /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option { self.0.checked_sub_duration(&duration).map(|t| Instant(t)) } @@ -418,7 +418,7 @@ impl SystemTime { /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option { self.0.checked_add_duration(&duration).map(|t| SystemTime(t)) } @@ -426,7 +426,7 @@ impl SystemTime { /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. - #[unstable(feature = "time_checked_add", issue = "55940")] + #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option { self.0.checked_sub_duration(&duration).map(|t| SystemTime(t)) } From ea2b1b035b3aa2e0e464dabb0e46f6c2092d357f Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Mon, 14 Jan 2019 10:02:27 -0500 Subject: [PATCH 0470/1064] rustdoc: wrap stability tags in colored spans --- src/librustdoc/html/render.rs | 15 ++++++++------- src/librustdoc/html/static/rustdoc.css | 13 ++++++++----- src/test/rustdoc/deprecated.rs | 6 ++++-- src/test/rustdoc/inline_cross/macros.rs | 3 ++- src/test/rustdoc/internal.rs | 6 ++++-- src/test/rustdoc/issue-32374.rs | 7 +++++-- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..c74e4647cdbde 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2798,9 +2798,13 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, fn stability_tags(item: &clean::Item) -> String { let mut tags = String::new(); + fn tag_html(class: &str, contents: &str) -> String { + format!(r#"{}"#, class, contents) + } + // The trailing space after each tag is to space it properly against the rest of the docs. if item.deprecation().is_some() { - tags.push_str("[

] "); + tags += &tag_html("deprecated", "Deprecated"); } if let Some(stab) = item @@ -2809,17 +2813,14 @@ fn stability_tags(item: &clean::Item) -> String { .filter(|s| s.level == stability::Unstable) { if stab.feature.as_ref().map(|s| &**s) == Some("rustc_private") { - tags.push_str("[
Internal
] "); + tags += &tag_html("internal", "Internal"); } else { - tags.push_str("[
Experimental
] "); + tags += &tag_html("unstable", "Experimental"); } } if let Some(ref cfg) = item.attrs.cfg { - tags.push_str(&format!( - "[
{}
] ", - cfg.render_short_html() - )); + tags += &tag_html("portability", &cfg.render_short_html()); } tags diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 36765496ff4e9..b210586006702 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -767,11 +767,14 @@ body.blur > :not(#help) { } .module-item .stab { - display: inline; - border-width: 0; - padding: 0; - margin: 0; - background: inherit !important; + border-radius: 3px; + display: inline-block; + font-size: 80%; + line-height: 1.2; + margin-bottom: 0; + margin-right: .3em; + padding: 2px; + vertical-align: text-bottom; } .module-item.unstable { diff --git a/src/test/rustdoc/deprecated.rs b/src/test/rustdoc/deprecated.rs index ca3f380ed2825..74bd94548e036 100644 --- a/src/test/rustdoc/deprecated.rs +++ b/src/test/rustdoc/deprecated.rs @@ -1,7 +1,9 @@ #![feature(deprecated)] -// @matches deprecated/index.html '//*[@class="docblock-short"]' \ -// '^\[Deprecated\] Deprecated docs' +// @has deprecated/index.html '//*[@class="docblock-short"]/span[@class="stab deprecated"]' \ +// 'Deprecated' +// @has - '//*[@class="docblock-short"]' 'Deprecated docs' + // @has deprecated/struct.S.html '//*[@class="stab deprecated"]' \ // 'Deprecated since 1.0.0: text' /// Deprecated docs diff --git a/src/test/rustdoc/inline_cross/macros.rs b/src/test/rustdoc/inline_cross/macros.rs index 4e370062385d0..f9bf982659e02 100644 --- a/src/test/rustdoc/inline_cross/macros.rs +++ b/src/test/rustdoc/inline_cross/macros.rs @@ -7,7 +7,8 @@ extern crate macros; -// @has foo/index.html '//*[@class="docblock-short"]' '[Deprecated] [Experimental]' +// @has foo/index.html '//*[@class="docblock-short"]/span[@class="stab deprecated"]' Deprecated +// @has - '//*[@class="docblock-short"]/span[@class="stab unstable"]' Experimental // @has foo/macro.my_macro.html // @has - '//*[@class="docblock"]' 'docs for my_macro' diff --git a/src/test/rustdoc/internal.rs b/src/test/rustdoc/internal.rs index ba58da138a8c0..2cb7c472cc84b 100644 --- a/src/test/rustdoc/internal.rs +++ b/src/test/rustdoc/internal.rs @@ -1,7 +1,9 @@ // compile-flags: -Z force-unstable-if-unmarked -// @matches internal/index.html '//*[@class="docblock-short"]' \ -// '^\[Internal\] Docs' +// @matches internal/index.html '//*[@class="docblock-short"]/span[@class="stab internal"]' \ +// 'Internal' +// @matches - '//*[@class="docblock-short"]' 'Docs' + // @has internal/struct.S.html '//*[@class="stab internal"]' \ // 'This is an internal compiler API. (rustc_private)' /// Docs diff --git a/src/test/rustdoc/issue-32374.rs b/src/test/rustdoc/issue-32374.rs index 58876a1aa1162..7babfaf6060f4 100644 --- a/src/test/rustdoc/issue-32374.rs +++ b/src/test/rustdoc/issue-32374.rs @@ -3,8 +3,11 @@ #![unstable(feature="test", issue = "32374")] -// @matches issue_32374/index.html '//*[@class="docblock-short"]' \ -// '^\[Deprecated\] \[Experimental\] Docs' +// @matches issue_32374/index.html '//*[@class="docblock-short"]/span[@class="stab deprecated"]' \ +// 'Deprecated' +// @matches issue_32374/index.html '//*[@class="docblock-short"]/span[@class="stab unstable"]' \ +// 'Experimental' +// @matches issue_32374/index.html '//*[@class="docblock-short"]/text()' 'Docs' // @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \ // 'Deprecated since 1.0.0: text' From 20b55b7e2cb345e92ed024f9fef46ca4a83cd0a0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 31 Jan 2019 21:24:23 +0100 Subject: [PATCH 0471/1064] Clarify semantics of #[repr(align(x))] on enums --- .../src/language-features/repr-align-enum.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/doc/unstable-book/src/language-features/repr-align-enum.md b/src/doc/unstable-book/src/language-features/repr-align-enum.md index 1fd9bd20f3f0d..415c6ebe8b4bc 100644 --- a/src/doc/unstable-book/src/language-features/repr-align-enum.md +++ b/src/doc/unstable-book/src/language-features/repr-align-enum.md @@ -24,3 +24,19 @@ fn main() { assert_eq!(std::mem::align_of::(), 8); } ``` + +This is equivalent to using an aligned wrapper struct everywhere: + +```rust +#[repr(align(8))] +struct Aligned(Unaligned); + +enum Unaligned { + Foo, + Bar { value: u32 }, +} + +fn main() { + assert_eq!(std::mem::align_of::(), 8); +} +``` From 397eb4f237b92f77eadf12c0bea7cfea5a31a92a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 30 Jan 2019 11:39:19 +0100 Subject: [PATCH 0472/1064] Add missing generation for test and proc_macro, remove old macro redirection --- src/bootstrap/bin/rustdoc.rs | 20 +++++++++++++++++--- src/bootstrap/doc.rs | 11 ++++++----- src/librustdoc/html/render.rs | 9 --------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index dec74e60c71f3..aeb15821b0bb7 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -16,6 +16,7 @@ fn main() { let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set"); let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); + let mut has_unstable = false; use std::str::FromStr; @@ -54,9 +55,22 @@ fn main() { // it up so we can make rustdoc print this into the docs if let Some(version) = env::var_os("RUSTDOC_CRATE_VERSION") { // This "unstable-options" can be removed when `--crate-version` is stabilized - cmd.arg("-Z") - .arg("unstable-options") - .arg("--crate-version").arg(version); + if !has_unstable { + cmd.arg("-Z") + .arg("unstable-options"); + } + cmd.arg("--crate-version").arg(version); + has_unstable = true; + } + + // Needed to be able to run all rustdoc tests. + if let Some(_) = env::var_os("RUSTDOC_GENERATE_REDIRECT_PAGES") { + // This "unstable-options" can be removed when `--generate-redirect-pages` is stabilized + if !has_unstable { + cmd.arg("-Z") + .arg("unstable-options"); + } + cmd.arg("--generate-redirect-pages"); } if verbose > 1 { diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 0028997a7df09..af95b622e23f3 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -317,8 +317,7 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned Date: Thu, 31 Jan 2019 23:18:07 +0100 Subject: [PATCH 0473/1064] Simplify lambdas --- src/libstd/time.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 6685ee202658a..b63d816ce44ca 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -247,7 +247,7 @@ impl Instant { /// otherwise. #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option { - self.0.checked_add_duration(&duration).map(|t| Instant(t)) + self.0.checked_add_duration(&duration).map(Instant) } /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as @@ -255,7 +255,7 @@ impl Instant { /// otherwise. #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option { - self.0.checked_sub_duration(&duration).map(|t| Instant(t)) + self.0.checked_sub_duration(&duration).map(Instant) } } @@ -420,7 +420,7 @@ impl SystemTime { /// otherwise. #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option { - self.0.checked_add_duration(&duration).map(|t| SystemTime(t)) + self.0.checked_add_duration(&duration).map(SystemTime) } /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as @@ -428,7 +428,7 @@ impl SystemTime { /// otherwise. #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option { - self.0.checked_sub_duration(&duration).map(|t| SystemTime(t)) + self.0.checked_sub_duration(&duration).map(SystemTime) } } From e8d028140e085f7d29916e016461744689e5529a Mon Sep 17 00:00:00 2001 From: Sergei Vorobev Date: Thu, 31 Jan 2019 22:26:19 -0800 Subject: [PATCH 0474/1064] Fix grammar in E0283 explanation --- src/librustc/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 1e10329bb55ce..6644175bbd8a8 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1187,7 +1187,7 @@ impl Generator for AnotherImpl { fn main() { let cont: u32 = Generator::create(); // error, impossible to choose one of Generator trait implementation - // Impl or AnotherImpl? Maybe anything else? + // Should it be Impl or AnotherImpl, maybe something else? } ``` From a90b23fd30cce3f83b9c1771bab31c1964ce2fe2 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Fri, 1 Feb 2019 13:58:49 +0530 Subject: [PATCH 0475/1064] Fix `std::os::fortanix_sgx::usercalls::raw::UsercallNrs` Fixes https://github.com/fortanix/rust-sgx/issues/88 --- src/libstd/os/fortanix_sgx/mod.rs | 17 +---------------- src/libstd/sys/sgx/abi/usercalls/raw.rs | 13 +++++++++---- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs index 810965fc1b85a..c6106b9f8278f 100644 --- a/src/libstd/os/fortanix_sgx/mod.rs +++ b/src/libstd/os/fortanix_sgx/mod.rs @@ -21,26 +21,11 @@ pub mod usercalls { /// Lowest-level interfaces to usercalls and usercall ABI type definitions. pub mod raw { - use sys::abi::usercalls::raw::invoke_with_usercalls; - pub use sys::abi::usercalls::raw::do_usercall; + pub use sys::abi::usercalls::raw::{do_usercall, Usercalls as UsercallNrs}; pub use sys::abi::usercalls::raw::{accept_stream, alloc, async_queues, bind_stream, close, connect_stream, exit, flush, free, insecure_time, launch_thread, read, read_alloc, send, wait, write}; - macro_rules! define_usercallnrs { - ($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:ty)*; )*) => { - /// Usercall numbers as per the ABI. - #[repr(C)] - #[unstable(feature = "sgx_platform", issue = "56975")] - #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] - #[allow(missing_docs)] - pub enum UsercallNrs { - $($f,)* - } - }; - } - invoke_with_usercalls!(define_usercallnrs); - // fortanix-sgx-abi re-exports pub use sys::abi::usercalls::raw::{ByteBuffer, FifoDescriptor, Return, Usercall}; pub use sys::abi::usercalls::raw::Error; diff --git a/src/libstd/sys/sgx/abi/usercalls/raw.rs b/src/libstd/sys/sgx/abi/usercalls/raw.rs index 27aca7c0903de..27f780ca224db 100644 --- a/src/libstd/sys/sgx/abi/usercalls/raw.rs +++ b/src/libstd/sys/sgx/abi/usercalls/raw.rs @@ -41,10 +41,15 @@ trait ReturnValue { macro_rules! define_usercalls { // Using `$r:tt` because `$r:ty` doesn't match ! in `clobber_diverging` ($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:tt)*; )*) => { - #[repr(C)] - #[allow(non_camel_case_types)] - enum Usercalls { - __enclave_usercalls_invalid, + /// Usercall numbers as per the ABI. + #[repr(u64)] + #[unstable(feature = "sgx_platform", issue = "56975")] + #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] + #[allow(missing_docs, non_camel_case_types)] + #[non_exhaustive] + pub enum Usercalls { + #[doc(hidden)] + __enclave_usercalls_invalid = 0, $($f,)* } From 2f5d2455a43203bce98a808b8687798199f4f815 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 1 Feb 2019 01:31:52 -0700 Subject: [PATCH 0476/1064] Make overflowing and wrapping negation const Remember that the signed and unsigned versions are slightly different here, so there's four functions made const instead of just two. --- src/libcore/num/mod.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f80f839282781..81aec346c93fc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1175,7 +1175,7 @@ $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline] - pub fn wrapping_neg(self) -> Self { + pub const fn wrapping_neg(self) -> Self { self.overflowing_neg().0 } } @@ -1529,12 +1529,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($Self ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_neg(self) -> (Self, bool) { - if self == Self::min_value() { - (Self::min_value(), true) - } else { - (-self, false) - } + pub const fn overflowing_neg(self) -> (Self, bool) { + ((self ^ -1).wrapping_add(1), s == $SelfT::min_value()) } } @@ -3017,7 +3013,7 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline] - pub fn wrapping_neg(self) -> Self { + pub const fn wrapping_neg(self) -> Self { self.overflowing_neg().0 } @@ -3322,7 +3318,7 @@ assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!( ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_neg(self) -> (Self, bool) { + pub const fn overflowing_neg(self) -> (Self, bool) { ((!self).wrapping_add(1), self != 0) } } From 26a354065c94c107a8fb98f1a48d730aa0502dbb Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 1 Feb 2019 01:50:11 -0700 Subject: [PATCH 0477/1064] Don't know why I wasn't using `self` properly there --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 81aec346c93fc..16364faa8000d 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1530,7 +1530,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($Self #[inline] #[stable(feature = "wrapping", since = "1.7.0")] pub const fn overflowing_neg(self) -> (Self, bool) { - ((self ^ -1).wrapping_add(1), s == $SelfT::min_value()) + ((self ^ -1).wrapping_add(1), self == Self::min_value()) } } From 6a01f8aecd610d1d1236c452d83561d8bab69f06 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 1 Feb 2019 11:24:12 +0100 Subject: [PATCH 0478/1064] Stabilize split_ascii_whitespace Tracking issue FCP to merge: https://github.com/rust-lang/rust/issues/48656#issuecomment-442372750 --- src/liballoc/lib.rs | 1 - src/liballoc/str.rs | 2 +- src/libcore/str/mod.rs | 11 +++++------ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5165a7ca5a8f3..bd2d8461bf678 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -98,7 +98,6 @@ #![feature(rustc_attrs)] #![feature(receiver_trait)] #![feature(specialization)] -#![feature(split_ascii_whitespace)] #![feature(staged_api)] #![feature(str_internals)] #![feature(trusted_len)] diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 60d9f1626138e..53dd1a5df30db 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -68,7 +68,7 @@ pub use core::str::SplitWhitespace; pub use core::str::pattern; #[stable(feature = "encode_utf16", since = "1.8.0")] pub use core::str::EncodeUtf16; -#[unstable(feature = "split_ascii_whitespace", issue = "48656")] +#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] pub use core::str::SplitAsciiWhitespace; #[unstable(feature = "slice_concat_ext", diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3cb3936038093..130142103a9ba 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2700,7 +2700,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(split_ascii_whitespace)] /// let mut iter = "A few words".split_ascii_whitespace(); /// /// assert_eq!(Some("A"), iter.next()); @@ -2722,7 +2721,7 @@ impl str { /// /// assert_eq!(None, iter.next()); /// ``` - #[unstable(feature = "split_ascii_whitespace", issue = "48656")] + #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace { let inner = self @@ -4009,7 +4008,7 @@ pub struct SplitWhitespace<'a> { /// /// [`split_ascii_whitespace`]: ../../std/primitive.str.html#method.split_ascii_whitespace /// [`str`]: ../../std/primitive.str.html -#[unstable(feature = "split_ascii_whitespace", issue = "48656")] +#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[derive(Clone, Debug)] pub struct SplitAsciiWhitespace<'a> { inner: Map, IsNotEmpty>, UnsafeBytesToStr>, @@ -4134,7 +4133,7 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for SplitWhitespace<'_> {} -#[unstable(feature = "split_ascii_whitespace", issue = "48656")] +#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl<'a> Iterator for SplitAsciiWhitespace<'a> { type Item = &'a str; @@ -4149,7 +4148,7 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { } } -#[unstable(feature = "split_ascii_whitespace", issue = "48656")] +#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { #[inline] fn next_back(&mut self) -> Option<&'a str> { @@ -4157,7 +4156,7 @@ impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { } } -#[unstable(feature = "split_ascii_whitespace", issue = "48656")] +#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl FusedIterator for SplitAsciiWhitespace<'_> {} /// An iterator of [`u16`] over the string encoded as UTF-16. From 5cf20ca3c539d8d2e2560055f516ef95251837c1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 31 Jan 2019 15:42:45 +0100 Subject: [PATCH 0479/1064] Fix image link in the settings menu --- src/librustdoc/html/layout.rs | 28 ++++++++++++++++++---------- src/librustdoc/html/render.rs | 20 ++++++++++++++++---- src/test/rustdoc/keyword.rs | 2 +- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index c34dcbbb672e9..b444993c1b5ec 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -4,6 +4,8 @@ use std::path::PathBuf; use externalfiles::ExternalHtml; +use html::render::SlashChecker; + #[derive(Clone)] pub struct Layout { pub logo: String, @@ -176,16 +178,22 @@ pub fn render( static_root_path = static_root_path, root_path = page.root_path, css_class = page.css_class, - logo = if layout.logo.is_empty() { - format!("
\ - logo", - static_root_path=static_root_path, - suffix=page.resource_suffix) - } else { - format!("\ - logo", - page.root_path, layout.krate, - layout.logo) + logo = { + let p = format!("{}{}", page.root_path, layout.krate); + let p = SlashChecker(&p); + if layout.logo.is_empty() { + format!("\ + logo", + path=p, + static_root_path=static_root_path, + suffix=page.resource_suffix) + } else { + format!("\ + logo", + p, + layout.logo) + } }, title = page.title, description = page.description, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..f2bd56978c287 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -73,6 +73,18 @@ use minifier; /// A pair of name and its optional document. pub type NameDoc = (String, Option); +pub struct SlashChecker<'a>(pub &'a str); + +impl<'a> Display for SlashChecker<'a> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + if !self.0.ends_with("/") && !self.0.is_empty() { + write!(f, "{}/", self.0) + } else { + write!(f, "{}", self.0) + } + } +} + /// Major driving force in all rustdoc rendering. This contains information /// about where in the tree-like hierarchy rendering is occurring and controls /// how the current page is being rendered. @@ -1140,7 +1152,8 @@ themePicker.onblur = handleThemeButtonsBlur; krates .iter() .map(|s| { - format!("
  • {}
  • ", s, s) + format!("
  • {}
  • ", + SlashChecker(s), s) }) .collect::()); try_err!(layout::render(&mut w, &cx.shared.layout, @@ -2074,8 +2087,7 @@ impl Context { let mut themes = self.shared.themes.clone(); let sidebar = "

    Settings

    "; themes.push(PathBuf::from("settings.css")); - let mut layout = self.shared.layout.clone(); - layout.krate = String::new(); + let layout = self.shared.layout.clone(); try_err!(layout::render(&mut w, &layout, &page, &sidebar, &settings, self.shared.css_file_extension.is_some(), @@ -2454,7 +2466,7 @@ impl<'a> fmt::Display for Item<'a> { fn item_path(ty: ItemType, name: &str) -> String { match ty { - ItemType::Module => format!("{}/index.html", name), + ItemType::Module => format!("{}index.html", SlashChecker(name)), _ => format!("{}.{}.html", ty.css_class(), name), } } diff --git a/src/test/rustdoc/keyword.rs b/src/test/rustdoc/keyword.rs index d3327ae7ae117..c721c024468dd 100644 --- a/src/test/rustdoc/keyword.rs +++ b/src/test/rustdoc/keyword.rs @@ -7,7 +7,7 @@ // @has foo/keyword.match.html '//a[@class="keyword"]' 'match' // @has foo/keyword.match.html '//span[@class="in-band"]' 'Keyword match' // @has foo/keyword.match.html '//section[@id="main"]//div[@class="docblock"]//p' 'this is a test!' -// @!has foo/index.html '//a/@href' 'foo/index.html' +// @has foo/index.html '//a/@href' '../foo/index.html' // @!has foo/foo/index.html // @!has-dir foo/foo #[doc(keyword = "match")] From cc1e05f0ca92805d17aaba5613f85287c9ce8dd7 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 1 Feb 2019 11:29:02 +0100 Subject: [PATCH 0480/1064] Stabilize std::error::Error::type_id This should have been part of https://github.com/rust-lang/rust/pull/57834 FCP: https://github.com/rust-lang/rust/issues/27745#issuecomment-373906749 --- src/libstd/error.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 2f9efb3f0fb57..50415d9aeb9c8 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -197,9 +197,7 @@ pub trait Error: Debug + Display { /// Get the `TypeId` of `self` #[doc(hidden)] - #[unstable(feature = "error_type_id", - reason = "unclear whether to commit to this public implementation detail", - issue = "27745")] + #[stable(feature = "error_type_id", since = "1.34.0")] fn type_id(&self) -> TypeId where Self: 'static { TypeId::of::() } From 3dbf7d4a0eba779fd0ec8eb1e9b1966554fc4599 Mon Sep 17 00:00:00 2001 From: king6cong Date: Fri, 1 Feb 2019 18:41:51 +0800 Subject: [PATCH 0481/1064] Fix typo --- src/tools/remote-test-server/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index 3f56d4da6a3ed..750eea3a28aef 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -174,7 +174,7 @@ fn handle_run(socket: TcpStream, work: &Path, lock: &Mutex<()>) { // other thread created a child process with the file open for writing, and // we attempt to execute it, so we get an error. // - // This race is resolve by ensuring that only one thread can writ ethe file + // This race is resolve by ensuring that only one thread can write the file // and spawn a child process at once. Kinda an unfortunate solution, but we // don't have many other choices with this sort of setup! // From 8b6f3ddf2347509f9ff90c34e48673a25624d6e5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 15 Dec 2018 07:00:15 -0500 Subject: [PATCH 0482/1064] Initial implementation work --- src/librustc/lint/builtin.rs | 6 ++ src/librustc/session/config.rs | 24 ++++++ src/librustc_lint/builtin.rs | 2 + src/librustc_lint/lib.rs | 5 ++ src/librustc_privacy/lib.rs | 129 +++++++++++++++++++++++++++++++-- src/libsyntax/feature_gate.rs | 3 + 6 files changed, 164 insertions(+), 5 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 35a0382359572..16f7f9903f7d5 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -125,6 +125,12 @@ declare_lint! { "detect private items in public interfaces not caught by the old implementation" } +declare_lint! { + pub LEAKED_PRIVATE_DEPENDENCY, + Warn, + "public interface leaks type from a private dependency" +} + declare_lint! { pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, Deny, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 4b1aefb2216fb..5c2aa882a06c6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -411,6 +411,10 @@ top_level_options!( remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], edition: Edition [TRACKED], + + // The list of crates to consider public for + // checking leaked private dependency types in public interfaces + extern_public: FxHashSet [UNTRACKED], } ); @@ -606,6 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, + extern_public: FxHashSet::default() } } } @@ -1648,6 +1653,13 @@ pub fn rustc_short_optgroups() -> Vec { for the compiler to emit", "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]", ), + opt::multi_s( + "", + "extern-public", + "Comma separated list of crates to consider 'public' + for linting purposes", + "CRATES", + ), opt::opt_s( "", "crate-name", @@ -1905,6 +1917,17 @@ pub fn build_session_options_and_crate_config( let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); + if matches.opt_present("extern-public") && !nightly_options::is_nightly_build() { + early_error( + ErrorOutputType::default(), + "'--extern-public' is unstable and only \ + available for nightly builds of rustc." + ) + } + + let extern_public: FxHashSet = matches.opt_strs("extern-public"). + iter().cloned().collect(); + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); @@ -2287,6 +2310,7 @@ pub fn build_session_options_and_crate_config( cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, edition, + extern_public }, cfg, ) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 46e784c4099c8..b0846822b24e1 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1883,3 +1883,5 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } } + + diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 6607951d2cd14..e2e63b418c72c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -229,6 +229,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #34537 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(LEAKED_PRIVATE_DEPENDENCY), + reference: "issue #44663 ", + edition: None, + }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index dcbb9ff4a7576..c7cdb30521bf0 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1458,6 +1458,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { has_pub_restricted: bool, has_old_errors: bool, in_assoc_ty: bool, + public_crates: FxHashSet } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { @@ -1514,22 +1515,134 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC, node_id, self.span, &format!("{} (error {})", msg, err_code)); } + + if self.leaks_private_dep(trait_ref.def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + node_id, + self.span, + &format!("trait `{}` from private dependency '{}' in public \ + interface", trait_ref, + trait_ref.def_id.krate)); + + } } - false + } + + /// An item is 'leaked' from a private dependency if all + /// of the following are true: + /// 1. It's contained within a public type + /// 2. It does not come from a crate marked as public + fn leaks_private_dep(&self, item_id: DefId) -> bool { + // Never do any leak checking if the feature is not enabled + if !self.tcx.features().public_private_dependencies { + return false + } + self.required_visibility == ty::Visibility::Public && + !item_id.is_local() && + !self.public_crates.contains(&item_id.krate) } } -impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } - fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { - self.check_def_id(def_id, kind, descr) +impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { + let ty_def_id = match ty.sty { + ty::Adt(adt, _) => Some(adt.did), + ty::Foreign(did) => Some(did), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), + ty::Projection(ref proj) => { + if self.required_visibility == ty::Visibility::Invisible { + // Conservatively approximate the whole type alias as public without + // recursing into its components when determining impl publicity. + // For example, `impl ::Alias {...}` may be a public impl + // even if both `Type` and `Trait` are private. + // Ideally, associated types should be substituted in the same way as + // free type aliases, but this isn't done yet. + return false; + } + let trait_ref = proj.trait_ref(self.tcx); + Some(trait_ref.def_id) + } + _ => None + }; + + if let Some(def_id) = ty_def_id { + // Non-local means public (private items can't leave their crate, modulo bugs). + if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) { + let hir_vis = match self.tcx.hir().find(node_id) { + Some(Node::Item(item)) => &item.vis, + Some(Node::ForeignItem(item)) => &item.vis, + _ => bug!("expected item of foreign item"), + }; + + let vis = ty::Visibility::from_hir(hir_vis, node_id, self.tcx); + + if !vis.is_at_least(self.min_visibility, self.tcx) { + self.min_visibility = vis; + } + if !vis.is_at_least(self.required_visibility, self.tcx) { + let vis_adj = match hir_vis.node { + hir::VisibilityKind::Crate(_) => "crate-visible", + hir::VisibilityKind::Restricted { .. } => "restricted", + _ => "private" + }; + + if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty { + let mut err = struct_span_err!(self.tcx.sess, self.span, E0446, + "{} type `{}` in public interface", vis_adj, ty); + err.span_label(self.span, format!("can't leak {} type", vis_adj)); + err.span_label(hir_vis.span, format!("`{}` declared as {}", ty, vis_adj)); + err.emit(); + } else { + self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC, + node_id, + self.span, + &format!("{} type `{}` in public \ + interface (error E0446)", vis_adj, ty)); + } + } + + if self.leaks_private_dep(def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + node_id, + self.span, + &format!("type '{}' from private dependency '{}' in \ + public interface", ty, def_id.krate)); + } + } + } + + ty.super_visit_with(self) + } +} + +/*struct LeakedPrivateDependenciesVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + public_crates: FxHashSet +} + +impl<'a, 'tcx> LeakedPrivateDependenciesVisitor<'a, 'tcx> { + fn is_private_dep(&self, item_id: DefId) { + !item_id.is_local() && !self.public_crates.contains(item_id.krate) } + } +impl<'a, 'tcx> Visitor<'tcx> for LeakedPrivateDependenciesVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> nestedvisitormap<'this, 'tcx> { + nestedvisitormap::onlybodies(&self.tcx.hir()) + } + + fn visit_item(&mut self, item: &'tcx hir::Item) { + + } + +}*/ + struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, old_error_set: &'a NodeSet, + public_crates: FxHashSet } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1566,6 +1679,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { has_pub_restricted: self.has_pub_restricted, has_old_errors, in_assoc_ty: false, + public_crates: self.public_crates.clone() } } @@ -1690,6 +1804,10 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc { fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); + let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { + tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() + }).collect(); + // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { tcx, @@ -1767,6 +1885,7 @@ fn privacy_access_levels<'tcx>( tcx, has_pub_restricted, old_error_set: &visitor.old_error_set, + public_crates }; krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9dd17b420aa44..55eb6723188b9 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -462,6 +462,9 @@ declare_features! ( // #[optimize(X)] (active, optimize_attribute, "1.34.0", Some(54882), None), + + // Allows using the 'leaked private dependencies' lint + (active, public_private_dependencies, "1.32.0", Some(44663), None), ); declare_features! ( From 09ff0bacef6dd6bc3854f5c0dafff09e3ae22c6e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 15 Dec 2018 08:01:57 -0500 Subject: [PATCH 0483/1064] Fix emitting lint --- src/librustc_privacy/Cargo.toml | 3 ++- src/librustc_privacy/lib.rs | 46 +++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 62eab40f3ec9a..dfc4e5b5db45d 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -13,4 +13,5 @@ rustc = { path = "../librustc" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file +rustc_data_structures = { path = "../librustc_data_structures" } +log = "0.4" diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index c7cdb30521bf0..ce0a4a654825a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -9,6 +9,7 @@ #[macro_use] extern crate rustc; #[macro_use] extern crate syntax; +#[macro_use] extern crate log; extern crate rustc_typeck; extern crate syntax_pos; extern crate rustc_data_structures; @@ -1451,6 +1452,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_id: ast::NodeId, item_def_id: DefId, span: Span, /// The visitor checks that each component type is at least this visible. @@ -1516,16 +1518,18 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { &format!("{} (error {})", msg, err_code)); } - if self.leaks_private_dep(trait_ref.def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - node_id, - self.span, - &format!("trait `{}` from private dependency '{}' in public \ - interface", trait_ref, - trait_ref.def_id.krate)); + } + + if self.leaks_private_dep(trait_ref.def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.item_id, + self.span, + &format!("trait `{}` from private dependency '{}' in public \ + interface", trait_ref, + self.tcx.crate_name(trait_ref.def_id.krate))); - } } + } /// An item is 'leaked' from a private dependency if all @@ -1537,9 +1541,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { if !self.tcx.features().public_private_dependencies { return false } - self.required_visibility == ty::Visibility::Public && + let ret = self.required_visibility == ty::Visibility::Public && !item_id.is_local() && - !self.public_crates.contains(&item_id.krate) + !self.public_crates.contains(&item_id.krate); + + + debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); + return ret; } } @@ -1601,14 +1609,17 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' } } - if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - node_id, - self.span, - &format!("type '{}' from private dependency '{}' in \ - public interface", ty, def_id.krate)); - } } + + if self.leaks_private_dep(def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.item_id, + self.span, + &format!("type '{}' from private dependency '{}' in \ + public interface", ty, + self.tcx.crate_name(def_id.krate))); + } + } ty.super_visit_with(self) @@ -1673,6 +1684,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { SearchInterfaceForPrivateItemsVisitor { tcx: self.tcx, + item_id, item_def_id: self.tcx.hir().local_def_id(item_id), span: self.tcx.hir().span(item_id), required_visibility, From afb1921c79064a6fb99d2b93ef4835d9da14b517 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 18:07:42 -0500 Subject: [PATCH 0484/1064] Fixup code --- Cargo.lock | 1 + src/librustc_privacy/lib.rs | 104 +++++++----------------------------- 2 files changed, 21 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 058f1b1e716a9..1ac2dfe25c395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2878,6 +2878,7 @@ dependencies = [ name = "rustc_privacy" version = "0.0.0" dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_typeck 0.0.0", diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ce0a4a654825a..f37d0ce426003 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1495,6 +1495,16 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { + if self.leaks_private_dep(def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.item_id, + self.span, + &format!("{} `{}` from private dependency '{}' in public \ + interface", kind, descr, + self.tcx.crate_name(def_id.krate))); + + } + let node_id = match self.tcx.hir().as_local_node_id(def_id) { Some(node_id) => node_id, None => return false, @@ -1520,16 +1530,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } - if self.leaks_private_dep(trait_ref.def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - self.item_id, - self.span, - &format!("trait `{}` from private dependency '{}' in public \ - interface", trait_ref, - self.tcx.crate_name(trait_ref.def_id.krate))); - - } - + false } /// An item is 'leaked' from a private dependency if all @@ -1551,80 +1552,6 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } } -impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { - let ty_def_id = match ty.sty { - ty::Adt(adt, _) => Some(adt.did), - ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), - ty::Projection(ref proj) => { - if self.required_visibility == ty::Visibility::Invisible { - // Conservatively approximate the whole type alias as public without - // recursing into its components when determining impl publicity. - // For example, `impl ::Alias {...}` may be a public impl - // even if both `Type` and `Trait` are private. - // Ideally, associated types should be substituted in the same way as - // free type aliases, but this isn't done yet. - return false; - } - let trait_ref = proj.trait_ref(self.tcx); - Some(trait_ref.def_id) - } - _ => None - }; - - if let Some(def_id) = ty_def_id { - // Non-local means public (private items can't leave their crate, modulo bugs). - if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) { - let hir_vis = match self.tcx.hir().find(node_id) { - Some(Node::Item(item)) => &item.vis, - Some(Node::ForeignItem(item)) => &item.vis, - _ => bug!("expected item of foreign item"), - }; - - let vis = ty::Visibility::from_hir(hir_vis, node_id, self.tcx); - - if !vis.is_at_least(self.min_visibility, self.tcx) { - self.min_visibility = vis; - } - if !vis.is_at_least(self.required_visibility, self.tcx) { - let vis_adj = match hir_vis.node { - hir::VisibilityKind::Crate(_) => "crate-visible", - hir::VisibilityKind::Restricted { .. } => "restricted", - _ => "private" - }; - - if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty { - let mut err = struct_span_err!(self.tcx.sess, self.span, E0446, - "{} type `{}` in public interface", vis_adj, ty); - err.span_label(self.span, format!("can't leak {} type", vis_adj)); - err.span_label(hir_vis.span, format!("`{}` declared as {}", ty, vis_adj)); - err.emit(); - } else { - self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC, - node_id, - self.span, - &format!("{} type `{}` in public \ - interface (error E0446)", vis_adj, ty)); - } - } - - } - - if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - self.item_id, - self.span, - &format!("type '{}' from private dependency '{}' in \ - public interface", ty, - self.tcx.crate_name(def_id.krate))); - } - - } - - ty.super_visit_with(self) - } -} /*struct LeakedPrivateDependenciesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1649,6 +1576,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LeakedPrivateDependenciesVisitor<'a, 'tcx> { }*/ + + +impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } + fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { + self.check_def_id(def_id, kind, descr) + } +} + struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, From 23014b4036ef88522e5134e71622b64eebbcf703 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 18:50:16 -0500 Subject: [PATCH 0485/1064] Properly register lint --- src/librustc/lint/builtin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 16f7f9903f7d5..1651175525e05 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -411,6 +411,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, + LEAKED_PRIVATE_DEPENDENCY, PUB_USE_OF_PRIVATE_EXTERN_CRATE, INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, From 93d872dbc88412c2ef1c22be1f81961cae730ac2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 18:50:24 -0500 Subject: [PATCH 0486/1064] Add UI test --- .../pub-priv-dep/auxiliary/priv_dep.rs | 1 + src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 31 +++++++++++++++++++ .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 25 +++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs create mode 100644 src/test/ui/privacy/pub-priv-dep/pub-priv1.rs create mode 100644 src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr diff --git a/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs new file mode 100644 index 0000000000000..23426f96c75f0 --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -0,0 +1 @@ +pub struct OtherType; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs new file mode 100644 index 0000000000000..d8620944065c9 --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -0,0 +1,31 @@ + // aux-build:priv_dep.rs +#![feature(public_private_dependencies)] +#![deny(leaked_private_dependency)] + +// This crate is a private dependency +extern crate priv_dep; + +use priv_dep::OtherType; + +// Type from private dependency used in private +// type - this is fine +struct PrivateType { + field: OtherType +} + +pub struct PublicType { + pub field: OtherType, + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~| WARNING this was previously accepted + priv_field: OtherType, +} + +impl PublicType { + pub fn pub_fn(param: OtherType) {} + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~| WARNING this was previously accepted + + fn priv_fn(param: OtherType) {} +} + +fn main() {} diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr new file mode 100644 index 0000000000000..330bf8a1f5226 --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -0,0 +1,25 @@ +error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:17:5 + | +LL | pub field: OtherType, + | ^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/pub-priv1.rs:3:9 + | +LL | #![deny(leaked_private_dependency)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #44663 + +error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:24:5 + | +LL | pub fn pub_fn(param: OtherType) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #44663 + +error: aborting due to 2 previous errors + From 08c901f0155b10c55427991e9da6fce83b541f2c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 20:35:14 -0500 Subject: [PATCH 0487/1064] Always treat 'std' and 'core' as public --- src/librustc/session/config.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5c2aa882a06c6..16d3d332e4056 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1925,9 +1925,13 @@ pub fn build_session_options_and_crate_config( ) } - let extern_public: FxHashSet = matches.opt_strs("extern-public"). + let mut extern_public: FxHashSet = matches.opt_strs("extern-public"). iter().cloned().collect(); + // TODO - come up with a better way of handling this + extern_public.insert("core".to_string()); + extern_public.insert("std".to_string()); + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); From 12f9b796ff9a551d540390647043f4bcd1728838 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 20:37:27 -0500 Subject: [PATCH 0488/1064] Improve UI tests --- .../pub-priv-dep/auxiliary/priv_dep.rs | 1 + .../privacy/pub-priv-dep/auxiliary/pub_dep.rs | 1 + src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 17 +++++++++++++++-- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 19 +++++++++++++++---- 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs diff --git a/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs index 23426f96c75f0..e7afeb84fb4f4 100644 --- a/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs +++ b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -1 +1,2 @@ pub struct OtherType; +pub trait OtherTrait {} diff --git a/src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs b/src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs new file mode 100644 index 0000000000000..3ebafd953addf --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs @@ -0,0 +1 @@ +pub struct PubType; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index d8620944065c9..f82c1ad1c93b5 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,11 +1,16 @@ // aux-build:priv_dep.rs + // aux-build:pub_dep.rs + // compile-flags: --extern-public=pub_dep #![feature(public_private_dependencies)] #![deny(leaked_private_dependency)] // This crate is a private dependency extern crate priv_dep; +// This crate is a public dependenct +extern crate pub_dep; -use priv_dep::OtherType; +use priv_dep::{OtherType, OtherTrait}; +use pub_dep::PubType; // Type from private dependency used in private // type - this is fine @@ -17,7 +22,8 @@ pub struct PublicType { pub field: OtherType, //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] //~| WARNING this was previously accepted - priv_field: OtherType, + priv_field: OtherType, // Private field - this is fine + pub other_field: PubType // Type from public dependency - this is fine } impl PublicType { @@ -28,4 +34,11 @@ impl PublicType { fn priv_fn(param: OtherType) {} } +pub trait MyPubTrait { + type Foo: OtherTrait; +} +//~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface [leaked_private_dependency] +//~| WARNING this was previously accepted + + fn main() {} diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 330bf8a1f5226..fa74eb2265d0c 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,11 +1,11 @@ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:17:5 + --> $DIR/pub-priv1.rs:22:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/pub-priv1.rs:3:9 + --> $DIR/pub-priv1.rs:5:9 | LL | #![deny(leaked_private_dependency)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(leaked_private_dependency)] = note: for more information, see issue #44663 error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:24:5 + --> $DIR/pub-priv1.rs:30:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,5 +21,16 @@ LL | pub fn pub_fn(param: OtherType) {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #44663 -error: aborting due to 2 previous errors +error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:37:1 + | +LL | / pub trait MyPubTrait { +LL | | type Foo: OtherTrait; +LL | | } + | |_^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #44663 + +error: aborting due to 3 previous errors From d60214cdf7bea6955d5c3a0bb905022bdae1b232 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:29:52 -0500 Subject: [PATCH 0489/1064] Clippy fixes, rename stuff to match RFC --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc/session/config.rs | 2 +- src/librustc_lint/builtin.rs | 2 -- src/librustc_lint/lib.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- .../ui/feature-gates/auxiliary/pub_dep.rs | 1 + ...eature-gate-public_private_dependencies.rs | 20 +++++++++++++++++++ src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 8 ++++---- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 4 ++-- 9 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/feature-gates/auxiliary/pub_dep.rs create mode 100644 src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 1651175525e05..473214a04c8ed 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -126,7 +126,7 @@ declare_lint! { } declare_lint! { - pub LEAKED_PRIVATE_DEPENDENCY, + pub EXTERNAL_PRIVATE_DEPENDENCY, Warn, "public interface leaks type from a private dependency" } @@ -411,7 +411,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, - LEAKED_PRIVATE_DEPENDENCY, + EXTERNAL_PRIVATE_DEPENDENCY, PUB_USE_OF_PRIVATE_EXTERN_CRATE, INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 16d3d332e4056..635ac6dcc48f8 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1928,7 +1928,7 @@ pub fn build_session_options_and_crate_config( let mut extern_public: FxHashSet = matches.opt_strs("extern-public"). iter().cloned().collect(); - // TODO - come up with a better way of handling this + // FIXME - come up with a better way of handling this extern_public.insert("core".to_string()); extern_public.insert("std".to_string()); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index b0846822b24e1..46e784c4099c8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1883,5 +1883,3 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } } - - diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index e2e63b418c72c..66e6368e83da0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -230,7 +230,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { edition: None, }, FutureIncompatibleInfo { - id: LintId::of(LEAKED_PRIVATE_DEPENDENCY), + id: LintId::of(EXTERNAL_PRIVATE_DEPENDENCY), reference: "issue #44663 ", edition: None, }, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f37d0ce426003..7b5b06257ce90 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1496,7 +1496,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.tcx.lint_node(lint::builtin::EXTERNAL_PRIVATE_DEPENDENCY, self.item_id, self.span, &format!("{} `{}` from private dependency '{}' in public \ diff --git a/src/test/ui/feature-gates/auxiliary/pub_dep.rs b/src/test/ui/feature-gates/auxiliary/pub_dep.rs new file mode 100644 index 0000000000000..3ebafd953addf --- /dev/null +++ b/src/test/ui/feature-gates/auxiliary/pub_dep.rs @@ -0,0 +1 @@ +pub struct PubType; diff --git a/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs new file mode 100644 index 0000000000000..bd27c844fc620 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs @@ -0,0 +1,20 @@ +// This test is different from other feature gate tests. +// Instead of checking that an error occurs without the feature gate, +// it checks that *no* errors/warnings occurs without the feature gate. +// This is due to the fact that 'public_private_dependencies' just enables +// a lint, so disabling it shouldn't cause any code to stop compiling. + +// run-pass +// aux-build:pub_dep.rs + +// Without ![feature(public_private_dependencies)], +// this should do nothing/ +#![deny(external_private_dependency)] + +extern crate pub_dep; + +pub struct Foo { + pub field: pub_dep::PubType +} + +fn main() {} diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index f82c1ad1c93b5..16a59dff8780e 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -2,7 +2,7 @@ // aux-build:pub_dep.rs // compile-flags: --extern-public=pub_dep #![feature(public_private_dependencies)] -#![deny(leaked_private_dependency)] +#![deny(external_private_dependency)] // This crate is a private dependency extern crate priv_dep; @@ -20,7 +20,7 @@ struct PrivateType { pub struct PublicType { pub field: OtherType, - //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted priv_field: OtherType, // Private field - this is fine pub other_field: PubType // Type from public dependency - this is fine @@ -28,7 +28,7 @@ pub struct PublicType { impl PublicType { pub fn pub_fn(param: OtherType) {} - //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted fn priv_fn(param: OtherType) {} @@ -37,7 +37,7 @@ impl PublicType { pub trait MyPubTrait { type Foo: OtherTrait; } -//~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface [leaked_private_dependency] +//~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index fa74eb2265d0c..9e5bffa6eea3e 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -7,8 +7,8 @@ LL | pub field: OtherType, note: lint level defined here --> $DIR/pub-priv1.rs:5:9 | -LL | #![deny(leaked_private_dependency)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(external_private_dependency)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #44663 From bc2221f7b6778de779113f1b9021477cf313010b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:33:06 -0500 Subject: [PATCH 0490/1064] Add test for 'std' crate being public --- src/test/ui/privacy/pub-priv-dep/std-pub.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/privacy/pub-priv-dep/std-pub.rs diff --git a/src/test/ui/privacy/pub-priv-dep/std-pub.rs b/src/test/ui/privacy/pub-priv-dep/std-pub.rs new file mode 100644 index 0000000000000..7acf0f89c5dbe --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/std-pub.rs @@ -0,0 +1,13 @@ +// The 'std' crates should always be implicitly public, +// without having to pass any compiler arguments + +// run-pass + +#![feature(public_private_dependencies)] +#![deny(external_private_dependency)] + +pub struct PublicType { + pub field: Option +} + +fn main() {} From d8fc6300525a71372300807f9ed76a37ae99649d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:39:24 -0500 Subject: [PATCH 0491/1064] Track extern_public command-line argument --- src/librustc/session/config.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 635ac6dcc48f8..e63336437cdb0 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -414,7 +414,7 @@ top_level_options!( // The list of crates to consider public for // checking leaked private dependency types in public interfaces - extern_public: FxHashSet [UNTRACKED], + extern_public: Vec [TRACKED], } ); @@ -610,7 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, - extern_public: FxHashSet::default() + extern_public: vec![] } } } @@ -1925,12 +1925,12 @@ pub fn build_session_options_and_crate_config( ) } - let mut extern_public: FxHashSet = matches.opt_strs("extern-public"). + let mut extern_public: Vec = matches.opt_strs("extern-public"). iter().cloned().collect(); // FIXME - come up with a better way of handling this - extern_public.insert("core".to_string()); - extern_public.insert("std".to_string()); + extern_public.push("core".to_string()); + extern_public.push("std".to_string()); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); From dfd26696674ecadc39aabcc94314cda8d571f71b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:42:36 -0500 Subject: [PATCH 0492/1064] Delete dead code --- src/librustc_privacy/lib.rs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 7b5b06257ce90..6a91ec81e4e71 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1552,32 +1552,6 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } } - -/*struct LeakedPrivateDependenciesVisitor<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - public_crates: FxHashSet -} - -impl<'a, 'tcx> LeakedPrivateDependenciesVisitor<'a, 'tcx> { - fn is_private_dep(&self, item_id: DefId) { - !item_id.is_local() && !self.public_crates.contains(item_id.krate) - } - -} - -impl<'a, 'tcx> Visitor<'tcx> for LeakedPrivateDependenciesVisitor<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> nestedvisitormap<'this, 'tcx> { - nestedvisitormap::onlybodies(&self.tcx.hir()) - } - - fn visit_item(&mut self, item: &'tcx hir::Item) { - - } - -}*/ - - - impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { From 3fa36471e81011b7b1c44ec66c5aa70a67dfe475 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 20 Jan 2019 22:04:22 -0500 Subject: [PATCH 0493/1064] Rename external_private_dependency to exported_private_dependencies --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc_lint/lib.rs | 2 +- src/librustc_privacy/lib.rs | 10 ++++++---- .../feature-gate-public_private_dependencies.rs | 2 +- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 2 +- src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr | 4 ++-- src/test/ui/privacy/pub-priv-dep/std-pub.rs | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 473214a04c8ed..3fe544d690640 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -126,7 +126,7 @@ declare_lint! { } declare_lint! { - pub EXTERNAL_PRIVATE_DEPENDENCY, + pub EXPORTED_PRIVATE_DEPENDENCIES, Warn, "public interface leaks type from a private dependency" } @@ -411,7 +411,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, - EXTERNAL_PRIVATE_DEPENDENCY, + EXPORTED_PRIVATE_DEPENDENCIES, PUB_USE_OF_PRIVATE_EXTERN_CRATE, INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 66e6368e83da0..128bc70087f94 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -230,7 +230,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { edition: None, }, FutureIncompatibleInfo { - id: LintId::of(EXTERNAL_PRIVATE_DEPENDENCY), + id: LintId::of(EXPORTED_PRIVATE_DEPENDENCIES), reference: "issue #44663 ", edition: None, }, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 6a91ec81e4e71..01694df1df106 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1496,7 +1496,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::EXTERNAL_PRIVATE_DEPENDENCY, + self.tcx.lint_node(lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES, self.item_id, self.span, &format!("{} `{}` from private dependency '{}' in public \ @@ -1726,9 +1726,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc { fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); - let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { - tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect(); // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { @@ -1765,6 +1762,11 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } + let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { + tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() + }).collect(); + + // Build up a set of all exported items in the AST. This is a set of all // items which are reachable from external crates based on visibility. let mut visitor = EmbargoVisitor { diff --git a/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs index bd27c844fc620..b8fb4b8dc19da 100644 --- a/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs +++ b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs @@ -9,7 +9,7 @@ // Without ![feature(public_private_dependencies)], // this should do nothing/ -#![deny(external_private_dependency)] +#![deny(exported_private_dependencies)] extern crate pub_dep; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 16a59dff8780e..7d71dbe6392d4 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -2,7 +2,7 @@ // aux-build:pub_dep.rs // compile-flags: --extern-public=pub_dep #![feature(public_private_dependencies)] -#![deny(external_private_dependency)] +#![deny(exported_private_dependencies)] // This crate is a private dependency extern crate priv_dep; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 9e5bffa6eea3e..11f4be8cbbc12 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -7,8 +7,8 @@ LL | pub field: OtherType, note: lint level defined here --> $DIR/pub-priv1.rs:5:9 | -LL | #![deny(external_private_dependency)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(exported_private_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #44663 diff --git a/src/test/ui/privacy/pub-priv-dep/std-pub.rs b/src/test/ui/privacy/pub-priv-dep/std-pub.rs index 7acf0f89c5dbe..3c1520c69027d 100644 --- a/src/test/ui/privacy/pub-priv-dep/std-pub.rs +++ b/src/test/ui/privacy/pub-priv-dep/std-pub.rs @@ -4,7 +4,7 @@ // run-pass #![feature(public_private_dependencies)] -#![deny(external_private_dependency)] +#![deny(exported_private_dependencies)] pub struct PublicType { pub field: Option From 173f5cf1164ded2409f8c019b5cd61b53119078c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 22 Jan 2019 18:37:58 -0500 Subject: [PATCH 0494/1064] Remove feature gate --- src/libsyntax/feature_gate.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 55eb6723188b9..9dd17b420aa44 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -462,9 +462,6 @@ declare_features! ( // #[optimize(X)] (active, optimize_attribute, "1.34.0", Some(54882), None), - - // Allows using the 'leaked private dependencies' lint - (active, public_private_dependencies, "1.32.0", Some(44663), None), ); declare_features! ( From fe15f7177f59f4ac9e9eb22dff727cd58a097e11 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Jan 2019 16:10:49 -0500 Subject: [PATCH 0495/1064] Move --extern-public behind -Z unstable-options --- src/librustc/session/config.rs | 39 +++++++++++++++++++--------------- src/librustc_privacy/lib.rs | 14 ++++++------ 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index e63336437cdb0..132a5a2a62bc2 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -414,7 +414,7 @@ top_level_options!( // The list of crates to consider public for // checking leaked private dependency types in public interfaces - extern_public: Vec [TRACKED], + extern_public: Option> [TRACKED], } ); @@ -610,7 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, - extern_public: vec![] + extern_public: None } } } @@ -1917,21 +1917,7 @@ pub fn build_session_options_and_crate_config( let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); - if matches.opt_present("extern-public") && !nightly_options::is_nightly_build() { - early_error( - ErrorOutputType::default(), - "'--extern-public' is unstable and only \ - available for nightly builds of rustc." - ) - } - - let mut extern_public: Vec = matches.opt_strs("extern-public"). - iter().cloned().collect(); - - // FIXME - come up with a better way of handling this - extern_public.push("core".to_string()); - extern_public.push("std".to_string()); - + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); @@ -1950,6 +1936,24 @@ pub fn build_session_options_and_crate_config( ); } + if matches.opt_present("extern-public") && !debugging_opts.unstable_options { + early_error( + ErrorOutputType::default(), + "'--extern-public' is unstable and only \ + available for nightly builds of rustc." + ) + } + + let mut extern_public: Option> = matches.opt_str("extern-public"). + map(|s| s.split(',').map(|c| (*c).to_string()).collect()); + + // FIXME - come up with a better way of handling this + if let Some(p) = extern_public.as_mut() { + p.push("core".to_string()); + p.push("std".to_string()); + } + + let mut output_types = BTreeMap::new(); if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { @@ -2488,6 +2492,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option<(String, u64)>); + impl_dep_tracking_hash_via_hash!(Option>); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 01694df1df106..f4f09db1087f4 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1460,7 +1460,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { has_pub_restricted: bool, has_old_errors: bool, in_assoc_ty: bool, - public_crates: FxHashSet + public_crates: Option> } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { @@ -1538,13 +1538,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 1. It's contained within a public type /// 2. It does not come from a crate marked as public fn leaks_private_dep(&self, item_id: DefId) -> bool { - // Never do any leak checking if the feature is not enabled - if !self.tcx.features().public_private_dependencies { + // Don't do any leak checking if no public crates were specified + if self.public_crates.is_none() { return false } let ret = self.required_visibility == ty::Visibility::Public && !item_id.is_local() && - !self.public_crates.contains(&item_id.krate); + !self.public_crates.as_ref().unwrap().contains(&item_id.krate); debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); @@ -1563,7 +1563,7 @@ struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, old_error_set: &'a NodeSet, - public_crates: FxHashSet + public_crates: Option> } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1762,9 +1762,9 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } - let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { + let public_crates: Option> = tcx.sess.opts.extern_public.as_ref().map(|s| s.iter().flat_map(|c| { tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect(); + }).collect()); // Build up a set of all exported items in the AST. This is a set of all From 45486cce2c22288ad30634743ba307008d0b2a07 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Jan 2019 16:16:57 -0500 Subject: [PATCH 0496/1064] Tidy fixes --- src/librustc/session/config.rs | 2 +- src/librustc_privacy/lib.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 132a5a2a62bc2..8e6a48f9d56bc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1917,7 +1917,7 @@ pub fn build_session_options_and_crate_config( let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); - + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f4f09db1087f4..4084e0495db5b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1762,9 +1762,10 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } - let public_crates: Option> = tcx.sess.opts.extern_public.as_ref().map(|s| s.iter().flat_map(|c| { - tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect()); + let public_crates: Option> = tcx.sess.opts.extern_public.as_ref() + .map(|s| s.iter().flat_map(|c| { + tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() + }).collect()); // Build up a set of all exported items in the AST. This is a set of all From b29a21fbae8e2c2efb121d998d804a4195065be0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Jan 2019 17:03:28 -0500 Subject: [PATCH 0497/1064] Remove feature from test --- src/test/ui/privacy/pub-priv-dep/std-pub.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/privacy/pub-priv-dep/std-pub.rs b/src/test/ui/privacy/pub-priv-dep/std-pub.rs index 3c1520c69027d..e25aa93a02e60 100644 --- a/src/test/ui/privacy/pub-priv-dep/std-pub.rs +++ b/src/test/ui/privacy/pub-priv-dep/std-pub.rs @@ -3,7 +3,6 @@ // run-pass -#![feature(public_private_dependencies)] #![deny(exported_private_dependencies)] pub struct PublicType { From 48ec29d38e031a2b15c7768e94fa8185f3e08847 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 15:33:50 -0500 Subject: [PATCH 0498/1064] Replace --extern-public with --extern-private --- src/librustc/session/config.rs | 41 ++++++++++--------- src/librustc_privacy/lib.rs | 20 ++++----- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 3 +- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 8 ++-- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 8e6a48f9d56bc..6b12e549c3388 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -412,9 +412,9 @@ top_level_options!( edition: Edition [TRACKED], - // The list of crates to consider public for + // The list of crates to consider private when // checking leaked private dependency types in public interfaces - extern_public: Option> [TRACKED], + extern_private: Vec [TRACKED], } ); @@ -610,7 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, - extern_public: None + extern_private: Vec::new() } } } @@ -1736,6 +1736,12 @@ pub fn rustc_optgroups() -> Vec { "Specify where an external rust library is located", "NAME=PATH", ), + opt::multi_s( + "", + "extern-private", + "Specify where an extern rust library is located, marking it as a private dependency", + "NAME=PATH", + ), opt::opt_s("", "sysroot", "Override the system root", "PATH"), opt::multi("Z", "", "Set internal debugging options", "FLAG"), opt::opt_s( @@ -1936,22 +1942,7 @@ pub fn build_session_options_and_crate_config( ); } - if matches.opt_present("extern-public") && !debugging_opts.unstable_options { - early_error( - ErrorOutputType::default(), - "'--extern-public' is unstable and only \ - available for nightly builds of rustc." - ) - } - - let mut extern_public: Option> = matches.opt_str("extern-public"). - map(|s| s.split(',').map(|c| (*c).to_string()).collect()); - // FIXME - come up with a better way of handling this - if let Some(p) = extern_public.as_mut() { - p.push("core".to_string()); - p.push("std".to_string()); - } let mut output_types = BTreeMap::new(); @@ -2249,8 +2240,18 @@ pub fn build_session_options_and_crate_config( ); } + if matches.opt_present("extern-private") && !debugging_opts.unstable_options { + early_error( + ErrorOutputType::default(), + "'--extern-private' is unstable and only \ + available for nightly builds of rustc." + ) + } + + let extern_private = matches.opt_strs("extern-private"); + let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new(); - for arg in &matches.opt_strs("extern") { + for arg in matches.opt_strs("extern").into_iter().chain(matches.opt_strs("extern-private")) { let mut parts = arg.splitn(2, '='); let name = parts.next().unwrap_or_else(|| early_error(error_format, "--extern value must not be empty")); @@ -2318,7 +2319,7 @@ pub fn build_session_options_and_crate_config( cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, edition, - extern_public + extern_private }, cfg, ) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4084e0495db5b..0f3c586383363 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1460,7 +1460,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { has_pub_restricted: bool, has_old_errors: bool, in_assoc_ty: bool, - public_crates: Option> + private_crates: FxHashSet } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { @@ -1538,13 +1538,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 1. It's contained within a public type /// 2. It does not come from a crate marked as public fn leaks_private_dep(&self, item_id: DefId) -> bool { - // Don't do any leak checking if no public crates were specified - if self.public_crates.is_none() { + // Don't do any leak checking if no private crates were specified + if self.private_crates.is_empty() { return false } let ret = self.required_visibility == ty::Visibility::Public && !item_id.is_local() && - !self.public_crates.as_ref().unwrap().contains(&item_id.krate); + self.private_crates.contains(&item_id.krate); debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); @@ -1563,7 +1563,7 @@ struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, old_error_set: &'a NodeSet, - public_crates: Option> + private_crates: FxHashSet } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1601,7 +1601,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { has_pub_restricted: self.has_pub_restricted, has_old_errors, in_assoc_ty: false, - public_crates: self.public_crates.clone() + private_crates: self.private_crates.clone() } } @@ -1762,10 +1762,10 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } - let public_crates: Option> = tcx.sess.opts.extern_public.as_ref() - .map(|s| s.iter().flat_map(|c| { + let private_crates: FxHashSet = tcx.sess.opts.extern_private.iter() + .flat_map(|c| { tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect()); + }).collect(); // Build up a set of all exported items in the AST. This is a set of all @@ -1810,7 +1810,7 @@ fn privacy_access_levels<'tcx>( tcx, has_pub_restricted, old_error_set: &visitor.old_error_set, - public_crates + private_crates }; krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 7d71dbe6392d4..9c60284f66c48 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,7 +1,6 @@ // aux-build:priv_dep.rs // aux-build:pub_dep.rs - // compile-flags: --extern-public=pub_dep -#![feature(public_private_dependencies)] + // compile-flags: --extern-private priv_dep #![deny(exported_private_dependencies)] // This crate is a private dependency diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 11f4be8cbbc12..7c701035d2877 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,11 +1,11 @@ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:22:5 + --> $DIR/pub-priv1.rs:21:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/pub-priv1.rs:5:9 + --> $DIR/pub-priv1.rs:4:9 | LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(exported_private_dependencies)] = note: for more information, see issue #44663 error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:30:5 + --> $DIR/pub-priv1.rs:29:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | pub fn pub_fn(param: OtherType) {} = note: for more information, see issue #44663 error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:37:1 + --> $DIR/pub-priv1.rs:36:1 | LL | / pub trait MyPubTrait { LL | | type Foo: OtherTrait; From a05bfc6aeb8e5be70d15b3296cd4ba68d3578e01 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 15:37:27 -0500 Subject: [PATCH 0499/1064] Test allowing individual struct field --- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 9c60284f66c48..ca77378d3613e 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -39,5 +39,11 @@ pub trait MyPubTrait { //~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted +pub struct AllowedPrivType { + #[allow(exported_private_dependencies)] + pub allowed: OtherType +} + + fn main() {} From 24f3595c02064340a85c1b15d1a7c8e670c6d5de Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 16:00:40 -0500 Subject: [PATCH 0500/1064] Remove unnecessary is_local() check --- src/librustc_privacy/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 0f3c586383363..3d67aeff00e8a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1536,14 +1536,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// An item is 'leaked' from a private dependency if all /// of the following are true: /// 1. It's contained within a public type - /// 2. It does not come from a crate marked as public + /// 2. It comes from a private crate fn leaks_private_dep(&self, item_id: DefId) -> bool { // Don't do any leak checking if no private crates were specified if self.private_crates.is_empty() { return false } let ret = self.required_visibility == ty::Visibility::Public && - !item_id.is_local() && self.private_crates.contains(&item_id.krate); From bfcd14dd2b6476980df2a18137d09faf2b796919 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 17:09:31 -0500 Subject: [PATCH 0501/1064] Add future compat lint declaration --- src/librustc_lint/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 128bc70087f94..6607951d2cd14 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -229,11 +229,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #34537 ", edition: None, }, - FutureIncompatibleInfo { - id: LintId::of(EXPORTED_PRIVATE_DEPENDENCIES), - reference: "issue #44663 ", - edition: None, - }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", From 541d31531322bd1d5f2bf7bb8b9cf4c79d85f01d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 17:28:41 -0500 Subject: [PATCH 0502/1064] Update tests for future-compat warning removal --- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 3 --- src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr | 12 ++---------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index ca77378d3613e..9ebc96017fe9c 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -20,7 +20,6 @@ struct PrivateType { pub struct PublicType { pub field: OtherType, //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - //~| WARNING this was previously accepted priv_field: OtherType, // Private field - this is fine pub other_field: PubType // Type from public dependency - this is fine } @@ -28,7 +27,6 @@ pub struct PublicType { impl PublicType { pub fn pub_fn(param: OtherType) {} //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - //~| WARNING this was previously accepted fn priv_fn(param: OtherType) {} } @@ -37,7 +35,6 @@ pub trait MyPubTrait { type Foo: OtherTrait; } //~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface -//~| WARNING this was previously accepted pub struct AllowedPrivType { #[allow(exported_private_dependencies)] diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 7c701035d2877..b31efdbd781dc 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -9,28 +9,20 @@ note: lint level defined here | LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #44663 error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:29:5 + --> $DIR/pub-priv1.rs:28:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #44663 error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:36:1 + --> $DIR/pub-priv1.rs:34:1 | LL | / pub trait MyPubTrait { LL | | type Foo: OtherTrait; LL | | } | |_^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #44663 error: aborting due to 3 previous errors From 369faaeaffa1b960f8260a1905b1fc34f33a23f6 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 31 Jan 2019 14:36:26 -0500 Subject: [PATCH 0503/1064] Cleanup unecessary code --- src/librustc/session/config.rs | 10 ---------- src/librustc_privacy/lib.rs | 5 ----- 2 files changed, 15 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 6b12e549c3388..86f676fbf888a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1653,13 +1653,6 @@ pub fn rustc_short_optgroups() -> Vec { for the compiler to emit", "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]", ), - opt::multi_s( - "", - "extern-public", - "Comma separated list of crates to consider 'public' - for linting purposes", - "CRATES", - ), opt::opt_s( "", "crate-name", @@ -1942,9 +1935,6 @@ pub fn build_session_options_and_crate_config( ); } - - - let mut output_types = BTreeMap::new(); if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 3d67aeff00e8a..73f83eb6f7a3a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1538,14 +1538,9 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 1. It's contained within a public type /// 2. It comes from a private crate fn leaks_private_dep(&self, item_id: DefId) -> bool { - // Don't do any leak checking if no private crates were specified - if self.private_crates.is_empty() { - return false - } let ret = self.required_visibility == ty::Visibility::Public && self.private_crates.contains(&item_id.krate); - debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); return ret; } From 381c5416855f53e130d5156aec5f9067fc981dfa Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 25 Jan 2019 15:04:15 +0100 Subject: [PATCH 0504/1064] Add FIXME --- src/librustc_typeck/check/writeback.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 238b087fe32f8..00917be538fb3 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -561,6 +561,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { if def_id == defin_ty_def_id { // Concrete type resolved to the existential type itself // Force a cycle error + // FIXME(oli-obk): we could just not insert it into `concrete_existential_types` + // which simply would make this use not a defining use. self.tcx().at(span).type_of(defin_ty_def_id); } } From 6982fd21d1d7963b2acc489d9de246f2715aab80 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 25 Jan 2019 16:14:59 +0100 Subject: [PATCH 0505/1064] Be more permissive with required bounds on existential types --- src/librustc_typeck/check/mod.rs | 3 --- .../ui/existential_types/generic_duplicate_param_use.rs | 4 +++- src/test/ui/existential_types/unused_generic_param.rs | 7 +++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 48475b3dcb802..5390382ee2d76 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1385,10 +1385,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite } hir::ItemKind::Existential(..) => { let def_id = tcx.hir().local_def_id(it.id); - let pty_ty = tcx.type_of(def_id); - let generics = tcx.generics_of(def_id); - check_bounds_are_used(tcx, &generics, pty_ty); let substs = Substs::identity_for_item(tcx, def_id); check_opaque(tcx, def_id, substs, it.span); } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.rs b/src/test/ui/existential_types/generic_duplicate_param_use.rs index 380fbdeb8c27c..14d63ecc6bb5d 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use.rs @@ -1,8 +1,10 @@ +// compile-pass #![feature(existential_type)] fn main() {} -existential type Two: 'static; //~ ERROR type parameter `U` is unused +// test that unused generic parameters are ok +existential type Two: 'static; fn one(t: T) -> Two { t diff --git a/src/test/ui/existential_types/unused_generic_param.rs b/src/test/ui/existential_types/unused_generic_param.rs index bd7b343b402f5..7af6508788129 100644 --- a/src/test/ui/existential_types/unused_generic_param.rs +++ b/src/test/ui/existential_types/unused_generic_param.rs @@ -1,15 +1,18 @@ +// compile-pass #![feature(existential_type)] fn main() { } -existential type PartiallyDefined: 'static; //~ `T` is unused +// test that unused generic parameters are ok +existential type PartiallyDefined: 'static; fn partially_defined(_: T) -> PartiallyDefined { 4u32 } -existential type PartiallyDefined2: 'static; //~ `T` is unused +// test that unused generic parameters are ok +existential type PartiallyDefined2: 'static; fn partially_defined2(_: T) -> PartiallyDefined2 { 4u32 From ed10a5ba01cb0e73e3872434da65bf4f3a976f28 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 25 Jan 2019 20:32:45 +0100 Subject: [PATCH 0506/1064] Test all the things --- .../generic_duplicate_param_use.stderr | 9 --------- .../generic_duplicate_param_use2.rs | 15 +++++++++++++++ .../generic_duplicate_param_use3.rs | 19 +++++++++++++++++++ .../generic_duplicate_param_use3.stderr | 19 +++++++++++++++++++ .../generic_duplicate_param_use4.rs | 15 +++++++++++++++ .../generic_duplicate_param_use4.stderr | 19 +++++++++++++++++++ .../unused_generic_param.stderr | 15 --------------- 7 files changed, 87 insertions(+), 24 deletions(-) delete mode 100644 src/test/ui/existential_types/generic_duplicate_param_use.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use2.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use3.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use3.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use4.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use4.stderr delete mode 100644 src/test/ui/existential_types/unused_generic_param.stderr diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.stderr b/src/test/ui/existential_types/generic_duplicate_param_use.stderr deleted file mode 100644 index 66706c210541c..0000000000000 --- a/src/test/ui/existential_types/generic_duplicate_param_use.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0091]: type parameter `U` is unused - --> $DIR/generic_duplicate_param_use.rs:5:25 - | -LL | existential type Two: 'static; //~ ERROR type parameter `U` is unused - | ^ unused type parameter - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0091`. diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.rs b/src/test/ui/existential_types/generic_duplicate_param_use2.rs new file mode 100644 index 0000000000000..b6cb22da41d7f --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use2.rs @@ -0,0 +1,15 @@ +// compile-pass +#![feature(existential_type)] + +fn main() {} + +// test that unused generic parameters are ok +existential type Two: 'static; + +fn one(t: T) -> Two { + t +} + +fn two(t: T, _: U) -> Two { + t +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.rs b/src/test/ui/existential_types/generic_duplicate_param_use3.rs new file mode 100644 index 0000000000000..43650a6a35296 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use3.rs @@ -0,0 +1,19 @@ +#![feature(existential_type)] + +fn main() {} + +// test that unused generic parameters are ok +existential type Two: 'static; + +fn one(t: T) -> Two { + t +} + +fn two(t: T, _: U) -> Two { + t +} + +fn three(_: T, u: U) -> Two { + //~^ ERROR defining existential type use differs from previous + u +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr new file mode 100644 index 0000000000000..67c30ad648b35 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr @@ -0,0 +1,19 @@ +error: defining existential type use differs from previous + --> $DIR/generic_duplicate_param_use3.rs:16:1 + | +LL | / fn three(_: T, u: U) -> Two { +LL | | //~^ ERROR defining existential type use differs from previous +LL | | u +LL | | } + | |_^ + | +note: previous use here + --> $DIR/generic_duplicate_param_use3.rs:8:1 + | +LL | / fn one(t: T) -> Two { +LL | | t +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.rs b/src/test/ui/existential_types/generic_duplicate_param_use4.rs new file mode 100644 index 0000000000000..79df528d209c6 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use4.rs @@ -0,0 +1,15 @@ +#![feature(existential_type)] + +fn main() {} + +// test that unused generic parameters are ok +existential type Two: 'static; + +fn one(t: T) -> Two { + t +} + +fn three(_: T, u: U) -> Two { +//~^ ERROR defining existential type use differs from previous + u +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr b/src/test/ui/existential_types/generic_duplicate_param_use4.stderr new file mode 100644 index 0000000000000..e7a372e0e0c9b --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use4.stderr @@ -0,0 +1,19 @@ +error: defining existential type use differs from previous + --> $DIR/generic_duplicate_param_use4.rs:12:1 + | +LL | / fn three(_: T, u: U) -> Two { +LL | | //~^ ERROR defining existential type use differs from previous +LL | | u +LL | | } + | |_^ + | +note: previous use here + --> $DIR/generic_duplicate_param_use4.rs:8:1 + | +LL | / fn one(t: T) -> Two { +LL | | t +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/unused_generic_param.stderr b/src/test/ui/existential_types/unused_generic_param.stderr deleted file mode 100644 index 348aed3c43914..0000000000000 --- a/src/test/ui/existential_types/unused_generic_param.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0091]: type parameter `T` is unused - --> $DIR/unused_generic_param.rs:6:35 - | -LL | existential type PartiallyDefined: 'static; //~ `T` is unused - | ^ unused type parameter - -error[E0091]: type parameter `T` is unused - --> $DIR/unused_generic_param.rs:12:36 - | -LL | existential type PartiallyDefined2: 'static; //~ `T` is unused - | ^ unused type parameter - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0091`. From 0d25ff8842ca35b7eabd2d8a22669c5b2216ad82 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 25 Jan 2019 20:37:10 +0100 Subject: [PATCH 0507/1064] Test aller things --- .../generic_duplicate_param_use5.rs | 15 +++++++++++++++ .../generic_duplicate_param_use5.stderr | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use5.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use5.stderr diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.rs b/src/test/ui/existential_types/generic_duplicate_param_use5.rs new file mode 100644 index 0000000000000..f9d336d759b62 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use5.rs @@ -0,0 +1,15 @@ +#![feature(existential_type)] + +fn main() {} + +// test that unused generic parameters are ok +existential type Two: 'static; + +fn one(t: T) -> Two { + t +} + +fn two(t: T, _: U) -> Two { +//~^ ERROR defining existential type use differs from previous + t +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr new file mode 100644 index 0000000000000..e2bf4a9e0dfef --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr @@ -0,0 +1,19 @@ +error: defining existential type use differs from previous + --> $DIR/generic_duplicate_param_use5.rs:12:1 + | +LL | / fn two(t: T, _: U) -> Two { +LL | | //~^ ERROR defining existential type use differs from previous +LL | | t +LL | | } + | |_^ + | +note: previous use here + --> $DIR/generic_duplicate_param_use5.rs:8:1 + | +LL | / fn one(t: T) -> Two { +LL | | t +LL | | } + | |_^ + +error: aborting due to previous error + From cf01b514c876656696e87672a1c118a3ce7817ed Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 25 Jan 2019 22:57:31 +0100 Subject: [PATCH 0508/1064] Generic type parameters are flexible even for existential types --- src/librustc_typeck/collect.rs | 11 ++++++++++- .../generic_duplicate_param_use.rs | 6 ++++-- .../generic_duplicate_param_use2.rs | 8 +++++--- .../generic_duplicate_param_use3.rs | 12 +++++++----- .../generic_duplicate_param_use3.stderr | 19 ------------------- .../generic_duplicate_param_use4.rs | 10 ++++++---- .../generic_duplicate_param_use4.stderr | 19 ------------------- .../generic_duplicate_param_use5.rs | 15 --------------- .../generic_duplicate_param_use5.stderr | 19 ------------------- 9 files changed, 32 insertions(+), 87 deletions(-) delete mode 100644 src/test/ui/existential_types/generic_duplicate_param_use3.stderr delete mode 100644 src/test/ui/existential_types/generic_duplicate_param_use4.stderr delete mode 100644 src/test/ui/existential_types/generic_duplicate_param_use5.rs delete mode 100644 src/test/ui/existential_types/generic_duplicate_param_use5.stderr diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b0b266a61a5b6..e4fc1925eb377 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1346,7 +1346,16 @@ fn find_existential_constraints<'a, 'tcx>( // FIXME(oli-obk): trace the actual span from inference to improve errors let span = self.tcx.def_span(def_id); if let Some((prev_span, prev_ty)) = self.found { - if ty != prev_ty { + let mut ty = ty.walk().fuse(); + let mut prev_ty = prev_ty.walk().fuse(); + let iter_eq = (&mut ty).zip(&mut prev_ty).all(|(t, p)| match (&t.sty, &p.sty) { + // type parameters are equal to any other type parameter for the purpose of + // concrete type equality, as it is possible to obtain the same type just + // by passing matching parameters to a function. + (ty::Param(_), ty::Param(_)) => true, + _ => t == p, + }); + if !iter_eq || ty.next().is_some() || prev_ty.next().is_some() { // found different concrete types for the existential type let mut err = self.tcx.sess.struct_span_err( span, diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.rs b/src/test/ui/existential_types/generic_duplicate_param_use.rs index 14d63ecc6bb5d..d08cd88c600d0 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use.rs @@ -1,11 +1,13 @@ // compile-pass #![feature(existential_type)] +use std::fmt::Debug; + fn main() {} // test that unused generic parameters are ok -existential type Two: 'static; +existential type Two: Debug; -fn one(t: T) -> Two { +fn one(t: T) -> Two { t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.rs b/src/test/ui/existential_types/generic_duplicate_param_use2.rs index b6cb22da41d7f..c27fbb74cf19d 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use2.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use2.rs @@ -1,15 +1,17 @@ // compile-pass #![feature(existential_type)] +use std::fmt::Debug; + fn main() {} // test that unused generic parameters are ok -existential type Two: 'static; +existential type Two: Debug; -fn one(t: T) -> Two { +fn one(t: T) -> Two { t } -fn two(t: T, _: U) -> Two { +fn two(t: T, _: U) -> Two { t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.rs b/src/test/ui/existential_types/generic_duplicate_param_use3.rs index 43650a6a35296..b4d1b26dbabda 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use3.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use3.rs @@ -1,19 +1,21 @@ +// compile-pass #![feature(existential_type)] +use std::fmt::Debug; + fn main() {} // test that unused generic parameters are ok -existential type Two: 'static; +existential type Two: Debug; -fn one(t: T) -> Two { +fn one(t: T) -> Two { t } -fn two(t: T, _: U) -> Two { +fn two(t: T, _: U) -> Two { t } -fn three(_: T, u: U) -> Two { - //~^ ERROR defining existential type use differs from previous +fn three(_: T, u: U) -> Two { u } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr deleted file mode 100644 index 67c30ad648b35..0000000000000 --- a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: defining existential type use differs from previous - --> $DIR/generic_duplicate_param_use3.rs:16:1 - | -LL | / fn three(_: T, u: U) -> Two { -LL | | //~^ ERROR defining existential type use differs from previous -LL | | u -LL | | } - | |_^ - | -note: previous use here - --> $DIR/generic_duplicate_param_use3.rs:8:1 - | -LL | / fn one(t: T) -> Two { -LL | | t -LL | | } - | |_^ - -error: aborting due to previous error - diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.rs b/src/test/ui/existential_types/generic_duplicate_param_use4.rs index 79df528d209c6..afab86c3ff075 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use4.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use4.rs @@ -1,15 +1,17 @@ +// compile-pass #![feature(existential_type)] +use std::fmt::Debug; + fn main() {} // test that unused generic parameters are ok -existential type Two: 'static; +existential type Two: Debug; -fn one(t: T) -> Two { +fn one(t: T) -> Two { t } -fn three(_: T, u: U) -> Two { -//~^ ERROR defining existential type use differs from previous +fn three(_: T, u: U) -> Two { u } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr b/src/test/ui/existential_types/generic_duplicate_param_use4.stderr deleted file mode 100644 index e7a372e0e0c9b..0000000000000 --- a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: defining existential type use differs from previous - --> $DIR/generic_duplicate_param_use4.rs:12:1 - | -LL | / fn three(_: T, u: U) -> Two { -LL | | //~^ ERROR defining existential type use differs from previous -LL | | u -LL | | } - | |_^ - | -note: previous use here - --> $DIR/generic_duplicate_param_use4.rs:8:1 - | -LL | / fn one(t: T) -> Two { -LL | | t -LL | | } - | |_^ - -error: aborting due to previous error - diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.rs b/src/test/ui/existential_types/generic_duplicate_param_use5.rs deleted file mode 100644 index f9d336d759b62..0000000000000 --- a/src/test/ui/existential_types/generic_duplicate_param_use5.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(existential_type)] - -fn main() {} - -// test that unused generic parameters are ok -existential type Two: 'static; - -fn one(t: T) -> Two { - t -} - -fn two(t: T, _: U) -> Two { -//~^ ERROR defining existential type use differs from previous - t -} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr deleted file mode 100644 index e2bf4a9e0dfef..0000000000000 --- a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: defining existential type use differs from previous - --> $DIR/generic_duplicate_param_use5.rs:12:1 - | -LL | / fn two(t: T, _: U) -> Two { -LL | | //~^ ERROR defining existential type use differs from previous -LL | | t -LL | | } - | |_^ - | -note: previous use here - --> $DIR/generic_duplicate_param_use5.rs:8:1 - | -LL | / fn one(t: T) -> Two { -LL | | t -LL | | } - | |_^ - -error: aborting due to previous error - From 6f83dcc192e989eba6f4e531f4931ae057e62f9e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 29 Jan 2019 16:33:53 +0100 Subject: [PATCH 0509/1064] Restrict concrete types to equivalent types --- src/librustc/ich/impls_ty.rs | 5 ++ src/librustc/infer/opaque_types/mod.rs | 2 +- src/librustc/ty/context.rs | 13 +++- src/librustc/ty/mod.rs | 2 +- src/librustc_typeck/check/writeback.rs | 12 ++- src/librustc_typeck/collect.rs | 74 ++++++++++++++++--- .../different_defining_uses.rs | 2 +- .../different_defining_uses.stderr | 4 +- .../different_defining_uses_never_type.rs | 4 +- .../different_defining_uses_never_type.stderr | 8 +- .../generic_different_defining_uses.rs | 2 +- .../generic_different_defining_uses.stderr | 4 +- .../generic_duplicate_param_use.rs | 3 +- .../generic_duplicate_param_use.stderr | 17 +++++ .../generic_duplicate_param_use2.rs | 2 +- .../generic_duplicate_param_use2.stderr | 11 +++ .../generic_duplicate_param_use3.rs | 3 +- .../generic_duplicate_param_use3.stderr | 28 +++++++ .../generic_duplicate_param_use4.rs | 2 +- .../generic_duplicate_param_use4.stderr | 11 +++ .../generic_duplicate_param_use5.rs | 17 +++++ .../generic_duplicate_param_use5.stderr | 19 +++++ .../generic_duplicate_param_use6.rs | 17 +++++ .../generic_duplicate_param_use6.stderr | 19 +++++ .../generic_duplicate_param_use7.rs | 16 ++++ 25 files changed, 264 insertions(+), 33 deletions(-) create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use2.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use3.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use4.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use5.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use5.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use6.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use6.stderr create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use7.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index bd2349161f74a..040494a279941 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -233,6 +233,11 @@ impl_stable_hash_for!(struct ty::FnSig<'tcx> { abi }); +impl_stable_hash_for!(struct ty::ResolvedOpaqueTy<'tcx> { + concrete_type, + substs +}); + impl<'a, 'gcx, T> HashStable> for ty::Binder where T: HashStable> { diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 5e94bb1f877fb..eabbb943c6ef2 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -26,7 +26,7 @@ pub struct OpaqueTypeDecl<'tcx> { /// /// winds up desugared to: /// - /// abstract type Foo<'x, T>: Trait<'x> + /// abstract type Foo<'x, X>: Trait<'x> /// fn foo<'a, 'b, T>() -> Foo<'a, T> /// /// then `substs` would be `['a, T]`. diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 881c0d4e6d239..350dcdf571be3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -315,6 +315,17 @@ impl<'a, V> LocalTableInContextMut<'a, V> { } } +/// All information necessary to validate and reveal an `impl Trait` or `existential Type` +#[derive(RustcEncodable, RustcDecodable, Debug)] +pub struct ResolvedOpaqueTy<'tcx> { + /// The revealed type as seen by this function. + pub concrete_type: Ty<'tcx>, + /// Generic parameters on the opaque type as passed by this function. + /// For `existential type Foo; fn foo() -> Foo { .. }` this is `[T, U]`, not + /// `[A, B]` + pub substs: &'tcx Substs<'tcx>, +} + #[derive(RustcEncodable, RustcDecodable, Debug)] pub struct TypeckTables<'tcx> { /// The HirId::owner all ItemLocalIds in this table are relative to. @@ -417,7 +428,7 @@ pub struct TypeckTables<'tcx> { /// All the existential types that are restricted to concrete types /// by this function - pub concrete_existential_types: FxHashMap>, + pub concrete_existential_types: FxHashMap>, /// Given the closure ID this map provides the list of UpvarIDs used by it. /// The upvarID contains the HIR node ID and it also contains the full path diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c9089428b2324..3a7441e9215df 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -74,7 +74,7 @@ pub use self::context::{TyCtxt, FreeRegionInfo, GlobalArenas, AllArenas, tls, ke pub use self::context::{Lift, TypeckTables, CtxtInterners}; pub use self::context::{ UserTypeAnnotationIndex, UserType, CanonicalUserType, - CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, + CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy, }; pub use self::instance::{Instance, InstanceDef}; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 00917be538fb3..c9dd83dcd5e22 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -567,17 +567,23 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } + let new = ty::ResolvedOpaqueTy { + concrete_type: definition_ty, + substs: self.tcx().lift_to_global(&opaque_defn.substs).unwrap(), + }; + let old = self.tables .concrete_existential_types - .insert(def_id, definition_ty); + .insert(def_id, new); if let Some(old) = old { - if old != definition_ty { + if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { span_bug!( span, "visit_opaque_types tried to write \ - different types for the same existential type: {:?}, {:?}, {:?}", + different types for the same existential type: {:?}, {:?}, {:?}, {:?}", def_id, definition_ty, + opaque_defn, old, ); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e4fc1925eb377..7cdcfec339eee 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -23,9 +23,10 @@ use middle::resolve_lifetime as rl; use middle::weak_lang_items; use rustc::mir::mono::Linkage; use rustc::ty::query::Providers; -use rustc::ty::subst::Substs; +use rustc::ty::subst::{Subst, Substs}; use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; +use rustc::ty::subst::UnpackedKind; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc::util::captures::Captures; @@ -1193,7 +1194,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> { tcx.typeck_tables_of(owner) .concrete_existential_types .get(&def_id) - .cloned() + .map(|opaque| opaque.concrete_type) .unwrap_or_else(|| { // This can occur if some error in the // owner fn prevented us from populating @@ -1325,7 +1326,13 @@ fn find_existential_constraints<'a, 'tcx>( struct ConstraintLocator<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, - found: Option<(Span, ty::Ty<'tcx>)>, + // First found type span, actual type, mapping from the existential type's generic + // parameters to the concrete type's generic parameters + // + // The mapping is an index for each use site of a generic parameter in the concrete type + // + // The indices index into the generic parameters on the existential type. + found: Option<(Span, ty::Ty<'tcx>, Vec)>, } impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> { @@ -1340,13 +1347,50 @@ fn find_existential_constraints<'a, 'tcx>( .tcx .typeck_tables_of(def_id) .concrete_existential_types - .get(&self.def_id) - .cloned(); - if let Some(ty) = ty { + .get(&self.def_id); + if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty { // FIXME(oli-obk): trace the actual span from inference to improve errors let span = self.tcx.def_span(def_id); - if let Some((prev_span, prev_ty)) = self.found { - let mut ty = ty.walk().fuse(); + // used to quickly look up the position of a generic parameter + let mut index_map: FxHashMap = FxHashMap::default(); + // skip binder is ok, since we only use this to find generic parameters and their + // positions. + for subst in substs.iter() { + if let UnpackedKind::Type(ty) = subst.unpack() { + if let ty::Param(p) = ty.sty { + let idx = index_map.len(); + if index_map.insert(p, idx).is_some() { + // there was already an entry for `p`, meaning a generic parameter + // was used twice + self.tcx.sess.span_err( + span, + &format!("defining existential type use restricts existential \ + type by using the generic parameter `{}` twice", p.name), + ); + return; + } + } else { + self.tcx.sess.delay_span_bug( + span, + &format!( + "non-defining exist ty use in defining scope: {:?}, {:?}", + concrete_type, substs, + ), + ); + } + } + } + // compute the index within the existential type for each generic parameter used in + // the concrete type + let indices = concrete_type + .subst(self.tcx, substs) + .walk() + .filter_map(|t| match &t.sty { + ty::Param(p) => Some(*index_map.get(p).unwrap()), + _ => None, + }).collect(); + if let Some((prev_span, prev_ty, ref prev_indices)) = self.found { + let mut ty = concrete_type.walk().fuse(); let mut prev_ty = prev_ty.walk().fuse(); let iter_eq = (&mut ty).zip(&mut prev_ty).all(|(t, p)| match (&t.sty, &p.sty) { // type parameters are equal to any other type parameter for the purpose of @@ -1359,13 +1403,21 @@ fn find_existential_constraints<'a, 'tcx>( // found different concrete types for the existential type let mut err = self.tcx.sess.struct_span_err( span, - "defining existential type use differs from previous", + "concrete type differs from previous defining existential type use", + ); + err.span_note(prev_span, "previous use here"); + err.emit(); + } else if indices != *prev_indices { + // found "same" concrete types, but the generic parameter order differs + let mut err = self.tcx.sess.struct_span_err( + span, + "concrete type's generic parameters differ from previous defining use", ); err.span_note(prev_span, "previous use here"); err.emit(); } } else { - self.found = Some((span, ty)); + self.found = Some((span, concrete_type, indices)); } } } @@ -1424,7 +1476,7 @@ fn find_existential_constraints<'a, 'tcx>( } match locator.found { - Some((_, ty)) => ty, + Some((_, ty, _)) => ty, None => { let span = tcx.def_span(def_id); tcx.sess.span_err(span, "could not find defining uses"); diff --git a/src/test/ui/existential_types/different_defining_uses.rs b/src/test/ui/existential_types/different_defining_uses.rs index c51fca75a24e9..a8670cc07f2e1 100644 --- a/src/test/ui/existential_types/different_defining_uses.rs +++ b/src/test/ui/existential_types/different_defining_uses.rs @@ -9,6 +9,6 @@ fn foo() -> Foo { "" } -fn bar() -> Foo { //~ ERROR defining existential type use differs from previous +fn bar() -> Foo { //~ ERROR concrete type differs from previous 42i32 } diff --git a/src/test/ui/existential_types/different_defining_uses.stderr b/src/test/ui/existential_types/different_defining_uses.stderr index f782a00229732..3b3449bbf11f4 100644 --- a/src/test/ui/existential_types/different_defining_uses.stderr +++ b/src/test/ui/existential_types/different_defining_uses.stderr @@ -1,7 +1,7 @@ -error: defining existential type use differs from previous +error: concrete type differs from previous defining existential type use --> $DIR/different_defining_uses.rs:12:1 | -LL | / fn bar() -> Foo { //~ ERROR defining existential type use differs from previous +LL | / fn bar() -> Foo { //~ ERROR concrete type differs from previous LL | | 42i32 LL | | } | |_^ diff --git a/src/test/ui/existential_types/different_defining_uses_never_type.rs b/src/test/ui/existential_types/different_defining_uses_never_type.rs index c6c6ae8d2dccf..13ada63e4bc45 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type.rs +++ b/src/test/ui/existential_types/different_defining_uses_never_type.rs @@ -9,10 +9,10 @@ fn foo() -> Foo { "" } -fn bar() -> Foo { //~ ERROR defining existential type use differs from previous +fn bar() -> Foo { //~ ERROR concrete type differs from previous panic!() } -fn boo() -> Foo { //~ ERROR defining existential type use differs from previous +fn boo() -> Foo { //~ ERROR concrete type differs from previous loop {} } diff --git a/src/test/ui/existential_types/different_defining_uses_never_type.stderr b/src/test/ui/existential_types/different_defining_uses_never_type.stderr index 04b0cf2778455..161111e3379f5 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type.stderr +++ b/src/test/ui/existential_types/different_defining_uses_never_type.stderr @@ -1,7 +1,7 @@ -error: defining existential type use differs from previous +error: concrete type differs from previous defining existential type use --> $DIR/different_defining_uses_never_type.rs:12:1 | -LL | / fn bar() -> Foo { //~ ERROR defining existential type use differs from previous +LL | / fn bar() -> Foo { //~ ERROR concrete type differs from previous LL | | panic!() LL | | } | |_^ @@ -14,10 +14,10 @@ LL | | "" LL | | } | |_^ -error: defining existential type use differs from previous +error: concrete type differs from previous defining existential type use --> $DIR/different_defining_uses_never_type.rs:16:1 | -LL | / fn boo() -> Foo { //~ ERROR defining existential type use differs from previous +LL | / fn boo() -> Foo { //~ ERROR concrete type differs from previous LL | | loop {} LL | | } | |_^ diff --git a/src/test/ui/existential_types/generic_different_defining_uses.rs b/src/test/ui/existential_types/generic_different_defining_uses.rs index 3bd104251fb70..ce3ab88a1c0bb 100644 --- a/src/test/ui/existential_types/generic_different_defining_uses.rs +++ b/src/test/ui/existential_types/generic_different_defining_uses.rs @@ -8,6 +8,6 @@ fn my_iter(t: T) -> MyIter { std::iter::once(t) } -fn my_iter2(t: T) -> MyIter { //~ ERROR defining existential type use differs from previous +fn my_iter2(t: T) -> MyIter { //~ ERROR concrete type differs from previous Some(t).into_iter() } diff --git a/src/test/ui/existential_types/generic_different_defining_uses.stderr b/src/test/ui/existential_types/generic_different_defining_uses.stderr index 234bcf232ae79..89f70a873d9dc 100644 --- a/src/test/ui/existential_types/generic_different_defining_uses.stderr +++ b/src/test/ui/existential_types/generic_different_defining_uses.stderr @@ -1,7 +1,7 @@ -error: defining existential type use differs from previous +error: concrete type differs from previous defining existential type use --> $DIR/generic_different_defining_uses.rs:11:1 | -LL | / fn my_iter2(t: T) -> MyIter { //~ ERROR defining existential type use differs from previous +LL | / fn my_iter2(t: T) -> MyIter { //~ ERROR concrete type differs from previous LL | | Some(t).into_iter() LL | | } | |_^ diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.rs b/src/test/ui/existential_types/generic_duplicate_param_use.rs index d08cd88c600d0..3f8753333aa7a 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use.rs @@ -1,4 +1,3 @@ -// compile-pass #![feature(existential_type)] use std::fmt::Debug; @@ -7,7 +6,9 @@ fn main() {} // test that unused generic parameters are ok existential type Two: Debug; +//~^ could not find defining uses fn one(t: T) -> Two { +//~^ ERROR defining existential type use restricts existential type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.stderr b/src/test/ui/existential_types/generic_duplicate_param_use.stderr new file mode 100644 index 0000000000000..d4deda999da16 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use.stderr @@ -0,0 +1,17 @@ +error: defining existential type use restricts existential type by using the generic parameter `T` twice + --> $DIR/generic_duplicate_param_use.rs:11:1 + | +LL | / fn one(t: T) -> Two { +LL | | //~^ ERROR defining existential type use restricts existential type +LL | | t +LL | | } + | |_^ + +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:8:1 + | +LL | existential type Two: Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.rs b/src/test/ui/existential_types/generic_duplicate_param_use2.rs index c27fbb74cf19d..3842292decd57 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use2.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use2.rs @@ -1,4 +1,3 @@ -// compile-pass #![feature(existential_type)] use std::fmt::Debug; @@ -9,6 +8,7 @@ fn main() {} existential type Two: Debug; fn one(t: T) -> Two { +//~^ defining existential type use restricts existential type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.stderr b/src/test/ui/existential_types/generic_duplicate_param_use2.stderr new file mode 100644 index 0000000000000..0a8be3218c759 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use2.stderr @@ -0,0 +1,11 @@ +error: defining existential type use restricts existential type by using the generic parameter `T` twice + --> $DIR/generic_duplicate_param_use2.rs:10:1 + | +LL | / fn one(t: T) -> Two { +LL | | //~^ defining existential type use restricts existential type +LL | | t +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.rs b/src/test/ui/existential_types/generic_duplicate_param_use3.rs index b4d1b26dbabda..05c77c8947333 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use3.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use3.rs @@ -1,4 +1,3 @@ -// compile-pass #![feature(existential_type)] use std::fmt::Debug; @@ -9,6 +8,7 @@ fn main() {} existential type Two: Debug; fn one(t: T) -> Two { +//~^ defining existential type use restricts existential type t } @@ -17,5 +17,6 @@ fn two(t: T, _: U) -> Two { } fn three(_: T, u: U) -> Two { +//~^ concrete type's generic parameters differ from previous defining use u } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr new file mode 100644 index 0000000000000..8f860e7ee0a40 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr @@ -0,0 +1,28 @@ +error: defining existential type use restricts existential type by using the generic parameter `T` twice + --> $DIR/generic_duplicate_param_use3.rs:10:1 + | +LL | / fn one(t: T) -> Two { +LL | | //~^ defining existential type use restricts existential type +LL | | t +LL | | } + | |_^ + +error: concrete type's generic parameters differ from previous defining use + --> $DIR/generic_duplicate_param_use3.rs:19:1 + | +LL | / fn three(_: T, u: U) -> Two { +LL | | //~^ concrete type's generic parameters differ from previous defining use +LL | | u +LL | | } + | |_^ + | +note: previous use here + --> $DIR/generic_duplicate_param_use3.rs:15:1 + | +LL | / fn two(t: T, _: U) -> Two { +LL | | t +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.rs b/src/test/ui/existential_types/generic_duplicate_param_use4.rs index afab86c3ff075..609dbe06cd733 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use4.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use4.rs @@ -1,4 +1,3 @@ -// compile-pass #![feature(existential_type)] use std::fmt::Debug; @@ -9,6 +8,7 @@ fn main() {} existential type Two: Debug; fn one(t: T) -> Two { +//~^ ERROR defining existential type use restricts existential type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr b/src/test/ui/existential_types/generic_duplicate_param_use4.stderr new file mode 100644 index 0000000000000..24b1caf7c1bfe --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use4.stderr @@ -0,0 +1,11 @@ +error: defining existential type use restricts existential type by using the generic parameter `T` twice + --> $DIR/generic_duplicate_param_use4.rs:10:1 + | +LL | / fn one(t: T) -> Two { +LL | | //~^ ERROR defining existential type use restricts existential type +LL | | t +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.rs b/src/test/ui/existential_types/generic_duplicate_param_use5.rs new file mode 100644 index 0000000000000..3f4a23b8b41fa --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use5.rs @@ -0,0 +1,17 @@ +#![feature(existential_type)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +existential type Two: Debug; + +fn two(t: T, u: U) -> Two { + (t, u) +} + +fn three(t: T, u: U) -> Two { +//~^ concrete type differs from previous + (u, t) +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr new file mode 100644 index 0000000000000..52befb9c2e12c --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr @@ -0,0 +1,19 @@ +error: concrete type differs from previous defining existential type use + --> $DIR/generic_duplicate_param_use5.rs:14:1 + | +LL | / fn three(t: T, u: U) -> Two { +LL | | //~^ concrete type differs from previous +LL | | (u, t) +LL | | } + | |_^ + | +note: previous use here + --> $DIR/generic_duplicate_param_use5.rs:10:1 + | +LL | / fn two(t: T, u: U) -> Two { +LL | | (t, u) +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use6.rs b/src/test/ui/existential_types/generic_duplicate_param_use6.rs new file mode 100644 index 0000000000000..3b8c56352bda4 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use6.rs @@ -0,0 +1,17 @@ +#![feature(existential_type)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +existential type Two: Debug; + +fn two(t: T, u: U) -> Two { + (t, t) +} + +fn three(t: T, u: U) -> Two { +//~^ concrete type differs from previous + (u, t) +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use6.stderr b/src/test/ui/existential_types/generic_duplicate_param_use6.stderr new file mode 100644 index 0000000000000..2bf1d0c05e625 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use6.stderr @@ -0,0 +1,19 @@ +error: concrete type differs from previous defining existential type use + --> $DIR/generic_duplicate_param_use6.rs:14:1 + | +LL | / fn three(t: T, u: U) -> Two { +LL | | //~^ concrete type differs from previous +LL | | (u, t) +LL | | } + | |_^ + | +note: previous use here + --> $DIR/generic_duplicate_param_use6.rs:10:1 + | +LL | / fn two(t: T, u: U) -> Two { +LL | | (t, t) +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/generic_duplicate_param_use7.rs b/src/test/ui/existential_types/generic_duplicate_param_use7.rs new file mode 100644 index 0000000000000..3906b85aadbde --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use7.rs @@ -0,0 +1,16 @@ +// compile-pass +#![feature(existential_type)] + +use std::fmt::Debug; + +fn main() {} + +existential type Two: Debug; + +fn two(t: T, u: U) -> Two { + (t, t) +} + +fn three(t: T, t2: T, u: U) -> Two { + (t, t2) +} From 984688ace34ec0add8f365ead6587237537fc230 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 29 Jan 2019 16:36:46 +0100 Subject: [PATCH 0510/1064] Test more related cases --- .../ui/existential_types/generic_duplicate_param_use7.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/ui/existential_types/generic_duplicate_param_use7.rs b/src/test/ui/existential_types/generic_duplicate_param_use7.rs index 3906b85aadbde..2bcac315f5a96 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use7.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use7.rs @@ -14,3 +14,12 @@ fn two(t: T, u: U) -> Two { fn three(t: T, t2: T, u: U) -> Two { (t, t2) } + +fn four(t: T, t2: T, u: U, v: V) -> Two { + (t, t2) +} + +fn five(x: X, y: Y, y2: Y) -> Two { + (y, y2) +} + From f2241f640bb9f04cce88b2d28092cbfcee04c43e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 29 Jan 2019 17:10:08 +0100 Subject: [PATCH 0511/1064] Make the existential type errors a little bit more helpful --- src/librustc_typeck/collect.rs | 30 +++++++++++++++---- .../different_defining_uses.stderr | 2 +- .../different_defining_uses_never_type.stderr | 4 +-- .../generic_different_defining_uses.stderr | 2 +- .../generic_duplicate_param_use3.stderr | 2 +- .../generic_duplicate_param_use5.stderr | 2 +- .../generic_duplicate_param_use6.stderr | 2 +- 7 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7cdcfec339eee..b26a6a2292a04 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1355,10 +1355,9 @@ fn find_existential_constraints<'a, 'tcx>( let mut index_map: FxHashMap = FxHashMap::default(); // skip binder is ok, since we only use this to find generic parameters and their // positions. - for subst in substs.iter() { + for (idx, subst) in substs.iter().enumerate() { if let UnpackedKind::Type(ty) = subst.unpack() { if let ty::Param(p) = ty.sty { - let idx = index_map.len(); if index_map.insert(p, idx).is_some() { // there was already an entry for `p`, meaning a generic parameter // was used twice @@ -1391,20 +1390,24 @@ fn find_existential_constraints<'a, 'tcx>( }).collect(); if let Some((prev_span, prev_ty, ref prev_indices)) = self.found { let mut ty = concrete_type.walk().fuse(); - let mut prev_ty = prev_ty.walk().fuse(); - let iter_eq = (&mut ty).zip(&mut prev_ty).all(|(t, p)| match (&t.sty, &p.sty) { + let mut p_ty = prev_ty.walk().fuse(); + let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.sty, &p.sty) { // type parameters are equal to any other type parameter for the purpose of // concrete type equality, as it is possible to obtain the same type just // by passing matching parameters to a function. (ty::Param(_), ty::Param(_)) => true, _ => t == p, }); - if !iter_eq || ty.next().is_some() || prev_ty.next().is_some() { + if !iter_eq || ty.next().is_some() || p_ty.next().is_some() { // found different concrete types for the existential type let mut err = self.tcx.sess.struct_span_err( span, "concrete type differs from previous defining existential type use", ); + err.span_label( + span, + format!("expected `{}`, got `{}`", prev_ty, concrete_type), + ); err.span_note(prev_span, "previous use here"); err.emit(); } else if indices != *prev_indices { @@ -1413,6 +1416,23 @@ fn find_existential_constraints<'a, 'tcx>( span, "concrete type's generic parameters differ from previous defining use", ); + use std::fmt::Write; + let mut s = String::new(); + write!(s, "expected [").unwrap(); + let list = |s: &mut String, indices: &Vec| { + let mut indices = indices.iter().cloned(); + if let Some(first) = indices.next() { + write!(s, "`{}`", substs[first]).unwrap(); + for i in indices { + write!(s, ", `{}`", substs[i]).unwrap(); + } + } + }; + list(&mut s, prev_indices); + write!(s, "], got [").unwrap(); + list(&mut s, &indices); + write!(s, "]").unwrap(); + err.span_label(span, s); err.span_note(prev_span, "previous use here"); err.emit(); } diff --git a/src/test/ui/existential_types/different_defining_uses.stderr b/src/test/ui/existential_types/different_defining_uses.stderr index 3b3449bbf11f4..3f9ed96400b54 100644 --- a/src/test/ui/existential_types/different_defining_uses.stderr +++ b/src/test/ui/existential_types/different_defining_uses.stderr @@ -4,7 +4,7 @@ error: concrete type differs from previous defining existential type use LL | / fn bar() -> Foo { //~ ERROR concrete type differs from previous LL | | 42i32 LL | | } - | |_^ + | |_^ expected `&'static str`, got `i32` | note: previous use here --> $DIR/different_defining_uses.rs:8:1 diff --git a/src/test/ui/existential_types/different_defining_uses_never_type.stderr b/src/test/ui/existential_types/different_defining_uses_never_type.stderr index 161111e3379f5..e29256a5014f9 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type.stderr +++ b/src/test/ui/existential_types/different_defining_uses_never_type.stderr @@ -4,7 +4,7 @@ error: concrete type differs from previous defining existential type use LL | / fn bar() -> Foo { //~ ERROR concrete type differs from previous LL | | panic!() LL | | } - | |_^ + | |_^ expected `&'static str`, got `()` | note: previous use here --> $DIR/different_defining_uses_never_type.rs:8:1 @@ -20,7 +20,7 @@ error: concrete type differs from previous defining existential type use LL | / fn boo() -> Foo { //~ ERROR concrete type differs from previous LL | | loop {} LL | | } - | |_^ + | |_^ expected `&'static str`, got `()` | note: previous use here --> $DIR/different_defining_uses_never_type.rs:8:1 diff --git a/src/test/ui/existential_types/generic_different_defining_uses.stderr b/src/test/ui/existential_types/generic_different_defining_uses.stderr index 89f70a873d9dc..3f129658b8fd0 100644 --- a/src/test/ui/existential_types/generic_different_defining_uses.stderr +++ b/src/test/ui/existential_types/generic_different_defining_uses.stderr @@ -4,7 +4,7 @@ error: concrete type differs from previous defining existential type use LL | / fn my_iter2(t: T) -> MyIter { //~ ERROR concrete type differs from previous LL | | Some(t).into_iter() LL | | } - | |_^ + | |_^ expected `std::iter::Once`, got `std::option::IntoIter` | note: previous use here --> $DIR/generic_different_defining_uses.rs:7:1 diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr index 8f860e7ee0a40..1c96c15a76919 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr +++ b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr @@ -14,7 +14,7 @@ LL | / fn three(_: T, u: U) -> Two { LL | | //~^ concrete type's generic parameters differ from previous defining use LL | | u LL | | } - | |_^ + | |_^ expected [`T`], got [`U`] | note: previous use here --> $DIR/generic_duplicate_param_use3.rs:15:1 diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr index 52befb9c2e12c..166623801c246 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr +++ b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr @@ -5,7 +5,7 @@ LL | / fn three(t: T, u: U) -> Two { LL | | //~^ concrete type differs from previous LL | | (u, t) LL | | } - | |_^ + | |_^ expected `(T, U)`, got `(U, T)` | note: previous use here --> $DIR/generic_duplicate_param_use5.rs:10:1 diff --git a/src/test/ui/existential_types/generic_duplicate_param_use6.stderr b/src/test/ui/existential_types/generic_duplicate_param_use6.stderr index 2bf1d0c05e625..da49a83be1f70 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use6.stderr +++ b/src/test/ui/existential_types/generic_duplicate_param_use6.stderr @@ -5,7 +5,7 @@ LL | / fn three(t: T, u: U) -> Two { LL | | //~^ concrete type differs from previous LL | | (u, t) LL | | } - | |_^ + | |_^ expected `(T, T)`, got `(U, T)` | note: previous use here --> $DIR/generic_duplicate_param_use6.rs:10:1 From c955f172b2f09f28d187ed7634e18861258833e5 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 1 Feb 2019 11:17:33 -0600 Subject: [PATCH 0512/1064] don't try to get a DefId for a Def that doesn't have one --- src/librustdoc/clean/inline.rs | 7 +++++-- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/visit_ast.rs | 7 ++++--- src/test/rustdoc/use-attr.rs | 8 ++++++++ 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 src/test/rustdoc/use-attr.rs diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9cb21df713e5b..8c8151e1e9509 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -37,8 +37,11 @@ use super::Clean; /// and `Some` of a vector of items if it was successfully expanded. pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHashSet) -> Option> { - if def == Def::Err { return None } - let did = def.def_id(); + let did = if let Some(did) = def.opt_def_id() { + did + } else { + return None; + }; if did.is_local() { return None } let mut ret = Vec::new(); let inner = match def { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6eea95b61c990..7d736d40b2547 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3818,7 +3818,7 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId { fn resolve_use_source(cx: &DocContext, path: Path) -> ImportSource { ImportSource { - did: if path.def == Def::Err { + did: if path.def.opt_def_id().is_none() { None } else { Some(register_def(cx, path.def)) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 953ab7c2565bf..b8eb777a54ba4 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -284,10 +284,11 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { debug!("maybe_inline_local def: {:?}", def); let tcx = self.cx.tcx; - if def == Def::Err { + let def_did = if let Some(did) = def.opt_def_id() { + did + } else { return false; - } - let def_did = def.def_id(); + }; let use_attrs = tcx.hir().attrs(id); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. diff --git a/src/test/rustdoc/use-attr.rs b/src/test/rustdoc/use-attr.rs new file mode 100644 index 0000000000000..996b7bba62181 --- /dev/null +++ b/src/test/rustdoc/use-attr.rs @@ -0,0 +1,8 @@ +// edition:2018 + +// ICE when rustdoc encountered a use statement of a non-macro attribute (see #58054) + +// @has use_attr/index.html +// @has - '//code' 'pub use proc_macro_attribute' +pub use proc_macro_attribute; +use proc_macro_derive; From 9d2a0b9e82d2e0581ba73e193d73a4b8103f0792 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 1 Feb 2019 12:08:50 -0500 Subject: [PATCH 0513/1064] add regression test for #57979 --- src/test/ui/issues/issue-57979.rs | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/test/ui/issues/issue-57979.rs diff --git a/src/test/ui/issues/issue-57979.rs b/src/test/ui/issues/issue-57979.rs new file mode 100644 index 0000000000000..abd46b60ab194 --- /dev/null +++ b/src/test/ui/issues/issue-57979.rs @@ -0,0 +1,42 @@ +// Regression test for #57979. This situation is meant to be an error. +// As noted in the issue thread, we decided to forbid nested impl +// trait of this kind: +// +// ```rust +// fn foo() -> impl Foo { .. } +// ``` +// +// Basically there are two hidden variables here, let's call them `X` +// and `Y`, and we must prove that: +// +// ``` +// X: Foo +// Y: Bar +// ``` +// +// However, the user is only giving us the return type `X`. It's true +// that in some cases, we can infer `Y` from `X`, because `X` only +// implements `Foo` for one type (and indeed the compiler does +// inference of this kind), but I do recall that we intended to forbid +// this -- in part because such inference is fragile, and there is not +// necessarily a way for the user to be more explicit should the +// inference fail (so you could get stuck with no way to port your +// code forward if, for example, more impls are added to an existing +// type). +// +// The same seems to apply in this situation. Here there are three impl traits, so we have +// +// ``` +// X: IntoIterator +// Y: Borrow> +// Z: AsRef<[u8]> +// ``` + +use std::borrow::Borrow; + +pub struct Data(TBody); + +pub fn collect(_: impl IntoIterator>>>) { + //~^ ERROR + unimplemented!() +} From 6bfb280189ef6960525f18364c1b4644a913f4ce Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Feb 2019 19:53:32 +0100 Subject: [PATCH 0514/1064] deprecate before_exec in favor of unsafe pre_exec --- src/libstd/sys/unix/ext/process.rs | 26 ++++++++++++++++--- src/libstd/sys/unix/process/process_common.rs | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 0282aaae90923..f5fc26dc9cca6 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -45,12 +45,32 @@ pub trait CommandExt { /// like `malloc` or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// This also means that all resources such as file descriptors and + /// memory-mapped regions got duplicated. It is your responsibility to make + /// sure that the closure does not violate library invariants by making + /// invalid use of these duplicates. + /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these /// locations may not appear where intended. + #[stable(feature = "process_pre_exec", since = "1.34.0")] + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command + where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + + /// Schedules a closure to be run just before the `exec` function is + /// invoked. + /// + /// This method should be unsafe, so it got deprecated in favor of the + /// unsafe [`pre_exec`]. + /// + /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] + #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + where F: FnMut() -> io::Result<()> + Send + Sync + 'static + { + unsafe { self.pre_exec(f) } + } /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -97,10 +117,10 @@ impl CommandExt for process::Command { self } - fn before_exec(&mut self, f: F) -> &mut process::Command + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { - self.as_inner_mut().before_exec(Box::new(f)); + self.as_inner_mut().pre_exec(Box::new(f)); self } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 2c55813c5cd39..9975064ca655f 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -149,7 +149,7 @@ impl Command { &mut self.closures } - pub fn before_exec(&mut self, + pub unsafe fn pre_exec(&mut self, f: Box io::Result<()> + Send + Sync>) { self.closures.push(f); } From d48433d920ad27ab57a27f087bcdec79ab36bfdc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Feb 2019 19:57:06 +0100 Subject: [PATCH 0515/1064] also replace before_exec by pre_exec on redox --- src/libstd/sys/redox/ext/process.rs | 28 ++++++++++++++++++++++++---- src/libstd/sys/redox/process.rs | 2 +- src/libstd/sys/unix/ext/process.rs | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 941fba8755b4a..78917ea91886b 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -36,7 +36,7 @@ pub trait CommandExt { /// will be called and the spawn operation will immediately return with a /// failure. /// - /// # Notes + /// # Notes and Safety /// /// This closure will be run in the context of the child process after a /// `fork`. This primarily means that any modifications made to memory on @@ -45,12 +45,32 @@ pub trait CommandExt { /// like `malloc` or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// This also means that all resources such as file descriptors and + /// memory-mapped regions got duplicated. It is your responsibility to make + /// sure that the closure does not violate library invariants by making + /// invalid use of these duplicates. + /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these /// locations may not appear where intended. + #[stable(feature = "process_pre_exec", since = "1.34.0")] + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command + where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + + /// Schedules a closure to be run just before the `exec` function is + /// invoked. + /// + /// This method should be unsafe, so it got deprecated in favor of the + /// unsafe [`pre_exec`]. + /// + /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] + #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + where F: FnMut() -> io::Result<()> + Send + Sync + 'static + { + unsafe { self.pre_exec(f) } + } /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -87,10 +107,10 @@ impl CommandExt for process::Command { self } - fn before_exec(&mut self, f: F) -> &mut process::Command + unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { - self.as_inner_mut().before_exec(Box::new(f)); + self.as_inner_mut().pre_exec(Box::new(f)); self } diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 4199ab98cf17e..9b85fa41a0a4f 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -116,7 +116,7 @@ impl Command { self.gid = Some(id); } - pub fn before_exec(&mut self, + pub unsafe fn pre_exec(&mut self, f: Box io::Result<()> + Send + Sync>) { self.closures.push(f); } diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index f5fc26dc9cca6..7cc5e9945938d 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -36,7 +36,7 @@ pub trait CommandExt { /// will be called and the spawn operation will immediately return with a /// failure. /// - /// # Notes + /// # Notes and Safety /// /// This closure will be run in the context of the child process after a /// `fork`. This primarily means that any modifications made to memory on From b1709d25e12fbffca53c30d05c16854256185900 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Feb 2019 20:00:08 +0100 Subject: [PATCH 0516/1064] update test --- ...and-before-exec.rs => command-pre-exec.rs} | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) rename src/test/run-pass/{command-before-exec.rs => command-pre-exec.rs} (75%) diff --git a/src/test/run-pass/command-before-exec.rs b/src/test/run-pass/command-pre-exec.rs similarity index 75% rename from src/test/run-pass/command-before-exec.rs rename to src/test/run-pass/command-pre-exec.rs index 91d2636b2ae63..bca2b8410fa84 100644 --- a/src/test/run-pass/command-before-exec.rs +++ b/src/test/run-pass/command-pre-exec.rs @@ -29,53 +29,53 @@ fn main() { let me = env::current_exe().unwrap(); - let output = Command::new(&me).arg("test1").before_exec(|| { + let output = unsafe { Command::new(&me).arg("test1").pre_exec(|| { println!("hello"); Ok(()) - }).output().unwrap(); + }).output().unwrap() }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert_eq!(output.stdout, b"hello\nhello2\n"); - let output = Command::new(&me).arg("test2").before_exec(|| { + let output = unsafe { Command::new(&me).arg("test2").pre_exec(|| { env::set_var("FOO", "BAR"); Ok(()) - }).output().unwrap(); + }).output().unwrap() }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); - let output = Command::new(&me).arg("test3").before_exec(|| { + let output = unsafe { Command::new(&me).arg("test3").pre_exec(|| { env::set_current_dir("/").unwrap(); Ok(()) - }).output().unwrap(); + }).output().unwrap() }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); - let output = Command::new(&me).arg("bad").before_exec(|| { + let output = unsafe { Command::new(&me).arg("bad").pre_exec(|| { Err(Error::from_raw_os_error(102)) - }).output().unwrap_err(); + }).output().unwrap_err() }; assert_eq!(output.raw_os_error(), Some(102)); let pid = unsafe { libc::getpid() }; assert!(pid >= 0); - let output = Command::new(&me).arg("empty").before_exec(move || { - let child = unsafe { libc::getpid() }; + let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { + let child = libc::getpid(); assert!(child >= 0); assert!(pid != child); Ok(()) - }).output().unwrap(); + }).output().unwrap() }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); let mem = Arc::new(AtomicUsize::new(0)); let mem2 = mem.clone(); - let output = Command::new(&me).arg("empty").before_exec(move || { + let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); Ok(()) - }).output().unwrap(); + }).output().unwrap() }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); From cd1047e0d45619f1d668bfbf6cccbbf6396335be Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 1 Feb 2019 20:02:21 +0000 Subject: [PATCH 0517/1064] Fix bug in integer range matching --- src/librustc_mir/build/matches/simplify.rs | 21 ++++++++++++------- .../ui/match-on-negative-integer-ranges.rs | 7 +++++++ 2 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/match-on-negative-integer-ranges.rs diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 22bc3506803f2..c219fd2218223 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -106,27 +106,34 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } PatternKind::Range(PatternRange { lo, hi, ty, end }) => { - let range = match ty.sty { + let (range, bias) = match ty.sty { ty::Char => { - Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))) + (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0) } ty::Int(ity) => { // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); - let min = 1u128 << (size.bits() - 1); - let max = (1u128 << (size.bits() - 1)) - 1; - Some((min, max, size)) + let max = !0u128 >> (128 - size.bits()); + let bias = 1u128 << (size.bits() - 1); + (Some((0, max, size)), bias) } ty::Uint(uty) => { // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); let max = !0u128 >> (128 - size.bits()); - Some((0, max, size)) + (Some((0, max, size)), 0) } - _ => None, + _ => (None, 0), }; if let Some((min, max, sz)) = range { if let (Some(lo), Some(hi)) = (lo.val.try_to_bits(sz), hi.val.try_to_bits(sz)) { + // We want to compare ranges numerically, but the order of the bitwise + // representation of signed integers does not match their numeric order. + // Thus, to correct the ordering, we need to shift the range of signed + // integers to correct the comparison. This is achieved by XORing with a + // bias (see pattern/_match.rs for another pertinent example of this + // pattern). + let (lo, hi) = (lo ^ bias, hi ^ bias); if lo <= min && (hi > max || hi == max && end == RangeEnd::Included) { // Irrefutable pattern match. return Ok(()); diff --git a/src/test/ui/match-on-negative-integer-ranges.rs b/src/test/ui/match-on-negative-integer-ranges.rs new file mode 100644 index 0000000000000..53e9ea9a5775b --- /dev/null +++ b/src/test/ui/match-on-negative-integer-ranges.rs @@ -0,0 +1,7 @@ +// run-pass + +fn main() { + assert_eq!(false, match -50_i8 { -128i8..=-101i8 => true, _ => false, }); + + assert_eq!(false, if let -128i8..=-101i8 = -50_i8 { true } else { false }); +} From c4e46140f6a295d2d668ccc5bf25858233b11cbb Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Fri, 1 Feb 2019 22:11:40 +0100 Subject: [PATCH 0518/1064] targets: aarch64-unknown-none: Add +strict-align On AArch64, an unaligned access causes a synchronous exception. In the current state of the target, the compiler might generate unaligned accesses, see https://github.com/rust-embedded/rust-raspi3-tutorial/issues/10. Since this is a bare-metal target, it is possible that there is no exception handling in place (yet) to recover from this case, causing a binary to just silently fail. Add `+strict-align` to avoid this case. --- src/librustc_target/spec/aarch64_unknown_none.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_target/spec/aarch64_unknown_none.rs b/src/librustc_target/spec/aarch64_unknown_none.rs index 3440a4f8752db..8c02bc61088b4 100644 --- a/src/librustc_target/spec/aarch64_unknown_none.rs +++ b/src/librustc_target/spec/aarch64_unknown_none.rs @@ -11,6 +11,7 @@ use super::{LldFlavor, LinkerFlavor, Target, TargetOptions, PanicStrategy}; pub fn target() -> Result { let opts = TargetOptions { linker: Some("rust-lld".to_owned()), + features: "+strict-align".to_string(), executables: true, relocation_model: "static".to_string(), disable_redzone: true, From 61e92b586b550fc46d0d8b83f711b27f937ca87f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 1 Feb 2019 23:59:11 +0100 Subject: [PATCH 0519/1064] Rename iter::unfold to iter::from_fn and remove explicit state This API is unstable. CC https://github.com/rust-lang/rust/issues/55977#issuecomment-459657195 --- src/libcore/iter/mod.rs | 2 +- src/libcore/iter/sources.rs | 55 ++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index b6bb5f01b2d29..4e1dc108cc9bd 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -327,7 +327,7 @@ pub use self::sources::{Once, once}; #[unstable(feature = "iter_once_with", issue = "57581")] pub use self::sources::{OnceWith, once_with}; #[unstable(feature = "iter_unfold", issue = "55977")] -pub use self::sources::{Unfold, unfold, Successors, successors}; +pub use self::sources::{FromFn, from_fn, Successors, successors}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend}; diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 2590fa6023a53..2b741e66170aa 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -491,24 +491,24 @@ pub fn once_with A>(gen: F) -> OnceWith { } /// Creates a new iterator where each iteration calls the provided closure -/// `F: FnMut(&mut St) -> Option`. +/// `F: FnMut() -> Option`. /// /// This allows creating a custom iterator with any behavior /// without using the more verbose syntax of creating a dedicated type /// and implementing the `Iterator` trait for it. /// -/// In addition to its captures and environment, -/// the closure is given a mutable reference to some state -/// that is preserved across iterations. -/// That state starts as the given `initial_state` value. -/// -/// Note that the `Unfold` iterator doesn’t make assumptions about the behavior of the closure, +/// Note that the `FromFn` iterator doesn’t make assumptions about the behavior of the closure, /// and therefore conservatively does not implement [`FusedIterator`], /// or override [`Iterator::size_hint`] from its default `(0, None)`. /// /// [`FusedIterator`]: trait.FusedIterator.html /// [`Iterator::size_hint`]: trait.Iterator.html#method.size_hint /// +/// The closure can use its its captures and environment +/// to track state across iterations. +/// Depending on how the iterator is used, +/// this may require specifying the `move` keyword on the closure. +/// /// # Examples /// /// Let’s re-implement the counter iterator from [module-level documentation]: @@ -517,13 +517,14 @@ pub fn once_with A>(gen: F) -> OnceWith { /// /// ``` /// #![feature(iter_unfold)] -/// let counter = std::iter::unfold(0, |count| { +/// let mut count = 0; +/// let counter = std::iter::from_fn(move || { /// // Increment our count. This is why we started at zero. -/// *count += 1; +/// count += 1; /// /// // Check to see if we've finished counting or not. -/// if *count < 6 { -/// Some(*count) +/// if count < 6 { +/// Some(count) /// } else { /// None /// } @@ -532,46 +533,38 @@ pub fn once_with A>(gen: F) -> OnceWith { /// ``` #[inline] #[unstable(feature = "iter_unfold", issue = "55977")] -pub fn unfold(initial_state: St, f: F) -> Unfold - where F: FnMut(&mut St) -> Option +pub fn from_fn(f: F) -> FromFn + where F: FnMut() -> Option { - Unfold { - state: initial_state, - f, - } + FromFn(f) } -/// An iterator where each iteration calls the provided closure `F: FnMut(&mut St) -> Option`. +/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option`. /// -/// This `struct` is created by the [`unfold`] function. +/// This `struct` is created by the [`iter::from_fn`] function. /// See its documentation for more. /// -/// [`unfold`]: fn.unfold.html +/// [`iter::from_fn`]: fn.from_fn.html #[derive(Clone)] #[unstable(feature = "iter_unfold", issue = "55977")] -pub struct Unfold { - state: St, - f: F, -} +pub struct FromFn(F); #[unstable(feature = "iter_unfold", issue = "55977")] -impl Iterator for Unfold - where F: FnMut(&mut St) -> Option +impl Iterator for FromFn + where F: FnMut() -> Option { type Item = T; #[inline] fn next(&mut self) -> Option { - (self.f)(&mut self.state) + (self.0)() } } #[unstable(feature = "iter_unfold", issue = "55977")] -impl fmt::Debug for Unfold { +impl fmt::Debug for FromFn { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Unfold") - .field("state", &self.state) - .finish() + f.debug_struct("FromFn").finish() } } From a6fd6eccda42f86e40b73d788e8099adeb66e37b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Feb 2019 00:52:38 +0100 Subject: [PATCH 0520/1064] Test alloca with #[repr(align(x))] on enum --- src/test/codegen/align-enum.rs | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/test/codegen/align-enum.rs diff --git a/src/test/codegen/align-enum.rs b/src/test/codegen/align-enum.rs new file mode 100644 index 0000000000000..2251c54229ee0 --- /dev/null +++ b/src/test/codegen/align-enum.rs @@ -0,0 +1,36 @@ +// compile-flags: -C no-prepopulate-passes +// ignore-tidy-linelength +// min-llvm-version 7.0 + +#![crate_type = "lib"] +#![feature(repr_align_enum)] + +#[repr(align(64))] +pub enum Align64 { + A(u32), + B(u32), +} +// CHECK: %Align64 = type { [0 x i32], i32, [15 x i32] } + +pub struct Nested64 { + a: u8, + b: Align64, + c: u16, +} + +// CHECK-LABEL: @align64 +#[no_mangle] +pub fn align64(a: u32) -> Align64 { +// CHECK: %a64 = alloca %Align64, align 64 +// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 64 %{{.*}}, i8* align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) + let a64 = Align64::A(a); + a64 +} + +// CHECK-LABEL: @nested64 +#[no_mangle] +pub fn nested64(a: u8, b: u32, c: u16) -> Nested64 { +// CHECK: %n64 = alloca %Nested64, align 64 + let n64 = Nested64 { a, b: Align64::B(b), c }; + n64 +} From 481b354c9719a538b21547fcf06b8f65a43da604 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 1 Feb 2019 18:43:32 -0700 Subject: [PATCH 0521/1064] Simplify the overflowing_neg expression --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 16364faa8000d..2fbc5f7aa76cc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1530,7 +1530,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($Self #[inline] #[stable(feature = "wrapping", since = "1.7.0")] pub const fn overflowing_neg(self) -> (Self, bool) { - ((self ^ -1).wrapping_add(1), self == Self::min_value()) + ((!self).wrapping_add(1), self == Self::min_value()) } } From 5256efb80002bfcdbef2c6f007e43935c7d11432 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 1 Feb 2019 18:50:21 -0700 Subject: [PATCH 0522/1064] const-int-overflowing.rs += overflowing_neg --- src/test/run-pass/const-int-overflowing.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/run-pass/const-int-overflowing.rs b/src/test/run-pass/const-int-overflowing.rs index 289b1236cf1e2..e8fd022e68296 100644 --- a/src/test/run-pass/const-int-overflowing.rs +++ b/src/test/run-pass/const-int-overflowing.rs @@ -13,6 +13,9 @@ const SHL_B: (u32, bool) = 0x1u32.overflowing_shl(132); const SHR_A: (u32, bool) = 0x10u32.overflowing_shr(4); const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132); +const NEG_A: (u32, bool) = 0.overflowing_neg(); +const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg(); + fn ident(ident: T) -> T { ident } @@ -32,4 +35,7 @@ fn main() { assert_eq!(SHR_A, ident((0x1, false))); assert_eq!(SHR_B, ident((0x1, true))); + + assert_eq!(NEG_A, ident((0, false))); + assert_eq!(NEG_B, ident((1, true))); } From 31bf7e1b51ebb932036dd632396cd98c1e115a6b Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 1 Feb 2019 18:55:38 -0700 Subject: [PATCH 0523/1064] const-int-wrapping.rs += wrapping_neg --- src/test/run-pass/const-int-wrapping.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/run-pass/const-int-wrapping.rs b/src/test/run-pass/const-int-wrapping.rs index 5ab712015dfc3..fe001b625817a 100644 --- a/src/test/run-pass/const-int-wrapping.rs +++ b/src/test/run-pass/const-int-wrapping.rs @@ -13,6 +13,9 @@ const SHL_B: u32 = 1u32.wrapping_shl(128); const SHR_A: u32 = 128u32.wrapping_shr(7); const SHR_B: u32 = 128u32.wrapping_shr(128); +const NEG_A: u32 = 5u32.wrapping_neg(); +const NEG_B: u32 = 1234567890u32.wrapping_neg(); + fn ident(ident: T) -> T { ident } @@ -30,6 +33,6 @@ fn main() { assert_eq!(SHL_A, ident(128)); assert_eq!(SHL_B, ident(1)); - assert_eq!(SHR_A, ident(1)); - assert_eq!(SHR_B, ident(128)); + assert_eq!(SHR_A, ident(4294967291)); + assert_eq!(SHR_B, ident(3060399406)); } From e06302fda90dedd814c15f0517b98416b11cc204 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 1 Feb 2019 20:07:26 -0700 Subject: [PATCH 0524/1064] fix the build errors --- src/test/run-pass/const-int-overflowing.rs | 2 +- src/test/run-pass/const-int-wrapping.rs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/run-pass/const-int-overflowing.rs b/src/test/run-pass/const-int-overflowing.rs index e8fd022e68296..82057868b73bb 100644 --- a/src/test/run-pass/const-int-overflowing.rs +++ b/src/test/run-pass/const-int-overflowing.rs @@ -13,7 +13,7 @@ const SHL_B: (u32, bool) = 0x1u32.overflowing_shl(132); const SHR_A: (u32, bool) = 0x10u32.overflowing_shr(4); const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132); -const NEG_A: (u32, bool) = 0.overflowing_neg(); +const NEG_A: (u32, bool) = 0u32.overflowing_neg(); const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg(); fn ident(ident: T) -> T { diff --git a/src/test/run-pass/const-int-wrapping.rs b/src/test/run-pass/const-int-wrapping.rs index fe001b625817a..140fd57ecb802 100644 --- a/src/test/run-pass/const-int-wrapping.rs +++ b/src/test/run-pass/const-int-wrapping.rs @@ -33,6 +33,9 @@ fn main() { assert_eq!(SHL_A, ident(128)); assert_eq!(SHL_B, ident(1)); - assert_eq!(SHR_A, ident(4294967291)); - assert_eq!(SHR_B, ident(3060399406)); + assert_eq!(SHR_A, ident(1)); + assert_eq!(SHR_B, ident(128)); + + assert_eq!(NEG_A, ident(4294967291)); + assert_eq!(NEG_B, ident(3060399406)); } From 7754eb05c41debde225077e1708ab7ba01df62be Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 07:42:27 +0100 Subject: [PATCH 0525/1064] fix stabilization order of uniform_paths. --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9dd17b420aa44..bf4c637045f9c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -665,6 +665,8 @@ declare_features! ( (accepted, self_struct_ctor, "1.32.0", Some(51994), None), // `Self` in type definitions (RFC 2300) (accepted, self_in_typedefs, "1.32.0", Some(49303), None), + // Allows `use x::y;` to search `x` in the current scope. + (accepted, uniform_paths, "1.32.0", Some(53130), None), // Integer match exhaustiveness checking (RFC 2591) (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), // `use path as _;` and `extern crate c as _;` @@ -683,8 +685,6 @@ declare_features! ( (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), // Top level or-patterns (`p | q`) in `if let` and `while let`. (accepted, if_while_or_patterns, "1.33.0", Some(48215), None), - // Allows `use x::y;` to search `x` in the current scope. - (accepted, uniform_paths, "1.32.0", Some(53130), None), // Allows `cfg(target_vendor = "...")`. (accepted, cfg_target_vendor, "1.33.0", Some(29718), None), // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`. From 5594b0d5b8924e57f62d0408acb6d7982e93ad65 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 08:36:03 +0100 Subject: [PATCH 0526/1064] liballoc => edition = 2018. --- src/liballoc/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index 861c7cecb8879..f6d6c1de8f511 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -4,6 +4,7 @@ name = "alloc" version = "0.0.0" autotests = false autobenches = false +edition = "2018" [lib] name = "alloc" From e6e27924e17aa7def20ecaf88abc18ead6d97f93 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 08:36:45 +0100 Subject: [PATCH 0527/1064] liballoc: cargo check passes on 2018 --- src/liballoc/borrow.rs | 4 ++-- src/liballoc/boxed.rs | 6 +++--- src/liballoc/collections/binary_heap.rs | 4 ++-- src/liballoc/collections/btree/map.rs | 2 +- src/liballoc/collections/btree/node.rs | 4 ++-- src/liballoc/collections/btree/search.rs | 2 +- src/liballoc/collections/btree/set.rs | 4 ++-- src/liballoc/collections/linked_list.rs | 2 +- src/liballoc/collections/mod.rs | 2 +- src/liballoc/collections/vec_deque.rs | 6 +++--- src/liballoc/fmt.rs | 2 +- src/liballoc/prelude.rs | 10 +++++----- src/liballoc/raw_vec.rs | 10 +++++----- src/liballoc/rc.rs | 8 ++++---- src/liballoc/slice.rs | 13 +++++++------ src/liballoc/str.rs | 10 +++++----- src/liballoc/string.rs | 10 +++++----- src/liballoc/sync.rs | 10 +++++----- src/liballoc/task.rs | 2 +- src/liballoc/vec.rs | 10 +++++----- 20 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index b47337e44b2fe..4c6f150ca1b42 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -6,8 +6,8 @@ use core::cmp::Ordering; use core::hash::{Hash, Hasher}; use core::ops::{Add, AddAssign, Deref}; -use fmt; -use string::String; +use crate::fmt; +use crate::string::String; use self::Cow::*; diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 14a1242e3e569..7b322a5c39692 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -73,9 +73,9 @@ use core::ops::{ use core::ptr::{self, NonNull, Unique}; use core::task::{LocalWaker, Poll}; -use vec::Vec; -use raw_vec::RawVec; -use str::from_boxed_utf8_unchecked; +use crate::vec::Vec; +use crate::raw_vec::RawVec; +use crate::str::from_boxed_utf8_unchecked; /// A pointer type for heap allocation. /// diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index ad544e6015e4a..079c6290ebd40 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -151,8 +151,8 @@ use core::mem::{swap, size_of, ManuallyDrop}; use core::ptr; use core::fmt; -use slice; -use vec::{self, Vec}; +use crate::slice; +use crate::vec::{self, Vec}; use super::SpecExtend; diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 717650aca9600..efb4b8afdb70a 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -8,7 +8,7 @@ use core::ops::Index; use core::ops::RangeBounds; use core::{fmt, intrinsics, mem, ptr}; -use borrow::Borrow; +use crate::borrow::Borrow; use super::node::{self, Handle, NodeRef, marker}; use super::search; diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index e969e119dbe88..92664bad4e4a5 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -36,8 +36,8 @@ use core::mem::{self, MaybeUninit}; use core::ptr::{self, Unique, NonNull}; use core::slice; -use alloc::{Global, Alloc, Layout}; -use boxed::Box; +use crate::alloc::{Global, Alloc, Layout}; +use crate::boxed::Box; const B: usize = 6; pub const MIN_LEN: usize = B - 1; diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 9010de7c16ac3..242dc4b94d8ad 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -1,6 +1,6 @@ use core::cmp::Ordering; -use borrow::Borrow; +use crate::borrow::Borrow; use super::node::{Handle, NodeRef, marker}; diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 71fec7da9a5ed..01a0562bc2153 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -8,8 +8,8 @@ use core::fmt; use core::iter::{Peekable, FromIterator, FusedIterator}; use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}; -use borrow::Borrow; -use collections::btree_map::{self, BTreeMap, Keys}; +use crate::borrow::Borrow; +use crate::collections::btree_map::{self, BTreeMap, Keys}; use super::Recover; // FIXME(conventions): implement bounded iterators diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 804a2e9c8873b..c666adb41a738 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -20,7 +20,7 @@ use core::marker::PhantomData; use core::mem; use core::ptr::NonNull; -use boxed::Box; +use crate::boxed::Box; use super::SpecExtend; /// A doubly-linked list with owned nodes. diff --git a/src/liballoc/collections/mod.rs b/src/liballoc/collections/mod.rs index 138f5d79bb008..5f3f849373091 100644 --- a/src/liballoc/collections/mod.rs +++ b/src/liballoc/collections/mod.rs @@ -41,7 +41,7 @@ pub use self::linked_list::LinkedList; #[doc(no_inline)] pub use self::vec_deque::VecDeque; -use alloc::{AllocErr, LayoutErr}; +use crate::alloc::{AllocErr, LayoutErr}; /// Augments `AllocErr` with a CapacityOverflow variant. #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 579d7de96e6da..65d4253d0c67c 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -20,9 +20,9 @@ use core::slice; use core::hash::{Hash, Hasher}; use core::cmp; -use collections::CollectionAllocErr; -use raw_vec::RawVec; -use vec::Vec; +use crate::collections::CollectionAllocErr; +use crate::raw_vec::RawVec; +use crate::vec::Vec; const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 const MINIMUM_CAPACITY: usize = 1; // 2 - 1 diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index a1e7533449c69..8d12b19a06d12 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -527,7 +527,7 @@ pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub use core::fmt::{Alignment}; -use string; +use crate::string; /// The `format` function takes an [`Arguments`] struct and returns the resulting /// formatted string. diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs index 7cd22095de417..6767cf89f73ba 100644 --- a/src/liballoc/prelude.rs +++ b/src/liballoc/prelude.rs @@ -12,8 +12,8 @@ #![unstable(feature = "alloc", issue = "27783")] -#[unstable(feature = "alloc", issue = "27783")] pub use borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use vec::Vec; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 5e4aac9ce7871..9f9dd134826f0 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -7,10 +7,10 @@ use core::ops::Drop; use core::ptr::{self, NonNull, Unique}; use core::slice; -use alloc::{Alloc, Layout, Global, handle_alloc_error}; -use collections::CollectionAllocErr; -use collections::CollectionAllocErr::*; -use boxed::Box; +use crate::alloc::{Alloc, Layout, Global, handle_alloc_error}; +use crate::collections::CollectionAllocErr; +use crate::collections::CollectionAllocErr::*; +use crate::boxed::Box; /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases @@ -639,7 +639,7 @@ impl RawVec { strategy: ReserveStrategy, ) -> Result<(), CollectionAllocErr> { unsafe { - use alloc::AllocErr; + use crate::alloc::AllocErr; // NOTE: we don't early branch on ZSTs here because we want this // to actually catch "asking for more than usize::MAX" in that case. diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index c1f428658bd05..3c28c6d06fe75 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -227,7 +227,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #[cfg(not(test))] -use boxed::Box; +use crate::boxed::Box; #[cfg(test)] use std::boxed::Box; @@ -248,9 +248,9 @@ use core::ptr::{self, NonNull}; use core::convert::From; use core::usize; -use alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; -use string::String; -use vec::Vec; +use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; +use crate::string::String; +use crate::vec::Vec; struct RcBox { strong: Cell, diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index db19f778617f4..0ed8aa6a2e420 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -93,9 +93,9 @@ use core::mem; use core::ptr; use core::{u8, u16, u32}; -use borrow::{Borrow, BorrowMut, ToOwned}; -use boxed::Box; -use vec::Vec; +use crate::borrow::{Borrow, BorrowMut, ToOwned}; +use crate::boxed::Box; +use crate::vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] pub use core::slice::{Chunks, Windows}; @@ -137,12 +137,13 @@ pub use self::hack::to_vec; // `core::slice::SliceExt` - we need to supply these functions for the // `test_permutations` test mod hack { - use boxed::Box; use core::mem; + use crate::boxed::Box; #[cfg(test)] - use string::ToString; - use vec::Vec; + use crate::string::ToString; + + use crate::vec::Vec; pub fn into_vec(mut b: Box<[T]>) -> Vec { unsafe { diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 60d9f1626138e..a44838d560a70 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,11 +37,11 @@ use core::ptr; use core::iter::FusedIterator; use core::unicode::conversions; -use borrow::{Borrow, ToOwned}; -use boxed::Box; -use slice::{SliceConcatExt, SliceIndex}; -use string::String; -use vec::Vec; +use crate::borrow::{Borrow, ToOwned}; +use crate::boxed::Box; +use crate::slice::{SliceConcatExt, SliceIndex}; +use crate::string::String; +use crate::vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{FromStr, Utf8Error}; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index fa15e9ad9018e..d8f46374ce21b 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -56,11 +56,11 @@ use core::ptr; use core::str::pattern::Pattern; use core::str::lossy; -use collections::CollectionAllocErr; -use borrow::{Cow, ToOwned}; -use boxed::Box; -use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; -use vec::Vec; +use crate::collections::CollectionAllocErr; +use crate::borrow::{Cow, ToOwned}; +use crate::boxed::Box; +use crate::str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; +use crate::vec::Vec; /// A UTF-8 encoded, growable string. /// diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index f6cafd50dc8c9..b387f07f231e6 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -23,11 +23,11 @@ use core::hash::{Hash, Hasher}; use core::{isize, usize}; use core::convert::From; -use alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; -use boxed::Box; -use rc::is_dangling; -use string::String; -use vec::Vec; +use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; +use crate::boxed::Box; +use crate::rc::is_dangling; +use crate::string::String; +use crate::vec::Vec; /// A soft limit on the amount of references that may be made to an `Arc`. /// diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index 604c56dd01762..ba4e0dcda02df 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -11,7 +11,7 @@ mod if_arc { use core::marker::PhantomData; use core::mem; use core::ptr::{self, NonNull}; - use sync::Arc; + use crate::sync::Arc; /// A way of waking up a specific task. /// diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index ba3b3dfbfc2e1..b942bce678b97 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -70,11 +70,11 @@ use core::ptr; use core::ptr::NonNull; use core::slice; -use collections::CollectionAllocErr; -use borrow::ToOwned; -use borrow::Cow; -use boxed::Box; -use raw_vec::RawVec; +use crate::collections::CollectionAllocErr; +use crate::borrow::ToOwned; +use crate::borrow::Cow; +use crate::boxed::Box; +use crate::raw_vec::RawVec; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. /// From 7693e3e6662c2ae8aa24d69434161f501d855420 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 10:14:40 +0100 Subject: [PATCH 0528/1064] liballoc: refactor & fix some imports. --- src/liballoc/alloc.rs | 14 ++-- src/liballoc/benches/btree/map.rs | 8 ++- src/liballoc/benches/slice.rs | 11 ++-- src/liballoc/borrow.rs | 11 ++-- src/liballoc/boxed.rs | 38 +++++------ src/liballoc/boxed_test.rs | 14 ++-- src/liballoc/collections/binary_heap.rs | 20 +++--- src/liballoc/collections/btree/map.rs | 33 +++++----- src/liballoc/collections/btree/node.rs | 16 +++-- src/liballoc/collections/btree/search.rs | 3 +- src/liballoc/collections/btree/set.rs | 23 ++++--- src/liballoc/collections/linked_list.rs | 21 +++--- src/liballoc/collections/vec_deque.rs | 43 +++++++------ src/liballoc/fmt.rs | 25 +++----- src/liballoc/prelude.rs | 13 ++-- src/liballoc/raw_vec.rs | 25 ++++---- src/liballoc/rc.rs | 65 +++++++++---------- src/liballoc/slice.rs | 21 +++--- src/liballoc/str.rs | 33 ++++++---- src/liballoc/string.rs | 39 +++++++----- src/liballoc/sync.rs | 81 ++++++++++++------------ src/liballoc/task.rs | 8 ++- src/liballoc/tests/arc.rs | 10 +-- src/liballoc/tests/binary_heap.rs | 11 ++-- src/liballoc/tests/btree/map.rs | 11 ++-- src/liballoc/tests/btree/set.rs | 11 ++-- src/liballoc/tests/lib.rs | 6 +- src/liballoc/tests/linked_list.rs | 6 +- src/liballoc/tests/rc.rs | 10 +-- src/liballoc/tests/slice.rs | 29 +++++---- src/liballoc/tests/str.rs | 15 +++-- src/liballoc/tests/string.rs | 10 +-- src/liballoc/tests/vec.rs | 12 ++-- src/liballoc/tests/vec_deque.rs | 21 +++--- src/liballoc/vec.rs | 49 +++++++------- 35 files changed, 424 insertions(+), 342 deletions(-) diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 096cb51e0d3ef..bb88897323eaf 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -2,9 +2,11 @@ #![stable(feature = "alloc_module", since = "1.28.0")] -use core::intrinsics::{min_align_of_val, size_of_val}; -use core::ptr::{NonNull, Unique}; -use core::usize; +use core::{ + intrinsics::{min_align_of_val, size_of_val}, + ptr::{NonNull, Unique}, + usize, +}; #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] @@ -228,8 +230,10 @@ pub fn handle_alloc_error(layout: Layout) -> ! { mod tests { extern crate test; use self::test::Bencher; - use boxed::Box; - use alloc::{Global, Alloc, Layout, handle_alloc_error}; + use crate::{ + boxed::Box, + alloc::{Global, Alloc, Layout, handle_alloc_error}, + }; #[test] fn allocate_zeroed() { diff --git a/src/liballoc/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs index a6f584534d174..3865ec866aeed 100644 --- a/src/liballoc/benches/btree/map.rs +++ b/src/liballoc/benches/btree/map.rs @@ -1,6 +1,8 @@ -use std::iter::Iterator; -use std::vec::Vec; -use std::collections::BTreeMap; +use std::{ + iter::Iterator, + vec::Vec, + collections::BTreeMap, +}; use rand::{Rng, seq::SliceRandom, thread_rng}; use test::{Bencher, black_box}; diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs index b9ebd74f7999a..d87b70f2d932c 100644 --- a/src/liballoc/benches/slice.rs +++ b/src/liballoc/benches/slice.rs @@ -1,9 +1,8 @@ -use rand::{thread_rng}; -use std::mem; -use std::ptr; - -use rand::{Rng, SeedableRng}; -use rand::distributions::{Standard, Alphanumeric}; +use std::{mem, ptr}; +use rand::{ + thread_rng, Rng, SeedableRng, + distributions::{Standard, Alphanumeric}, +}; use rand_xorshift::XorShiftRng; use test::{Bencher, black_box}; diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 4c6f150ca1b42..8161d588fbdb8 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -2,12 +2,13 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::cmp::Ordering; -use core::hash::{Hash, Hasher}; -use core::ops::{Add, AddAssign, Deref}; +use core::{ + cmp::Ordering, + hash::{Hash, Hasher}, + ops::{Add, AddAssign, Deref}, +}; -use crate::fmt; -use crate::string::String; +use crate::{fmt, string::String}; use self::Cow::*; diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 7b322a5c39692..f590b6488d9da 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -56,26 +56,28 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::any::Any; -use core::borrow; -use core::cmp::Ordering; -use core::convert::From; -use core::fmt; -use core::future::Future; -use core::hash::{Hash, Hasher}; -use core::iter::{Iterator, FromIterator, FusedIterator}; -use core::marker::{Unpin, Unsize}; -use core::mem; -use core::pin::Pin; -use core::ops::{ - CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState +use core::{ + any::Any, + borrow, + cmp::Ordering, + convert::From, + fmt, + future::Future, + hash::{Hash, Hasher}, + iter::{Iterator, FromIterator, FusedIterator}, + marker::{Unpin, Unsize}, + mem, + pin::Pin, + ops::{CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState}, + ptr::{self, NonNull, Unique}, + task::{LocalWaker, Poll}, }; -use core::ptr::{self, NonNull, Unique}; -use core::task::{LocalWaker, Poll}; -use crate::vec::Vec; -use crate::raw_vec::RawVec; -use crate::str::from_boxed_utf8_unchecked; +use crate::{ + vec::Vec, + raw_vec::RawVec, + str::from_boxed_utf8_unchecked, +}; /// A pointer type for heap allocation. /// diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs index 654eabd070326..6fb01fbc6a150 100644 --- a/src/liballoc/boxed_test.rs +++ b/src/liballoc/boxed_test.rs @@ -1,11 +1,13 @@ //! Test for `boxed` mod. -use core::any::Any; -use core::ops::Deref; -use core::result::Result::{Err, Ok}; -use core::clone::Clone; -use core::f64; -use core::i64; +use core::{ + any::Any, + ops::Deref, + result::Result::{Err, Ok}, + clone::Clone, + f64, + i64, +}; use std::boxed::Box; diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 079c6290ebd40..4a38f041636ef 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -145,14 +145,18 @@ #![allow(missing_docs)] #![stable(feature = "rust1", since = "1.0.0")] -use core::ops::{Deref, DerefMut}; -use core::iter::{FromIterator, FusedIterator}; -use core::mem::{swap, size_of, ManuallyDrop}; -use core::ptr; -use core::fmt; - -use crate::slice; -use crate::vec::{self, Vec}; +use core::{ + ops::{Deref, DerefMut}, + iter::{FromIterator, FusedIterator}, + mem::{swap, size_of, ManuallyDrop}, + ptr, + fmt, +}; + +use crate::{ + slice, + vec::{self, Vec}, +}; use super::SpecExtend; diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index efb4b8afdb70a..f81cf6f104719 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1,23 +1,24 @@ -use core::cmp::Ordering; -use core::fmt::Debug; -use core::hash::{Hash, Hasher}; -use core::iter::{FromIterator, Peekable, FusedIterator}; -use core::marker::PhantomData; -use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::Index; -use core::ops::RangeBounds; -use core::{fmt, intrinsics, mem, ptr}; +use core::{ + cmp::Ordering, + fmt::Debug, + hash::{Hash, Hasher}, + iter::{FromIterator, Peekable, FusedIterator}, + marker::PhantomData, + ops::{ + Bound::{Excluded, Included, Unbounded}, + Index, RangeBounds, + }, + fmt, intrinsics, mem, ptr, +}; use crate::borrow::Borrow; -use super::node::{self, Handle, NodeRef, marker}; -use super::search; +use super::{ + node::{self, Handle, NodeRef, marker, InsertResult::*, ForceResult::*}, + search::{self, SearchResult::*}, +}; -use super::node::InsertResult::*; -use super::node::ForceResult::*; -use super::search::SearchResult::*; -use self::UnderflowResult::*; -use self::Entry::*; +use self::{UnderflowResult::*, Entry::*}; /// A map based on a B-Tree. /// diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 92664bad4e4a5..f33a75bc45e02 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -31,13 +31,17 @@ // - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges. // This implies that even an empty internal node has at least one edge. -use core::marker::PhantomData; -use core::mem::{self, MaybeUninit}; -use core::ptr::{self, Unique, NonNull}; -use core::slice; +use core::{ + marker::PhantomData, + mem::{self, MaybeUninit}, + ptr::{self, Unique, NonNull}, + slice, +}; -use crate::alloc::{Global, Alloc, Layout}; -use crate::boxed::Box; +use crate::{ + alloc::{Global, Alloc, Layout}, + boxed::Box, +}; const B: usize = 6; pub const MIN_LEN: usize = B - 1; diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 242dc4b94d8ad..a3b56ad17c6b7 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -2,9 +2,8 @@ use core::cmp::Ordering; use crate::borrow::Borrow; -use super::node::{Handle, NodeRef, marker}; +use super::node::{Handle, NodeRef, marker, ForceResult::*}; -use super::node::ForceResult::*; use self::SearchResult::*; pub enum SearchResult { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 01a0562bc2153..298d165a91afa 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1,15 +1,20 @@ // This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface // to TreeMap -use core::cmp::Ordering::{self, Less, Greater, Equal}; -use core::cmp::{min, max}; -use core::fmt::Debug; -use core::fmt; -use core::iter::{Peekable, FromIterator, FusedIterator}; -use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}; - -use crate::borrow::Borrow; -use crate::collections::btree_map::{self, BTreeMap, Keys}; +use core::{ + cmp::{ + Ordering::{self, Less, Greater, Equal}, + min, max, + }, + fmt::{self, Debug}, + iter::{Peekable, FromIterator, FusedIterator}, + ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}, +}; + +use crate::{ + borrow::Borrow, + collections::btree_map::{self, BTreeMap, Keys}, +}; use super::Recover; // FIXME(conventions): implement bounded iterators diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index c666adb41a738..8f72c6babaf35 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -12,13 +12,15 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::cmp::Ordering; -use core::fmt; -use core::hash::{Hasher, Hash}; -use core::iter::{FromIterator, FusedIterator}; -use core::marker::PhantomData; -use core::mem; -use core::ptr::NonNull; +use core::{ + cmp::Ordering, + fmt, + hash::{Hasher, Hash}, + iter::{FromIterator, FusedIterator}, + marker::PhantomData, + mem, + ptr::NonNull, +}; use crate::boxed::Box; use super::SpecExtend; @@ -1213,11 +1215,8 @@ unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {} #[cfg(test)] mod tests { - use std::thread; - use std::vec::Vec; - + use std::{thread, vec::Vec}; use rand::{thread_rng, RngCore}; - use super::{LinkedList, Node}; #[cfg(test)] diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 65d4253d0c67c..de78783983d7c 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -7,22 +7,25 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::cmp::Ordering; -use core::fmt; -use core::iter::{repeat_with, FromIterator, FusedIterator}; -use core::mem; -use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{Index, IndexMut, RangeBounds, Try}; -use core::ptr; -use core::ptr::NonNull; -use core::slice; - -use core::hash::{Hash, Hasher}; -use core::cmp; - -use crate::collections::CollectionAllocErr; -use crate::raw_vec::RawVec; -use crate::vec::Vec; +use core::{ + cmp::{self, Ordering}, + fmt, + iter::{repeat_with, FromIterator, FusedIterator}, + mem, + ops::{ + Bound::{Excluded, Included, Unbounded}, + Index, IndexMut, RangeBounds, Try, + }, + ptr::{self, NonNull}, + slice, + hash::{Hash, Hasher}, +}; + +use crate::{ + collections::CollectionAllocErr, + raw_vec::RawVec, + vec::Vec, +}; const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 const MINIMUM_CAPACITY: usize = 1; // 2 - 1 @@ -2758,7 +2761,7 @@ impl From> for Vec { #[cfg(test)] mod tests { - use test; + use ::test; use super::VecDeque; @@ -3036,7 +3039,7 @@ mod tests { #[test] fn test_from_vec() { - use vec::Vec; + use crate::vec::Vec; for cap in 0..35 { for len in 0..=cap { let mut vec = Vec::with_capacity(cap); @@ -3052,7 +3055,7 @@ mod tests { #[test] fn test_vec_from_vecdeque() { - use vec::Vec; + use crate::vec::Vec; fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) { let mut vd = VecDeque::with_capacity(cap); @@ -3114,7 +3117,7 @@ mod tests { #[test] fn issue_53529() { - use boxed::Box; + use crate::boxed::Box; let mut dst = VecDeque::new(); dst.push_front(Box::new(1)); diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 8d12b19a06d12..be35b4487509b 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -509,21 +509,16 @@ #[unstable(feature = "fmt_internals", issue = "0")] pub use core::fmt::rt; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{Formatter, Result, Write}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{Binary, Octal}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{Debug, Display}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{LowerHex, Pointer, UpperHex}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{LowerExp, UpperExp}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::Error; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{write, ArgumentV1, Arguments}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; +pub use core::fmt::{ + Formatter, Result, Write, + Binary, Octal, + Debug, Display, + LowerHex, Pointer, UpperHex, + LowerExp, UpperExp, + Error, + write, ArgumentV1, Arguments, + DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple +}; #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub use core::fmt::{Alignment}; diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs index 6767cf89f73ba..3f1d6ded66d35 100644 --- a/src/liballoc/prelude.rs +++ b/src/liballoc/prelude.rs @@ -12,8 +12,11 @@ #![unstable(feature = "alloc", issue = "27783")] -#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; +#[unstable(feature = "alloc", issue = "27783")] +pub use crate::{ + borrow::ToOwned, + boxed::Box, + slice::SliceConcatExt, + string::{String, ToString}, + vec::Vec, +}; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 9f9dd134826f0..92d482b1f052a 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -1,16 +1,19 @@ #![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "0")] #![doc(hidden)] -use core::cmp; -use core::mem; -use core::ops::Drop; -use core::ptr::{self, NonNull, Unique}; -use core::slice; - -use crate::alloc::{Alloc, Layout, Global, handle_alloc_error}; -use crate::collections::CollectionAllocErr; -use crate::collections::CollectionAllocErr::*; -use crate::boxed::Box; +use core::{ + cmp, + mem, + ops::Drop, + ptr::{self, NonNull, Unique}, + slice, +}; + +use crate::{ + alloc::{Alloc, Layout, Global, handle_alloc_error}, + collections::CollectionAllocErr::{self, *}, + boxed::Box, +}; /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases @@ -753,7 +756,7 @@ mod tests { #[test] fn allocator_param() { - use alloc::AllocErr; + use crate::alloc::AllocErr; // Writing a test of integration between third-party // allocators and RawVec is a little tricky because the RawVec diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 3c28c6d06fe75..720ac4b630aee 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -231,26 +231,28 @@ use crate::boxed::Box; #[cfg(test)] use std::boxed::Box; -use core::any::Any; -use core::borrow; -use core::cell::Cell; -use core::cmp::Ordering; -use core::fmt; -use core::hash::{Hash, Hasher}; -use core::intrinsics::abort; -use core::marker; -use core::marker::{Unpin, Unsize, PhantomData}; -use core::mem::{self, align_of_val, forget, size_of_val}; -use core::ops::{Deref, Receiver}; -use core::ops::{CoerceUnsized, DispatchFromDyn}; -use core::pin::Pin; -use core::ptr::{self, NonNull}; -use core::convert::From; -use core::usize; - -use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; -use crate::string::String; -use crate::vec::Vec; +use core::{ + any::Any, + borrow, + cell::Cell, + cmp::Ordering, + fmt, + hash::{Hash, Hasher}, + intrinsics::abort, + marker::{self, Unpin, Unsize, PhantomData}, + mem::{self, align_of_val, forget, size_of_val}, + ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}, + pin::Pin, + ptr::{self, NonNull}, + convert::From, + usize, +}; + +use crate::{ + alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}, + string::String, + vec::Vec, +}; struct RcBox { strong: Cell, @@ -1562,14 +1564,15 @@ impl RcBoxPtr for RcBox { #[cfg(test)] mod tests { use super::{Rc, Weak}; - use std::boxed::Box; - use std::cell::RefCell; - use std::option::Option; - use std::option::Option::{None, Some}; - use std::result::Result::{Err, Ok}; - use std::mem::drop; - use std::clone::Clone; - use std::convert::From; + use std::{ + boxed::Box, + cell::RefCell, + option::Option::{self, None, Some}, + result::Result::{Err, Ok}, + mem::drop, + clone::Clone, + convert::From, + }; #[test] fn test_clone() { @@ -1733,8 +1736,7 @@ mod tests { #[test] fn test_into_from_raw_unsized() { - use std::fmt::Display; - use std::string::ToString; + use std::{fmt::Display, string::ToString}; let rc: Rc = Rc::from("foo"); @@ -1942,8 +1944,7 @@ mod tests { #[test] fn test_from_box_trait() { - use std::fmt::Display; - use std::string::ToString; + use std::{fmt::Display, string::ToString}; let b: Box = box 123; let r: Rc = Rc::from(b); diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 0ed8aa6a2e420..1cee3aa415b8b 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -87,15 +87,18 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![cfg_attr(test, allow(unused_imports, dead_code))] -use core::cmp::Ordering::{self, Less}; -use core::mem::size_of; -use core::mem; -use core::ptr; -use core::{u8, u16, u32}; - -use crate::borrow::{Borrow, BorrowMut, ToOwned}; -use crate::boxed::Box; -use crate::vec::Vec; +use core::{ + cmp::Ordering::{self, Less}, + mem::{self, size_of}, + ptr, + u8, u16, u32, +}; + +use crate::{ + borrow::{Borrow, BorrowMut, ToOwned}, + boxed::Box, + vec::Vec, +}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::slice::{Chunks, Windows}; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index a44838d560a70..85437defd5733 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -28,20 +28,25 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![allow(unused_imports)] -use core::fmt; -use core::str as core_str; -use core::str::pattern::Pattern; -use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; -use core::mem; -use core::ptr; -use core::iter::FusedIterator; -use core::unicode::conversions; - -use crate::borrow::{Borrow, ToOwned}; -use crate::boxed::Box; -use crate::slice::{SliceConcatExt, SliceIndex}; -use crate::string::String; -use crate::vec::Vec; +use core::{ + fmt, + str::{ + self as core_str, + pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher}, + }, + mem, + ptr, + iter::FusedIterator, + unicode::conversions, +}; + +use crate::{ + borrow::{Borrow, ToOwned}, + boxed::Box, + slice::{SliceConcatExt, SliceIndex}, + string::String, + vec::Vec, +}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{FromStr, Utf8Error}; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index d8f46374ce21b..e9da10b3597f2 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -46,21 +46,30 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::char::{decode_utf16, REPLACEMENT_CHARACTER}; -use core::fmt; -use core::hash; -use core::iter::{FromIterator, FusedIterator}; -use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds}; -use core::ptr; -use core::str::pattern::Pattern; -use core::str::lossy; - -use crate::collections::CollectionAllocErr; -use crate::borrow::{Cow, ToOwned}; -use crate::boxed::Box; -use crate::str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; -use crate::vec::Vec; +use core::{ + char::{decode_utf16, REPLACEMENT_CHARACTER}, + fmt, + hash, + iter::{FromIterator, FusedIterator}, + ops::{ + self, + Bound::{Excluded, Included, Unbounded}, + Add, AddAssign, Index, IndexMut, RangeBounds, + }, + ptr, + str::{ + pattern::Pattern, + lossy, + } +}; + +use crate::{ + collections::CollectionAllocErr, + borrow::{Cow, ToOwned}, + boxed::Box, + str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}, + vec::Vec, +}; /// A UTF-8 encoded, growable string. /// diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index b387f07f231e6..2a4b3113bfe75 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -6,28 +6,33 @@ //! //! [arc]: struct.Arc.html -use core::any::Any; -use core::sync::atomic; -use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; -use core::borrow; -use core::fmt; -use core::cmp::{self, Ordering}; -use core::intrinsics::abort; -use core::mem::{self, align_of_val, size_of_val}; -use core::ops::{Deref, Receiver}; -use core::ops::{CoerceUnsized, DispatchFromDyn}; -use core::pin::Pin; -use core::ptr::{self, NonNull}; -use core::marker::{Unpin, Unsize, PhantomData}; -use core::hash::{Hash, Hasher}; -use core::{isize, usize}; -use core::convert::From; - -use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; -use crate::boxed::Box; -use crate::rc::is_dangling; -use crate::string::String; -use crate::vec::Vec; +use core::{ + any::Any, + sync::atomic::{ + self, + Ordering::{Acquire, Relaxed, Release, SeqCst} + }, + borrow, + fmt, + cmp::{self, Ordering}, + intrinsics::abort, + mem::{self, align_of_val, size_of_val}, + ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}, + pin::Pin, + ptr::{self, NonNull}, + marker::{Unpin, Unsize, PhantomData}, + hash::{Hash, Hasher}, + isize, usize, + convert::From, +}; + +use crate::{ + alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}, + boxed::Box, + rc::is_dangling, + string::String, + vec::Vec, +}; /// A soft limit on the amount of references that may be made to an `Arc`. /// @@ -1650,21 +1655,21 @@ impl From> for Arc<[T]> { #[cfg(test)] mod tests { - use std::boxed::Box; - use std::clone::Clone; - use std::sync::mpsc::channel; - use std::mem::drop; - use std::ops::Drop; - use std::option::Option; - use std::option::Option::{None, Some}; - use std::sync::atomic; - use std::sync::atomic::Ordering::{Acquire, SeqCst}; - use std::thread; - use std::sync::Mutex; - use std::convert::From; + use std::{ + boxed::Box, + clone::Clone, + sync::mpsc::channel, + mem::drop, + ops::Drop, + option::Option::{self, None, Some}, + sync::atomic::{self, Ordering::{Acquire, SeqCst}}, + thread, + sync::Mutex, + convert::From, + }; use super::{Arc, Weak}; - use vec::Vec; + use crate::vec::Vec; struct Canary(*mut atomic::AtomicUsize); @@ -1770,8 +1775,7 @@ mod tests { #[test] fn test_into_from_raw_unsized() { - use std::fmt::Display; - use std::string::ToString; + use std::{fmt::Display, string::ToString}; let arc: Arc = Arc::from("foo"); @@ -2083,8 +2087,7 @@ mod tests { #[test] fn test_from_box_trait() { - use std::fmt::Display; - use std::string::ToString; + use std::{fmt::Display, string::ToString}; let b: Box = box 123; let r: Arc = Arc::from(b); diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index ba4e0dcda02df..89dc2b10a9294 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -8,9 +8,11 @@ pub use self::if_arc::*; #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] mod if_arc { use super::*; - use core::marker::PhantomData; - use core::mem; - use core::ptr::{self, NonNull}; + use core::{ + marker::PhantomData, + mem, + ptr::{self, NonNull}, + }; use crate::sync::Arc; /// A way of waking up a specific task. diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index 2759b1b1cac27..b71cf3bd47795 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -1,7 +1,9 @@ -use std::any::Any; -use std::sync::{Arc, Weak}; -use std::cell::RefCell; -use std::cmp::PartialEq; +use std::{ + any::Any, + sync::{Arc, Weak}, + cell::RefCell, + cmp::PartialEq, +}; #[test] fn uninhabited() { diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 94ae43237d19c..f19d641fe83eb 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -1,8 +1,9 @@ -use std::cmp; -use std::collections::BinaryHeap; -use std::collections::binary_heap::{Drain, PeekMut}; -use std::panic::{self, AssertUnwindSafe}; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{ + cmp, + collections::{BinaryHeap, binary_heap::{Drain, PeekMut}}, + panic::{self, AssertUnwindSafe}, + sync::atomic::{AtomicUsize, Ordering}, +}; use rand::{thread_rng, seq::SliceRandom}; diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 05e0bdffaa86b..33f65980784a1 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -1,9 +1,10 @@ -use std::collections::BTreeMap; -use std::collections::btree_map::Entry::{Occupied, Vacant}; -use std::ops::Bound::{self, Excluded, Included, Unbounded}; -use std::rc::Rc; +use std::{ + collections::{BTreeMap, btree_map::Entry::{Occupied, Vacant}}, + ops::Bound::{self, Excluded, Included, Unbounded}, + rc::Rc, + iter::FromIterator, +}; -use std::iter::FromIterator; use super::DeterministicRng; #[test] diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index e24c04fd8acb3..b90ecd9e3f136 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -1,6 +1,7 @@ -use std::collections::BTreeSet; - -use std::iter::FromIterator; +use std::{ + collections::BTreeSet, + iter::FromIterator +}; use super::DeterministicRng; #[test] @@ -15,6 +16,8 @@ fn test_clone_eq() { #[test] fn test_hash() { + use crate::hash; + let mut x = BTreeSet::new(); let mut y = BTreeSet::new(); @@ -26,7 +29,7 @@ fn test_hash() { y.insert(2); y.insert(1); - assert!(::hash(&x) == ::hash(&y)); + assert!(hash(&x) == hash(&y)); } fn check(a: &[i32], b: &[i32], expected: &[i32], f: F) diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index a76fd87a1a92d..100b3986370ab 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -13,8 +13,10 @@ extern crate core; extern crate rand; -use std::hash::{Hash, Hasher}; -use std::collections::hash_map::DefaultHasher; +use std::{ + hash::{Hash, Hasher}, + collections::hash_map::DefaultHasher, +}; mod arc; mod binary_heap; diff --git a/src/liballoc/tests/linked_list.rs b/src/liballoc/tests/linked_list.rs index 6e775f9650d12..0fbfbdccd4537 100644 --- a/src/liballoc/tests/linked_list.rs +++ b/src/liballoc/tests/linked_list.rs @@ -241,10 +241,12 @@ fn test_eq() { #[test] fn test_hash() { + use crate::hash; + let mut x = LinkedList::new(); let mut y = LinkedList::new(); - assert!(::hash(&x) == ::hash(&y)); + assert!(hash(&x) == hash(&y)); x.push_back(1); x.push_back(2); @@ -254,7 +256,7 @@ fn test_hash() { y.push_front(2); y.push_front(1); - assert!(::hash(&x) == ::hash(&y)); + assert!(hash(&x) == hash(&y)); } #[test] diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index 18f82e8041008..caa3c914fc248 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -1,7 +1,9 @@ -use std::any::Any; -use std::rc::{Rc, Weak}; -use std::cell::RefCell; -use std::cmp::PartialEq; +use std::{ + any::Any, + rc::{Rc, Weak}, + cell::RefCell, + cmp::PartialEq, +}; #[test] fn uninhabited() { diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 0300bd7f3f6d4..d0a8b65ae8be0 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1,15 +1,18 @@ -use std::cell::Cell; -use std::cmp::Ordering::{Equal, Greater, Less}; -use std::cmp::Ordering; -use std::mem; -use std::panic; -use std::rc::Rc; -use std::sync::atomic::Ordering::Relaxed; -use std::sync::atomic::AtomicUsize; -use std::thread; - -use rand::{Rng, RngCore, thread_rng, seq::SliceRandom}; -use rand::distributions::Standard; +use std::{ + cell::Cell, + cmp::Ordering::{self, Equal, Greater, Less}, + mem, + panic, + rc::Rc, + sync::atomic::{Ordering::Relaxed, AtomicUsize}, + thread, +}; + +use rand::{ + Rng, RngCore, thread_rng, + seq::SliceRandom, + distributions::Standard, +}; fn square(n: usize) -> usize { n * n @@ -476,7 +479,7 @@ fn test_sort_stability() { // the second item represents which occurrence of that // number this element is, i.e., the second elements // will occur in sorted order. - let mut orig: Vec<_> = (0..len) + let orig: Vec<_> = (0..len) .map(|_| { let n = thread_rng().gen::() % 10; counts[n] += 1; diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 66a1b947a7d3a..583e616bf6d75 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1,6 +1,8 @@ -use std::borrow::Cow; -use std::cmp::Ordering::{Equal, Greater, Less}; -use std::str::from_utf8; +use std::{ + borrow::Cow, + cmp::Ordering::{Equal, Greater, Less}, + str::from_utf8, +}; #[test] fn test_le() { @@ -1599,9 +1601,10 @@ fn test_repeat() { } mod pattern { - use std::str::pattern::Pattern; - use std::str::pattern::{Searcher, ReverseSearcher}; - use std::str::pattern::SearchStep::{self, Match, Reject, Done}; + use std::str::pattern::{ + Pattern, Searcher, ReverseSearcher, + SearchStep::{self, Match, Reject, Done}, + }; macro_rules! make_test { ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => { diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 8a5bfca8b7db5..9e4ffb5be9d6e 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -1,7 +1,9 @@ -use std::borrow::Cow; -use std::collections::CollectionAllocErr::*; -use std::mem::size_of; -use std::{usize, isize}; +use std::{ + borrow::Cow, + collections::CollectionAllocErr::*, + mem::size_of, + usize, isize, +}; pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { fn into_cow(self) -> Cow<'a, B>; diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 0fdcf34c783a8..473d41d483eff 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,8 +1,10 @@ -use std::borrow::Cow; -use std::mem::size_of; -use std::{usize, isize}; -use std::vec::{Drain, IntoIter}; -use std::collections::CollectionAllocErr::*; +use std::{ + borrow::Cow, + mem::size_of, + usize, isize, + vec::{Drain, IntoIter}, + collections::CollectionAllocErr::*, +}; struct DropCounter<'a> { count: &'a mut u32, diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index c9d16a06b4773..cbc9fefcdff9e 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1,9 +1,14 @@ -use std::collections::VecDeque; -use std::fmt::Debug; -use std::collections::vec_deque::{Drain}; -use std::collections::CollectionAllocErr::*; -use std::mem::size_of; -use std::{usize, isize}; +use std::{ + fmt::Debug, + collections::{ + VecDeque, vec_deque::Drain, + CollectionAllocErr::*, + }, + mem::size_of, + usize, isize, +}; + +use crate::hash; use self::Taggy::*; use self::Taggypar::*; @@ -583,7 +588,7 @@ fn test_hash() { y.push_back(2); y.push_back(3); - assert!(::hash(&x) == ::hash(&y)); + assert!(hash(&x) == hash(&y)); } #[test] @@ -599,7 +604,7 @@ fn test_hash_after_rotation() { *elt -= 1; } ring.push_back(len - 1); - assert_eq!(::hash(&orig), ::hash(&ring)); + assert_eq!(hash(&orig), hash(&ring)); assert_eq!(orig, ring); assert_eq!(ring, orig); } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b942bce678b97..69fcd87dae697 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -56,25 +56,30 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::cmp::{self, Ordering}; -use core::fmt; -use core::hash::{self, Hash}; -use core::intrinsics::{arith_offset, assume}; -use core::iter::{FromIterator, FusedIterator, TrustedLen}; -use core::marker::PhantomData; -use core::mem; -use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{Index, IndexMut, RangeBounds}; -use core::ops; -use core::ptr; -use core::ptr::NonNull; -use core::slice; - -use crate::collections::CollectionAllocErr; -use crate::borrow::ToOwned; -use crate::borrow::Cow; -use crate::boxed::Box; -use crate::raw_vec::RawVec; +use core::{ + cmp::{self, Ordering}, + fmt, + hash::{self, Hash}, + intrinsics::{arith_offset, assume}, + iter::{FromIterator, FusedIterator, TrustedLen}, + marker::PhantomData, + mem, + ops::{ + self, + Bound::{Excluded, Included, Unbounded}, + Index, IndexMut, RangeBounds, + }, + ptr::{self, NonNull}, + slice, +}; + +use crate::{ + collections::CollectionAllocErr, + borrow::ToOwned, + borrow::Cow, + boxed::Box, + raw_vec::RawVec, +}; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. /// @@ -1646,7 +1651,7 @@ impl Clone for Vec { // NB see the slice::hack module in slice.rs for more information #[cfg(test)] fn clone(&self) -> Vec { - ::slice::to_vec(&**self) + crate::slice::to_vec(&**self) } fn clone_from(&mut self, other: &Vec) { @@ -2193,7 +2198,7 @@ impl<'a, T: Clone> From<&'a [T]> for Vec { } #[cfg(test)] fn from(s: &'a [T]) -> Vec { - ::slice::to_vec(s) + crate::slice::to_vec(s) } } @@ -2205,7 +2210,7 @@ impl<'a, T: Clone> From<&'a mut [T]> for Vec { } #[cfg(test)] fn from(s: &'a mut [T]) -> Vec { - ::slice::to_vec(s) + crate::slice::to_vec(s) } } From f09f62f62c401a42bf338a23f8721c7f5a28a800 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 10:34:36 +0100 Subject: [PATCH 0529/1064] liballoc: adjust abolute imports + more import fixes. --- src/liballoc/lib.rs | 2 +- src/liballoc/raw_vec.rs | 2 +- src/liballoc/rc.rs | 3 +-- src/liballoc/slice.rs | 4 +--- src/liballoc/string.rs | 2 +- src/liballoc/sync.rs | 3 +-- src/liballoc/tests/btree/map.rs | 2 +- src/liballoc/tests/str.rs | 4 ++-- src/liballoc/tests/string.rs | 4 ++-- src/liballoc/tests/vec.rs | 2 +- src/liballoc/vec.rs | 12 +++--------- 11 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5165a7ca5a8f3..5d69b10054719 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -165,5 +165,5 @@ pub mod vec; #[cfg(not(test))] mod std { - pub use core::ops; // RangeFull + pub use core::ops; // RangeFull } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 92d482b1f052a..016185791edb6 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -736,7 +736,7 @@ unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec { #[inline] fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> { - if mem::size_of::() < 8 && alloc_size > ::core::isize::MAX as usize { + if mem::size_of::() < 8 && alloc_size > core::isize::MAX as usize { Err(CapacityOverflow) } else { Ok(()) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 720ac4b630aee..c24e216383974 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -244,6 +244,7 @@ use core::{ ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}, pin::Pin, ptr::{self, NonNull}, + slice::from_raw_parts_mut, convert::From, usize, }; @@ -768,8 +769,6 @@ impl RcFromSlice for Rc<[T]> { impl Drop for Guard { fn drop(&mut self) { - use core::slice::from_raw_parts_mut; - unsafe { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 1cee3aa415b8b..771d8f5d3473c 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -141,13 +141,11 @@ pub use self::hack::to_vec; // `test_permutations` test mod hack { use core::mem; - use crate::boxed::Box; + use crate::{boxed::Box, vec::Vec}; #[cfg(test)] use crate::string::ToString; - use crate::vec::Vec; - pub fn into_vec(mut b: Box<[T]>) -> Vec { unsafe { let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len()); diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index e9da10b3597f2..95f6b28a16817 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2165,7 +2165,7 @@ pub trait ToString { impl ToString for T { #[inline] default fn to_string(&self) -> String { - use core::fmt::Write; + use fmt::Write; let mut buf = String::new(); buf.write_fmt(format_args!("{}", self)) .expect("a Display implementation returned an error unexpectedly"); diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 2a4b3113bfe75..5e7a26132cb13 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -24,6 +24,7 @@ use core::{ hash::{Hash, Hasher}, isize, usize, convert::From, + slice::from_raw_parts_mut, }; use crate::{ @@ -677,8 +678,6 @@ impl ArcFromSlice for Arc<[T]> { impl Drop for Guard { fn drop(&mut self) { - use core::slice::from_raw_parts_mut; - unsafe { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 33f65980784a1..6859b0138b5ed 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -200,7 +200,7 @@ fn test_range_inclusive() { #[test] fn test_range_inclusive_max_value() { - let max = ::std::usize::MAX; + let max = std::usize::MAX; let map: BTreeMap<_, _> = vec![(max, 0)].into_iter().collect(); assert_eq!(map.range(max..=max).collect::>(), &[(&max, &0)]); diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 583e616bf6d75..28e021c741e7d 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1070,7 +1070,7 @@ fn test_rev_iterator() { #[test] fn test_chars_decoding() { let mut bytes = [0; 4]; - for c in (0..0x110000).filter_map(::std::char::from_u32) { + for c in (0..0x110000).filter_map(std::char::from_u32) { let s = c.encode_utf8(&mut bytes); if Some(c) != s.chars().next() { panic!("character {:x}={} does not decode correctly", c as u32, c); @@ -1081,7 +1081,7 @@ fn test_chars_decoding() { #[test] fn test_chars_rev_decoding() { let mut bytes = [0; 4]; - for c in (0..0x110000).filter_map(::std::char::from_u32) { + for c in (0..0x110000).filter_map(std::char::from_u32) { let s = c.encode_utf8(&mut bytes); if Some(c) != s.chars().rev().next() { panic!("character {:x}={} does not decode correctly", c as u32, c); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 9e4ffb5be9d6e..14f70fdf3034d 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -23,7 +23,7 @@ impl<'a> IntoCow<'a, str> for &'a str { #[test] fn test_from_str() { - let owned: Option<::std::string::String> = "string".parse().ok(); + let owned: Option = "string".parse().ok(); assert_eq!(owned.as_ref().map(|s| &**s), Some("string")); } @@ -124,7 +124,7 @@ fn test_from_utf16() { let s_as_utf16 = s.encode_utf16().collect::>(); let u_as_string = String::from_utf16(&u).unwrap(); - assert!(::core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok())); + assert!(core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok())); assert_eq!(s_as_utf16, u); assert_eq!(u_as_string, s); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 473d41d483eff..b65c68d51a502 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -640,7 +640,7 @@ fn test_splice_unbounded() { fn test_splice_forget() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; - ::std::mem::forget(v.splice(2..4, a.iter().cloned())); + std::mem::forget(v.splice(2..4, a.iter().cloned())); assert_eq!(v, &[1, 2]); } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 69fcd87dae697..2ef1497ade715 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -70,7 +70,7 @@ use core::{ Index, IndexMut, RangeBounds, }, ptr::{self, NonNull}, - slice, + slice::{self, SliceIndex}, }; use crate::{ @@ -1672,10 +1672,7 @@ impl Hash for Vec { message="vector indices are of type `usize` or ranges of `usize`", label="vector indices are of type `usize` or ranges of `usize`", )] -impl Index for Vec -where - I: ::core::slice::SliceIndex<[T]>, -{ +impl> Index for Vec { type Output = I::Output; #[inline] @@ -1689,10 +1686,7 @@ where message="vector indices are of type `usize` or ranges of `usize`", label="vector indices are of type `usize` or ranges of `usize`", )] -impl IndexMut for Vec -where - I: ::core::slice::SliceIndex<[T]>, -{ +impl> IndexMut for Vec { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { IndexMut::index_mut(&mut **self, index) From 3bfa0a35f65b08197fe677731ac8a9a81a7710bd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 10:53:27 +0100 Subject: [PATCH 0530/1064] liballoc: prefer imports of borrow from libcore. --- src/liballoc/collections/btree/map.rs | 3 +-- src/liballoc/collections/btree/search.rs | 7 ++++--- src/liballoc/collections/btree/set.rs | 6 ++---- src/liballoc/slice.rs | 3 ++- src/liballoc/str.rs | 3 ++- src/liballoc/string.rs | 2 +- src/liballoc/vec.rs | 3 +-- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index f81cf6f104719..b1a5fcbe6b6c2 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1,4 +1,5 @@ use core::{ + borrow::Borrow, cmp::Ordering, fmt::Debug, hash::{Hash, Hasher}, @@ -11,8 +12,6 @@ use core::{ fmt, intrinsics, mem, ptr, }; -use crate::borrow::Borrow; - use super::{ node::{self, Handle, NodeRef, marker, InsertResult::*, ForceResult::*}, search::{self, SearchResult::*}, diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index a3b56ad17c6b7..23c41b4dd4ceb 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -1,6 +1,7 @@ -use core::cmp::Ordering; - -use crate::borrow::Borrow; +use core::{ + borrow::Borrow, + cmp::Ordering, +}; use super::node::{Handle, NodeRef, marker, ForceResult::*}; diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 298d165a91afa..9231d2e67cf81 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -2,6 +2,7 @@ // to TreeMap use core::{ + borrow::Borrow, cmp::{ Ordering::{self, Less, Greater, Equal}, min, max, @@ -11,10 +12,7 @@ use core::{ ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}, }; -use crate::{ - borrow::Borrow, - collections::btree_map::{self, BTreeMap, Keys}, -}; +use crate::collections::btree_map::{self, BTreeMap, Keys}; use super::Recover; // FIXME(conventions): implement bounded iterators diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 771d8f5d3473c..5e17396f6d7a9 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -88,6 +88,7 @@ #![cfg_attr(test, allow(unused_imports, dead_code))] use core::{ + borrow::{Borrow, BorrowMut}, cmp::Ordering::{self, Less}, mem::{self, size_of}, ptr, @@ -95,7 +96,7 @@ use core::{ }; use crate::{ - borrow::{Borrow, BorrowMut, ToOwned}, + borrow::ToOwned, boxed::Box, vec::Vec, }; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 85437defd5733..9681572d883f5 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -29,6 +29,7 @@ #![allow(unused_imports)] use core::{ + borrow::Borrow, fmt, str::{ self as core_str, @@ -41,7 +42,7 @@ use core::{ }; use crate::{ - borrow::{Borrow, ToOwned}, + borrow::ToOwned, boxed::Box, slice::{SliceConcatExt, SliceIndex}, string::String, diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 95f6b28a16817..d74a3f004a305 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -64,8 +64,8 @@ use core::{ }; use crate::{ - collections::CollectionAllocErr, borrow::{Cow, ToOwned}, + collections::CollectionAllocErr, boxed::Box, str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}, vec::Vec, diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 2ef1497ade715..8e09720688156 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -74,9 +74,8 @@ use core::{ }; use crate::{ + borrow::{ToOwned, Cow}, collections::CollectionAllocErr, - borrow::ToOwned, - borrow::Cow, boxed::Box, raw_vec::RawVec, }; From cbbf8a7ff932b599227b27d34e9b015374f5b37a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 11:00:55 +0100 Subject: [PATCH 0531/1064] deprecate things a bit slower --- src/libstd/sys/redox/ext/process.rs | 2 +- src/libstd/sys/unix/ext/process.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 78917ea91886b..4e669bbb2d7dc 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -65,7 +65,7 @@ pub trait CommandExt { /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] - #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] + #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 7cc5e9945938d..da0507c65423d 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -65,7 +65,7 @@ pub trait CommandExt { /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] - #[rustc_deprecated(since = "1.34.0", reason = "should be unsafe, use `pre_exec` instead")] + #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { From 748970dfa9c12c1a09da4ff3ec724e4dbf7e796d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 11:05:20 +0100 Subject: [PATCH 0532/1064] liballoc: apply uniform_paths. --- src/liballoc/alloc.rs | 2 +- src/liballoc/borrow.rs | 8 ++++---- src/liballoc/collections/btree/map.rs | 3 ++- src/liballoc/collections/btree/search.rs | 2 +- src/liballoc/collections/mod.rs | 10 +++++----- src/liballoc/raw_vec.rs | 4 ++-- src/liballoc/slice.rs | 4 ++-- src/liballoc/task.rs | 2 +- src/liballoc/tests/vec_deque.rs | 4 ++-- 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index bb88897323eaf..515de9852d1a6 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -229,7 +229,7 @@ pub fn handle_alloc_error(layout: Layout) -> ! { #[cfg(test)] mod tests { extern crate test; - use self::test::Bencher; + use test::Bencher; use crate::{ boxed::Box, alloc::{Global, Alloc, Layout, handle_alloc_error}, diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 8161d588fbdb8..c1696005373a0 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -8,13 +8,13 @@ use core::{ ops::{Add, AddAssign, Deref}, }; -use crate::{fmt, string::String}; - -use self::Cow::*; - #[stable(feature = "rust1", since = "1.0.0")] pub use core::borrow::{Borrow, BorrowMut}; +use crate::{fmt, string::String}; + +use Cow::*; + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: ?Sized> Borrow for Cow<'a, B> where B: ToOwned, diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index b1a5fcbe6b6c2..d0e35c557a4d0 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -17,7 +17,8 @@ use super::{ search::{self, SearchResult::*}, }; -use self::{UnderflowResult::*, Entry::*}; +use UnderflowResult::*; +use Entry::*; /// A map based on a B-Tree. /// diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 23c41b4dd4ceb..1645e48cb5299 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -5,7 +5,7 @@ use core::{ use super::node::{Handle, NodeRef, marker, ForceResult::*}; -use self::SearchResult::*; +use SearchResult::*; pub enum SearchResult { Found(Handle, marker::KV>), diff --git a/src/liballoc/collections/mod.rs b/src/liballoc/collections/mod.rs index 5f3f849373091..5a33ddc14f004 100644 --- a/src/liballoc/collections/mod.rs +++ b/src/liballoc/collections/mod.rs @@ -23,23 +23,23 @@ pub mod btree_set { #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use self::binary_heap::BinaryHeap; +pub use binary_heap::BinaryHeap; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use self::btree_map::BTreeMap; +pub use btree_map::BTreeMap; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use self::btree_set::BTreeSet; +pub use btree_set::BTreeSet; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use self::linked_list::LinkedList; +pub use linked_list::LinkedList; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use self::vec_deque::VecDeque; +pub use vec_deque::VecDeque; use crate::alloc::{AllocErr, LayoutErr}; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 016185791edb6..f1839f736341c 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -624,14 +624,14 @@ enum Fallibility { Infallible, } -use self::Fallibility::*; +use Fallibility::*; enum ReserveStrategy { Exact, Amortized, } -use self::ReserveStrategy::*; +use ReserveStrategy::*; impl RawVec { fn reserve_internal( diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 5e17396f6d7a9..9d1197117bbda 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -129,12 +129,12 @@ pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut}; // HACK(japaric) needed for the implementation of `vec!` macro during testing // NB see the hack module in this file for more details #[cfg(test)] -pub use self::hack::into_vec; +pub use hack::into_vec; // HACK(japaric) needed for the implementation of `Vec::clone` during testing // NB see the hack module in this file for more details #[cfg(test)] -pub use self::hack::to_vec; +pub use hack::to_vec; // HACK(japaric): With cfg(test) `impl [T]` is not available, these three // functions are actually methods that are in `impl [T]` but not in diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index 89dc2b10a9294..0bf1ff35cc175 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -3,7 +3,7 @@ pub use core::task::*; #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] -pub use self::if_arc::*; +pub use if_arc::*; #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] mod if_arc { diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index cbc9fefcdff9e..44183956d8fc7 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -10,8 +10,8 @@ use std::{ use crate::hash; -use self::Taggy::*; -use self::Taggypar::*; +use Taggy::*; +use Taggypar::*; #[test] fn test_simple() { From 6c67a7625fbd38b4b986981c553dc7eb5a7a4765 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 11:05:43 +0100 Subject: [PATCH 0533/1064] pre_exec: expand docs --- src/libstd/sys/redox/ext/process.rs | 7 ++++--- src/libstd/sys/unix/ext/process.rs | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 4e669bbb2d7dc..55824dc4c059f 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -48,7 +48,8 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. + /// invalid use of these duplicates. Moreover, POSIX demands that you only + /// perform operations that are explicitly documented as async-signal-safe. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these @@ -60,8 +61,8 @@ pub trait CommandExt { /// Schedules a closure to be run just before the `exec` function is /// invoked. /// - /// This method should be unsafe, so it got deprecated in favor of the - /// unsafe [`pre_exec`]. + /// This method is stable and usable, but it should be unsafe. To fix + /// that, it got deprecated in favor of the unsafe [`pre_exec`]. /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index da0507c65423d..ac0abc761ffb5 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -48,7 +48,8 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. + /// invalid use of these duplicates. Moreover, POSIX demands that you only + /// perform operations that are explicitly documented as async-signal-safe. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these @@ -60,8 +61,8 @@ pub trait CommandExt { /// Schedules a closure to be run just before the `exec` function is /// invoked. /// - /// This method should be unsafe, so it got deprecated in favor of the - /// unsafe [`pre_exec`]. + /// This method is stable and usable, but it should be unsafe. To fix + /// that, it got deprecated in favor of the unsafe [`pre_exec`]. /// /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] From 59da97d2b2d0e3d4baf70cd6fdf49c31c7def380 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 11:08:21 +0100 Subject: [PATCH 0534/1064] rustfmt the test --- src/test/run-pass/command-pre-exec.rs | 92 ++++++++++++++++++--------- 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/src/test/run-pass/command-pre-exec.rs b/src/test/run-pass/command-pre-exec.rs index bca2b8410fa84..21783fedd39c9 100644 --- a/src/test/run-pass/command-pre-exec.rs +++ b/src/test/run-pass/command-pre-exec.rs @@ -2,7 +2,6 @@ // ignore-windows - this is a unix-specific test // ignore-cloudabi no processes // ignore-emscripten no processes - #![feature(process_exec, rustc_private)] extern crate libc; @@ -11,71 +10,104 @@ use std::env; use std::io::Error; use std::os::unix::process::CommandExt; use std::process::Command; -use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; fn main() { if let Some(arg) = env::args().nth(1) { match &arg[..] { "test1" => println!("hello2"), "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), - "test3" => assert_eq!(env::current_dir().unwrap() - .to_str().unwrap(), "/"), + "test3" => assert_eq!(env::current_dir().unwrap().to_str().unwrap(), "/"), "empty" => {} _ => panic!("unknown argument: {}", arg), } - return + return; } let me = env::current_exe().unwrap(); - let output = unsafe { Command::new(&me).arg("test1").pre_exec(|| { - println!("hello"); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("test1") + .pre_exec(|| { + println!("hello"); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert_eq!(output.stdout, b"hello\nhello2\n"); - let output = unsafe { Command::new(&me).arg("test2").pre_exec(|| { - env::set_var("FOO", "BAR"); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("test2") + .pre_exec(|| { + env::set_var("FOO", "BAR"); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); - let output = unsafe { Command::new(&me).arg("test3").pre_exec(|| { - env::set_current_dir("/").unwrap(); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("test3") + .pre_exec(|| { + env::set_current_dir("/").unwrap(); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); - let output = unsafe { Command::new(&me).arg("bad").pre_exec(|| { - Err(Error::from_raw_os_error(102)) - }).output().unwrap_err() }; + let output = unsafe { + Command::new(&me) + .arg("bad") + .pre_exec(|| Err(Error::from_raw_os_error(102))) + .output() + .unwrap_err() + }; assert_eq!(output.raw_os_error(), Some(102)); let pid = unsafe { libc::getpid() }; assert!(pid >= 0); - let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { - let child = libc::getpid(); - assert!(child >= 0); - assert!(pid != child); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + let child = libc::getpid(); + assert!(child >= 0); + assert!(pid != child); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); let mem = Arc::new(AtomicUsize::new(0)); let mem2 = mem.clone(); - let output = unsafe { Command::new(&me).arg("empty").pre_exec(move || { - assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); - Ok(()) - }).output().unwrap() }; + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); + Ok(()) + }) + .output() + .unwrap() + }; assert!(output.status.success()); assert!(output.stderr.is_empty()); assert!(output.stdout.is_empty()); From e70c2fbd5cbe8bf176f1ed01ba9a53cec7e842a5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 12:23:15 +0100 Subject: [PATCH 0535/1064] liballoc: elide some lifetimes. --- src/liballoc/borrow.rs | 20 ++++-------- src/liballoc/boxed.rs | 4 +-- src/liballoc/collections/binary_heap.rs | 24 +++++++------- src/liballoc/collections/btree/map.rs | 43 ++++++++++++------------- src/liballoc/collections/btree/set.rs | 32 +++++++++--------- src/liballoc/collections/linked_list.rs | 22 ++++++------- src/liballoc/collections/vec_deque.rs | 42 ++++++++++++------------ src/liballoc/string.rs | 20 ++++++------ src/liballoc/sync.rs | 4 +-- src/liballoc/tests/vec.rs | 2 +- src/liballoc/tests/vec_deque.rs | 2 +- src/liballoc/vec.rs | 30 ++++++++--------- 12 files changed, 119 insertions(+), 126 deletions(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index c1696005373a0..816cdbc9ce673 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -183,9 +183,7 @@ pub enum Cow<'a, B: ?Sized + 'a> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, B: ?Sized> Clone for Cow<'a, B> - where B: ToOwned -{ +impl<'a, B: ?Sized + ToOwned> Clone for Cow<'a, B> { fn clone(&self) -> Cow<'a, B> { match *self { Borrowed(b) => Borrowed(b), @@ -208,9 +206,7 @@ impl<'a, B: ?Sized> Clone for Cow<'a, B> } } -impl<'a, B: ?Sized> Cow<'a, B> - where B: ToOwned -{ +impl Cow<'_, B> { /// Acquires a mutable reference to the owned form of the data. /// /// Clones the data if it is not already owned. @@ -286,9 +282,7 @@ impl<'a, B: ?Sized> Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, B: ?Sized> Deref for Cow<'a, B> - where B: ToOwned -{ +impl Deref for Cow<'_, B> { type Target = B; fn deref(&self) -> &B { @@ -300,7 +294,7 @@ impl<'a, B: ?Sized> Deref for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {} +impl Eq for Cow<'_, B> where B: Eq + ToOwned {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: ?Sized> Ord for Cow<'a, B> @@ -334,7 +328,7 @@ impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> +impl fmt::Debug for Cow<'_, B> where B: fmt::Debug + ToOwned, ::Owned: fmt::Debug { @@ -347,7 +341,7 @@ impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> +impl fmt::Display for Cow<'_, B> where B: fmt::Display + ToOwned, ::Owned: fmt::Display { @@ -381,7 +375,7 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { +impl AsRef for Cow<'_, T> { fn as_ref(&self) -> &T { self } diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index f590b6488d9da..6f6fff0a657d0 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -739,7 +739,7 @@ impl FnBox
    for F #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] -impl<'a, A, R> FnOnce for Box + 'a> { +impl FnOnce for Box + '_> { type Output = R; extern "rust-call" fn call_once(self, args: A) -> R { @@ -749,7 +749,7 @@ impl<'a, A, R> FnOnce for Box + 'a> { #[unstable(feature = "fnbox", reason = "will be deprecated if and when `Box` becomes usable", issue = "28796")] -impl<'a, A, R> FnOnce for Box + Send + 'a> { +impl FnOnce for Box + Send + '_> { type Output = R; extern "rust-call" fn call_once(self, args: A) -> R { diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 4a38f041636ef..43416e57591bc 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -231,7 +231,7 @@ pub struct PeekMut<'a, T: 'a + Ord> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: Ord + fmt::Debug> fmt::Debug for PeekMut<'a, T> { +impl fmt::Debug for PeekMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("PeekMut") .field(&self.heap.data[0]) @@ -240,7 +240,7 @@ impl<'a, T: Ord + fmt::Debug> fmt::Debug for PeekMut<'a, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl<'a, T: Ord> Drop for PeekMut<'a, T> { +impl Drop for PeekMut<'_, T> { fn drop(&mut self) { if self.sift { self.heap.sift_down(0); @@ -249,7 +249,7 @@ impl<'a, T: Ord> Drop for PeekMut<'a, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl<'a, T: Ord> Deref for PeekMut<'a, T> { +impl Deref for PeekMut<'_, T> { type Target = T; fn deref(&self) -> &T { &self.heap.data[0] @@ -257,7 +257,7 @@ impl<'a, T: Ord> Deref for PeekMut<'a, T> { } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] -impl<'a, T: Ord> DerefMut for PeekMut<'a, T> { +impl DerefMut for PeekMut<'_, T> { fn deref_mut(&mut self) -> &mut T { &mut self.heap.data[0] } @@ -912,7 +912,7 @@ impl<'a, T> Hole<'a, T> { } } -impl<'a, T> Drop for Hole<'a, T> { +impl Drop for Hole<'_, T> { #[inline] fn drop(&mut self) { // fill the hole again @@ -936,7 +936,7 @@ pub struct Iter<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { +impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Iter") .field(&self.iter.as_slice()) @@ -976,14 +976,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for Iter<'a, T> { +impl ExactSizeIterator for Iter<'_, T> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Iter<'a, T> {} +impl FusedIterator for Iter<'_, T> {} /// An owning iterator over the elements of a `BinaryHeap`. /// @@ -1054,7 +1054,7 @@ pub struct Drain<'a, T: 'a> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> Iterator for Drain<'a, T> { +impl Iterator for Drain<'_, T> { type Item = T; #[inline] @@ -1069,7 +1069,7 @@ impl<'a, T: 'a> Iterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { +impl DoubleEndedIterator for Drain<'_, T> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1077,14 +1077,14 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> { +impl ExactSizeIterator for Drain<'_, T> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T: 'a> FusedIterator for Drain<'a, T> {} +impl FusedIterator for Drain<'_, T> {} #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] impl From> for BinaryHeap { diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index d0e35c557a4d0..27f162b114736 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -279,7 +279,7 @@ pub struct Iter<'a, K: 'a, V: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Iter<'a, K, V> { +impl fmt::Debug for Iter<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } @@ -337,7 +337,7 @@ pub struct Keys<'a, K: 'a, V: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, K: 'a + fmt::Debug, V: 'a> fmt::Debug for Keys<'a, K, V> { +impl fmt::Debug for Keys<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } @@ -356,7 +356,7 @@ pub struct Values<'a, K: 'a, V: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, K: 'a, V: 'a + fmt::Debug> fmt::Debug for Values<'a, K, V> { +impl fmt::Debug for Values<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } @@ -389,7 +389,7 @@ pub struct Range<'a, K: 'a, V: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Range<'a, K, V> { +impl fmt::Debug for Range<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } @@ -412,7 +412,7 @@ pub struct RangeMut<'a, K: 'a, V: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for RangeMut<'a, K, V> { +impl fmt::Debug for RangeMut<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let range = Range { front: self.front.reborrow(), @@ -442,7 +442,7 @@ pub enum Entry<'a, K: 'a, V: 'a> { } #[stable(feature= "debug_btree_map", since = "1.12.0")] -impl<'a, K: 'a + Debug + Ord, V: 'a + Debug> Debug for Entry<'a, K, V> { +impl Debug for Entry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Vacant(ref v) => f.debug_tuple("Entry") @@ -470,7 +470,7 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> { } #[stable(feature= "debug_btree_map", since = "1.12.0")] -impl<'a, K: 'a + Debug + Ord, V: 'a> Debug for VacantEntry<'a, K, V> { +impl Debug for VacantEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("VacantEntry") .field(self.key()) @@ -493,7 +493,7 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { } #[stable(feature= "debug_btree_map", since = "1.12.0")] -impl<'a, K: 'a + Debug + Ord, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> { +impl Debug for OccupiedEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("OccupiedEntry") .field("key", self.key()) @@ -1202,7 +1202,7 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for Iter<'a, K, V> {} +impl FusedIterator for Iter<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> { @@ -1217,7 +1217,7 @@ impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K: 'a, V: 'a> ExactSizeIterator for Iter<'a, K, V> { +impl ExactSizeIterator for Iter<'_, K, V> { fn len(&self) -> usize { self.length } @@ -1274,14 +1274,14 @@ impl<'a, K: 'a, V: 'a> DoubleEndedIterator for IterMut<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K: 'a, V: 'a> ExactSizeIterator for IterMut<'a, K, V> { +impl ExactSizeIterator for IterMut<'_, K, V> { fn len(&self) -> usize { self.length } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {} +impl FusedIterator for IterMut<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for BTreeMap { @@ -1437,14 +1437,14 @@ impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> { +impl ExactSizeIterator for Keys<'_, K, V> { fn len(&self) -> usize { self.inner.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for Keys<'a, K, V> {} +impl FusedIterator for Keys<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Clone for Keys<'a, K, V> { @@ -1474,14 +1474,14 @@ impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> { +impl ExactSizeIterator for Values<'_, K, V> { fn len(&self) -> usize { self.inner.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for Values<'a, K, V> {} +impl FusedIterator for Values<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Clone for Values<'a, K, V> { @@ -1524,15 +1524,14 @@ impl<'a, K, V> DoubleEndedIterator for ValuesMut<'a, K, V> { } #[stable(feature = "map_values_mut", since = "1.10.0")] -impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> { +impl ExactSizeIterator for ValuesMut<'_, K, V> { fn len(&self) -> usize { self.inner.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {} - +impl FusedIterator for ValuesMut<'_, K, V> {} impl<'a, K, V> Range<'a, K, V> { unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) { @@ -1610,7 +1609,7 @@ impl<'a, K, V> Range<'a, K, V> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for Range<'a, K, V> {} +impl FusedIterator for Range<'_, K, V> {} #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> Clone for Range<'a, K, V> { @@ -1679,7 +1678,7 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, K, V> FusedIterator for RangeMut<'a, K, V> {} +impl FusedIterator for RangeMut<'_, K, V> {} impl<'a, K, V> RangeMut<'a, K, V> { unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) { @@ -1790,7 +1789,7 @@ impl Debug for BTreeMap { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap +impl Index<&Q> for BTreeMap where K: Borrow, Q: Ord { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 9231d2e67cf81..9c50bd7e91866 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -79,7 +79,7 @@ pub struct Iter<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { +impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Iter") .field(&self.iter.clone()) @@ -127,7 +127,7 @@ pub struct Difference<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Difference<'a, T> { +impl fmt::Debug for Difference<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Difference") .field(&self.a) @@ -150,7 +150,7 @@ pub struct SymmetricDifference<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for SymmetricDifference<'a, T> { +impl fmt::Debug for SymmetricDifference<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("SymmetricDifference") .field(&self.a) @@ -173,7 +173,7 @@ pub struct Intersection<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Intersection<'a, T> { +impl fmt::Debug for Intersection<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Intersection") .field(&self.a) @@ -196,7 +196,7 @@ pub struct Union<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Union<'a, T> { +impl fmt::Debug for Union<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Union") .field(&self.a) @@ -812,7 +812,7 @@ impl Default for BTreeSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet> for &'a BTreeSet { +impl Sub<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the difference of `self` and `rhs` as a new `BTreeSet`. @@ -835,7 +835,7 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet> for &'a BTreeSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet> for &'a BTreeSet { +impl BitXor<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet`. @@ -858,7 +858,7 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet> for &'a BTreeSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet> for &'a BTreeSet { +impl BitAnd<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the intersection of `self` and `rhs` as a new `BTreeSet`. @@ -881,7 +881,7 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet> for &'a BTreeSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { +impl BitOr<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the union of `self` and `rhs` as a new `BTreeSet`. @@ -934,12 +934,12 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for Iter<'a, T> { +impl ExactSizeIterator for Iter<'_, T> { fn len(&self) -> usize { self.iter.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Iter<'a, T> {} +impl FusedIterator for Iter<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for IntoIter { @@ -990,7 +990,7 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Range<'a, T> {} +impl FusedIterator for Range<'_, T> {} /// Compare `x` and `y`, but return `short` if x is None and `long` if y is None fn cmp_opt(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering { @@ -1037,7 +1037,7 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T: Ord> FusedIterator for Difference<'a, T> {} +impl FusedIterator for Difference<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for SymmetricDifference<'a, T> { @@ -1071,7 +1071,7 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T: Ord> FusedIterator for SymmetricDifference<'a, T> {} +impl FusedIterator for SymmetricDifference<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Intersection<'a, T> { @@ -1109,7 +1109,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T: Ord> FusedIterator for Intersection<'a, T> {} +impl FusedIterator for Intersection<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Union<'a, T> { @@ -1143,4 +1143,4 @@ impl<'a, T: Ord> Iterator for Union<'a, T> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T: Ord> FusedIterator for Union<'a, T> {} +impl FusedIterator for Union<'_, T> {} diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 8f72c6babaf35..e2da0041b4a8d 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -63,7 +63,7 @@ pub struct Iter<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { +impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Iter") .field(&self.len) @@ -73,7 +73,7 @@ impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> Clone for Iter<'a, T> { +impl Clone for Iter<'_, T> { fn clone(&self) -> Self { Iter { ..*self } } @@ -95,7 +95,7 @@ pub struct IterMut<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { +impl fmt::Debug for IterMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IterMut") .field(&self.list) @@ -834,10 +834,10 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for Iter<'a, T> {} +impl ExactSizeIterator for Iter<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Iter<'a, T> {} +impl FusedIterator for Iter<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Iterator for IterMut<'a, T> { @@ -883,12 +883,12 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} +impl ExactSizeIterator for IterMut<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for IterMut<'a, T> {} +impl FusedIterator for IterMut<'_, T> {} -impl<'a, T> IterMut<'a, T> { +impl IterMut<'_, T> { /// Inserts the given element just after the element most recently returned by `.next()`. /// The inserted element does not appear in the iteration. /// @@ -984,7 +984,7 @@ pub struct DrainFilter<'a, T: 'a, F: 'a> } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<'a, T, F> Iterator for DrainFilter<'a, T, F> +impl Iterator for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { type Item = T; @@ -1011,7 +1011,7 @@ impl<'a, T, F> Iterator for DrainFilter<'a, T, F> } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<'a, T, F> Drop for DrainFilter<'a, T, F> +impl Drop for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { @@ -1020,7 +1020,7 @@ impl<'a, T, F> Drop for DrainFilter<'a, T, F> } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<'a, T: 'a + fmt::Debug, F> fmt::Debug for DrainFilter<'a, T, F> +impl fmt::Debug for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index de78783983d7c..abfb83d4139e1 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2086,7 +2086,7 @@ trait RingSlices: Sized { } } -impl<'a, T> RingSlices for &'a [T] { +impl RingSlices for &[T] { fn slice(self, from: usize, to: usize) -> Self { &self[from..to] } @@ -2095,7 +2095,7 @@ impl<'a, T> RingSlices for &'a [T] { } } -impl<'a, T> RingSlices for &'a mut [T] { +impl RingSlices for &mut [T] { fn slice(self, from: usize, to: usize) -> Self { &mut self[from..to] } @@ -2126,7 +2126,7 @@ pub struct Iter<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { +impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); f.debug_tuple("Iter") @@ -2206,14 +2206,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for Iter<'a, T> { +impl ExactSizeIterator for Iter<'_, T> { fn is_empty(&self) -> bool { self.head == self.tail } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Iter<'a, T> {} +impl FusedIterator for Iter<'_, T> {} /// A mutable iterator over the elements of a `VecDeque`. @@ -2231,7 +2231,7 @@ pub struct IterMut<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { +impl<'a, T: fmt::Debug> fmt::Debug for IterMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (front, back) = RingSlices::ring_slices(&*self.ring, self.head, self.tail); f.debug_tuple("IterMut") @@ -2299,14 +2299,14 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for IterMut<'a, T> { +impl ExactSizeIterator for IterMut<'_, T> { fn is_empty(&self) -> bool { self.head == self.tail } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for IterMut<'a, T> {} +impl FusedIterator for IterMut<'_, T> {} /// An owning iterator over the elements of a `VecDeque`. /// @@ -2380,7 +2380,7 @@ pub struct Drain<'a, T: 'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a, T: 'a + fmt::Debug> fmt::Debug for Drain<'a, T> { +impl fmt::Debug for Drain<'_, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Drain") .field(&self.after_tail) @@ -2391,12 +2391,12 @@ impl<'a, T: 'a + fmt::Debug> fmt::Debug for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {} +unsafe impl Sync for Drain<'_, T> {} #[stable(feature = "drain", since = "1.6.0")] -unsafe impl<'a, T: Send> Send for Drain<'a, T> {} +unsafe impl Send for Drain<'_, T> {} #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> Drop for Drain<'a, T> { +impl Drop for Drain<'_, T> { fn drop(&mut self) { self.for_each(drop); @@ -2443,7 +2443,7 @@ impl<'a, T: 'a> Drop for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> Iterator for Drain<'a, T> { +impl Iterator for Drain<'_, T> { type Item = T; #[inline] @@ -2458,7 +2458,7 @@ impl<'a, T: 'a> Iterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { +impl DoubleEndedIterator for Drain<'_, T> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| unsafe { ptr::read(elt) }) @@ -2466,10 +2466,10 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} +impl ExactSizeIterator for Drain<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T: 'a> FusedIterator for Drain<'a, T> {} +impl FusedIterator for Drain<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for VecDeque { @@ -2519,7 +2519,7 @@ macro_rules! __impl_slice_eq1 { }; ($Lhs: ty, $Rhs: ty, $Bound: ident) => { #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")] - impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { + impl PartialEq<$Rhs> for $Lhs where A: PartialEq { fn eq(&self, other: &$Rhs) -> bool { if self.len() != other.len() { return false; @@ -2533,15 +2533,15 @@ macro_rules! __impl_slice_eq1 { } __impl_slice_eq1! { VecDeque, Vec } -__impl_slice_eq1! { VecDeque, &'b [B] } -__impl_slice_eq1! { VecDeque, &'b mut [B] } +__impl_slice_eq1! { VecDeque, &[B] } +__impl_slice_eq1! { VecDeque, &mut [B] } macro_rules! array_impls { ($($N: expr)+) => { $( __impl_slice_eq1! { VecDeque, [B; $N] } - __impl_slice_eq1! { VecDeque, &'b [B; $N] } - __impl_slice_eq1! { VecDeque, &'b mut [B; $N] } + __impl_slice_eq1! { VecDeque, &[B; $N] } + __impl_slice_eq1! { VecDeque, &mut [B; $N] } )+ } } diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index d74a3f004a305..92d3e52d60c73 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1935,7 +1935,7 @@ impl hash::Hash for String { /// let c = a.to_string() + b; /// ``` #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> Add<&'a str> for String { +impl Add<&str> for String { type Output = String; #[inline] @@ -1949,7 +1949,7 @@ impl<'a> Add<&'a str> for String { /// /// This has the same behavior as the [`push_str`][String::push_str] method. #[stable(feature = "stringaddassign", since = "1.12.0")] -impl<'a> AddAssign<&'a str> for String { +impl AddAssign<&str> for String { #[inline] fn add_assign(&mut self, other: &str) { self.push_str(other); @@ -2183,7 +2183,7 @@ impl ToString for str { } #[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")] -impl<'a> ToString for Cow<'a, str> { +impl ToString for Cow<'_, str> { #[inline] fn to_string(&self) -> String { self[..].to_owned() @@ -2373,19 +2373,19 @@ pub struct Drain<'a> { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<'a> fmt::Debug for Drain<'a> { +impl fmt::Debug for Drain<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Drain { .. }") } } #[stable(feature = "drain", since = "1.6.0")] -unsafe impl<'a> Sync for Drain<'a> {} +unsafe impl Sync for Drain<'_> {} #[stable(feature = "drain", since = "1.6.0")] -unsafe impl<'a> Send for Drain<'a> {} +unsafe impl Send for Drain<'_> {} #[stable(feature = "drain", since = "1.6.0")] -impl<'a> Drop for Drain<'a> { +impl Drop for Drain<'_> { fn drop(&mut self) { unsafe { // Use Vec::drain. "Reaffirm" the bounds checks to avoid @@ -2399,7 +2399,7 @@ impl<'a> Drop for Drain<'a> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a> Iterator for Drain<'a> { +impl Iterator for Drain<'_> { type Item = char; #[inline] @@ -2413,7 +2413,7 @@ impl<'a> Iterator for Drain<'a> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a> DoubleEndedIterator for Drain<'a> { +impl DoubleEndedIterator for Drain<'_> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -2421,4 +2421,4 @@ impl<'a> DoubleEndedIterator for Drain<'a> { } #[stable(feature = "fused", since = "1.26.0")] -impl<'a> FusedIterator for Drain<'a> {} +impl FusedIterator for Drain<'_> {} diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 5e7a26132cb13..2512e27e316b7 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1605,7 +1605,7 @@ impl From for Arc { } #[stable(feature = "shared_from_slice", since = "1.21.0")] -impl<'a, T: Clone> From<&'a [T]> for Arc<[T]> { +impl From<&[T]> for Arc<[T]> { #[inline] fn from(v: &[T]) -> Arc<[T]> { >::from_slice(v) @@ -1613,7 +1613,7 @@ impl<'a, T: Clone> From<&'a [T]> for Arc<[T]> { } #[stable(feature = "shared_from_slice", since = "1.21.0")] -impl<'a> From<&'a str> for Arc { +impl From<&str> for Arc { #[inline] fn from(v: &str) -> Arc { let arc = Arc::<[u8]>::from(v.as_bytes()); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index b65c68d51a502..e8fea287e1cb4 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -10,7 +10,7 @@ struct DropCounter<'a> { count: &'a mut u32, } -impl<'a> Drop for DropCounter<'a> { +impl Drop for DropCounter<'_> { fn drop(&mut self) { *self.count += 1; } diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 44183956d8fc7..313aa55a2b28e 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1003,7 +1003,7 @@ struct DropCounter<'a> { count: &'a mut u32, } -impl<'a> Drop for DropCounter<'a> { +impl Drop for DropCounter<'_> { fn drop(&mut self) { *self.count += 1; } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 8e09720688156..b43ba6cb57cad 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1481,7 +1481,7 @@ impl<'a> SetLenOnDrop<'a> { } } -impl<'a> Drop for SetLenOnDrop<'a> { +impl Drop for SetLenOnDrop<'_> { #[inline] fn drop(&mut self) { *self.len = self.local_len; @@ -2471,12 +2471,12 @@ impl<'a, T: 'a + fmt::Debug> fmt::Debug for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {} +unsafe impl Sync for Drain<'_, T> {} #[stable(feature = "drain", since = "1.6.0")] -unsafe impl<'a, T: Send> Send for Drain<'a, T> {} +unsafe impl Send for Drain<'_, T> {} #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T> Iterator for Drain<'a, T> { +impl Iterator for Drain<'_, T> { type Item = T; #[inline] @@ -2490,7 +2490,7 @@ impl<'a, T> Iterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T> DoubleEndedIterator for Drain<'a, T> { +impl DoubleEndedIterator for Drain<'_, T> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) }) @@ -2498,7 +2498,7 @@ impl<'a, T> DoubleEndedIterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T> Drop for Drain<'a, T> { +impl Drop for Drain<'_, T> { fn drop(&mut self) { // exhaust self first self.for_each(drop); @@ -2522,14 +2522,14 @@ impl<'a, T> Drop for Drain<'a, T> { #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T> ExactSizeIterator for Drain<'a, T> { +impl ExactSizeIterator for Drain<'_, T> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Drain<'a, T> {} +impl FusedIterator for Drain<'_, T> {} /// A splicing iterator for `Vec`. /// @@ -2546,7 +2546,7 @@ pub struct Splice<'a, I: Iterator + 'a> { } #[stable(feature = "vec_splice", since = "1.21.0")] -impl<'a, I: Iterator> Iterator for Splice<'a, I> { +impl Iterator for Splice<'_, I> { type Item = I::Item; fn next(&mut self) -> Option { @@ -2559,18 +2559,18 @@ impl<'a, I: Iterator> Iterator for Splice<'a, I> { } #[stable(feature = "vec_splice", since = "1.21.0")] -impl<'a, I: Iterator> DoubleEndedIterator for Splice<'a, I> { +impl DoubleEndedIterator for Splice<'_, I> { fn next_back(&mut self) -> Option { self.drain.next_back() } } #[stable(feature = "vec_splice", since = "1.21.0")] -impl<'a, I: Iterator> ExactSizeIterator for Splice<'a, I> {} +impl ExactSizeIterator for Splice<'_, I> {} #[stable(feature = "vec_splice", since = "1.21.0")] -impl<'a, I: Iterator> Drop for Splice<'a, I> { +impl Drop for Splice<'_, I> { fn drop(&mut self) { self.drain.by_ref().for_each(drop); @@ -2611,7 +2611,7 @@ impl<'a, I: Iterator> Drop for Splice<'a, I> { } /// Private helper methods for `Splice::drop` -impl<'a, T> Drain<'a, T> { +impl Drain<'_, T> { /// The range from `self.vec.len` to `self.tail_start` contains elements /// that have been moved out. /// Fill that range as much as possible with new elements from the `replace_with` iterator. @@ -2663,7 +2663,7 @@ pub struct DrainFilter<'a, T: 'a, F> } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<'a, T, F> Iterator for DrainFilter<'a, T, F> +impl Iterator for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { type Item = T; @@ -2697,7 +2697,7 @@ impl<'a, T, F> Iterator for DrainFilter<'a, T, F> } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<'a, T, F> Drop for DrainFilter<'a, T, F> +impl Drop for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { From 95a95189570001e37712661f46a496cdedce62b3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 12:27:41 +0100 Subject: [PATCH 0536/1064] liballoc: elide &'static. --- src/liballoc/tests/str.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 28e021c741e7d..b1586558713e7 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -586,7 +586,7 @@ mod slice_index { } mod boundary { - const DATA: &'static str = "abcαβγ"; + const DATA: &str = "abcαβγ"; const BAD_START: usize = 4; const GOOD_START: usize = 3; @@ -650,7 +650,7 @@ mod slice_index { } } - const LOREM_PARAGRAPH: &'static str = "\ + const LOREM_PARAGRAPH: &str = "\ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem \ sit amet dolor ultricies condimentum. Praesent iaculis purus elit, ac malesuada \ quam malesuada in. Duis sed orci eros. Suspendisse sit amet magna mollis, mollis \ From 857530cef1f1419e296e5d9ad623b153c06cb3e6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 12:48:12 +0100 Subject: [PATCH 0537/1064] liballoc: fix some idiom lints. --- src/liballoc/borrow.rs | 4 +-- src/liballoc/boxed.rs | 6 ++--- src/liballoc/collections/binary_heap.rs | 14 +++++----- src/liballoc/collections/btree/map.rs | 34 ++++++++++++------------- src/liballoc/collections/btree/node.rs | 20 +++++++-------- src/liballoc/collections/btree/set.rs | 16 ++++++------ src/liballoc/collections/linked_list.rs | 16 ++++++------ src/liballoc/collections/vec_deque.rs | 16 ++++++------ src/liballoc/fmt.rs | 2 +- src/liballoc/lib.rs | 3 +++ src/liballoc/rc.rs | 8 +++--- src/liballoc/string.rs | 16 ++++++------ src/liballoc/sync.rs | 8 +++--- src/liballoc/vec.rs | 14 +++++----- 14 files changed, 90 insertions(+), 87 deletions(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 816cdbc9ce673..1fda36778f486 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -332,7 +332,7 @@ impl fmt::Debug for Cow<'_, B> where B: fmt::Debug + ToOwned, ::Owned: fmt::Debug { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Borrowed(ref b) => fmt::Debug::fmt(b, f), Owned(ref o) => fmt::Debug::fmt(o, f), @@ -345,7 +345,7 @@ impl fmt::Display for Cow<'_, B> where B: fmt::Display + ToOwned, ::Owned: fmt::Display { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Borrowed(ref b) => fmt::Display::fmt(b, f), Owned(ref o) => fmt::Display::fmt(o, f), diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 6f6fff0a657d0..40b091b92c1a5 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -605,21 +605,21 @@ impl Box { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Pointer for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // It's not possible to extract the inner Uniq directly from the Box, // instead we cast it to a *const which aliases the Unique let ptr: *const T = &**self; diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 43416e57591bc..5f0386400d707 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -232,7 +232,7 @@ pub struct PeekMut<'a, T: 'a + Ord> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for PeekMut<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("PeekMut") .field(&self.heap.data[0]) .finish() @@ -295,7 +295,7 @@ impl Default for BinaryHeap { #[stable(feature = "binaryheap_debug", since = "1.4.0")] impl fmt::Debug for BinaryHeap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } } @@ -353,7 +353,7 @@ impl BinaryHeap { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T> { Iter { iter: self.data.iter() } } @@ -404,7 +404,7 @@ impl BinaryHeap { /// assert_eq!(heap.peek(), Some(&2)); /// ``` #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] - pub fn peek_mut(&mut self) -> Option> { + pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { @@ -765,7 +765,7 @@ impl BinaryHeap { /// ``` #[inline] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain { + pub fn drain(&mut self) -> Drain<'_, T> { Drain { iter: self.data.drain(..) } } @@ -937,7 +937,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Iter") .field(&self.iter.as_slice()) .finish() @@ -1000,7 +1000,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter") .field(&self.iter.as_slice()) .finish() diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 27f162b114736..fe6b5fef210e1 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -249,7 +249,7 @@ impl super::Recover for BTreeMap fn replace(&mut self, key: K) -> Option { self.ensure_root_is_owned(); - match search::search_tree::(self.root.as_mut(), &key) { + match search::search_tree::, K, (), K>(self.root.as_mut(), &key) { Found(handle) => Some(mem::replace(handle.into_kv_mut().0, key)), GoDown(handle) => { VacantEntry { @@ -280,7 +280,7 @@ pub struct Iter<'a, K: 'a, V: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } @@ -315,7 +315,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let range = Range { front: self.front.reborrow(), back: self.back.reborrow(), @@ -338,7 +338,7 @@ pub struct Keys<'a, K: 'a, V: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Keys<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } @@ -357,7 +357,7 @@ pub struct Values<'a, K: 'a, V: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Values<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } @@ -390,7 +390,7 @@ pub struct Range<'a, K: 'a, V: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Range<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } @@ -413,7 +413,7 @@ pub struct RangeMut<'a, K: 'a, V: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for RangeMut<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let range = Range { front: self.front.reborrow(), back: self.back.reborrow(), @@ -443,7 +443,7 @@ pub enum Entry<'a, K: 'a, V: 'a> { #[stable(feature= "debug_btree_map", since = "1.12.0")] impl Debug for Entry<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Vacant(ref v) => f.debug_tuple("Entry") .field(v) @@ -471,7 +471,7 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> { #[stable(feature= "debug_btree_map", since = "1.12.0")] impl Debug for VacantEntry<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("VacantEntry") .field(self.key()) .finish() @@ -494,7 +494,7 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { #[stable(feature= "debug_btree_map", since = "1.12.0")] impl Debug for OccupiedEntry<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OccupiedEntry") .field("key", self.key()) .field("value", self.get()) @@ -818,7 +818,7 @@ impl BTreeMap { /// assert_eq!(Some((&5, &"b")), map.range(4..).next()); /// ``` #[stable(feature = "btree_range", since = "1.17.0")] - pub fn range(&self, range: R) -> Range + pub fn range(&self, range: R) -> Range<'_, K, V> where T: Ord, K: Borrow, R: RangeBounds { let root1 = self.root.as_ref(); @@ -859,7 +859,7 @@ impl BTreeMap { /// } /// ``` #[stable(feature = "btree_range", since = "1.17.0")] - pub fn range_mut(&mut self, range: R) -> RangeMut + pub fn range_mut(&mut self, range: R) -> RangeMut<'_, K, V> where T: Ord, K: Borrow, R: RangeBounds { let root1 = self.root.as_mut(); @@ -892,7 +892,7 @@ impl BTreeMap { /// assert_eq!(count["a"], 3); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn entry(&mut self, key: K) -> Entry { + pub fn entry(&mut self, key: K) -> Entry<'_, K, V> { // FIXME(@porglezomp) Avoid allocating if we don't insert self.ensure_root_is_owned(); match search::search_tree(self.root.as_mut(), &key) { @@ -1783,7 +1783,7 @@ impl Ord for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.iter()).finish() } } @@ -1940,7 +1940,7 @@ impl BTreeMap { /// assert_eq!((*first_key, *first_value), (1, "a")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, K, V> { Iter { range: Range { front: first_leaf_edge(self.root.as_ref()), @@ -1972,7 +1972,7 @@ impl BTreeMap { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { let root1 = self.root.as_mut(); let root2 = unsafe { ptr::read(&root1) }; IterMut { @@ -2049,7 +2049,7 @@ impl BTreeMap { /// String::from("goodbye!")]); /// ``` #[stable(feature = "map_values_mut", since = "1.10.0")] - pub fn values_mut(&mut self) -> ValuesMut { + pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { ValuesMut { inner: self.iter_mut() } } diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index f33a75bc45e02..a5f90aa8974b6 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -230,7 +230,7 @@ impl Root { } pub fn as_ref(&self) - -> NodeRef { + -> NodeRef, K, V, marker::LeafOrInternal> { NodeRef { height: self.height, node: self.node.as_ptr(), @@ -240,7 +240,7 @@ impl Root { } pub fn as_mut(&mut self) - -> NodeRef { + -> NodeRef, K, V, marker::LeafOrInternal> { NodeRef { height: self.height, node: self.node.as_ptr(), @@ -262,7 +262,7 @@ impl Root { /// Adds a new internal node with a single edge, pointing to the previous root, and make that /// new node the root. This increases the height by 1 and is the opposite of `pop_level`. pub fn push_level(&mut self) - -> NodeRef { + -> NodeRef, K, V, marker::Internal> { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); @@ -535,7 +535,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { /// Unsafely asserts to the compiler some static information about whether this /// node is a `Leaf`. unsafe fn cast_unchecked(&mut self) - -> NodeRef { + -> NodeRef, K, V, NewType> { NodeRef { height: self.height, @@ -555,7 +555,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { /// of a reborrowed handle, out of bounds. // FIXME(@gereeter) consider adding yet another type parameter to `NodeRef` that restricts // the use of `ascend` and `into_root_mut` on reborrowed pointers, preventing this unsafety. - unsafe fn reborrow_mut(&mut self) -> NodeRef { + unsafe fn reborrow_mut(&mut self) -> NodeRef, K, V, Type> { NodeRef { height: self.height, node: self.node, @@ -932,7 +932,7 @@ impl /// Temporarily takes out another, immutable handle on the same location. pub fn reborrow(&self) - -> Handle, HandleType> { + -> Handle, K, V, NodeType>, HandleType> { // We can't use Handle::new_kv or Handle::new_edge because we don't know our type Handle { @@ -957,7 +957,7 @@ impl<'a, K, V, NodeType, HandleType> // FIXME(@gereeter) consider adding yet another type parameter to `NodeRef` that restricts // the use of `ascend` and `into_root_mut` on reborrowed pointers, preventing this unsafety. pub unsafe fn reborrow_mut(&mut self) - -> Handle, HandleType> { + -> Handle, K, V, NodeType>, HandleType> { // We can't use Handle::new_kv or Handle::new_edge because we don't know our type Handle { @@ -1072,7 +1072,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// Unsafely asserts to the compiler some static information about whether the underlying /// node of this handle is a `Leaf`. unsafe fn cast_unchecked(&mut self) - -> Handle, marker::Edge> { + -> Handle, K, V, NewType>, marker::Edge> { Handle::new_edge(self.node.cast_unchecked(), self.idx) } @@ -1562,8 +1562,8 @@ unsafe fn move_kv( // Source and destination must have the same height. unsafe fn move_edges( - mut source: NodeRef, source_offset: usize, - mut dest: NodeRef, dest_offset: usize, + mut source: NodeRef, K, V, marker::Internal>, source_offset: usize, + mut dest: NodeRef, K, V, marker::Internal>, dest_offset: usize, count: usize) { let source_ptr = source.as_internal_mut().edges.as_mut_ptr(); diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 9c50bd7e91866..ba3b3ed76c82f 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -80,7 +80,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Iter") .field(&self.iter.clone()) .finish() @@ -128,7 +128,7 @@ pub struct Difference<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Difference<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Difference") .field(&self.a) .field(&self.b) @@ -151,7 +151,7 @@ pub struct SymmetricDifference<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for SymmetricDifference<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("SymmetricDifference") .field(&self.a) .field(&self.b) @@ -174,7 +174,7 @@ pub struct Intersection<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Intersection<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Intersection") .field(&self.a) .field(&self.b) @@ -197,7 +197,7 @@ pub struct Union<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Union<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Union") .field(&self.a) .field(&self.b) @@ -244,7 +244,7 @@ impl BTreeSet { /// assert_eq!(Some(&5), set.range(4..).next()); /// ``` #[stable(feature = "btree_range", since = "1.17.0")] - pub fn range(&self, range: R) -> Range + pub fn range(&self, range: R) -> Range<'_, T> where K: Ord, T: Borrow, R: RangeBounds { Range { iter: self.map.range(range) } @@ -706,7 +706,7 @@ impl BTreeSet { /// assert_eq!(set_iter.next(), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T> { Iter { iter: self.map.keys() } } @@ -905,7 +905,7 @@ impl BitOr<&BTreeSet> for &BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeSet { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() } } diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index e2da0041b4a8d..f601fa2c8d190 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -64,7 +64,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Iter") .field(&self.len) .finish() @@ -96,7 +96,7 @@ pub struct IterMut<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IterMut<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IterMut") .field(&self.list) .field(&self.len) @@ -119,7 +119,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter") .field(&self.list) .finish() @@ -333,7 +333,7 @@ impl LinkedList { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T> { Iter { head: self.head, tail: self.tail, @@ -367,7 +367,7 @@ impl LinkedList { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, T> { IterMut { head: self.head, tail: self.tail, @@ -766,7 +766,7 @@ impl LinkedList { /// assert_eq!(odds.into_iter().collect::>(), vec![1, 3, 5, 9, 11, 13, 15]); /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter(&mut self, filter: F) -> DrainFilter + pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool { // avoid borrow issues. @@ -1023,7 +1023,7 @@ impl Drop for DrainFilter<'_, T, F> impl fmt::Debug for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("DrainFilter") .field(&self.list) .finish() @@ -1166,7 +1166,7 @@ impl Clone for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for LinkedList { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self).finish() } } diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index abfb83d4139e1..f92c7ed04f4e3 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -801,7 +801,7 @@ impl VecDeque { /// assert_eq!(&c[..], b); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, T> { Iter { tail: self.tail, head: self.head, @@ -827,7 +827,7 @@ impl VecDeque { /// assert_eq!(&buf.iter_mut().collect::>()[..], b); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut<'_, T> { IterMut { tail: self.tail, head: self.head, @@ -961,7 +961,7 @@ impl VecDeque { /// ``` #[inline] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self, range: R) -> Drain + pub fn drain(&mut self, range: R) -> Drain<'_, T> where R: RangeBounds { // Memory safety @@ -2127,7 +2127,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); f.debug_tuple("Iter") .field(&front) @@ -2232,7 +2232,7 @@ pub struct IterMut<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl<'a, T: fmt::Debug> fmt::Debug for IterMut<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (front, back) = RingSlices::ring_slices(&*self.ring, self.head, self.tail); f.debug_tuple("IterMut") .field(&front) @@ -2323,7 +2323,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter") .field(&self.inner) .finish() @@ -2381,7 +2381,7 @@ pub struct Drain<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Drain<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain") .field(&self.after_tail) .field(&self.after_head) @@ -2657,7 +2657,7 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for VecDeque { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for VecDeque { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self).finish() } } diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index be35b4487509b..a8a99c7e7a3d3 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -552,7 +552,7 @@ use crate::string; /// [`format_args!`]: ../../std/macro.format_args.html /// [`format!`]: ../../std/macro.format.html #[stable(feature = "rust1", since = "1.0.0")] -pub fn format(args: Arguments) -> string::String { +pub fn format(args: Arguments<'_>) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); output diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5d69b10054719..ab0ade7e5547c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -63,6 +63,9 @@ #![no_std] #![needs_allocator] +#![deny(rust_2018_idioms)] +#![allow(explicit_outlives_requirements)] + #![warn(deprecated_in_future)] #![warn(intra_doc_link_resolution_failure)] #![warn(missing_debug_implementations)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index c24e216383974..01a26b6f42337 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1122,21 +1122,21 @@ impl Hash for Rc { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Rc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Rc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Pointer for Rc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&(&**self as *const T), f) } } @@ -1460,7 +1460,7 @@ impl Clone for Weak { #[stable(feature = "rc_weak", since = "1.4.0")] impl fmt::Debug for Weak { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(Weak)") } } diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 92d3e52d60c73..cb497f5bde212 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1494,7 +1494,7 @@ impl String { /// assert_eq!(s, ""); /// ``` #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self, range: R) -> Drain + pub fn drain(&mut self, range: R) -> Drain<'_> where R: RangeBounds { // Memory safety @@ -1678,14 +1678,14 @@ impl FromUtf8Error { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for FromUtf8Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.error, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for FromUtf16Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt("invalid utf-16: lone surrogate found", f) } } @@ -1876,7 +1876,7 @@ impl Default for String { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for String { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&**self, f) } } @@ -1884,7 +1884,7 @@ impl fmt::Display for String { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for String { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } @@ -2106,14 +2106,14 @@ impl Clone for ParseError { #[stable(feature = "str_parse_error", since = "1.5.0")] impl fmt::Debug for ParseError { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { match *self {} } } #[stable(feature = "str_parse_error2", since = "1.8.0")] impl fmt::Display for ParseError { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { match *self {} } } @@ -2374,7 +2374,7 @@ pub struct Drain<'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Drain<'_> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("Drain { .. }") } } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 2512e27e316b7..52f8879d1844b 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -257,7 +257,7 @@ impl, U: ?Sized> DispatchFromDyn> for Weak {} #[stable(feature = "arc_weak", since = "1.4.0")] impl fmt::Debug for Weak { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(Weak)") } } @@ -1554,21 +1554,21 @@ impl Eq for Arc {} #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Arc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Arc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Pointer for Arc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&(&**self as *const T), f) } } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b43ba6cb57cad..66a73e7579951 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1122,7 +1122,7 @@ impl Vec { /// assert_eq!(v, &[]); /// ``` #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self, range: R) -> Drain + pub fn drain(&mut self, range: R) -> Drain<'_, T> where R: RangeBounds { // Memory safety @@ -1979,7 +1979,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "vec_splice", since = "1.21.0")] - pub fn splice(&mut self, range: R, replace_with: I) -> Splice + pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter> where R: RangeBounds, I: IntoIterator { Splice { @@ -2034,7 +2034,7 @@ impl Vec { /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]); /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter(&mut self, filter: F) -> DrainFilter + pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { let old_len = self.len(); @@ -2150,7 +2150,7 @@ impl Default for Vec { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Vec { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } @@ -2293,7 +2293,7 @@ pub struct IntoIter { #[stable(feature = "vec_intoiter_debug", since = "1.13.0")] impl fmt::Debug for IntoIter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter") .field(&self.as_slice()) .finish() @@ -2463,7 +2463,7 @@ pub struct Drain<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl<'a, T: 'a + fmt::Debug> fmt::Debug for Drain<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain") .field(&self.iter.as_slice()) .finish() @@ -2652,7 +2652,7 @@ impl Drain<'_, T> { /// An iterator produced by calling `drain_filter` on Vec. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] #[derive(Debug)] -pub struct DrainFilter<'a, T: 'a, F> +pub struct DrainFilter<'a, T, F> where F: FnMut(&mut T) -> bool, { vec: &'a mut Vec, From 71023394772e9194e3c7a2426364faef6c3ad2c4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 26 Jan 2019 20:30:52 +0100 Subject: [PATCH 0538/1064] Update visibility of intermediate use items. Currently, the target of a use statement will be updated with the visibility of the use statement itself (if the use statement was visible). This commit ensures that if the path to the target item is via another use statement then that intermediate use statement will also have the visibility updated like the target. This silences incorrect `unreachable_pub` lints with inactionable suggestions. --- src/libcore/iter/adapters/mod.rs | 1 + src/libcore/iter/traits/mod.rs | 2 ++ src/librustc/hir/def.rs | 10 ++++++ src/librustc/middle/privacy.rs | 19 +++++++----- src/librustc_privacy/lib.rs | 47 +++++++++++++++++++++++++++-- src/libstd/sys/mod.rs | 2 ++ src/test/ui/issues/issue-57410-1.rs | 18 +++++++++++ src/test/ui/issues/issue-57410.rs | 17 +++++++++++ 8 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/issues/issue-57410-1.rs create mode 100644 src/test/ui/issues/issue-57410.rs diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index f8d6bedeace25..bca1b76dbb975 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -11,6 +11,7 @@ mod flatten; mod zip; pub use self::chain::Chain; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::flatten::{FlatMap, Flatten}; pub use self::zip::Zip; pub(crate) use self::zip::TrustedRandomAccess; diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index 000b9fad70b94..cf3013f423c94 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -5,9 +5,11 @@ mod collect; mod accum; mod marker; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::iterator::Iterator; pub use self::double_ended::DoubleEndedIterator; pub use self::exact_size::ExactSizeIterator; pub use self::collect::{FromIterator, IntoIterator, Extend}; pub use self::accum::{Sum, Product}; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::marker::{FusedIterator, TrustedLen}; diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 8a74c51d3f723..f8f27992b3ea8 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -252,12 +252,14 @@ impl NonMacroAttrKind { } impl Def { + /// Return the `DefId` of this `Def` if it has an id, else panic. pub fn def_id(&self) -> DefId { self.opt_def_id().unwrap_or_else(|| { bug!("attempted .def_id() on invalid def: {:?}", self) }) } + /// Return `Some(..)` with the `DefId` of this `Def` if it has a id, else `None`. pub fn opt_def_id(&self) -> Option { match *self { Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) | @@ -284,6 +286,14 @@ impl Def { } } + /// Return the `DefId` of this `Def` if it represents a module. + pub fn mod_def_id(&self) -> Option { + match *self { + Def::Mod(id) => Some(id), + _ => None, + } + } + /// A human readable name for the def kind ("function", "module", etc.). pub fn kind_name(&self) -> &'static str { match *self { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 7736d5e795ea0..3baf0f0ea39ff 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -11,16 +11,16 @@ use syntax::ast::NodeId; // Accessibility levels, sorted in ascending order #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AccessLevel { - // Superset of Reachable used to mark impl Trait items. + /// Superset of `AccessLevel::Reachable` used to mark impl Trait items. ReachableFromImplTrait, - // Exported items + items participating in various kinds of public interfaces, - // but not directly nameable. For example, if function `fn f() -> T {...}` is - // public, then type `T` is reachable. Its values can be obtained by other crates - // even if the type itself is not nameable. + /// Exported items + items participating in various kinds of public interfaces, + /// but not directly nameable. For example, if function `fn f() -> T {...}` is + /// public, then type `T` is reachable. Its values can be obtained by other crates + /// even if the type itself is not nameable. Reachable, - // Public items + items accessible to other crates with help of `pub use` re-exports + /// Public items + items accessible to other crates with help of `pub use` re-exports Exported, - // Items accessible to other crates directly, without help of re-exports + /// Items accessible to other crates directly, without help of re-exports Public, } @@ -31,12 +31,17 @@ pub struct AccessLevels { } impl AccessLevels { + /// See `AccessLevel::Reachable`. pub fn is_reachable(&self, id: Id) -> bool { self.map.get(&id) >= Some(&AccessLevel::Reachable) } + + /// See `AccessLevel::Exported`. pub fn is_exported(&self, id: Id) -> bool { self.map.get(&id) >= Some(&AccessLevel::Exported) } + + /// See `AccessLevel::Public`. pub fn is_public(&self, id: Id) -> bool { self.map.get(&id) >= Some(&AccessLevel::Public) } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 1bdc22b37d73b..05d20562d34e7 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -437,6 +437,43 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { ev: self, } } + + + /// Given the path segments of a `ItemKind::Use`, then we need + /// to update the visibility of the intermediate use so that it isn't linted + /// by `unreachable_pub`. + /// + /// This isn't trivial as `path.def` has the `DefId` of the eventual target + /// of the use statement not of the next intermediate use statement. + /// + /// To do this, consider the last two segments of the path to our intermediate + /// use statement. We expect the penultimate segment to be a module and the + /// last segment to be the name of the item we are exporting. We can then + /// look at the items contained in the module for the use statement with that + /// name and update that item's visibility. + /// + /// FIXME: This solution won't work with glob imports and doesn't respect + /// namespaces. See . + fn update_visibility_of_intermediate_use_statements(&mut self, segments: &[hir::PathSegment]) { + if let Some([module, segment]) = segments.rchunks_exact(2).next() { + if let Some(item) = module.def + .and_then(|def| def.mod_def_id()) + .and_then(|def_id| self.tcx.hir().as_local_node_id(def_id)) + .map(|module_node_id| self.tcx.hir().expect_item(module_node_id)) + { + if let hir::ItemKind::Mod(m) = &item.node { + for item_id in m.item_ids.as_ref() { + let item = self.tcx.hir().expect_item(item_id.id); + let def_id = self.tcx.hir().local_def_id(item_id.id); + if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; } + if let hir::ItemKind::Use(..) = item.node { + self.update(item.id, Some(AccessLevel::Exported)); + } + } + } + } + } + } } impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { @@ -523,8 +560,14 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { hir::ItemKind::ExternCrate(..) => {} // All nested items are checked by `visit_item`. hir::ItemKind::Mod(..) => {} - // Re-exports are handled in `visit_mod`. - hir::ItemKind::Use(..) => {} + // Re-exports are handled in `visit_mod`. However, in order to avoid looping over + // all of the items of a mod in `visit_mod` looking for use statements, we handle + // making sure that intermediate use statements have their visibilities updated here. + hir::ItemKind::Use(ref path, _) => { + if item_level.is_some() { + self.update_visibility_of_intermediate_use_statements(path.segments.as_ref()); + } + } // The interface is empty. hir::ItemKind::GlobalAsm(..) => {} hir::ItemKind::Existential(..) => { diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index f398a2a6225ce..99ef74179c2ba 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -54,6 +54,7 @@ cfg_if! { cfg_if! { if #[cfg(any(unix, target_os = "redox"))] { // On unix we'll document what's already available + #[stable(feature = "rust1", since = "1.0.0")] pub use self::ext as unix_ext; } else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32", @@ -77,6 +78,7 @@ cfg_if! { if #[cfg(windows)] { // On windows we'll just be documenting what's already available #[allow(missing_docs)] + #[stable(feature = "rust1", since = "1.0.0")] pub use self::ext as windows_ext; } else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32", diff --git a/src/test/ui/issues/issue-57410-1.rs b/src/test/ui/issues/issue-57410-1.rs new file mode 100644 index 0000000000000..dab77bd660ca0 --- /dev/null +++ b/src/test/ui/issues/issue-57410-1.rs @@ -0,0 +1,18 @@ +// compile-pass + +// Originally from #53925. +// Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`. + +#![deny(unreachable_pub)] + +mod foo { + mod bar { + pub struct Bar; + } + + pub use self::bar::Bar; +} + +pub use foo::Bar; + +fn main() {} diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/issues/issue-57410.rs new file mode 100644 index 0000000000000..0d697e5619d24 --- /dev/null +++ b/src/test/ui/issues/issue-57410.rs @@ -0,0 +1,17 @@ +// compile-pass + +// Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`. + +#![deny(unreachable_pub)] + +mod m { + mod imp { + pub fn f() {} + } + + pub use self::imp::f; +} + +pub use self::m::f; + +fn main() {} From 55ef78e885f0f7a15237fff7cb204fa65a526aac Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sat, 2 Feb 2019 15:40:08 +0100 Subject: [PATCH 0539/1064] hir: add HirId to main Hir nodes --- src/librustc/hir/check_attr.rs | 2 +- src/librustc/hir/intravisit.rs | 2 +- src/librustc/hir/lowering.rs | 257 ++++++++++++------ src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 37 ++- src/librustc/hir/pat_util.rs | 6 +- src/librustc/hir/print.rs | 3 +- src/librustc/ich/impls_hir.rs | 20 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- .../borrowck/gather_loans/gather_moves.rs | 2 +- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/nonstandard_style.rs | 2 +- src/librustc_metadata/encoder.rs | 2 +- .../borrow_check/mutability_errors.rs | 1 + src/librustc_mir/build/mod.rs | 8 +- src/librustc_mir/hair/pattern/check_match.rs | 4 +- src/librustc_mir/hair/pattern/mod.rs | 2 +- src/librustc_mir/transform/mod.rs | 2 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/collect.rs | 4 +- src/librustdoc/clean/mod.rs | 3 +- src/librustdoc/core.rs | 2 + 24 files changed, 257 insertions(+), 114 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index a2947fa0d8c1f..4ce41fec18240 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -362,7 +362,7 @@ fn is_c_like_enum(item: &hir::Item) -> bool { if let hir::ItemKind::Enum(ref def, _) = item.node { for variant in &def.variants { match variant.node.data { - hir::VariantData::Unit(_) => { /* continue */ } + hir::VariantData::Unit(..) => { /* continue */ } _ => { return false; } } } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 592fb7898f3e6..5f85e33fb87ee 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -694,7 +694,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { PatKind::Ref(ref subpattern, _) => { visitor.visit_pat(subpattern) } - PatKind::Binding(_, canonical_id, ident, ref optional_subpattern) => { + PatKind::Binding(_, canonical_id, _hir_id, ident, ref optional_subpattern) => { visitor.visit_def_mention(Def::Local(canonical_id)); visitor.visit_ident(ident); walk_list!(visitor, visit_pat, optional_subpattern); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 51dbad92225e1..e3c913313adee 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -741,7 +741,7 @@ impl<'a> LoweringContext<'a> { let params = lifetimes_to_define .into_iter() .map(|(span, hir_name)| { - let def_node_id = self.next_id().node_id; + let LoweredNodeId { node_id, hir_id } = self.next_id(); // Get the name we'll use to make the def-path. Note // that collisions are ok here and this shouldn't @@ -764,7 +764,7 @@ impl<'a> LoweringContext<'a> { // Add a definition for the in-band lifetime def. self.resolver.definitions().create_def_with_parent( parent_id.index, - def_node_id, + node_id, DefPathData::LifetimeParam(str_name), DefIndexAddressSpace::High, Mark::root(), @@ -772,7 +772,8 @@ impl<'a> LoweringContext<'a> { ); hir::GenericParam { - id: def_node_id, + id: node_id, + hir_id, name: hir_name, attrs: hir_vec![], bounds: hir_vec![], @@ -1138,8 +1139,11 @@ impl<'a> LoweringContext<'a> { fn lower_ty_binding(&mut self, b: &TypeBinding, itctx: ImplTraitContext<'_>) -> hir::TypeBinding { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(b.id); + hir::TypeBinding { - id: self.lower_node_id(b.id).node_id, + id: node_id, + hir_id, ident: b.ident, ty: self.lower_ty(&b.ty, itctx), span: b.span, @@ -1261,7 +1265,7 @@ impl<'a> LoweringContext<'a> { ) } ImplTraitContext::Universal(in_band_ty_params) => { - self.lower_node_id(def_node_id); + let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(def_node_id); // Add a definition for the in-band `Param`. let def_index = self .resolver @@ -1277,6 +1281,7 @@ impl<'a> LoweringContext<'a> { let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span); in_band_ty_params.push(hir::GenericParam { id: def_node_id, + hir_id, name: ParamName::Plain(ident), pure_wrt_drop: false, attrs: hir_vec![], @@ -1368,11 +1373,13 @@ impl<'a> LoweringContext<'a> { ); self.with_hir_id_owner(exist_ty_node_id, |lctx| { + let LoweredNodeId { node_id, hir_id } = lctx.next_id(); let exist_ty_item_kind = hir::ItemKind::Existential(hir::ExistTy { generics: hir::Generics { params: lifetime_defs, where_clause: hir::WhereClause { - id: lctx.next_id().node_id, + id: node_id, + hir_id, predicates: Vec::new().into(), }, span, @@ -1505,8 +1512,10 @@ impl<'a> LoweringContext<'a> { && !self.already_defined_lifetimes.contains(&name) { self.already_defined_lifetimes.insert(name); + let LoweredNodeId { node_id, hir_id } = self.context.next_id(); self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime { - id: self.context.next_id().node_id, + id: node_id, + hir_id, span: lifetime.span, name, })); @@ -1515,7 +1524,8 @@ impl<'a> LoweringContext<'a> { // definitions will go into the explicit `existential type` // declaration and thus need to have their owner set to that item let def_node_id = self.context.sess.next_node_id(); - let _ = self.context.lower_node_id_with_owner(def_node_id, self.exist_ty_id); + let LoweredNodeId { node_id: _, hir_id } = + self.context.lower_node_id_with_owner(def_node_id, self.exist_ty_id); self.context.resolver.definitions().create_def_with_parent( self.parent, def_node_id, @@ -1539,6 +1549,7 @@ impl<'a> LoweringContext<'a> { self.output_lifetime_params.push(hir::GenericParam { id: def_node_id, + hir_id, name, span: lifetime.span, pure_wrt_drop: false, @@ -1904,6 +1915,7 @@ impl<'a> LoweringContext<'a> { hir::PathSegment::new( segment.ident, Some(id.node_id), + Some(id.hir_id), Some(def), generic_args, infer_types, @@ -1950,13 +1962,15 @@ impl<'a> LoweringContext<'a> { let LoweredNodeId { node_id, hir_id } = this.next_id(); hir::Ty { node: hir::TyKind::Tup(tys), id: node_id, hir_id, span } }; + let LoweredNodeId { node_id, hir_id } = this.next_id(); ( hir::GenericArgs { args: hir_vec![GenericArg::Type(mk_tup(this, inputs, span))], bindings: hir_vec![ hir::TypeBinding { - id: this.next_id().node_id, + id: node_id, + hir_id, ident: Ident::from_str(FN_OUTPUT_NAME), ty: output .as_ref() @@ -2286,7 +2300,7 @@ impl<'a> LoweringContext<'a> { let LoweredNodeId { node_id, hir_id } = this.next_id(); P(hir::Ty { id: node_id, - hir_id: hir_id, + hir_id, node: hir::TyKind::Tup(hir_vec![]), span: *span, }) @@ -2294,12 +2308,14 @@ impl<'a> LoweringContext<'a> { }; // "" + let LoweredNodeId { node_id, hir_id } = this.next_id(); let future_params = P(hir::GenericArgs { args: hir_vec![], bindings: hir_vec![hir::TypeBinding { ident: Ident::from_str(FN_OUTPUT_NAME), ty: output_ty, - id: this.next_id().node_id, + id: node_id, + hir_id, span, }], parenthesized: false, @@ -2325,8 +2341,9 @@ impl<'a> LoweringContext<'a> { ]; if let Some((name, span)) = bound_lifetime { + let LoweredNodeId { node_id, hir_id } = this.next_id(); bounds.push(hir::GenericBound::Outlives( - hir::Lifetime { id: this.next_id().node_id, name, span })); + hir::Lifetime { id: node_id, hir_id, name, span })); } hir::HirVec::from(bounds) @@ -2393,8 +2410,11 @@ impl<'a> LoweringContext<'a> { span: Span, name: hir::LifetimeName, ) -> hir::Lifetime { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id); + hir::Lifetime { - id: self.lower_node_id(id).node_id, + id: node_id, + hir_id, span, name: name, } @@ -2439,6 +2459,7 @@ impl<'a> LoweringContext<'a> { }; let param = hir::GenericParam { id: lt.id, + hir_id: lt.hir_id, name: param_name, span: lt.span, pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"), @@ -2470,9 +2491,11 @@ impl<'a> LoweringContext<'a> { .chain(params) .collect(); } + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(param.id); hir::GenericParam { - id: self.lower_node_id(param.id).node_id, + id: node_id, + hir_id, name: hir::ParamName::Plain(ident), pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"), attrs: self.lower_attrs(¶m.attrs), @@ -2562,8 +2585,11 @@ impl<'a> LoweringContext<'a> { self.with_anonymous_lifetime_mode( AnonymousLifetimeMode::ReportError, |this| { + let LoweredNodeId { node_id, hir_id } = this.lower_node_id(wc.id); + hir::WhereClause { - id: this.lower_node_id(wc.id).node_id, + id: node_id, + hir_id, predicates: wc.predicates .iter() .map(|predicate| this.lower_where_predicate(predicate)) @@ -2622,34 +2648,53 @@ impl<'a> LoweringContext<'a> { ref lhs_ty, ref rhs_ty, span, - }) => hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { - id: self.lower_node_id(id).node_id, - lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()), - rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()), - span, - }), + }) => { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id); + + hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { + id: node_id, + hir_id, + lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()), + rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()), + span, + }) + }, } } fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData { match *vdata { - VariantData::Struct(ref fields, id) => hir::VariantData::Struct( - fields - .iter() - .enumerate() - .map(|f| self.lower_struct_field(f)) - .collect(), - self.lower_node_id(id).node_id, - ), - VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple( - fields - .iter() - .enumerate() - .map(|f| self.lower_struct_field(f)) - .collect(), - self.lower_node_id(id).node_id, - ), - VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id), + VariantData::Struct(ref fields, id) => { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id); + + hir::VariantData::Struct( + fields + .iter() + .enumerate() + .map(|f| self.lower_struct_field(f)) + .collect(), + node_id, + hir_id, + ) + }, + VariantData::Tuple(ref fields, id) => { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id); + + hir::VariantData::Tuple( + fields + .iter() + .enumerate() + .map(|f| self.lower_struct_field(f)) + .collect(), + node_id, + hir_id, + ) + }, + VariantData::Unit(id) => { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id); + + hir::VariantData::Unit(node_id, hir_id) + }, } } @@ -2689,9 +2734,12 @@ impl<'a> LoweringContext<'a> { } fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(f.id); + hir::StructField { span: f.span, - id: self.lower_node_id(f.id).node_id, + id: node_id, + hir_id, ident: match f.ident { Some(ident) => ident, // FIXME(jseyfried): positional field hygiene @@ -2704,8 +2752,11 @@ impl<'a> LoweringContext<'a> { } fn lower_field(&mut self, f: &Field) -> hir::Field { + let LoweredNodeId { node_id, hir_id } = self.next_id(); + hir::Field { - id: self.next_id().node_id, + id: node_id, + hir_id, ident: f.ident, expr: P(self.lower_expr(&f.expr)), span: f.span, @@ -3463,11 +3514,13 @@ impl<'a> LoweringContext<'a> { if !def.legacy || attr::contains_name(&i.attrs, "macro_export") || attr::contains_name(&i.attrs, "rustc_doc_only_macro") { let body = self.lower_token_stream(def.stream()); + let hir_id = self.lower_node_id(i.id).hir_id; self.exported_macros.push(hir::MacroDef { name: ident.name, vis, attrs, id: i.id, + hir_id, span: i.span, body, legacy: def.legacy, @@ -3492,10 +3545,11 @@ impl<'a> LoweringContext<'a> { } fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem { - let node_id = self.lower_node_id(i.id).node_id; + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); let def_id = self.resolver.definitions().local_def_id(node_id); hir::ForeignItem { id: node_id, + hir_id, ident: i.ident, attrs: self.lower_attrs(&i.attrs), node: match i.node { @@ -3632,9 +3686,11 @@ impl<'a> LoweringContext<'a> { Some(Def::Local(id)) => id, _ => p.id, }; + let hir_id = self.lower_node_id(canonical_id).hir_id; hir::PatKind::Binding( self.lower_binding_mode(binding_mode), canonical_id, + hir_id, ident, sub.as_ref().map(|x| self.lower_pat(x)), ) @@ -3685,14 +3741,19 @@ impl<'a> LoweringContext<'a> { let fs = fields .iter() - .map(|f| Spanned { - span: f.span, - node: hir::FieldPat { - id: self.next_id().node_id, - ident: f.node.ident, - pat: self.lower_pat(&f.node.pat), - is_shorthand: f.node.is_shorthand, - }, + .map(|f| { + let LoweredNodeId { node_id, hir_id } = self.next_id(); + + Spanned { + span: f.span, + node: hir::FieldPat { + id: node_id, + hir_id, + ident: f.node.ident, + pat: self.lower_pat(&f.node.pat), + is_shorthand: f.node.is_shorthand, + }, + } }) .collect(); hir::PatKind::Struct(qpath, fs, etc) @@ -4347,8 +4408,10 @@ impl<'a> LoweringContext<'a> { ThinVec::new(), )) }; + let LoweredNodeId { node_id, hir_id } = self.next_id(); let match_stmt = hir::Stmt { - id: self.next_id().node_id, + id: node_id, + hir_id, node: hir::StmtKind::Expr(match_expr), span: head_sp, }; @@ -4374,8 +4437,10 @@ impl<'a> LoweringContext<'a> { let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); let body_expr = P(self.expr_block(body_block, ThinVec::new())); + let LoweredNodeId { node_id, hir_id } = self.next_id(); let body_stmt = hir::Stmt { - id: self.next_id().node_id, + id: node_id, + hir_id, node: hir::StmtKind::Expr(body_expr), span: body.span, }; @@ -4551,16 +4616,26 @@ impl<'a> LoweringContext<'a> { let (l, item_ids) = self.lower_local(l); let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids .into_iter() - .map(|item_id| hir::Stmt { - id: self.next_id().node_id, - node: hir::StmtKind::Item(P(item_id)), - span: s.span, + .map(|item_id| { + let LoweredNodeId { node_id, hir_id } = self.next_id(); + + hir::Stmt { + id: node_id, + hir_id, + node: hir::StmtKind::Item(P(item_id)), + span: s.span, + } }) .collect(); - ids.push(hir::Stmt { - id: self.lower_node_id(s.id).node_id, - node: hir::StmtKind::Local(P(l)), - span: s.span, + ids.push({ + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(s.id); + + hir::Stmt { + id: node_id, + hir_id, + node: hir::StmtKind::Local(P(l)), + span: s.span, + } }); return ids; }, @@ -4569,24 +4644,39 @@ impl<'a> LoweringContext<'a> { let mut id = Some(s.id); return self.lower_item_id(it) .into_iter() - .map(|item_id| hir::Stmt { - id: id.take() - .map(|id| self.lower_node_id(id).node_id) - .unwrap_or_else(|| self.next_id().node_id), - node: hir::StmtKind::Item(P(item_id)), - span: s.span, + .map(|item_id| { + let LoweredNodeId { node_id, hir_id } = id.take() + .map(|id| self.lower_node_id(id)) + .unwrap_or_else(|| self.next_id()); + + hir::Stmt { + id: node_id, + hir_id, + node: hir::StmtKind::Item(P(item_id)), + span: s.span, + } }) .collect(); } - StmtKind::Expr(ref e) => hir::Stmt { - id: self.lower_node_id(s.id).node_id, - node: hir::StmtKind::Expr(P(self.lower_expr(e))), - span: s.span, + StmtKind::Expr(ref e) => { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(s.id); + + hir::Stmt { + id: node_id, + hir_id, + node: hir::StmtKind::Expr(P(self.lower_expr(e))), + span: s.span, + } }, - StmtKind::Semi(ref e) => hir::Stmt { - id: self.lower_node_id(s.id).node_id, - node: hir::StmtKind::Semi(P(self.lower_expr(e))), - span: s.span, + StmtKind::Semi(ref e) => { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(s.id); + + hir::Stmt { + id: node_id, + hir_id, + node: hir::StmtKind::Semi(P(self.lower_expr(e))), + span: s.span, + } }, StmtKind::Mac(..) => panic!("Shouldn't exist here"), }] @@ -4697,8 +4787,11 @@ impl<'a> LoweringContext<'a> { } fn field(&mut self, ident: Ident, expr: P, span: Span) -> hir::Field { + let LoweredNodeId { node_id, hir_id } = self.next_id(); + hir::Field { - id: self.next_id().node_id, + id: node_id, + hir_id, ident, span, expr, @@ -4810,8 +4903,11 @@ impl<'a> LoweringContext<'a> { attrs: ThinVec::new(), source, }; + + let LoweredNodeId { node_id, hir_id } = self.next_id(); hir::Stmt { - id: self.next_id().node_id, + id: node_id, + hir_id, node: hir::StmtKind::Local(P(local)), span: sp } @@ -4906,7 +5002,7 @@ impl<'a> LoweringContext<'a> { P(hir::Pat { id: node_id, hir_id, - node: hir::PatKind::Binding(bm, node_id, ident.with_span_pos(span), None), + node: hir::PatKind::Binding(bm, node_id, hir_id, ident.with_span_pos(span), None), span, }) } @@ -4992,8 +5088,10 @@ impl<'a> LoweringContext<'a> { // `'f`. AnonymousLifetimeMode::CreateParameter => { let fresh_name = self.collect_fresh_in_band_lifetime(span); + let LoweredNodeId { node_id, hir_id } = self.next_id(); hir::Lifetime { - id: self.next_id().node_id, + id: node_id, + hir_id, span, name: hir::LifetimeName::Param(fresh_name), } @@ -5093,8 +5191,11 @@ impl<'a> LoweringContext<'a> { } fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime { + let LoweredNodeId { node_id, hir_id } = self.next_id(); + hir::Lifetime { - id: self.next_id().node_id, + id: node_id, + hir_id, span, name: hir::LifetimeName::Implicit, } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index c3e4f0c05014c..9066f2238cf24 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -875,7 +875,7 @@ impl<'hir> Map<'hir> { Node::Field(f) => f.ident.name, Node::Lifetime(lt) => lt.name.ident().name, Node::GenericParam(param) => param.name.ident().name, - Node::Binding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.name, + Node::Binding(&Pat { node: PatKind::Binding(_, _, _, l, _), .. }) => l.name, Node::StructCtor(_) => self.name(self.get_parent(id)), _ => bug!("no name for {}", self.node_to_string(id)) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 657e6e5dcde35..924b044da5fc3 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -146,6 +146,7 @@ pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX; #[derive(Clone, RustcEncodable, RustcDecodable, Copy)] pub struct Lifetime { pub id: NodeId, + pub hir_id: HirId, pub span: Span, /// Either "'a", referring to a named lifetime definition, @@ -321,6 +322,7 @@ pub struct PathSegment { // affected. (In general, we don't bother to get the defs for synthesized // segments, only for segments which have come from the AST). pub id: Option, + pub hir_id: Option, pub def: Option, /// Type/lifetime parameters attached to this path. They come in @@ -343,6 +345,7 @@ impl PathSegment { PathSegment { ident, id: None, + hir_id: None, def: None, infer_types: true, args: None, @@ -352,6 +355,7 @@ impl PathSegment { pub fn new( ident: Ident, id: Option, + hir_id: Option, def: Option, args: GenericArgs, infer_types: bool, @@ -359,6 +363,7 @@ impl PathSegment { PathSegment { ident, id, + hir_id, def, infer_types, args: if args.is_empty() { @@ -528,6 +533,7 @@ pub enum GenericParamKind { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct GenericParam { pub id: NodeId, + pub hir_id: HirId, pub name: ParamName, pub attrs: HirVec, pub bounds: GenericBounds, @@ -558,6 +564,7 @@ impl Generics { params: HirVec::new(), where_clause: WhereClause { id: DUMMY_NODE_ID, + hir_id: DUMMY_HIR_ID, predicates: HirVec::new(), }, span: DUMMY_SP, @@ -601,6 +608,7 @@ pub enum SyntheticTyParamKind { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereClause { pub id: NodeId, + pub hir_id: HirId, pub predicates: HirVec, } @@ -661,6 +669,7 @@ pub struct WhereRegionPredicate { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereEqPredicate { pub id: NodeId, + pub hir_id: HirId, pub span: Span, pub lhs_ty: P, pub rhs_ty: P, @@ -789,6 +798,7 @@ pub struct MacroDef { pub vis: Visibility, pub attrs: HirVec, pub id: NodeId, + pub hir_id: HirId, pub span: Span, pub body: TokenStream, pub legacy: bool, @@ -878,6 +888,7 @@ impl Pat { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct FieldPat { pub id: NodeId, + pub hir_id: HirId, /// The identifier for the field pub ident: Ident, /// The pattern the field is destructured to @@ -924,7 +935,7 @@ pub enum PatKind { /// The `NodeId` is the canonical ID for the variable being bound, /// e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID, /// which is the pattern ID of the first `x`. - Binding(BindingAnnotation, NodeId, Ident, Option>), + Binding(BindingAnnotation, NodeId, HirId, Ident, Option>), /// A struct or struct variant pattern, e.g., `Variant {x, y, ..}`. /// The `bool` is `true` in the presence of a `..`. @@ -1137,6 +1148,7 @@ impl UnOp { #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct Stmt { pub id: NodeId, + pub hir_id: HirId, pub node: StmtKind, pub span: Span, } @@ -1204,6 +1216,7 @@ pub enum Guard { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Field { pub id: NodeId, + pub hir_id: HirId, pub ident: Ident, pub expr: P, pub span: Span, @@ -1711,6 +1724,7 @@ pub enum ImplItemKind { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct TypeBinding { pub id: NodeId, + pub hir_id: HirId, pub ident: Ident, pub ty: P, pub span: Span, @@ -2106,6 +2120,7 @@ pub struct StructField { pub ident: Ident, pub vis: Visibility, pub id: NodeId, + pub hir_id: HirId, pub ty: P, pub attrs: HirVec, } @@ -2131,21 +2146,30 @@ impl StructField { /// Id of the whole struct lives in `Item`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum VariantData { - Struct(HirVec, NodeId), - Tuple(HirVec, NodeId), - Unit(NodeId), + Struct(HirVec, NodeId, HirId), + Tuple(HirVec, NodeId, HirId), + Unit(NodeId, HirId), } impl VariantData { pub fn fields(&self) -> &[StructField] { match *self { - VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields, + VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => fields, _ => &[], } } pub fn id(&self) -> NodeId { match *self { - VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id, + VariantData::Struct(_, id, ..) + | VariantData::Tuple(_, id, ..) + | VariantData::Unit(id, ..) => id, + } + } + pub fn hir_id(&self) -> HirId { + match *self { + VariantData::Struct(_, _, hir_id) + | VariantData::Tuple(_, _, hir_id) + | VariantData::Unit(_, hir_id) => hir_id, } } pub fn is_struct(&self) -> bool { @@ -2343,6 +2367,7 @@ pub struct ForeignItem { pub attrs: HirVec, pub node: ForeignItemKind, pub id: NodeId, + pub hir_id: HirId, pub span: Span, pub vis: Visibility, } diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 4df71a8768ab2..e2a03c638764d 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -83,7 +83,7 @@ impl hir::Pat { where F: FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident), { self.walk(|p| { - if let PatKind::Binding(binding_mode, _, ident, _) = p.node { + if let PatKind::Binding(binding_mode, _, _, ident, _) = p.node { f(binding_mode, p.hir_id, p.span, ident); } true @@ -123,8 +123,8 @@ impl hir::Pat { pub fn simple_ident(&self) -> Option { match self.node { - PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) | - PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, None) => Some(ident), + PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, ident, None) | + PatKind::Binding(hir::BindingAnnotation::Mutable, _, _, ident, None) => Some(ident), _ => None, } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index e950f25c2ac9a..89b5b7a190df6 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1768,7 +1768,7 @@ impl<'a> State<'a> { // is that it doesn't matter match pat.node { PatKind::Wild => self.s.word("_")?, - PatKind::Binding(binding_mode, _, ident, ref sub) => { + PatKind::Binding(binding_mode, _, _, ident, ref sub) => { match binding_mode { hir::BindingAnnotation::Ref => { self.word_nbsp("ref")?; @@ -2246,6 +2246,7 @@ impl<'a> State<'a> { params: hir::HirVec::new(), where_clause: hir::WhereClause { id: ast::DUMMY_NODE_ID, + hir_id: hir::DUMMY_HIR_ID, predicates: hir::HirVec::new(), }, span: syntax_pos::DUMMY_SP, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 9022cabe7798d..1061ea752af11 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -159,6 +159,7 @@ impl_stable_hash_for!(struct ast::Label { impl_stable_hash_for!(struct hir::Lifetime { id, + hir_id, span, name }); @@ -172,6 +173,7 @@ impl_stable_hash_for!(struct hir::Path { impl_stable_hash_for!(struct hir::PathSegment { ident -> (ident.name), id, + hir_id, def, infer_types, args @@ -200,6 +202,7 @@ impl_stable_hash_for!(enum hir::TraitBoundModifier { impl_stable_hash_for!(struct hir::GenericParam { id, + hir_id, name, pure_wrt_drop, attrs, @@ -244,6 +247,7 @@ impl_stable_hash_for!(enum hir::SyntheticTyParamKind { impl_stable_hash_for!(struct hir::WhereClause { id, + hir_id, predicates }); @@ -268,6 +272,7 @@ impl_stable_hash_for!(struct hir::WhereRegionPredicate { impl_stable_hash_for!(struct hir::WhereEqPredicate { id, + hir_id, span, lhs_ty, rhs_ty @@ -285,6 +290,7 @@ impl_stable_hash_for!(struct hir::MethodSig { impl_stable_hash_for!(struct hir::TypeBinding { id, + hir_id, ident -> (ident.name), ty, span @@ -397,6 +403,7 @@ impl_stable_hash_for!(struct hir::MacroDef { vis, attrs, id, + hir_id, span, legacy, body @@ -423,6 +430,7 @@ impl_stable_hash_for_spanned!(hir::FieldPat); impl_stable_hash_for!(struct hir::FieldPat { id -> _, + hir_id -> _, ident -> (ident.name), pat, is_shorthand, @@ -442,7 +450,7 @@ impl_stable_hash_for!(enum hir::RangeEnd { impl_stable_hash_for!(enum hir::PatKind { Wild, - Binding(binding_mode, var, name, sub), + Binding(binding_mode, var, hir_id, name, sub), Struct(path, field_pats, dotdot), TupleStruct(path, field_pats, dotdot), Path(path), @@ -485,6 +493,7 @@ impl_stable_hash_for!(enum hir::UnOp { impl_stable_hash_for!(struct hir::Stmt { id, + hir_id, node, span, }); @@ -514,6 +523,7 @@ impl_stable_hash_for!(enum hir::Guard { impl_stable_hash_for!(struct hir::Field { id -> _, + hir_id -> _, ident, expr, span, @@ -836,14 +846,15 @@ impl_stable_hash_for!(struct hir::StructField { ident -> (ident.name), vis, id, + hir_id, ty, attrs }); impl_stable_hash_for!(enum hir::VariantData { - Struct(fields, id), - Tuple(fields, id), - Unit(id) + Struct(fields, id, hir_id), + Tuple(fields, id, hir_id), + Unit(id, hir_id) }); impl<'a> HashStable> for hir::Item { @@ -929,6 +940,7 @@ impl_stable_hash_for!(struct hir::ForeignItem { attrs, node, id, + hir_id, span, vis }); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 0724d3a262d28..d47ad009c1db6 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -408,7 +408,7 @@ fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P) { while let Some(pat) = pats.pop_front() { use hir::PatKind::*; match pat.node { - Binding(_, _, _, ref inner_pat) => { + Binding(_, _, _, _, ref inner_pat) => { pats.extend(inner_pat.iter()); } Struct(_, ref fields, _) => { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5debb11902988..ea3ea59c7613f 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1024,7 +1024,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Node::Variant(&hir::Variant { span, node: hir::VariantKind { - data: hir::VariantData::Tuple(ref fields, _), + data: hir::VariantData::Tuple(ref fields, ..), .. }, .. diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 72437e270b092..f5e27a953c27d 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -99,7 +99,7 @@ pub fn gather_move_from_pat<'a, 'c, 'tcx: 'c>(bccx: &BorrowckCtxt<'a, 'tcx>, cmt: &'c mc::cmt_<'tcx>) { let source = get_pattern_source(bccx.tcx,move_pat); let pat_span_path_opt = match move_pat.node { - PatKind::Binding(_, _, ident, _) => { + PatKind::Binding(_, _, _, ident, _) => { Some(MovePlace { span: move_pat.span, name: ident.name, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 46e784c4099c8..7c25d8d8b793f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -191,7 +191,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { // (Issue #49588) continue; } - if let PatKind::Binding(_, _, ident, None) = fieldpat.node.pat.node { + if let PatKind::Binding(_, _, _, ident, None) = fieldpat.node.pat.node { if cx.tcx.find_field_index(ident, &variant) == Some(cx.tcx.field_index(fieldpat.node.id, cx.tables)) { let mut err = cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index bbf0edc6efb75..ae2ed28104e5b 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -340,7 +340,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) { - if let &PatKind::Binding(_, _, ident, _) = &p.node { + if let &PatKind::Binding(_, _, _, ident, _) = &p.node { self.check_snake_case(cx, "variable", &ident); } } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index afb0218501d18..3b212f3b7472d 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -977,7 +977,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let body = self.tcx.hir().body(body_id); self.lazy_seq(body.arguments.iter().map(|arg| { match arg.pat.node { - PatKind::Binding(_, _, ident, _) => ident.name, + PatKind::Binding(_, _, _, ident, _) => ident.name, _ => keywords::Invalid.name(), } })) diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 4755c6daf0a77..9d3ce7693ea86 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -312,6 +312,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { if let hir::PatKind::Binding( hir::BindingAnnotation::Unannotated, _, + _, upvar_ident, _, ) = pat.node diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 420ae113ad330..f38648fda0e36 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -229,7 +229,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Mir<'tcx> { let span = tcx.hir().span(ctor_id); - if let hir::VariantData::Tuple(ref fields, ctor_id) = *v { + if let hir::VariantData::Tuple(ref fields, ctor_id, _) = *v { tcx.infer_ctxt().enter(|infcx| { let mut mir = shim::build_adt_ctor(&infcx, ctor_id, fields, span); @@ -671,7 +671,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, mutability: Mutability::Not, }; if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) { - if let hir::PatKind::Binding(_, _, ident, _) = pat.node { + if let hir::PatKind::Binding(_, _, _, ident, _) = pat.node { decl.debug_name = ident.name; if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) { if bm == ty::BindByValue(hir::MutMutable) { @@ -877,8 +877,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let mut name = None; if let Some(pat) = pattern { match pat.node { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) - | hir::PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, _) => { + hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, ident, _) + | hir::PatKind::Binding(hir::BindingAnnotation::Mutable, _, _, ident, _) => { name = Some(ident.name); } _ => (), diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 8d10227cd5901..a47d64319bdc5 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -285,7 +285,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor, pat: &Pat) { pat.walk(|p| { - if let PatKind::Binding(_, _, ident, None) = p.node { + if let PatKind::Binding(_, _, _, ident, None) = p.node { if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { if bm != ty::BindByValue(hir::MutImmutable) { // Nothing to check. @@ -503,7 +503,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, for pat in pats { pat.walk(|p| { - if let PatKind::Binding(_, _, _, ref sub) = p.node { + if let PatKind::Binding(_, _, _, _, ref sub) = p.node { if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { match bm { ty::BindByValue(..) => { diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 7d48cdc1d8aef..6b7e14161186d 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -513,7 +513,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } } - PatKind::Binding(_, id, ident, ref sub) => { + PatKind::Binding(_, id, _, ident, ref sub) => { let var_ty = self.tables.node_id_to_type(pat.hir_id); if let ty::Error = var_ty.sty { // Avoid ICE diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 6ba35052c8aad..a4f011b2e2ec9 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -80,7 +80,7 @@ fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum) _: &'tcx hir::Generics, _: ast::NodeId, _: Span) { - if let hir::VariantData::Tuple(_, node_id) = *v { + if let hir::VariantData::Tuple(_, node_id, _) = *v { self.set.insert(self.tcx.hir().local_def_id(node_id)); } intravisit::walk_struct_def(self, v) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 4203c71a00a41..a90d83f3f8be0 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -227,7 +227,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.demand_eqtype_pat(pat.span, expected, rhs_ty, match_discrim_span); common_type } - PatKind::Binding(ba, var_id, _, ref sub) => { + PatKind::Binding(ba, var_id, _, _, ref sub) => { let bm = if ba == hir::BindingAnnotation::Unannotated { def_bm } else { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 48475b3dcb802..3e2a9d720f1c1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1005,7 +1005,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { // Add pattern bindings. fn visit_pat(&mut self, p: &'gcx hir::Pat) { - if let PatKind::Binding(_, _, ident, _) = p.node { + if let PatKind::Binding(_, _, _, ident, _) = p.node { let var_ty = self.assign(p.span, p.id, None); if !self.fcx.tcx.features().unsized_locals { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b0b266a61a5b6..1c8dffaf628c4 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1455,11 +1455,11 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi) } - StructCtor(&VariantData::Tuple(ref fields, _)) + StructCtor(&VariantData::Tuple(ref fields, ..)) | Variant(&Spanned { node: hir::VariantKind { - data: VariantData::Tuple(ref fields, _), + data: VariantData::Tuple(ref fields, ..), .. }, .. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6eea95b61c990..c328dbe82e4b1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3692,7 +3692,7 @@ fn name_from_pat(p: &hir::Pat) -> String { match p.node { PatKind::Wild => "_".to_string(), - PatKind::Binding(_, _, ident, _) => ident.to_string(), + PatKind::Binding(_, _, _, ident, _) => ident.to_string(), PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), PatKind::Struct(ref name, ref fields, etc) => { format!("{} {{ {}{} }}", qpath_to_string(name), @@ -4071,6 +4071,7 @@ where F: Fn(DefId) -> Def { segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment { ident: ast::Ident::from_str(&s), id: None, + hir_id: None, def: None, args: None, infer_types: false, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 7069f04fe188c..2cff6bb3924fe 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -174,6 +174,7 @@ impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> { real_name.unwrap_or(last.ident), None, None, + None, self.generics_to_path_params(generics.clone()), false, )); @@ -206,6 +207,7 @@ impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> { args.push(hir::GenericArg::Lifetime(hir::Lifetime { id: ast::DUMMY_NODE_ID, + hir_id: hir::DUMMY_HIR_ID, span: DUMMY_SP, name: hir::LifetimeName::Param(name), })); From 017cf53798f8d5a98089d3fc37b739c98e9f75b7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 17:43:55 +0100 Subject: [PATCH 0540/1064] liballoc: remove redundant extern crate. --- src/liballoc/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index ab0ade7e5547c..bd2adee15c9fe 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -125,8 +125,6 @@ extern crate std; #[cfg(test)] extern crate test; -#[cfg(test)] -extern crate rand; // Module with internal macros used by other modules (needs to be included before other modules). #[macro_use] From d80a558e4a50d0a89a753c903bd7f7d0d25e7ab4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 3 Feb 2019 00:14:32 +0100 Subject: [PATCH 0541/1064] Improve file list display --- src/librustdoc/html/static/rustdoc.css | 3 ++- src/librustdoc/html/static/source-script.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 36765496ff4e9..2e77ce2b0fd72 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1570,5 +1570,6 @@ div.name::before { } div.name.expand::before { transform: rotate(90deg); - left: -14px; + left: -15px; + top: 2px; } diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index c5d6fa16f550e..509c628ce5a46 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -94,7 +94,7 @@ function createSidebarToggle() { inner1.style.position = "relative"; var inner2 = document.createElement("div"); - inner2.style.marginTop = "-2px"; + inner2.style.paddingTop = "3px"; if (getCurrentValue("rustdoc-source-sidebar-show") === "true") { inner2.innerText = "<"; } else { From 6e72077b3b01aa33accf4925bd6faf701e322194 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 3 Feb 2019 09:48:18 +0900 Subject: [PATCH 0542/1064] submodule: update rls from c9d25b667a to f331ff7 --- Cargo.lock | 28 ++++++++++++++-------------- src/tools/rls | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ac2dfe25c395..b52f2094584ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1232,7 +1232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jsonrpc-core" -version = "9.0.0" +version = "10.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1352,7 +1352,7 @@ dependencies = [ [[package]] name = "lsp-codec" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1362,7 +1362,7 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.54.0" +version = "0.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2045,7 +2045,7 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.16" +version = "2.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2246,10 +2246,10 @@ dependencies = [ [[package]] name = "rls" -version = "1.31.6" +version = "1.34.0" dependencies = [ "cargo 0.35.0", - "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.212", "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2258,14 +2258,14 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lsp-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lsp-types 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-types 0.55.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4040,7 +4040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" "checksum jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "dd80e58f77e0cdea53ba96acc5e04479e5ffc5d869626a6beafe50fed867eace" "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be" -"checksum jsonrpc-core 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e9cbeda300803d381390fb65e8158437728c39e6987ed23bee82728b73511a7" +"checksum jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a5152c3fda235dfd68341b3edf4121bc4428642c93acbd6de88c26bf95fc5d7" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" @@ -4053,8 +4053,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd" -"checksum lsp-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b29e3d1632fef13c1286b0b2f8545a7d894ae565a7fac013b90a17ee5bfbc91" -"checksum lsp-types 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a252cc2be87d9329dd91c505a951996b3263582ba304870960faaae77b642183" +"checksum lsp-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3570f641b984e3e4613a1ca34db2ea72549bbc3c0316d33f5af91ab514dcbff" +"checksum lsp-types 0.55.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca49aeb430780992121d582520170411658b1e41bf968b917d85fd0fb6da3c5" "checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2c4deaccc2ead6a28c16c0ba82f07d52b6475397415ce40876e559b0b0ea510" @@ -4123,7 +4123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" -"checksum racer 2.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fbfcf2686b50f75a279cb42d9c6d253a1e68a475b415ea4baf7fb177ce94839a" +"checksum racer 2.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "11db0de64c3eed7ee25f7b0af2109d296a67efa1efe7566ed17cc01115f961c8" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" diff --git a/src/tools/rls b/src/tools/rls index c9d25b667af76..f331ff713917f 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit c9d25b667af766e8fe6d3b6168a5f99a0e4d722a +Subproject commit f331ff713917f6edb044c7e5c6c28c3845afebe7 From 285106a40e70cd5b240625749e4eac8fce96fcf9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 3 Feb 2019 04:37:50 +0100 Subject: [PATCH 0543/1064] liballoc: alloc-extern-crates test needs --edition=2018 --- src/test/run-make-fulldeps/alloc-extern-crates/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/alloc-extern-crates/Makefile b/src/test/run-make-fulldeps/alloc-extern-crates/Makefile index 7197f4e17e3cc..338caa5614ee5 100644 --- a/src/test/run-make-fulldeps/alloc-extern-crates/Makefile +++ b/src/test/run-make-fulldeps/alloc-extern-crates/Makefile @@ -2,4 +2,4 @@ all: $(RUSTC) fakealloc.rs - $(RUSTC) --crate-type=rlib ../../../liballoc/lib.rs --cfg feature=\"external_crate\" --extern external=$(TMPDIR)/$(shell $(RUSTC) --print file-names fakealloc.rs) + $(RUSTC) --edition=2018 --crate-type=rlib ../../../liballoc/lib.rs --cfg feature=\"external_crate\" --extern external=$(TMPDIR)/$(shell $(RUSTC) --print file-names fakealloc.rs) From 2396780cdaedf097dd6a8f3927749bcaf5b1238b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 3 Feb 2019 08:27:44 +0100 Subject: [PATCH 0544/1064] liballoc: revert nested imports style changes. --- src/liballoc/alloc.rs | 14 ++--- src/liballoc/benches/btree/map.rs | 9 ++- src/liballoc/benches/slice.rs | 7 +-- src/liballoc/borrow.rs | 11 ++-- src/liballoc/boxed.rs | 38 ++++++------ src/liballoc/boxed_test.rs | 14 ++--- src/liballoc/collections/binary_heap.rs | 20 +++--- src/liballoc/collections/btree/map.rs | 30 ++++----- src/liballoc/collections/btree/node.rs | 16 ++--- src/liballoc/collections/btree/search.rs | 6 +- src/liballoc/collections/btree/set.rs | 16 ++--- src/liballoc/collections/linked_list.rs | 21 ++++--- src/liballoc/collections/vec_deque.rs | 32 ++++------ src/liballoc/fmt.rs | 25 +++++--- src/liballoc/prelude.rs | 13 ++-- src/liballoc/raw_vec.rs | 22 +++---- src/liballoc/rc.rs | 64 +++++++++---------- src/liballoc/slice.rs | 25 ++++---- src/liballoc/str.rs | 34 +++++------ src/liballoc/string.rs | 38 +++++------- src/liballoc/sync.rs | 78 +++++++++++------------- src/liballoc/task.rs | 8 +-- src/liballoc/tests/arc.rs | 10 ++- src/liballoc/tests/binary_heap.rs | 11 ++-- src/liballoc/tests/btree/map.rs | 11 ++-- src/liballoc/tests/btree/set.rs | 7 +-- src/liballoc/tests/lib.rs | 6 +- src/liballoc/tests/rc.rs | 10 ++- src/liballoc/tests/slice.rs | 26 ++++---- src/liballoc/tests/str.rs | 14 ++--- src/liballoc/tests/string.rs | 10 ++- src/liballoc/tests/vec.rs | 12 ++-- src/liballoc/tests/vec_deque.rs | 14 ++--- src/liballoc/vec.rs | 39 +++++------- 34 files changed, 305 insertions(+), 406 deletions(-) diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 515de9852d1a6..ec652df3b37a4 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -2,11 +2,9 @@ #![stable(feature = "alloc_module", since = "1.28.0")] -use core::{ - intrinsics::{min_align_of_val, size_of_val}, - ptr::{NonNull, Unique}, - usize, -}; +use core::intrinsics::{min_align_of_val, size_of_val}; +use core::ptr::{NonNull, Unique}; +use core::usize; #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] @@ -230,10 +228,8 @@ pub fn handle_alloc_error(layout: Layout) -> ! { mod tests { extern crate test; use test::Bencher; - use crate::{ - boxed::Box, - alloc::{Global, Alloc, Layout, handle_alloc_error}, - }; + use crate::boxed::Box; + use crate::alloc::{Global, Alloc, Layout, handle_alloc_error}; #[test] fn allocate_zeroed() { diff --git a/src/liballoc/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs index 3865ec866aeed..4c17bdc3e9e9d 100644 --- a/src/liballoc/benches/btree/map.rs +++ b/src/liballoc/benches/btree/map.rs @@ -1,8 +1,7 @@ -use std::{ - iter::Iterator, - vec::Vec, - collections::BTreeMap, -}; +use std::iter::Iterator; +use std::vec::Vec; +use std::collections::BTreeMap; + use rand::{Rng, seq::SliceRandom, thread_rng}; use test::{Bencher, black_box}; diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs index d87b70f2d932c..f17fb8212ce19 100644 --- a/src/liballoc/benches/slice.rs +++ b/src/liballoc/benches/slice.rs @@ -1,8 +1,7 @@ use std::{mem, ptr}; -use rand::{ - thread_rng, Rng, SeedableRng, - distributions::{Standard, Alphanumeric}, -}; + +use rand::{thread_rng, Rng, SeedableRng}; +use rand::distributions::{Standard, Alphanumeric}; use rand_xorshift::XorShiftRng; use test::{Bencher, black_box}; diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 1fda36778f486..270f48e80835a 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -2,16 +2,15 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - cmp::Ordering, - hash::{Hash, Hasher}, - ops::{Add, AddAssign, Deref}, -}; +use core::cmp::Ordering; +use core::hash::{Hash, Hasher}; +use core::ops::{Add, AddAssign, Deref}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::borrow::{Borrow, BorrowMut}; -use crate::{fmt, string::String}; +use crate::fmt; +use crate::string::String; use Cow::*; diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 40b091b92c1a5..8e01e12e0b8de 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -56,28 +56,26 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - any::Any, - borrow, - cmp::Ordering, - convert::From, - fmt, - future::Future, - hash::{Hash, Hasher}, - iter::{Iterator, FromIterator, FusedIterator}, - marker::{Unpin, Unsize}, - mem, - pin::Pin, - ops::{CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState}, - ptr::{self, NonNull, Unique}, - task::{LocalWaker, Poll}, +use core::any::Any; +use core::borrow; +use core::cmp::Ordering; +use core::convert::From; +use core::fmt; +use core::future::Future; +use core::hash::{Hash, Hasher}; +use core::iter::{Iterator, FromIterator, FusedIterator}; +use core::marker::{Unpin, Unsize}; +use core::mem; +use core::pin::Pin; +use core::ops::{ + CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState }; +use core::ptr::{self, NonNull, Unique}; +use core::task::{LocalWaker, Poll}; -use crate::{ - vec::Vec, - raw_vec::RawVec, - str::from_boxed_utf8_unchecked, -}; +use crate::vec::Vec; +use crate::raw_vec::RawVec; +use crate::str::from_boxed_utf8_unchecked; /// A pointer type for heap allocation. /// diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs index 6fb01fbc6a150..654eabd070326 100644 --- a/src/liballoc/boxed_test.rs +++ b/src/liballoc/boxed_test.rs @@ -1,13 +1,11 @@ //! Test for `boxed` mod. -use core::{ - any::Any, - ops::Deref, - result::Result::{Err, Ok}, - clone::Clone, - f64, - i64, -}; +use core::any::Any; +use core::ops::Deref; +use core::result::Result::{Err, Ok}; +use core::clone::Clone; +use core::f64; +use core::i64; use std::boxed::Box; diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 5f0386400d707..f97522140a8a1 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -145,18 +145,14 @@ #![allow(missing_docs)] #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - ops::{Deref, DerefMut}, - iter::{FromIterator, FusedIterator}, - mem::{swap, size_of, ManuallyDrop}, - ptr, - fmt, -}; - -use crate::{ - slice, - vec::{self, Vec}, -}; +use core::ops::{Deref, DerefMut}; +use core::iter::{FromIterator, FusedIterator}; +use core::mem::{swap, size_of, ManuallyDrop}; +use core::ptr; +use core::fmt; + +use crate::slice; +use crate::vec::{self, Vec}; use super::SpecExtend; diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index fe6b5fef210e1..aaaa419dcb849 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1,21 +1,15 @@ -use core::{ - borrow::Borrow, - cmp::Ordering, - fmt::Debug, - hash::{Hash, Hasher}, - iter::{FromIterator, Peekable, FusedIterator}, - marker::PhantomData, - ops::{ - Bound::{Excluded, Included, Unbounded}, - Index, RangeBounds, - }, - fmt, intrinsics, mem, ptr, -}; - -use super::{ - node::{self, Handle, NodeRef, marker, InsertResult::*, ForceResult::*}, - search::{self, SearchResult::*}, -}; +use core::borrow::Borrow; +use core::cmp::Ordering; +use core::fmt::Debug; +use core::hash::{Hash, Hasher}; +use core::iter::{FromIterator, Peekable, FusedIterator}; +use core::marker::PhantomData; +use core::ops::Bound::{Excluded, Included, Unbounded}; +use core::ops::{Index, RangeBounds}; +use core::{fmt, intrinsics, mem, ptr}; + +use super::node::{self, Handle, NodeRef, marker, InsertResult::*, ForceResult::*}; +use super::search::{self, SearchResult::*}; use UnderflowResult::*; use Entry::*; diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index a5f90aa8974b6..c4f39430533dc 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -31,17 +31,13 @@ // - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges. // This implies that even an empty internal node has at least one edge. -use core::{ - marker::PhantomData, - mem::{self, MaybeUninit}, - ptr::{self, Unique, NonNull}, - slice, -}; +use core::marker::PhantomData; +use core::mem::{self, MaybeUninit}; +use core::ptr::{self, Unique, NonNull}; +use core::slice; -use crate::{ - alloc::{Global, Alloc, Layout}, - boxed::Box, -}; +use crate::alloc::{Global, Alloc, Layout}; +use crate::boxed::Box; const B: usize = 6; pub const MIN_LEN: usize = B - 1; diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs index 1645e48cb5299..dfb67d2ea5756 100644 --- a/src/liballoc/collections/btree/search.rs +++ b/src/liballoc/collections/btree/search.rs @@ -1,7 +1,5 @@ -use core::{ - borrow::Borrow, - cmp::Ordering, -}; +use core::borrow::Borrow; +use core::cmp::Ordering; use super::node::{Handle, NodeRef, marker, ForceResult::*}; diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index ba3b3ed76c82f..78cd21dd4118d 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1,16 +1,12 @@ // This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface // to TreeMap -use core::{ - borrow::Borrow, - cmp::{ - Ordering::{self, Less, Greater, Equal}, - min, max, - }, - fmt::{self, Debug}, - iter::{Peekable, FromIterator, FusedIterator}, - ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}, -}; +use core::borrow::Borrow; +use core::cmp::Ordering::{self, Less, Greater, Equal}; +use core::cmp::{min, max}; +use core::fmt::{self, Debug}; +use core::iter::{Peekable, FromIterator, FusedIterator}; +use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}; use crate::collections::btree_map::{self, BTreeMap, Keys}; use super::Recover; diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index f601fa2c8d190..afd8078cdd753 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -12,15 +12,13 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - cmp::Ordering, - fmt, - hash::{Hasher, Hash}, - iter::{FromIterator, FusedIterator}, - marker::PhantomData, - mem, - ptr::NonNull, -}; +use core::cmp::Ordering; +use core::fmt; +use core::hash::{Hasher, Hash}; +use core::iter::{FromIterator, FusedIterator}; +use core::marker::PhantomData; +use core::mem; +use core::ptr::NonNull; use crate::boxed::Box; use super::SpecExtend; @@ -1215,8 +1213,11 @@ unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {} #[cfg(test)] mod tests { - use std::{thread, vec::Vec}; + use std::thread; + use std::vec::Vec; + use rand::{thread_rng, RngCore}; + use super::{LinkedList, Node}; #[cfg(test)] diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index f92c7ed04f4e3..99fa54acb0836 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -7,25 +7,19 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - cmp::{self, Ordering}, - fmt, - iter::{repeat_with, FromIterator, FusedIterator}, - mem, - ops::{ - Bound::{Excluded, Included, Unbounded}, - Index, IndexMut, RangeBounds, Try, - }, - ptr::{self, NonNull}, - slice, - hash::{Hash, Hasher}, -}; - -use crate::{ - collections::CollectionAllocErr, - raw_vec::RawVec, - vec::Vec, -}; +use core::cmp::{self, Ordering}; +use core::fmt; +use core::iter::{repeat_with, FromIterator, FusedIterator}; +use core::mem; +use core::ops::Bound::{Excluded, Included, Unbounded}; +use core::ops::{Index, IndexMut, RangeBounds, Try}; +use core::ptr::{self, NonNull}; +use core::slice; +use core::hash::{Hash, Hasher}; + +use crate::collections::CollectionAllocErr; +use crate::raw_vec::RawVec; +use crate::vec::Vec; const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 const MINIMUM_CAPACITY: usize = 1; // 2 - 1 diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index a8a99c7e7a3d3..9bda7034a621b 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -509,16 +509,21 @@ #[unstable(feature = "fmt_internals", issue = "0")] pub use core::fmt::rt; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{ - Formatter, Result, Write, - Binary, Octal, - Debug, Display, - LowerHex, Pointer, UpperHex, - LowerExp, UpperExp, - Error, - write, ArgumentV1, Arguments, - DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple -}; +pub use core::fmt::{Formatter, Result, Write}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::{Binary, Octal}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::{Debug, Display}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::{LowerHex, Pointer, UpperHex}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::{LowerExp, UpperExp}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::Error; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::{write, ArgumentV1, Arguments}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub use core::fmt::{Alignment}; diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs index 3f1d6ded66d35..6767cf89f73ba 100644 --- a/src/liballoc/prelude.rs +++ b/src/liballoc/prelude.rs @@ -12,11 +12,8 @@ #![unstable(feature = "alloc", issue = "27783")] -#[unstable(feature = "alloc", issue = "27783")] -pub use crate::{ - borrow::ToOwned, - boxed::Box, - slice::SliceConcatExt, - string::{String, ToString}, - vec::Vec, -}; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index f1839f736341c..dcecf9bc76d88 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -1,19 +1,15 @@ #![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "0")] #![doc(hidden)] -use core::{ - cmp, - mem, - ops::Drop, - ptr::{self, NonNull, Unique}, - slice, -}; - -use crate::{ - alloc::{Alloc, Layout, Global, handle_alloc_error}, - collections::CollectionAllocErr::{self, *}, - boxed::Box, -}; +use core::cmp; +use core::mem; +use core::ops::Drop; +use core::ptr::{self, NonNull, Unique}; +use core::slice; + +use crate::alloc::{Alloc, Layout, Global, handle_alloc_error}; +use crate::collections::CollectionAllocErr::{self, *}; +use crate::boxed::Box; /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 01a26b6f42337..d78869270d563 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -231,29 +231,25 @@ use crate::boxed::Box; #[cfg(test)] use std::boxed::Box; -use core::{ - any::Any, - borrow, - cell::Cell, - cmp::Ordering, - fmt, - hash::{Hash, Hasher}, - intrinsics::abort, - marker::{self, Unpin, Unsize, PhantomData}, - mem::{self, align_of_val, forget, size_of_val}, - ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}, - pin::Pin, - ptr::{self, NonNull}, - slice::from_raw_parts_mut, - convert::From, - usize, -}; - -use crate::{ - alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}, - string::String, - vec::Vec, -}; +use core::any::Any; +use core::borrow; +use core::cell::Cell; +use core::cmp::Ordering; +use core::fmt; +use core::hash::{Hash, Hasher}; +use core::intrinsics::abort; +use core::marker::{self, Unpin, Unsize, PhantomData}; +use core::mem::{self, align_of_val, forget, size_of_val}; +use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; +use core::pin::Pin; +use core::ptr::{self, NonNull}; +use core::slice::from_raw_parts_mut; +use core::convert::From; +use core::usize; + +use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; +use crate::string::String; +use crate::vec::Vec; struct RcBox { strong: Cell, @@ -1563,15 +1559,13 @@ impl RcBoxPtr for RcBox { #[cfg(test)] mod tests { use super::{Rc, Weak}; - use std::{ - boxed::Box, - cell::RefCell, - option::Option::{self, None, Some}, - result::Result::{Err, Ok}, - mem::drop, - clone::Clone, - convert::From, - }; + use std::boxed::Box; + use std::cell::RefCell; + use std::option::Option::{self, None, Some}; + use std::result::Result::{Err, Ok}; + use std::mem::drop; + use std::clone::Clone; + use std::convert::From; #[test] fn test_clone() { @@ -1735,7 +1729,8 @@ mod tests { #[test] fn test_into_from_raw_unsized() { - use std::{fmt::Display, string::ToString}; + use std::fmt::Display; + use std::string::ToString; let rc: Rc = Rc::from("foo"); @@ -1943,7 +1938,8 @@ mod tests { #[test] fn test_from_box_trait() { - use std::{fmt::Display, string::ToString}; + use std::fmt::Display; + use std::string::ToString; let b: Box = box 123; let r: Rc = Rc::from(b); diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 9d1197117bbda..479959deeb1a7 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -87,19 +87,15 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![cfg_attr(test, allow(unused_imports, dead_code))] -use core::{ - borrow::{Borrow, BorrowMut}, - cmp::Ordering::{self, Less}, - mem::{self, size_of}, - ptr, - u8, u16, u32, -}; - -use crate::{ - borrow::ToOwned, - boxed::Box, - vec::Vec, -}; +use core::borrow::{Borrow, BorrowMut}; +use core::cmp::Ordering::{self, Less}; +use core::mem::{self, size_of}; +use core::ptr; +use core::{u8, u16, u32}; + +use crate::borrow::ToOwned; +use crate::boxed::Box; +use crate::vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] pub use core::slice::{Chunks, Windows}; @@ -142,8 +138,9 @@ pub use hack::to_vec; // `test_permutations` test mod hack { use core::mem; - use crate::{boxed::Box, vec::Vec}; + use crate::boxed::Box; + use crate::vec::Vec; #[cfg(test)] use crate::string::ToString; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 9681572d883f5..211e75bd91504 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -28,26 +28,20 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![allow(unused_imports)] -use core::{ - borrow::Borrow, - fmt, - str::{ - self as core_str, - pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher}, - }, - mem, - ptr, - iter::FusedIterator, - unicode::conversions, -}; - -use crate::{ - borrow::ToOwned, - boxed::Box, - slice::{SliceConcatExt, SliceIndex}, - string::String, - vec::Vec, -}; +use core::borrow::Borrow; +use core::fmt; +use core::str as core_str; +use core::str::pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher}; +use core::mem; +use core::ptr; +use core::iter::FusedIterator; +use core::unicode::conversions; + +use crate::borrow::ToOwned; +use crate::boxed::Box; +use crate::slice::{SliceConcatExt, SliceIndex}; +use crate::string::String; +use crate::vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{FromStr, Utf8Error}; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index cb497f5bde212..73f67e98f364e 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -46,30 +46,20 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - char::{decode_utf16, REPLACEMENT_CHARACTER}, - fmt, - hash, - iter::{FromIterator, FusedIterator}, - ops::{ - self, - Bound::{Excluded, Included, Unbounded}, - Add, AddAssign, Index, IndexMut, RangeBounds, - }, - ptr, - str::{ - pattern::Pattern, - lossy, - } -}; - -use crate::{ - borrow::{Cow, ToOwned}, - collections::CollectionAllocErr, - boxed::Box, - str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}, - vec::Vec, -}; +use core::char::{decode_utf16, REPLACEMENT_CHARACTER}; +use core::fmt; +use core::hash; +use core::iter::{FromIterator, FusedIterator}; +use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds}; +use core::ops::Bound::{Excluded, Included, Unbounded}; +use core::ptr; +use core::str::{pattern::Pattern, lossy}; + +use crate::borrow::{Cow, ToOwned}; +use crate::collections::CollectionAllocErr; +use crate::boxed::Box; +use crate::str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; +use crate::vec::Vec; /// A UTF-8 encoded, growable string. /// diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 52f8879d1844b..5bdb3616ed232 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -6,34 +6,28 @@ //! //! [arc]: struct.Arc.html -use core::{ - any::Any, - sync::atomic::{ - self, - Ordering::{Acquire, Relaxed, Release, SeqCst} - }, - borrow, - fmt, - cmp::{self, Ordering}, - intrinsics::abort, - mem::{self, align_of_val, size_of_val}, - ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}, - pin::Pin, - ptr::{self, NonNull}, - marker::{Unpin, Unsize, PhantomData}, - hash::{Hash, Hasher}, - isize, usize, - convert::From, - slice::from_raw_parts_mut, -}; - -use crate::{ - alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}, - boxed::Box, - rc::is_dangling, - string::String, - vec::Vec, -}; +use core::any::Any; +use core::sync::atomic; +use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; +use core::borrow; +use core::fmt; +use core::cmp::{self, Ordering}; +use core::intrinsics::abort; +use core::mem::{self, align_of_val, size_of_val}; +use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; +use core::pin::Pin; +use core::ptr::{self, NonNull}; +use core::marker::{Unpin, Unsize, PhantomData}; +use core::hash::{Hash, Hasher}; +use core::{isize, usize}; +use core::convert::From; +use core::slice::from_raw_parts_mut; + +use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; +use crate::boxed::Box; +use crate::rc::is_dangling; +use crate::string::String; +use crate::vec::Vec; /// A soft limit on the amount of references that may be made to an `Arc`. /// @@ -1654,18 +1648,16 @@ impl From> for Arc<[T]> { #[cfg(test)] mod tests { - use std::{ - boxed::Box, - clone::Clone, - sync::mpsc::channel, - mem::drop, - ops::Drop, - option::Option::{self, None, Some}, - sync::atomic::{self, Ordering::{Acquire, SeqCst}}, - thread, - sync::Mutex, - convert::From, - }; + use std::boxed::Box; + use std::clone::Clone; + use std::sync::mpsc::channel; + use std::mem::drop; + use std::ops::Drop; + use std::option::Option::{self, None, Some}; + use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; + use std::thread; + use std::sync::Mutex; + use std::convert::From; use super::{Arc, Weak}; use crate::vec::Vec; @@ -1774,7 +1766,8 @@ mod tests { #[test] fn test_into_from_raw_unsized() { - use std::{fmt::Display, string::ToString}; + use std::fmt::Display; + use std::string::ToString; let arc: Arc = Arc::from("foo"); @@ -2086,7 +2079,8 @@ mod tests { #[test] fn test_from_box_trait() { - use std::{fmt::Display, string::ToString}; + use std::fmt::Display; + use std::string::ToString; let b: Box = box 123; let r: Arc = Arc::from(b); diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index 0bf1ff35cc175..2261dabe2779a 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -8,11 +8,9 @@ pub use if_arc::*; #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] mod if_arc { use super::*; - use core::{ - marker::PhantomData, - mem, - ptr::{self, NonNull}, - }; + use core::marker::PhantomData; + use core::mem; + use core::ptr::{self, NonNull}; use crate::sync::Arc; /// A way of waking up a specific task. diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index b71cf3bd47795..2759b1b1cac27 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -1,9 +1,7 @@ -use std::{ - any::Any, - sync::{Arc, Weak}, - cell::RefCell, - cmp::PartialEq, -}; +use std::any::Any; +use std::sync::{Arc, Weak}; +use std::cell::RefCell; +use std::cmp::PartialEq; #[test] fn uninhabited() { diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index f19d641fe83eb..94ae43237d19c 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -1,9 +1,8 @@ -use std::{ - cmp, - collections::{BinaryHeap, binary_heap::{Drain, PeekMut}}, - panic::{self, AssertUnwindSafe}, - sync::atomic::{AtomicUsize, Ordering}, -}; +use std::cmp; +use std::collections::BinaryHeap; +use std::collections::binary_heap::{Drain, PeekMut}; +use std::panic::{self, AssertUnwindSafe}; +use std::sync::atomic::{AtomicUsize, Ordering}; use rand::{thread_rng, seq::SliceRandom}; diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 6859b0138b5ed..aaf504073285d 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -1,9 +1,8 @@ -use std::{ - collections::{BTreeMap, btree_map::Entry::{Occupied, Vacant}}, - ops::Bound::{self, Excluded, Included, Unbounded}, - rc::Rc, - iter::FromIterator, -}; +use std::collections::BTreeMap; +use std::collections::btree_map::Entry::{Occupied, Vacant}; +use std::ops::Bound::{self, Excluded, Included, Unbounded}; +use std::rc::Rc; +use std::iter::FromIterator; use super::DeterministicRng; diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index b90ecd9e3f136..4f5168f1ce572 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -1,7 +1,6 @@ -use std::{ - collections::BTreeSet, - iter::FromIterator -}; +use std::collections::BTreeSet; +use std::iter::FromIterator; + use super::DeterministicRng; #[test] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 100b3986370ab..a76fd87a1a92d 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -13,10 +13,8 @@ extern crate core; extern crate rand; -use std::{ - hash::{Hash, Hasher}, - collections::hash_map::DefaultHasher, -}; +use std::hash::{Hash, Hasher}; +use std::collections::hash_map::DefaultHasher; mod arc; mod binary_heap; diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index caa3c914fc248..18f82e8041008 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -1,9 +1,7 @@ -use std::{ - any::Any, - rc::{Rc, Weak}, - cell::RefCell, - cmp::PartialEq, -}; +use std::any::Any; +use std::rc::{Rc, Weak}; +use std::cell::RefCell; +use std::cmp::PartialEq; #[test] fn uninhabited() { diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index d0a8b65ae8be0..334466dfb25f5 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1,18 +1,14 @@ -use std::{ - cell::Cell, - cmp::Ordering::{self, Equal, Greater, Less}, - mem, - panic, - rc::Rc, - sync::atomic::{Ordering::Relaxed, AtomicUsize}, - thread, -}; - -use rand::{ - Rng, RngCore, thread_rng, - seq::SliceRandom, - distributions::Standard, -}; +use std::cell::Cell; +use std::cmp::Ordering::{self, Equal, Greater, Less}; +use std::mem; +use std::panic; +use std::rc::Rc; +use std::sync::atomic::{Ordering::Relaxed, AtomicUsize}; +use std::thread; + +use rand::{Rng, RngCore, thread_rng}; +use rand::seq::SliceRandom; +use rand::distributions::Standard; fn square(n: usize) -> usize { n * n diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b1586558713e7..1bc1bd8d78c57 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1,8 +1,6 @@ -use std::{ - borrow::Cow, - cmp::Ordering::{Equal, Greater, Less}, - str::from_utf8, -}; +use std::borrow::Cow; +use std::cmp::Ordering::{Equal, Greater, Less}; +use std::str::from_utf8; #[test] fn test_le() { @@ -1601,10 +1599,8 @@ fn test_repeat() { } mod pattern { - use std::str::pattern::{ - Pattern, Searcher, ReverseSearcher, - SearchStep::{self, Match, Reject, Done}, - }; + use std::str::pattern::{Pattern, Searcher, ReverseSearcher}; + use std::str::pattern::SearchStep::{self, Match, Reject, Done}; macro_rules! make_test { ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => { diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 14f70fdf3034d..e5ce51a36ee22 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -1,9 +1,7 @@ -use std::{ - borrow::Cow, - collections::CollectionAllocErr::*, - mem::size_of, - usize, isize, -}; +use std::borrow::Cow; +use std::collections::CollectionAllocErr::*; +use std::mem::size_of; +use std::{usize, isize}; pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { fn into_cow(self) -> Cow<'a, B>; diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index e8fea287e1cb4..89f2e0a046d91 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,10 +1,8 @@ -use std::{ - borrow::Cow, - mem::size_of, - usize, isize, - vec::{Drain, IntoIter}, - collections::CollectionAllocErr::*, -}; +use std::borrow::Cow; +use std::mem::size_of; +use std::{usize, isize}; +use std::vec::{Drain, IntoIter}; +use std::collections::CollectionAllocErr::*; struct DropCounter<'a> { count: &'a mut u32, diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 313aa55a2b28e..aa49bdb009086 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1,12 +1,8 @@ -use std::{ - fmt::Debug, - collections::{ - VecDeque, vec_deque::Drain, - CollectionAllocErr::*, - }, - mem::size_of, - usize, isize, -}; +use std::fmt::Debug; +use std::collections::{VecDeque, vec_deque::Drain}; +use std::collections::CollectionAllocErr::*; +use std::mem::size_of; +use std::{usize, isize}; use crate::hash; diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 66a73e7579951..57e10498b92db 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -56,29 +56,22 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::{ - cmp::{self, Ordering}, - fmt, - hash::{self, Hash}, - intrinsics::{arith_offset, assume}, - iter::{FromIterator, FusedIterator, TrustedLen}, - marker::PhantomData, - mem, - ops::{ - self, - Bound::{Excluded, Included, Unbounded}, - Index, IndexMut, RangeBounds, - }, - ptr::{self, NonNull}, - slice::{self, SliceIndex}, -}; - -use crate::{ - borrow::{ToOwned, Cow}, - collections::CollectionAllocErr, - boxed::Box, - raw_vec::RawVec, -}; +use core::cmp::{self, Ordering}; +use core::fmt; +use core::hash::{self, Hash}; +use core::intrinsics::{arith_offset, assume}; +use core::iter::{FromIterator, FusedIterator, TrustedLen}; +use core::marker::PhantomData; +use core::mem; +use core::ops::{self, Index, IndexMut, RangeBounds}; +use core::ops::Bound::{Excluded, Included, Unbounded}; +use core::ptr::{self, NonNull}; +use core::slice::{self, SliceIndex}; + +use crate::borrow::{ToOwned, Cow}; +use crate::collections::CollectionAllocErr; +use crate::boxed::Box; +use crate::raw_vec::RawVec; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. /// From 28fec683f552cb2bc20644f06895232c574751ab Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sun, 3 Feb 2019 08:51:50 +0100 Subject: [PATCH 0545/1064] cleanup: don't use node_to_hir_id where unneeded --- src/librustc/cfg/construct.rs | 3 +-- .../error_reporting/nice_region_error/find_anon_type.rs | 5 ++--- src/librustc/middle/region.rs | 2 +- src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_typeck/astconv.rs | 6 ++---- src/librustc_typeck/collect.rs | 6 ++---- src/librustdoc/clean/mod.rs | 3 +-- 7 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 6122fe6370940..669c2998d1cb2 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -99,7 +99,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex { - let hir_id = self.tcx.hir().node_to_hir_id(stmt.id); let exit = match stmt.node { hir::StmtKind::Local(ref local) => { let init_exit = self.opt_expr(&local.init, pred); @@ -113,7 +112,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.expr(&expr, pred) } }; - self.add_ast_node(hir_id.local_id, &[exit]) + self.add_ast_node(stmt.hir_id.local_id, &[exit]) } fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex { diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs index eeaa01375ed4d..ebaef4977f400 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -114,7 +114,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { hir::TyKind::Rptr(ref lifetime, _) => { // the lifetime of the TyRptr - let hir_id = self.tcx.hir().node_to_hir_id(lifetime.id); + let hir_id = lifetime.hir_id; match (self.tcx.named_region(hir_id), self.bound_region) { // Find the index of the anonymous region that was part of the // error. We will then search the function parameters for a bound @@ -221,8 +221,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { } fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { - let hir_id = self.tcx.hir().node_to_hir_id(lifetime.id); - match (self.tcx.named_region(hir_id), self.bound_region) { + match (self.tcx.named_region(lifetime.hir_id), self.bound_region) { // the lifetime of the TyPath! (Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => { if debruijn_index == self.current_index && anon_index == br_index { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 31f91a1bae57f..db52cc3074b9a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -840,7 +840,7 @@ fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: & } fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) { - let stmt_id = visitor.tcx.hir().node_to_hir_id(stmt.id).local_id; + let stmt_id = stmt.hir_id.local_id; debug!("resolve_stmt(stmt.id={:?})", stmt_id); // Every statement will clean up the temporaries created during diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index c50d9ddcb152e..518ae978ae17a 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -46,7 +46,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> Vec> { let mut result = vec![]; for (index, stmt) in stmts.iter().enumerate() { - let hir_id = cx.tcx.hir().node_to_hir_id(stmt.id); + let hir_id = stmt.hir_id; let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id); let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.id)); match stmt.node { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 61674070fbcb2..8da0b6dcbeac3 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -114,8 +114,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { tcx.hir().name(tcx.hir().as_local_node_id(def_id).unwrap()).as_interned_str() }; - let hir_id = tcx.hir().node_to_hir_id(lifetime.id); - let r = match tcx.named_region(hir_id) { + let r = match tcx.named_region(lifetime.hir_id) { Some(rl::Region::Static) => { tcx.types.re_static } @@ -1145,8 +1144,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { self.ast_region_to_region(lifetime, None) } else { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { - let hir_id = tcx.hir().node_to_hir_id(lifetime.id); - if tcx.named_region(hir_id).is_some() { + if tcx.named_region(lifetime.hir_id).is_some() { self.ast_region_to_region(lifetime, None) } else { self.re_infer(span, None).unwrap_or_else(|| { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1c8dffaf628c4..9dc74c5d63a4e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -814,8 +814,7 @@ fn has_late_bound_regions<'a, 'tcx>( return; } - let hir_id = self.tcx.hir().node_to_hir_id(lt.id); - match self.tcx.named_region(hir_id) { + match self.tcx.named_region(lt.hir_id) { Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {} Some(rl::Region::LateBound(debruijn, _, _)) | Some(rl::Region::LateBoundAnon(debruijn, _)) if debruijn < self.outer_index => {} @@ -841,8 +840,7 @@ fn has_late_bound_regions<'a, 'tcx>( }; for param in &generics.params { if let GenericParamKind::Lifetime { .. } = param.kind { - let hir_id = tcx.hir().node_to_hir_id(param.id); - if tcx.is_late_bound(hir_id) { + if tcx.is_late_bound(param.hir_id) { return Some(param.span); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c328dbe82e4b1..116e46df3c10a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1210,8 +1210,7 @@ impl Lifetime { impl Clean for hir::Lifetime { fn clean(&self, cx: &DocContext) -> Lifetime { if self.id != ast::DUMMY_NODE_ID { - let hir_id = cx.tcx.hir().node_to_hir_id(self.id); - let def = cx.tcx.named_region(hir_id); + let def = cx.tcx.named_region(self.hir_id); match def { Some(rl::Region::EarlyBound(_, node_id, _)) | Some(rl::Region::LateBound(_, node_id, _)) | From 73c39bbcd0d316c7a140521cd0fb8e9e1061f1ce Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 3 Feb 2019 18:41:09 +0900 Subject: [PATCH 0546/1064] submodule: update clippy from 6ce78d1 to 3bda548 --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 6ce78d1257ac6..3bda548f81bc2 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 6ce78d1257ac6fd77f245730fcfbadd536a173eb +Subproject commit 3bda548f81bc268a2e9813ce9168d2e40e8a11bd From 33ee99b26a499027546f88a7f4eeddd8d4985c39 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 11:16:37 +0100 Subject: [PATCH 0547/1064] more formatting --- src/libstd/sys/redox/process.rs | 6 ++++-- src/libstd/sys/unix/process/process_common.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 9b85fa41a0a4f..62eb8cb23ab56 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -116,8 +116,10 @@ impl Command { self.gid = Some(id); } - pub unsafe fn pre_exec(&mut self, - f: Box io::Result<()> + Send + Sync>) { + pub unsafe fn pre_exec( + &mut self, + f: Box io::Result<()> + Send + Sync>, + ) { self.closures.push(f); } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 9975064ca655f..7fa256e59b2db 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -149,8 +149,10 @@ impl Command { &mut self.closures } - pub unsafe fn pre_exec(&mut self, - f: Box io::Result<()> + Send + Sync>) { + pub unsafe fn pre_exec( + &mut self, + f: Box io::Result<()> + Send + Sync>, + ) { self.closures.push(f); } From e023403da2da17ba7320c53c415b960c93348247 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 11:17:59 +0100 Subject: [PATCH 0548/1064] POSIX requires async signal safety for fork in signal handlers, not in general --- src/libstd/sys/redox/ext/process.rs | 3 +-- src/libstd/sys/unix/ext/process.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 55824dc4c059f..18aef768b5db1 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -48,8 +48,7 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. Moreover, POSIX demands that you only - /// perform operations that are explicitly documented as async-signal-safe. + /// invalid use of these duplicates. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index ac0abc761ffb5..d869a2013dc27 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -48,8 +48,7 @@ pub trait CommandExt { /// This also means that all resources such as file descriptors and /// memory-mapped regions got duplicated. It is your responsibility to make /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. Moreover, POSIX demands that you only - /// perform operations that are explicitly documented as async-signal-safe. + /// invalid use of these duplicates. /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these From f832a809bbb08bc2bb08b012cee8ee6b2178d26d Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 3 Feb 2019 21:43:09 +0900 Subject: [PATCH 0549/1064] Transition remote-test-client to 2018 edition --- src/tools/remote-test-client/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/remote-test-client/Cargo.toml b/src/tools/remote-test-client/Cargo.toml index 54739101f1eff..1a4b24bd5b34c 100644 --- a/src/tools/remote-test-client/Cargo.toml +++ b/src/tools/remote-test-client/Cargo.toml @@ -2,5 +2,6 @@ name = "remote-test-client" version = "0.1.0" authors = ["The Rust Project Developers"] +edition = "2018" [dependencies] From d17b2ec0e3830a5b673907aa2e9f8347df4c4cf4 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 3 Feb 2019 21:44:21 +0900 Subject: [PATCH 0550/1064] Transition remote-test-server to 2018 edition --- src/tools/remote-test-server/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/remote-test-server/Cargo.toml b/src/tools/remote-test-server/Cargo.toml index 8704296289e83..5906c76c01d9f 100644 --- a/src/tools/remote-test-server/Cargo.toml +++ b/src/tools/remote-test-server/Cargo.toml @@ -2,5 +2,6 @@ name = "remote-test-server" version = "0.1.0" authors = ["The Rust Project Developers"] +edition = "2018" [dependencies] From 9f34d4b3572f7db45cbe7108f392280ebc18b301 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 3 Feb 2019 21:32:59 +0900 Subject: [PATCH 0551/1064] Use 2018 edition for cargotest --- src/tools/cargotest/Cargo.toml | 1 + src/tools/cargotest/main.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/tools/cargotest/Cargo.toml b/src/tools/cargotest/Cargo.toml index f4163a6f1170a..3811fee39368f 100644 --- a/src/tools/cargotest/Cargo.toml +++ b/src/tools/cargotest/Cargo.toml @@ -2,6 +2,7 @@ name = "cargotest2" version = "0.1.0" authors = ["Brian Anderson "] +edition = "2018" [[bin]] name = "cargotest" diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 120f238eb45c5..7f3c159075b97 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -1,3 +1,5 @@ +#![deny(rust_2018_idioms)] + use std::env; use std::process::Command; use std::path::{Path, PathBuf}; From 3a133f20887b9a9677ac9af8fa56d75e4d3b6e89 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Sun, 3 Feb 2019 21:37:08 +0900 Subject: [PATCH 0552/1064] Transition linkchecker to 2018 edition --- src/tools/linkchecker/Cargo.toml | 1 + src/tools/linkchecker/main.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index d6b7dafea40e0..0994cd2066246 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -2,6 +2,7 @@ name = "linkchecker" version = "0.1.0" authors = ["Alex Crichton "] +edition = "2018" [[bin]] name = "linkchecker" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 2cf0fcfd34cd6..af704ce260dc4 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -14,6 +14,8 @@ //! A few whitelisted exceptions are allowed as there's known bugs in rustdoc, //! but this should catch the majority of "broken link" cases. +#![deny(rust_2018_idioms)] + use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::env; @@ -21,7 +23,7 @@ use std::fs; use std::path::{Path, PathBuf, Component}; use std::rc::Rc; -use Redirect::*; +use crate::Redirect::*; macro_rules! t { ($e:expr) => (match $e { From 39394c8126dcea8570dc2108f0918478bfb6962e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 18:18:39 +0100 Subject: [PATCH 0553/1064] libfmt_macros => 2018 --- src/libfmt_macros/Cargo.toml | 1 + src/libfmt_macros/lib.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libfmt_macros/Cargo.toml b/src/libfmt_macros/Cargo.toml index b3f4d2deae2fc..50779a2d9ad08 100644 --- a/src/libfmt_macros/Cargo.toml +++ b/src/libfmt_macros/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "fmt_macros" version = "0.0.0" +edition = "2018" [lib] name = "fmt_macros" diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 4f516f18bbfdd..7bfe2377cea9e 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -10,14 +10,15 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))] -#![feature(nll)] +#![deny(rust_2018_idioms)] + #![feature(rustc_private)] -pub use self::Piece::*; -pub use self::Position::*; -pub use self::Alignment::*; -pub use self::Flag::*; -pub use self::Count::*; +pub use Piece::*; +pub use Position::*; +pub use Alignment::*; +pub use Flag::*; +pub use Count::*; use std::str; use std::string; From 7f41ed62e5cb9a5af7f742f9c4515a6d3a9530c0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 18:29:08 +0100 Subject: [PATCH 0554/1064] libgraphviz => 2018 --- src/libgraphviz/Cargo.toml | 1 + src/libgraphviz/lib.rs | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libgraphviz/Cargo.toml b/src/libgraphviz/Cargo.toml index 76ef3a1d188ce..a6a3c1a249d64 100644 --- a/src/libgraphviz/Cargo.toml +++ b/src/libgraphviz/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "graphviz" version = "0.0.0" +edition = "2018" [lib] name = "graphviz" diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 164dec97b8fdb..f05f6e6651f83 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -276,10 +276,11 @@ html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(allow(unused_variables), deny(warnings))))] -#![feature(nll)] +#![deny(rust_2018_idioms)] + #![feature(str_escape)] -use self::LabelText::*; +use LabelText::*; use std::borrow::Cow; use std::io::prelude::*; @@ -548,12 +549,12 @@ impl<'a> LabelText<'a> { } /// Puts `prefix` on a line above this label, with a blank line separator. - pub fn prefix_line(self, prefix: LabelText) -> LabelText<'static> { + pub fn prefix_line(self, prefix: LabelText<'_>) -> LabelText<'static> { prefix.suffix_line(self) } /// Puts `suffix` on a line below this label, with a blank line separator. - pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> { + pub fn suffix_line(self, suffix: LabelText<'_>) -> LabelText<'static> { let mut prefix = self.pre_escaped_content().into_owned(); let suffix = suffix.pre_escaped_content(); prefix.push_str(r"\n\n"); @@ -686,7 +687,7 @@ pub fn render_opts<'a, N, E, G, W>(g: &'a G, #[cfg(test)] mod tests { - use self::NodeLabels::*; + use NodeLabels::*; use super::{Id, Labeller, Nodes, Edges, GraphWalk, render, Style}; use super::LabelText::{self, LabelStr, EscStr, HtmlStr}; use std::io; From 46c2c274f27df759a7947fc4804780bda7e3432c Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Sun, 3 Feb 2019 15:47:15 +0100 Subject: [PATCH 0555/1064] Add NVPTX target into `build-manifest` --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 4ca285b9b1db1..91cfa0981ac3d 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -78,6 +78,7 @@ static TARGETS: &'static [&'static str] = &[ "mips64el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", + "nvptx64-nvidia-cuda", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", From 09275b5cb540e3a8431877321c72684df8ad8b07 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 2 Feb 2019 18:42:38 +0100 Subject: [PATCH 0556/1064] libpanic_abort => 2018 --- src/libpanic_abort/Cargo.toml | 1 + src/libpanic_abort/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libpanic_abort/Cargo.toml b/src/libpanic_abort/Cargo.toml index e304e61c32936..2bee0b716c750 100644 --- a/src/libpanic_abort/Cargo.toml +++ b/src/libpanic_abort/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "panic_abort" version = "0.0.0" +edition = "2018" [lib] path = "lib.rs" diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index f6306d23c30c0..daa1998d29d72 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -10,11 +10,12 @@ html_root_url = "https://doc.rust-lang.org/nightly/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] #![panic_runtime] + #![allow(unused_features)] +#![deny(rust_2018_idioms)] #![feature(core_intrinsics)] #![feature(libc)] -#![feature(nll)] #![feature(panic_runtime)] #![feature(staged_api)] #![feature(rustc_attrs)] @@ -46,7 +47,6 @@ pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 { #[cfg(any(unix, target_os = "cloudabi"))] unsafe fn abort() -> ! { - extern crate libc; libc::abort(); } From 582bbcc161169591d7e8a9de70e9a4c844dd9321 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 3 Feb 2019 03:58:25 +0100 Subject: [PATCH 0557/1064] librustc_privacy => 2018 --- src/librustc_privacy/Cargo.toml | 1 + src/librustc_privacy/lib.rs | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index dfc4e5b5db45d..5bf8024c56911 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_privacy" version = "0.0.0" +edition = "2018" [lib] name = "rustc_privacy" diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 1bdc22b37d73b..dda8cabc4f2f4 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -2,18 +2,15 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(nll)] +#![deny(rust_2018_idioms)] + #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] -#[macro_use] extern crate rustc; #[macro_use] extern crate syntax; -#[macro_use] extern crate log; -extern crate rustc_typeck; -extern crate syntax_pos; -extern crate rustc_data_structures; +use rustc::bug; use rustc::hir::{self, Node, PatKind, AssociatedItemKind}; use rustc::hir::def::Def; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId}; @@ -1541,7 +1538,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { let ret = self.required_visibility == ty::Visibility::Public && self.private_crates.contains(&item_id.krate); - debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); + log::debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); return ret; } } @@ -1705,7 +1702,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> } } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { privacy_access_levels, check_mod_privacy, From b5ca255cd45c3a73fcdbf97b6101f1119ff2932e Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 00:34:55 +0900 Subject: [PATCH 0558/1064] Transition tidy and unstable-book-gento 2018 edition --- src/tools/tidy/src/main.rs | 1 + src/tools/tidy/src/unstable_book.rs | 2 +- src/tools/unstable-book-gen/Cargo.toml | 1 + src/tools/unstable-book-gen/src/main.rs | 3 ++- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 81b7b2a7731ae..6622403826665 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -4,6 +4,7 @@ //! etc. This is run by default on `make check` and as part of the auto //! builders. +#![deny(rust_2018_idioms)] #![deny(warnings)] extern crate tidy; diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index bd3b1f033c761..e5f81ba29d8d3 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -1,7 +1,7 @@ use std::collections::BTreeSet; use std::fs; use std::path; -use features::{collect_lang_features, collect_lib_features, Features, Status}; +use crate::features::{collect_lang_features, collect_lib_features, Features, Status}; pub const PATH_STR: &str = "doc/unstable-book/src"; diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml index 2839f93f8e279..3209de09aeb68 100644 --- a/src/tools/unstable-book-gen/Cargo.toml +++ b/src/tools/unstable-book-gen/Cargo.toml @@ -4,6 +4,7 @@ authors = ["est31 ", name = "unstable-book-gen" version = "0.1.0" license = "MIT/Apache-2.0" +edition = "2018" [dependencies] tidy = { path = "../tidy" } diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index df12eaf0cb028..427014ce7fe55 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -1,8 +1,9 @@ //! Auto-generate stub docs for the unstable book +#![deny(rust_2018_idioms)] #![deny(warnings)] -extern crate tidy; + use tidy::features::{Feature, Features, collect_lib_features, collect_lang_features}; use tidy::unstable_book::{collect_unstable_feature_names, collect_unstable_book_section_file_names, From 9851a296885cc745eccbc33858915d08e839eadc Mon Sep 17 00:00:00 2001 From: topecongiro Date: Mon, 4 Feb 2019 00:35:12 +0900 Subject: [PATCH 0559/1064] Add the span of attributes of the lhs to the span of the assignment expression --- src/libsyntax/parse/parser.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 514b2952c5036..1c02a80df4683 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3455,6 +3455,14 @@ impl<'a> Parser<'a> { }), }?; + // Make sure that the span of the parent node is larger than the span of lhs and rhs, + // including the attributes. + let lhs_span = lhs + .attrs + .iter() + .filter(|a| a.style == AttrStyle::Outer) + .next() + .map_or(lhs_span, |a| a.span); let span = lhs_span.to(rhs.span); lhs = match op { AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide | From d11d1afa64ca2c29747074bce0f7bb2278b5ae66 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 00:45:42 +0900 Subject: [PATCH 0560/1064] Transition rustdoc-theme to 2018 edition --- src/tools/rustdoc-themes/Cargo.toml | 1 + src/tools/rustdoc-themes/main.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/tools/rustdoc-themes/Cargo.toml b/src/tools/rustdoc-themes/Cargo.toml index c0e2f527301be..c12a20fd56c7b 100644 --- a/src/tools/rustdoc-themes/Cargo.toml +++ b/src/tools/rustdoc-themes/Cargo.toml @@ -2,6 +2,7 @@ name = "rustdoc-themes" version = "0.1.0" authors = ["Guillaume Gomez "] +edition = "2018" [[bin]] name = "rustdoc-themes" diff --git a/src/tools/rustdoc-themes/main.rs b/src/tools/rustdoc-themes/main.rs index 616b5444832c1..63432a6585a84 100644 --- a/src/tools/rustdoc-themes/main.rs +++ b/src/tools/rustdoc-themes/main.rs @@ -1,3 +1,5 @@ +#![deny(rust_2018_idioms)] + use std::env::args; use std::fs::read_dir; use std::path::Path; From 3ad0aabddab0c73dcf80f13dfb80d1a175f7364a Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 01:05:45 +0900 Subject: [PATCH 0561/1064] Transition build_helper to 2018 edition --- src/build_helper/Cargo.toml | 1 + src/build_helper/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/build_helper/Cargo.toml b/src/build_helper/Cargo.toml index 01d704f816bbc..04c7820b45665 100644 --- a/src/build_helper/Cargo.toml +++ b/src/build_helper/Cargo.toml @@ -2,6 +2,7 @@ name = "build_helper" version = "0.1.0" authors = ["The Rust Project Developers"] +edition = "2018" [lib] name = "build_helper" diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index c66c5c9249087..93aa91768121c 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,3 +1,5 @@ +#![deny(rust_2018_idioms)] + use std::fs::File; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; From ea72066f5c0cc93ea7efe73396eb691724fccaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Sun, 3 Feb 2019 18:24:05 +0200 Subject: [PATCH 0562/1064] Avoid some bounds checks in binary_heap::{PeekMut,Hole} --- src/liballoc/collections/binary_heap.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index ad544e6015e4a..473f7aee5c76b 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -248,14 +248,18 @@ impl<'a, T: Ord> Drop for PeekMut<'a, T> { impl<'a, T: Ord> Deref for PeekMut<'a, T> { type Target = T; fn deref(&self) -> &T { - &self.heap.data[0] + debug_assert!(!self.heap.is_empty()); + // SAFE: PeekMut is only instantiated for non-empty heaps + unsafe { self.heap.data.get_unchecked(0) } } } #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] impl<'a, T: Ord> DerefMut for PeekMut<'a, T> { fn deref_mut(&mut self) -> &mut T { - &mut self.heap.data[0] + debug_assert!(!self.heap.is_empty()); + // SAFE: PeekMut is only instantiated for non-empty heaps + unsafe { self.heap.data.get_unchecked_mut(0) } } } @@ -865,7 +869,8 @@ impl<'a, T> Hole<'a, T> { #[inline] unsafe fn new(data: &'a mut [T], pos: usize) -> Self { debug_assert!(pos < data.len()); - let elt = ptr::read(&data[pos]); + // SAFE: pos should be inside the slice + let elt = ptr::read(data.get_unchecked(pos)); Hole { data, elt: ManuallyDrop::new(elt), From 6413480adf6bc788e515a9746cf382e1ceb153fe Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 4 Feb 2019 03:42:27 +0900 Subject: [PATCH 0563/1064] libsyntax_pos => 2018 --- src/libsyntax_pos/Cargo.toml | 1 + src/libsyntax_pos/analyze_source_file.rs | 2 +- src/libsyntax_pos/edition.rs | 2 +- src/libsyntax_pos/hygiene.rs | 10 ++--- src/libsyntax_pos/lib.rs | 41 ++++++++------------ src/libsyntax_pos/span_encoding.rs | 6 +-- src/libsyntax_pos/symbol.rs | 49 ++++++++++++------------ 7 files changed, 51 insertions(+), 60 deletions(-) diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml index 08ee2e0f37626..5658451c54f71 100644 --- a/src/libsyntax_pos/Cargo.toml +++ b/src/libsyntax_pos/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "syntax_pos" version = "0.0.0" +edition = "2018" [lib] name = "syntax_pos" diff --git a/src/libsyntax_pos/analyze_source_file.rs b/src/libsyntax_pos/analyze_source_file.rs index 3abd260ac6f8f..18387bd5a091a 100644 --- a/src/libsyntax_pos/analyze_source_file.rs +++ b/src/libsyntax_pos/analyze_source_file.rs @@ -36,7 +36,7 @@ pub fn analyze_source_file( (lines, multi_byte_chars, non_narrow_chars) } -cfg_if! { +cfg_if::cfg_if! { if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64")))] { fn analyze_source_file_dispatch(src: &str, source_file_start_pos: BytePos, diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs index f5a745a9cd501..a0b0052f26dab 100644 --- a/src/libsyntax_pos/edition.rs +++ b/src/libsyntax_pos/edition.rs @@ -27,7 +27,7 @@ pub const EDITION_NAME_LIST: &str = "2015|2018"; pub const DEFAULT_EDITION: Edition = Edition::Edition2015; impl fmt::Display for Edition { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match *self { Edition::Edition2015 => "2015", Edition::Edition2018 => "2018", diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 6e32a05dee361..0c645fc678caf 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -5,10 +5,10 @@ //! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216. //! DOI=10.1017/S0956796812000093 -use GLOBALS; -use Span; -use edition::{Edition, DEFAULT_EDITION}; -use symbol::{keywords, Symbol}; +use crate::GLOBALS; +use crate::Span; +use crate::edition::{Edition, DEFAULT_EDITION}; +use crate::symbol::{keywords, Symbol}; use serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -525,7 +525,7 @@ impl SyntaxContext { } impl fmt::Debug for SyntaxContext { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "#{}", self.0) } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 2a85779239689..13e7307570a4f 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -8,10 +8,11 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![deny(rust_2018_idioms)] + #![feature(const_fn)] #![feature(crate_visibility_modifier)] #![feature(custom_attribute)] -#![feature(nll)] #![feature(non_exhaustive)] #![feature(optin_builtin_traits)] #![feature(rustc_attrs)] @@ -19,23 +20,11 @@ #![feature(step_trait)] #![cfg_attr(not(stage0), feature(stdsimd))] -extern crate arena; -#[macro_use] -extern crate rustc_data_structures; - -#[macro_use] -extern crate scoped_tls; - use serialize::{Encodable, Decodable, Encoder, Decoder}; -extern crate serialize; +#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; // used by deriving -#[macro_use] -extern crate cfg_if; - -extern crate unicode_width; - pub mod edition; pub mod hygiene; pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind}; @@ -74,7 +63,7 @@ impl Globals { } } -scoped_thread_local!(pub static GLOBALS: Globals); +scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals); /// Differentiates between real files and common virtual files. #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)] @@ -100,8 +89,8 @@ pub enum FileName { } impl std::fmt::Display for FileName { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - use self::FileName::*; + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use FileName::*; match *self { Real(ref path) => write!(fmt, "{}", path.display()), Macros(ref name) => write!(fmt, "<{} macros>", name), @@ -127,7 +116,7 @@ impl From for FileName { impl FileName { pub fn is_real(&self) -> bool { - use self::FileName::*; + use FileName::*; match *self { Real(_) => true, Macros(_) | @@ -143,7 +132,7 @@ impl FileName { } pub fn is_macros(&self) -> bool { - use self::FileName::*; + use FileName::*; match *self { Real(_) | Anon(_) | @@ -611,7 +600,7 @@ impl serialize::UseSpecializedDecodable for Span { } } -pub fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result { +pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Span") .field("lo", &span.lo()) .field("hi", &span.hi()) @@ -620,13 +609,13 @@ pub fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result { } impl fmt::Debug for Span { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { SPAN_DEBUG.with(|span_debug| span_debug.get()(*self, f)) } } impl fmt::Debug for SpanData { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { SPAN_DEBUG.with(|span_debug| span_debug.get()(Span::new(self.lo, self.hi, self.ctxt), f)) } } @@ -1009,7 +998,7 @@ impl Decodable for SourceFile { // `crate_of_origin` has to be set by the importer. // This value matches up with rustc::hir::def_id::INVALID_CRATE. // That constant is not available here unfortunately :( - crate_of_origin: ::std::u32::MAX - 1, + crate_of_origin: std::u32::MAX - 1, start_pos, end_pos, src: None, @@ -1025,7 +1014,7 @@ impl Decodable for SourceFile { } impl fmt::Debug for SourceFile { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "SourceFile({})", self.name) } } @@ -1111,7 +1100,7 @@ impl SourceFile { /// Get a line from the list of pre-computed line-beginnings. /// The line number here is 0-based. - pub fn get_line(&self, line_number: usize) -> Option> { + pub fn get_line(&self, line_number: usize) -> Option> { fn get_until_newline(src: &str, begin: usize) -> &str { // We can't use `lines.get(line_number+1)` because we might // be parsing when we call this function and thus the current @@ -1353,7 +1342,7 @@ pub struct FileLines { pub lines: Vec } -thread_local!(pub static SPAN_DEBUG: Cell fmt::Result> = +thread_local!(pub static SPAN_DEBUG: Cell) -> fmt::Result> = Cell::new(default_span_debug)); #[derive(Debug)] diff --git a/src/libsyntax_pos/span_encoding.rs b/src/libsyntax_pos/span_encoding.rs index 8cb3bc2144da1..03d7a9eb74238 100644 --- a/src/libsyntax_pos/span_encoding.rs +++ b/src/libsyntax_pos/span_encoding.rs @@ -4,9 +4,9 @@ // The encoding format for inline spans were obtained by optimizing over crates in rustc/libstd. // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28 -use GLOBALS; -use {BytePos, SpanData}; -use hygiene::SyntaxContext; +use crate::GLOBALS; +use crate::{BytePos, SpanData}; +use crate::hygiene::SyntaxContext; use rustc_data_structures::fx::FxHashMap; use std::hash::{Hash, Hasher}; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 7097f332b8b8f..0eecdbfa97634 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -5,6 +5,7 @@ use arena::DroplessArena; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; +use rustc_data_structures::newtype_index; use serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; @@ -12,8 +13,8 @@ use std::str; use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; use std::hash::{Hash, Hasher}; -use hygiene::SyntaxContext; -use {Span, DUMMY_SP, GLOBALS}; +use crate::hygiene::SyntaxContext; +use crate::{Span, DUMMY_SP, GLOBALS}; #[derive(Copy, Clone, Eq)] pub struct Ident { @@ -100,13 +101,13 @@ impl Hash for Ident { } impl fmt::Debug for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}{:?}", self.name, self.span.ctxt()) } } impl fmt::Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.name, f) } } @@ -181,7 +182,7 @@ impl Symbol { pub fn as_str(self) -> LocalInternedString { with_interner(|interner| unsafe { LocalInternedString { - string: ::std::mem::transmute::<&str, &str>(interner.get(self)) + string: std::mem::transmute::<&str, &str>(interner.get(self)) } }) } @@ -198,7 +199,7 @@ impl Symbol { } impl fmt::Debug for Symbol { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let is_gensymed = with_interner(|interner| interner.is_gensymed(*self)); if is_gensymed { write!(f, "{}({:?})", self, self.0) @@ -209,7 +210,7 @@ impl fmt::Debug for Symbol { } impl fmt::Display for Symbol { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.as_str(), f) } } @@ -226,7 +227,7 @@ impl Decodable for Symbol { } } -impl> PartialEq for Symbol { +impl> PartialEq for Symbol { fn eq(&self, other: &T) -> bool { self.as_str() == other.deref() } @@ -335,7 +336,7 @@ macro_rules! declare_keywords {( }; )* - impl ::std::str::FromStr for Keyword { + impl std::str::FromStr for Keyword { type Err = (); fn from_str(s: &str) -> Result { @@ -519,40 +520,40 @@ impl LocalInternedString { } } -impl ::std::convert::AsRef for LocalInternedString +impl std::convert::AsRef for LocalInternedString where - str: ::std::convert::AsRef + str: std::convert::AsRef { fn as_ref(&self) -> &U { self.string.as_ref() } } -impl> ::std::cmp::PartialEq for LocalInternedString { +impl> std::cmp::PartialEq for LocalInternedString { fn eq(&self, other: &T) -> bool { self.string == other.deref() } } -impl ::std::cmp::PartialEq for str { +impl std::cmp::PartialEq for str { fn eq(&self, other: &LocalInternedString) -> bool { self == other.string } } -impl<'a> ::std::cmp::PartialEq for &'a str { +impl<'a> std::cmp::PartialEq for &'a str { fn eq(&self, other: &LocalInternedString) -> bool { *self == other.string } } -impl ::std::cmp::PartialEq for String { +impl std::cmp::PartialEq for String { fn eq(&self, other: &LocalInternedString) -> bool { self == other.string } } -impl<'a> ::std::cmp::PartialEq for &'a String { +impl<'a> std::cmp::PartialEq for &'a String { fn eq(&self, other: &LocalInternedString) -> bool { *self == other.string } @@ -561,19 +562,19 @@ impl<'a> ::std::cmp::PartialEq for &'a String { impl !Send for LocalInternedString {} impl !Sync for LocalInternedString {} -impl ::std::ops::Deref for LocalInternedString { +impl std::ops::Deref for LocalInternedString { type Target = str; fn deref(&self) -> &str { self.string } } impl fmt::Debug for LocalInternedString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(self.string, f) } } impl fmt::Display for LocalInternedString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self.string, f) } } @@ -640,7 +641,7 @@ impl Ord for InternedString { } } -impl> PartialEq for InternedString { +impl> PartialEq for InternedString { fn eq(&self, other: &T) -> bool { self.with(|string| string == other.deref()) } @@ -676,20 +677,20 @@ impl<'a> PartialEq for &'a String { } } -impl ::std::convert::From for String { +impl std::convert::From for String { fn from(val: InternedString) -> String { val.as_symbol().to_string() } } impl fmt::Debug for InternedString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.with(|str| fmt::Debug::fmt(&str, f)) } } impl fmt::Display for InternedString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.with(|str| fmt::Display::fmt(&str, f)) } } @@ -709,7 +710,7 @@ impl Encodable for InternedString { #[cfg(test)] mod tests { use super::*; - use Globals; + use crate::Globals; #[test] fn interner_tests() { From 18da195bab0d64680d42ae141e09cbde5514a371 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 4 Feb 2019 03:55:40 +0900 Subject: [PATCH 0564/1064] libproc_macro => 2018 --- src/libproc_macro/Cargo.toml | 1 + src/libproc_macro/bridge/buffer.rs | 6 +-- src/libproc_macro/bridge/client.rs | 62 +++++++++++++++++------------- src/libproc_macro/bridge/mod.rs | 8 ++-- src/libproc_macro/bridge/rpc.rs | 18 ++++----- src/libproc_macro/bridge/server.rs | 14 +++---- src/libproc_macro/diagnostic.rs | 12 +++--- src/libproc_macro/lib.rs | 33 ++++++++-------- src/libproc_macro/quote.rs | 36 ++++++++--------- 9 files changed, 100 insertions(+), 90 deletions(-) diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml index f903f79f9afc0..b3d0ee94f0e12 100644 --- a/src/libproc_macro/Cargo.toml +++ b/src/libproc_macro/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "proc_macro" version = "0.0.0" +edition = "2018" [lib] path = "lib.rs" diff --git a/src/libproc_macro/bridge/buffer.rs b/src/libproc_macro/bridge/buffer.rs index 8bc4f0fec85a8..0d8cc552d61ab 100644 --- a/src/libproc_macro/bridge/buffer.rs +++ b/src/libproc_macro/bridge/buffer.rs @@ -6,7 +6,7 @@ use std::ops::{Deref, DerefMut}; use std::slice; #[repr(C)] -struct Slice<'a, T: 'a> { +struct Slice<'a, T> { data: &'a [T; 0], len: usize, } @@ -42,7 +42,7 @@ pub struct Buffer { data: *mut T, len: usize, capacity: usize, - extend_from_slice: extern "C" fn(Buffer, Slice) -> Buffer, + extend_from_slice: extern "C" fn(Buffer, Slice<'_, T>) -> Buffer, drop: extern "C" fn(Buffer), } @@ -139,7 +139,7 @@ impl From> for Buffer { } } - extern "C" fn extend_from_slice(b: Buffer, xs: Slice) -> Buffer { + extern "C" fn extend_from_slice(b: Buffer, xs: Slice<'_, T>) -> Buffer { let mut v = to_vec(b); v.extend_from_slice(&xs); Buffer::from(v) diff --git a/src/libproc_macro/bridge/client.rs b/src/libproc_macro/bridge/client.rs index 3095c8041f2c1..b198bdb144699 100644 --- a/src/libproc_macro/bridge/client.rs +++ b/src/libproc_macro/bridge/client.rs @@ -66,7 +66,7 @@ macro_rules! define_handles { impl DecodeMut<'_, '_, HandleStore>> for Marked { - fn decode(r: &mut Reader, s: &mut HandleStore>) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { s.$oty.take(handle::Handle::decode(r, &mut ())) } } @@ -80,7 +80,7 @@ macro_rules! define_handles { impl Decode<'_, 's, HandleStore>> for &'s Marked { - fn decode(r: &mut Reader, s: &'s HandleStore>) -> Self { + fn decode(r: &mut Reader<'_>, s: &'s HandleStore>) -> Self { &s.$oty[handle::Handle::decode(r, &mut ())] } } @@ -94,7 +94,10 @@ macro_rules! define_handles { impl DecodeMut<'_, 's, HandleStore>> for &'s mut Marked { - fn decode(r: &mut Reader, s: &'s mut HandleStore>) -> Self { + fn decode( + r: &mut Reader<'_>, + s: &'s mut HandleStore> + ) -> Self { &mut s.$oty[handle::Handle::decode(r, &mut ())] } } @@ -108,7 +111,7 @@ macro_rules! define_handles { } impl DecodeMut<'_, '_, S> for $oty { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { $oty(handle::Handle::decode(r, s)) } } @@ -130,7 +133,7 @@ macro_rules! define_handles { impl DecodeMut<'_, '_, HandleStore>> for Marked { - fn decode(r: &mut Reader, s: &mut HandleStore>) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { s.$ity.copy(handle::Handle::decode(r, &mut ())) } } @@ -144,7 +147,7 @@ macro_rules! define_handles { } impl DecodeMut<'_, '_, S> for $ity { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { $ity(handle::Handle::decode(r, s)) } } @@ -200,7 +203,7 @@ impl Clone for Literal { // FIXME(eddyb) `Literal` should not expose internal `Debug` impls. impl fmt::Debug for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.debug()) } } @@ -212,7 +215,7 @@ impl Clone for SourceFile { } impl fmt::Debug for Span { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.debug()) } } @@ -275,7 +278,7 @@ impl BridgeState<'_> { /// /// N.B., while `f` is running, the thread-local state /// is `BridgeState::InUse`. - fn with(f: impl FnOnce(&mut BridgeState) -> R) -> R { + fn with(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R { BRIDGE_STATE.with(|state| { state.replace(BridgeState::InUse, |mut state| { // FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone @@ -306,7 +309,7 @@ impl Bridge<'_> { BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f)) } - fn with(f: impl FnOnce(&mut Bridge) -> R) -> R { + fn with(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R { BridgeState::with(|state| match state { BridgeState::NotConnected => { panic!("procedural macro API is used outside of a procedural macro"); @@ -331,15 +334,15 @@ impl Bridge<'_> { #[derive(Copy, Clone)] pub struct Client { pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters, - pub(super) run: extern "C" fn(Bridge, F) -> Buffer, + pub(super) run: extern "C" fn(Bridge<'_>, F) -> Buffer, pub(super) f: F, } // FIXME(#53451) public to work around `Cannot create local mono-item` ICE, // affecting not only the function itself, but also the `BridgeState` `thread_local!`. pub extern "C" fn __run_expand1( - mut bridge: Bridge, - f: fn(::TokenStream) -> ::TokenStream, + mut bridge: Bridge<'_>, + f: fn(crate::TokenStream) -> crate::TokenStream, ) -> Buffer { // The initial `cached_buffer` contains the input. let mut b = bridge.cached_buffer.take(); @@ -352,7 +355,7 @@ pub extern "C" fn __run_expand1( // Put the `cached_buffer` back in the `Bridge`, for requests. Bridge::with(|bridge| bridge.cached_buffer = b.take()); - let output = f(::TokenStream(input)).0; + let output = f(crate::TokenStream(input)).0; // Take the `cached_buffer` back out, for the output value. b = Bridge::with(|bridge| bridge.cached_buffer.take()); @@ -378,8 +381,8 @@ pub extern "C" fn __run_expand1( b } -impl Client ::TokenStream> { - pub const fn expand1(f: fn(::TokenStream) -> ::TokenStream) -> Self { +impl Client crate::TokenStream> { + pub const fn expand1(f: fn(crate::TokenStream) -> crate::TokenStream) -> Self { Client { get_handle_counters: HandleCounters::get, run: __run_expand1, @@ -391,8 +394,8 @@ impl Client ::TokenStream> { // FIXME(#53451) public to work around `Cannot create local mono-item` ICE, // affecting not only the function itself, but also the `BridgeState` `thread_local!`. pub extern "C" fn __run_expand2( - mut bridge: Bridge, - f: fn(::TokenStream, ::TokenStream) -> ::TokenStream, + mut bridge: Bridge<'_>, + f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream, ) -> Buffer { // The initial `cached_buffer` contains the input. let mut b = bridge.cached_buffer.take(); @@ -406,7 +409,7 @@ pub extern "C" fn __run_expand2( // Put the `cached_buffer` back in the `Bridge`, for requests. Bridge::with(|bridge| bridge.cached_buffer = b.take()); - let output = f(::TokenStream(input), ::TokenStream(input2)).0; + let output = f(crate::TokenStream(input), crate::TokenStream(input2)).0; // Take the `cached_buffer` back out, for the output value. b = Bridge::with(|bridge| bridge.cached_buffer.take()); @@ -432,8 +435,10 @@ pub extern "C" fn __run_expand2( b } -impl Client ::TokenStream> { - pub const fn expand2(f: fn(::TokenStream, ::TokenStream) -> ::TokenStream) -> Self { +impl Client crate::TokenStream> { + pub const fn expand2( + f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream + ) -> Self { Client { get_handle_counters: HandleCounters::get, run: __run_expand2, @@ -448,17 +453,17 @@ pub enum ProcMacro { CustomDerive { trait_name: &'static str, attributes: &'static [&'static str], - client: Client ::TokenStream>, + client: Client crate::TokenStream>, }, Attr { name: &'static str, - client: Client ::TokenStream>, + client: Client crate::TokenStream>, }, Bang { name: &'static str, - client: Client ::TokenStream>, + client: Client crate::TokenStream>, }, } @@ -466,7 +471,7 @@ impl ProcMacro { pub const fn custom_derive( trait_name: &'static str, attributes: &'static [&'static str], - expand: fn(::TokenStream) -> ::TokenStream, + expand: fn(crate::TokenStream) -> crate::TokenStream, ) -> Self { ProcMacro::CustomDerive { trait_name, @@ -477,7 +482,7 @@ impl ProcMacro { pub const fn attr( name: &'static str, - expand: fn(::TokenStream, ::TokenStream) -> ::TokenStream, + expand: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream, ) -> Self { ProcMacro::Attr { name, @@ -485,7 +490,10 @@ impl ProcMacro { } } - pub const fn bang(name: &'static str, expand: fn(::TokenStream) -> ::TokenStream) -> Self { + pub const fn bang( + name: &'static str, + expand: fn(crate::TokenStream) -> crate::TokenStream + ) -> Self { ProcMacro::Bang { name, client: Client::expand1(expand), diff --git a/src/libproc_macro/bridge/mod.rs b/src/libproc_macro/bridge/mod.rs index 6c3e534bf9197..3173651b03951 100644 --- a/src/libproc_macro/bridge/mod.rs +++ b/src/libproc_macro/bridge/mod.rs @@ -17,7 +17,7 @@ use std::panic; use std::sync::atomic::AtomicUsize; use std::sync::Once; use std::thread; -use {Delimiter, Level, LineColumn, Spacing}; +use crate::{Delimiter, Level, LineColumn, Spacing}; /// Higher-order macro describing the server RPC API, allowing automatic /// generation of type-safe Rust APIs, both client-side and server-side. @@ -196,9 +196,9 @@ mod scoped_cell; #[forbid(unsafe_code)] pub mod server; -use self::buffer::Buffer; -pub use self::rpc::PanicMessage; -use self::rpc::{Decode, DecodeMut, Encode, Reader, Writer}; +use buffer::Buffer; +pub use rpc::PanicMessage; +use rpc::{Decode, DecodeMut, Encode, Reader, Writer}; /// An active connection between a server and a client. /// The server creates the bridge (`Bridge::run_server` in `server.rs`), diff --git a/src/libproc_macro/bridge/rpc.rs b/src/libproc_macro/bridge/rpc.rs index 74ae711a47372..a3bc0d2290846 100644 --- a/src/libproc_macro/bridge/rpc.rs +++ b/src/libproc_macro/bridge/rpc.rs @@ -40,7 +40,7 @@ macro_rules! rpc_encode_decode { } impl DecodeMut<'_, '_, S> for $ty { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { let mut byte = 0x80; let mut v = 0; let mut shift = 0; @@ -61,7 +61,7 @@ macro_rules! rpc_encode_decode { } impl DecodeMut<'_, '_, S> for $name { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { $name { $($field: DecodeMut::decode(r, s)),* } @@ -119,7 +119,7 @@ impl Encode for () { } impl DecodeMut<'_, '_, S> for () { - fn decode(_: &mut Reader, _: &mut S) -> Self {} + fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {} } impl Encode for u8 { @@ -129,7 +129,7 @@ impl Encode for u8 { } impl DecodeMut<'_, '_, S> for u8 { - fn decode(r: &mut Reader, _: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, _: &mut S) -> Self { let x = r[0]; *r = &r[1..]; x @@ -146,7 +146,7 @@ impl Encode for bool { } impl DecodeMut<'_, '_, S> for bool { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { match u8::decode(r, s) { 0 => false, 1 => true, @@ -162,7 +162,7 @@ impl Encode for char { } impl DecodeMut<'_, '_, S> for char { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { char::from_u32(u32::decode(r, s)).unwrap() } } @@ -174,7 +174,7 @@ impl Encode for NonZeroU32 { } impl DecodeMut<'_, '_, S> for NonZeroU32 { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { Self::new(u32::decode(r, s)).unwrap() } } @@ -251,7 +251,7 @@ impl Encode for String { } impl DecodeMut<'_, '_, S> for String { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { <&str>::decode(r, s).to_string() } } @@ -306,7 +306,7 @@ impl Encode for PanicMessage { } impl DecodeMut<'_, '_, S> for PanicMessage { - fn decode(r: &mut Reader, s: &mut S) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { match Option::::decode(r, s) { Some(s) => PanicMessage::String(s), None => PanicMessage::Unknown, diff --git a/src/libproc_macro/bridge/server.rs b/src/libproc_macro/bridge/server.rs index 9a7cb1318dbe4..75806eb9d1760 100644 --- a/src/libproc_macro/bridge/server.rs +++ b/src/libproc_macro/bridge/server.rs @@ -131,7 +131,7 @@ pub trait ExecutionStrategy { &self, dispatcher: &mut impl DispatcherTrait, input: Buffer, - run_client: extern "C" fn(Bridge, D) -> Buffer, + run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, client_data: D, ) -> Buffer; } @@ -143,7 +143,7 @@ impl ExecutionStrategy for SameThread { &self, dispatcher: &mut impl DispatcherTrait, input: Buffer, - run_client: extern "C" fn(Bridge, D) -> Buffer, + run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, client_data: D, ) -> Buffer { let mut dispatch = |b| dispatcher.dispatch(b); @@ -168,7 +168,7 @@ impl ExecutionStrategy for CrossThread1 { &self, dispatcher: &mut impl DispatcherTrait, input: Buffer, - run_client: extern "C" fn(Bridge, D) -> Buffer, + run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, client_data: D, ) -> Buffer { use std::sync::mpsc::channel; @@ -206,7 +206,7 @@ impl ExecutionStrategy for CrossThread2 { &self, dispatcher: &mut impl DispatcherTrait, input: Buffer, - run_client: extern "C" fn(Bridge, D) -> Buffer, + run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, client_data: D, ) -> Buffer { use std::sync::{Arc, Mutex}; @@ -273,7 +273,7 @@ fn run_server< handle_counters: &'static client::HandleCounters, server: S, input: I, - run_client: extern "C" fn(Bridge, D) -> Buffer, + run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, client_data: D, ) -> Result { let mut dispatcher = Dispatcher { @@ -289,7 +289,7 @@ fn run_server< Result::decode(&mut &b[..], &mut dispatcher.handle_store) } -impl client::Client ::TokenStream> { +impl client::Client crate::TokenStream> { pub fn run( &self, strategy: &impl ExecutionStrategy, @@ -313,7 +313,7 @@ impl client::Client ::TokenStream> { } } -impl client::Client ::TokenStream> { +impl client::Client crate::TokenStream> { pub fn run( &self, strategy: &impl ExecutionStrategy, diff --git a/src/libproc_macro/diagnostic.rs b/src/libproc_macro/diagnostic.rs index 64d0c3893c730..7a0c9419f6234 100644 --- a/src/libproc_macro/diagnostic.rs +++ b/src/libproc_macro/diagnostic.rs @@ -1,4 +1,4 @@ -use Span; +use crate::Span; /// An enum representing a diagnostic level. #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] @@ -80,7 +80,7 @@ macro_rules! diagnostic_child_methods { /// Iterator over the children diagnostics of a `Diagnostic`. #[derive(Debug, Clone)] #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] -pub struct Children<'a>(::std::slice::Iter<'a, Diagnostic>); +pub struct Children<'a>(std::slice::Iter<'a, Diagnostic>); #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] impl<'a> Iterator for Children<'a> { @@ -161,22 +161,22 @@ impl Diagnostic { /// Returns an iterator over the children diagnostics of `self`. #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] - pub fn children(&self) -> Children { + pub fn children(&self) -> Children<'_> { Children(self.children.iter()) } /// Emit the diagnostic. #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] pub fn emit(self) { - fn to_internal(spans: Vec) -> ::bridge::client::MultiSpan { - let mut multi_span = ::bridge::client::MultiSpan::new(); + fn to_internal(spans: Vec) -> crate::bridge::client::MultiSpan { + let mut multi_span = crate::bridge::client::MultiSpan::new(); for span in spans { multi_span.push(span.0); } multi_span } - let mut diag = ::bridge::client::Diagnostic::new( + let mut diag = crate::bridge::client::Diagnostic::new( self.level, &self.message[..], to_internal(self.spans), diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 868190d01057d..bb6f5e234f7c2 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -17,7 +17,8 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] -#![feature(nll)] +#![deny(rust_2018_idioms)] + #![feature(staged_api)] #![feature(const_fn)] #![feature(extern_types)] @@ -114,7 +115,7 @@ impl ToString for TokenStream { /// with `Delimiter::None` delimiters and negative numeric literals. #[stable(feature = "proc_macro_lib", since = "1.15.0")] impl fmt::Display for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.to_string()) } } @@ -122,7 +123,7 @@ impl fmt::Display for TokenStream { /// Prints token in a form convenient for debugging. #[stable(feature = "proc_macro_lib", since = "1.15.0")] impl fmt::Debug for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("TokenStream ")?; f.debug_list().entries(self.clone()).finish() } @@ -183,7 +184,7 @@ impl Extend for TokenStream { /// Public implementation details for the `TokenStream` type, such as iterators. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub mod token_stream { - use {bridge, Group, Ident, Literal, Punct, TokenTree, TokenStream}; + use crate::{bridge, Group, Ident, Literal, Punct, TokenTree, TokenStream}; /// An iterator over `TokenStream`'s `TokenTree`s. /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups, @@ -340,7 +341,7 @@ impl Span { /// Prints a span in a form convenient for debugging. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Debug for Span { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } @@ -398,7 +399,7 @@ impl SourceFile { #[unstable(feature = "proc_macro_span", issue = "54725")] impl fmt::Debug for SourceFile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SourceFile") .field("path", &self.path()) .field("is_real", &self.is_real()) @@ -483,7 +484,7 @@ impl TokenTree { /// Prints token tree in a form convenient for debugging. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Debug for TokenTree { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Each of these has the name in the struct type in the derived debug, // so don't bother with an extra layer of indirection match *self { @@ -542,7 +543,7 @@ impl ToString for TokenTree { /// with `Delimiter::None` delimiters and negative numeric literals. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for TokenTree { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.to_string()) } } @@ -667,14 +668,14 @@ impl ToString for Group { /// with `Delimiter::None` delimiters. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for Group { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.to_string()) } } #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Debug for Group { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Group") .field("delimiter", &self.delimiter()) .field("stream", &self.stream()) @@ -763,14 +764,14 @@ impl ToString for Punct { /// back into the same character. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for Punct { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.to_string()) } } #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Debug for Punct { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Punct") .field("ch", &self.as_char()) .field("spacing", &self.spacing()) @@ -842,14 +843,14 @@ impl ToString for Ident { /// back into the same identifier. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.to_string()) } } #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Debug for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Ident") .field("ident", &self.to_string()) .field("span", &self.span()) @@ -1092,14 +1093,14 @@ impl ToString for Literal { /// back into the same literal (except for possible rounding for floating point literals). #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.to_string()) } } #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Debug for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // FIXME(eddyb) `Literal` should not expose internal `Debug` impls. self.0.fmt(f) } diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs index bd7e96210a950..e3d31b78f4a09 100644 --- a/src/libproc_macro/quote.rs +++ b/src/libproc_macro/quote.rs @@ -4,7 +4,7 @@ //! This quasiquoter uses macros 2.0 hygiene to reliably access //! items from `proc_macro`, to build a `proc_macro::TokenStream`. -use {Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; +use crate::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; macro_rules! quote_tt { (($($t:tt)*)) => { Group::new(Delimiter::Parenthesis, quote!($($t)*)) }; @@ -63,7 +63,7 @@ macro_rules! quote { #[unstable(feature = "proc_macro_quote", issue = "54722")] pub fn quote(stream: TokenStream) -> TokenStream { if stream.is_empty() { - return quote!(::TokenStream::new()); + return quote!(crate::TokenStream::new()); } let mut after_dollar = false; let tokens = stream @@ -73,7 +73,7 @@ pub fn quote(stream: TokenStream) -> TokenStream { after_dollar = false; match tree { TokenTree::Ident(_) => { - return Some(quote!(Into::<::TokenStream>::into( + return Some(quote!(Into::::into( Clone::clone(&(@ tree))),)); } TokenTree::Punct(ref tt) if tt.as_char() == '$' => {} @@ -86,33 +86,33 @@ pub fn quote(stream: TokenStream) -> TokenStream { } } - Some(quote!(::TokenStream::from((@ match tree { - TokenTree::Punct(tt) => quote!(::TokenTree::Punct(::Punct::new( + Some(quote!(crate::TokenStream::from((@ match tree { + TokenTree::Punct(tt) => quote!(crate::TokenTree::Punct(crate::Punct::new( (@ TokenTree::from(Literal::character(tt.as_char()))), (@ match tt.spacing() { - Spacing::Alone => quote!(::Spacing::Alone), - Spacing::Joint => quote!(::Spacing::Joint), + Spacing::Alone => quote!(crate::Spacing::Alone), + Spacing::Joint => quote!(crate::Spacing::Joint), }), ))), - TokenTree::Group(tt) => quote!(::TokenTree::Group(::Group::new( + TokenTree::Group(tt) => quote!(crate::TokenTree::Group(crate::Group::new( (@ match tt.delimiter() { - Delimiter::Parenthesis => quote!(::Delimiter::Parenthesis), - Delimiter::Brace => quote!(::Delimiter::Brace), - Delimiter::Bracket => quote!(::Delimiter::Bracket), - Delimiter::None => quote!(::Delimiter::None), + Delimiter::Parenthesis => quote!(crate::Delimiter::Parenthesis), + Delimiter::Brace => quote!(crate::Delimiter::Brace), + Delimiter::Bracket => quote!(crate::Delimiter::Bracket), + Delimiter::None => quote!(crate::Delimiter::None), }), (@ quote(tt.stream())), ))), - TokenTree::Ident(tt) => quote!(::TokenTree::Ident(::Ident::new( + TokenTree::Ident(tt) => quote!(crate::TokenTree::Ident(crate::Ident::new( (@ TokenTree::from(Literal::string(&tt.to_string()))), (@ quote_span(tt.span())), ))), - TokenTree::Literal(tt) => quote!(::TokenTree::Literal({ + TokenTree::Literal(tt) => quote!(crate::TokenTree::Literal({ let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string()))) - .parse::<::TokenStream>() + .parse::() .unwrap() .into_iter(); - if let (Some(::TokenTree::Literal(mut lit)), None) = + if let (Some(crate::TokenTree::Literal(mut lit)), None) = (iter.next(), iter.next()) { lit.set_span((@ quote_span(tt.span()))); @@ -129,12 +129,12 @@ pub fn quote(stream: TokenStream) -> TokenStream { panic!("unexpected trailing `$` in `quote!`"); } - quote!([(@ tokens)].iter().cloned().collect::<::TokenStream>()) + quote!([(@ tokens)].iter().cloned().collect::()) } /// Quote a `Span` into a `TokenStream`. /// This is needed to implement a custom quoter. #[unstable(feature = "proc_macro_quote", issue = "54722")] pub fn quote_span(_: Span) -> TokenStream { - quote!(::Span::def_site()) + quote!(crate::Span::def_site()) } From e8aeb83a4a1f242c4ff1394b645cc180fcdd5b23 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sun, 3 Feb 2019 09:14:31 +0100 Subject: [PATCH 0565/1064] hir: add HirId methods --- src/librustc/hir/map/collector.rs | 6 ++ src/librustc/hir/map/definitions.rs | 40 ++++++++++++- src/librustc/hir/map/mod.rs | 87 +++++++++++++++++++++++++++++ src/librustc/ty/item_path.rs | 6 ++ 4 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 7cc5d756ff311..9c4fa9e127287 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -1,5 +1,6 @@ use super::*; use dep_graph::{DepGraph, DepKind, DepNodeIndex}; +use hir; use hir::def_id::{LOCAL_CRATE, CrateNum}; use hir::intravisit::{Visitor, NestedVisitorMap}; use rustc_data_structures::svh::Svh; @@ -28,6 +29,8 @@ pub(super) struct NodeCollector<'a, 'hir> { /// The parent of this node parent_node: NodeId, + parent_hir: hir::HirId, + // These fields keep track of the currently relevant DepNodes during // the visitor's traversal. current_dep_node_owner: DefIndex, @@ -145,6 +148,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { source_map: sess.source_map(), map: repeat(None).take(sess.current_node_id_count()).collect(), parent_node: CRATE_NODE_ID, + parent_hir: hir::CRATE_HIR_ID, current_signature_dep_index: root_mod_sig_dep_index, current_full_dep_index: root_mod_full_dep_index, current_dep_node_owner: CRATE_DEF_INDEX, @@ -156,6 +160,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { }; collector.insert_entry(CRATE_NODE_ID, Entry { parent: CRATE_NODE_ID, + parent_hir: hir::CRATE_HIR_ID, dep_node: root_mod_sig_dep_index, node: Node::Crate, }); @@ -226,6 +231,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { fn insert(&mut self, span: Span, id: NodeId, node: Node<'hir>) { let entry = Entry { parent: self.parent_node, + parent_hir: self.parent_hir, dep_node: if self.currently_in_body { self.current_full_dep_index } else { diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 1b7445199475c..687daca3d3ff2 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -20,7 +20,7 @@ use syntax::ast; use syntax::ext::hygiene::Mark; use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{Span, DUMMY_SP}; -use util::nodemap::NodeMap; +use util::nodemap::{HirIdMap, NodeMap}; /// The DefPathTable maps DefIndexes to DefKeys and vice versa. /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey @@ -147,6 +147,7 @@ impl Decodable for DefPathTable { pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, + hir_to_def_index: HirIdMap, def_index_to_node: [Vec; 2], pub(super) node_to_hir_id: IndexVec, /// If `Mark` is an ID of some macro expansion, @@ -441,16 +442,34 @@ impl Definitions { self.node_to_def_index.get(&node).cloned() } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn opt_def_index_from_hir_id(&self, hir: hir::HirId) -> Option { + self.hir_to_def_index.get(&hir).cloned() + } + #[inline] pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { self.opt_def_index(node).map(DefId::local) } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn opt_local_def_id_from_hir_id(&self, hir: hir::HirId) -> Option { + self.opt_def_index_from_hir_id(hir).map(DefId::local) + } + #[inline] pub fn local_def_id(&self, node: ast::NodeId) -> DefId { self.opt_local_def_id(node).unwrap() } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn local_def_id_from_hir_id(&self, hir: hir::HirId) -> DefId { + self.opt_local_def_id_from_hir_id(hir).unwrap() + } + #[inline] pub fn as_local_node_id(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { @@ -467,6 +486,21 @@ impl Definitions { } } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn as_local_hir_id(&self, def_id: DefId) -> Option { + if def_id.krate == LOCAL_CRATE { + let hir_id = self.def_index_to_hir_id(def_id.index); + if hir_id != hir::DUMMY_HIR_ID { + Some(hir_id) + } else { + None + } + } else { + None + } + } + #[inline] pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId { self.node_to_hir_id[node_id] @@ -515,6 +549,7 @@ impl Definitions { assert!(self.def_index_to_node[address_space.index()].is_empty()); self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID); self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index); + self.hir_to_def_index.insert(hir::CRATE_HIR_ID, root_index); // Allocate some other DefIndices that always must exist. GlobalMetaDataKind::allocate_def_indices(self); @@ -575,6 +610,9 @@ impl Definitions { if node_id != ast::DUMMY_NODE_ID { debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id); self.node_to_def_index.insert(node_id, index); + if let Some(hir_id) = self.node_to_hir_id.get(node_id) { + self.hir_to_def_index.insert(*hir_id, index); + } } if expansion != Mark::root() { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 9066f2238cf24..c8e19c3b49260 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -40,6 +40,7 @@ pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High; #[derive(Copy, Clone, Debug)] pub struct Entry<'hir> { parent: NodeId, + parent_hir: HirId, dep_node: DepNodeIndex, node: Node<'hir>, } @@ -208,6 +209,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn read_by_hir_id(&self, hir_id: HirId) { + let node_id = self.hir_to_node_id(hir_id); + self.read(node_id); + } + #[inline] pub fn definitions(&self) -> &'hir Definitions { self.definitions @@ -224,6 +231,11 @@ impl<'hir> Map<'hir> { }) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn def_path_from_hir_id(&self, id: HirId) -> DefPath { + self.def_path(self.local_def_id_from_hir_id(id)) + } + pub fn def_path(&self, def_id: DefId) -> DefPath { assert!(def_id.is_local()); self.definitions.def_path(def_id.index) @@ -237,6 +249,22 @@ impl<'hir> Map<'hir> { }) } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn local_def_id_from_hir_id(&self, hir_id: HirId) -> DefId { + self.opt_local_def_id_from_hir_id(hir_id).unwrap_or_else(|| { + let node_id = self.hir_to_node_id(hir_id); + bug!("local_def_id_from_hir_id: no entry for `{:?}`, which has a map of `{:?}`", + hir_id, self.find_entry(node_id)) + }) + } + + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn opt_local_def_id_from_hir_id(&self, hir_id: HirId) -> Option { + self.definitions.opt_local_def_id_from_hir_id(hir_id) + } + #[inline] pub fn opt_local_def_id(&self, node: NodeId) -> Option { self.definitions.opt_local_def_id(node) @@ -247,6 +275,12 @@ impl<'hir> Map<'hir> { self.definitions.as_local_node_id(def_id) } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn as_local_hir_id(&self, def_id: DefId) -> Option { + self.definitions.as_local_hir_id(def_id) + } + #[inline] pub fn hir_to_node_id(&self, hir_id: HirId) -> NodeId { self.hir_to_node_id[&hir_id] @@ -566,6 +600,12 @@ impl<'hir> Map<'hir> { self.find(id).unwrap_or_else(|| bug!("couldn't find node id {} in the AST map", id)) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_by_hir_id(&self, id: HirId) -> Node<'hir> { + let node_id = self.hir_to_node_id(id); + self.get(node_id) + } + pub fn get_if_local(&self, id: DefId) -> Option> { self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get` } @@ -613,6 +653,12 @@ impl<'hir> Map<'hir> { result } + // FIXME(@ljedrz): replace the NodeId variant + pub fn find_by_hir_id(&self, hir_id: HirId) -> Option> { + let node_id = self.hir_to_node_id(hir_id); + self.find(node_id) + } + /// Similar to `get_parent`; returns the parent node-id, or own `id` if there is /// no parent. Note that the parent may be `CRATE_NODE_ID`, which is not itself /// present in the map -- so passing the return value of get_parent_node to @@ -633,6 +679,13 @@ impl<'hir> Map<'hir> { self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_parent_node_by_hir_id(&self, id: HirId) -> HirId { + let node_id = self.hir_to_node_id(id); + let parent_node_id = self.get_parent_node(node_id); + self.node_to_hir_id(parent_node_id) + } + /// Check if the node is an argument. An argument is a local variable whose /// immediate parent is an item or a closure. pub fn is_argument(&self, id: NodeId) -> bool { @@ -757,6 +810,13 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_parent_item(&self, id: HirId) -> HirId { + let node_id = self.hir_to_node_id(id); + let parent_node_id = self.get_parent(node_id); + self.node_to_hir_id(parent_node_id) + } + /// Returns the `DefId` of `id`'s nearest module parent, or `id` itself if no /// module parent is in this map. pub fn get_module_parent(&self, id: NodeId) -> DefId { @@ -814,6 +874,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn expect_item_by_hir_id(&self, id: HirId) -> &'hir Item { + let node_id = self.hir_to_node_id(id); + self.expect_item(node_id) + } + pub fn expect_impl_item(&self, id: NodeId) -> &'hir ImplItem { match self.find(id) { Some(Node::ImplItem(item)) => item, @@ -960,13 +1026,28 @@ impl<'hir> Map<'hir> { node_id_to_string(self, id, true) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_to_string(&self, id: HirId) -> String { + hir_id_to_string(self, id, true) + } + pub fn node_to_user_string(&self, id: NodeId) -> String { node_id_to_string(self, id, false) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_to_user_string(&self, id: HirId) -> String { + hir_id_to_string(self, id, false) + } + pub fn node_to_pretty_string(&self, id: NodeId) -> String { print::to_string(self, |s| s.print_node(self.get(id))) } + + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_to_pretty_string(&self, id: HirId) -> String { + print::to_string(self, |s| s.print_node(self.get_by_hir_id(id))) + } } pub struct NodesMatchingSuffix<'a, 'hir:'a> { @@ -1310,6 +1391,12 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { } } +// FIXME(@ljedrz): replace the NodeId variant +fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { + let node_id = map.hir_to_node_id(id); + node_id_to_string(map, node_id, include_id) +} + pub fn describe_def(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option { if let Some(node_id) = tcx.hir().as_local_node_id(def_id) { tcx.hir().describe_def(node_id) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 0ddc5ae87208d..adb7e1fb3e322 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -1,3 +1,4 @@ +use hir; use hir::map::DefPathData; use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use ty::{self, DefIdTree, Ty, TyCtxt}; @@ -76,6 +77,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.item_path_str(self.hir().local_def_id(id)) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_path_str(self, id: hir::HirId) -> String { + self.item_path_str(self.hir().local_def_id_from_hir_id(id)) + } + /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String { From 5440149229068ef202af1b59846d123a24e4c62f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 4 Feb 2019 06:00:16 +0900 Subject: [PATCH 0566/1064] libunwind => 2018 --- src/libunwind/Cargo.toml | 1 + src/libunwind/lib.rs | 4 ++-- src/libunwind/libunwind.rs | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index 2577d6dd31d8f..2378b0a315a16 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] name = "unwind" version = "0.0.0" build = "build.rs" +edition = "2018" [lib] name = "unwind" diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index 5f9c82431b786..b9a9929ef8b87 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -1,8 +1,9 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] +#![deny(rust_2018_idioms)] + #![feature(link_cfg)] -#![feature(nll)] #![feature(staged_api)] #![feature(unwind_attributes)] #![feature(static_nobundle)] @@ -18,7 +19,6 @@ cfg_if! { } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] { // no unwinder on the system! } else { - extern crate libc; mod libunwind; pub use libunwind::*; } diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 31e806c8fb656..339b554ed6abd 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -21,7 +21,7 @@ pub enum _Unwind_Reason_Code { _URC_CONTINUE_UNWIND = 8, _URC_FAILURE = 9, // used only by ARM EHABI } -pub use self::_Unwind_Reason_Code::*; +pub use _Unwind_Reason_Code::*; pub type _Unwind_Exception_Class = u64; pub type _Unwind_Word = uintptr_t; @@ -94,7 +94,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm _UA_FORCE_UNWIND = 8, _UA_END_OF_STACK = 16, } - pub use self::_Unwind_Action::*; + pub use _Unwind_Action::*; extern "C" { pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word; @@ -118,7 +118,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm _US_FORCE_UNWIND = 8, _US_END_OF_STACK = 16, } - pub use self::_Unwind_State::*; + pub use _Unwind_State::*; #[repr(C)] enum _Unwind_VRS_Result { @@ -134,7 +134,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm _UVRSC_WMMXD = 3, _UVRSC_WMMXC = 4, } - use self::_Unwind_VRS_RegClass::*; + use _Unwind_VRS_RegClass::*; #[repr(C)] enum _Unwind_VRS_DataRepresentation { _UVRSD_UINT32 = 0, @@ -144,7 +144,7 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm _UVRSD_FLOAT = 4, _UVRSD_DOUBLE = 5, } - use self::_Unwind_VRS_DataRepresentation::*; + use _Unwind_VRS_DataRepresentation::*; pub const UNWIND_POINTER_REG: c_int = 12; pub const UNWIND_IP_REG: c_int = 15; From 9a460aac37e91f66f9ba79824dbf62105733efee Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 22:10:39 +0100 Subject: [PATCH 0567/1064] some type-level docs for MaybeUninit; rename into_inner -> into_initialized --- src/libcore/macros.rs | 4 ++-- src/libcore/mem.rs | 45 +++++++++++++++++++++++++++++++++++++++++-- src/libcore/ptr.rs | 4 ++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 12b7adb8a9d26..664490c1997ef 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -555,12 +555,12 @@ macro_rules! unimplemented { #[macro_export] #[unstable(feature = "maybe_uninit", issue = "53491")] macro_rules! uninitialized_array { - // This `into_inner` is safe because an array of `MaybeUninit` does not + // This `into_initialized` is safe because an array of `MaybeUninit` does not // require initialization. // FIXME(#49147): Could be replaced by an array initializer, once those can // be any const expression. ($t:ty; $size:expr) => (unsafe { - MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_inner() + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_initialized() }); } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 8b6d9d882b5ad..998e892bffb26 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1034,7 +1034,41 @@ impl DerefMut for ManuallyDrop { } } -/// A newtype to construct uninitialized instances of `T` +/// A newtype to construct uninitialized instances of `T`. +/// +/// The compiler, in general, assumes that variables are properly initialized +/// at their respective type. For example, a variable of reference type must +/// be aligned and non-NULL. This is an invariant that must *always* be upheld, +/// even in unsafe code. As a consequence, 0-initializing a variable of reference +/// type causes instantaneous undefined behavior, no matter whether that reference +/// ever gets used to access memory: +/// ```rust,ignore +/// use std::mem; +/// +/// let x: &i32 = mem::zeroed(); // undefined behavior! +/// ``` +/// This is exploitet by the compiler for various optimizations, such as eliding +/// run-time checks and optimizing `enum` layout. +/// +/// Not initializing memory at all (instead of 0-initializing it) causes the same +/// issue: after all, the initial value of the variable might just happen to be +/// one that violates the invariant. +/// +/// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data: +/// it is a signal to the compiler indicating that the data here may *not* +/// be initialized: +/// ```rust +/// use std::mem::MaybeUninit; +/// +/// // Create an explicitly uninitialized reference. +/// let mut x = MaybeUninit::<&i32>::uninitialized(); +/// // Set it to a valid value. +/// x.set(&0); +/// // Extract the initialized data -- this is only allowed *after* properly +/// initializing `x`! +/// let x = unsafe { x.into_initialized() }; +/// ``` +/// The compiler then knows to not optimize this code. #[allow(missing_debug_implementations)] #[unstable(feature = "maybe_uninit", issue = "53491")] // NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::{uninitialized,zeroed}` @@ -1101,11 +1135,18 @@ impl MaybeUninit { /// state, otherwise this will immediately cause undefined behavior. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn into_inner(self) -> T { + pub unsafe fn into_initialized(self) -> T { intrinsics::panic_if_uninhabited::(); ManuallyDrop::into_inner(self.value) } + /// Deprecated alternative to `into_initialized`. Will never get stabilized. + /// Exists only to transition stdsimd to `into_initialized`. + #[inline(always)] + pub(crate) unsafe fn into_inner(self) -> T { + self.into_initialized() + } + /// Get a reference to the contained value. /// /// # Unsafety diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 02eef07afd7ab..537aa92c2cf4e 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -573,7 +573,7 @@ pub unsafe fn replace(dst: *mut T, mut src: T) -> T { pub unsafe fn read(src: *const T) -> T { let mut tmp = MaybeUninit::::uninitialized(); copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - tmp.into_inner() + tmp.into_initialized() } /// Reads the value from `src` without moving it. This leaves the @@ -642,7 +642,7 @@ pub unsafe fn read_unaligned(src: *const T) -> T { copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::()); - tmp.into_inner() + tmp.into_initialized() } /// Overwrites a memory location with the given value without reading or From 760424af17bc40c4fd2be95e96ebcebe70d217e9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 22:11:28 +0100 Subject: [PATCH 0568/1064] expand as_[mut_]ptr docs a bit --- src/libcore/mem.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 998e892bffb26..3348e774a0b7a 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1174,16 +1174,16 @@ impl MaybeUninit { &mut *self.value } - /// Get a pointer to the contained value. Reading from this pointer will be undefined - /// behavior unless the `MaybeUninit` is initialized. + /// Get a pointer to the contained value. Reading from this pointer or turning it + /// into a reference will be undefined behavior unless the `MaybeUninit` is initialized. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub fn as_ptr(&self) -> *const T { unsafe { &*self.value as *const T } } - /// Get a mutable pointer to the contained value. Reading from this pointer will be undefined - /// behavior unless the `MaybeUninit` is initialized. + /// Get a mutable pointer to the contained value. Reading from this pointer or turning it + /// into a reference will be undefined behavior unless the `MaybeUninit` is initialized. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut T { From f8c7d8dc8e8f779e6468e83f79456ed1916a93d7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 22:14:14 +0100 Subject: [PATCH 0569/1064] make set return a mutable reference --- src/libcore/mem.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 3348e774a0b7a..4712df1fa7cd2 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1117,11 +1117,14 @@ impl MaybeUninit { } /// Set the value of the `MaybeUninit`. This overwrites any previous value without dropping it. + /// For your convenience, this also returns a mutable reference to the (now + /// safely initialized) content of `self`. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub fn set(&mut self, val: T) { + pub fn set(&mut self, val: T) -> &mut T { unsafe { self.value = ManuallyDrop::new(val); + self.get_mut() } } From 272f4dfff6d0a6ae172e3efbef7d563ea088f6fd Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sun, 3 Feb 2019 22:27:52 +0100 Subject: [PATCH 0570/1064] hir: remove Definitions::hir_to_def_index --- src/librustc/hir/map/definitions.rs | 25 +------------------------ src/librustc/hir/map/mod.rs | 7 ++++--- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 687daca3d3ff2..4c622adefbdb1 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -20,7 +20,7 @@ use syntax::ast; use syntax::ext::hygiene::Mark; use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{Span, DUMMY_SP}; -use util::nodemap::{HirIdMap, NodeMap}; +use util::nodemap::NodeMap; /// The DefPathTable maps DefIndexes to DefKeys and vice versa. /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey @@ -147,7 +147,6 @@ impl Decodable for DefPathTable { pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, - hir_to_def_index: HirIdMap, def_index_to_node: [Vec; 2], pub(super) node_to_hir_id: IndexVec, /// If `Mark` is an ID of some macro expansion, @@ -442,34 +441,16 @@ impl Definitions { self.node_to_def_index.get(&node).cloned() } - // FIXME(@ljedrz): replace the NodeId variant - #[inline] - pub fn opt_def_index_from_hir_id(&self, hir: hir::HirId) -> Option { - self.hir_to_def_index.get(&hir).cloned() - } - #[inline] pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { self.opt_def_index(node).map(DefId::local) } - // FIXME(@ljedrz): replace the NodeId variant - #[inline] - pub fn opt_local_def_id_from_hir_id(&self, hir: hir::HirId) -> Option { - self.opt_def_index_from_hir_id(hir).map(DefId::local) - } - #[inline] pub fn local_def_id(&self, node: ast::NodeId) -> DefId { self.opt_local_def_id(node).unwrap() } - // FIXME(@ljedrz): replace the NodeId variant - #[inline] - pub fn local_def_id_from_hir_id(&self, hir: hir::HirId) -> DefId { - self.opt_local_def_id_from_hir_id(hir).unwrap() - } - #[inline] pub fn as_local_node_id(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { @@ -549,7 +530,6 @@ impl Definitions { assert!(self.def_index_to_node[address_space.index()].is_empty()); self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID); self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index); - self.hir_to_def_index.insert(hir::CRATE_HIR_ID, root_index); // Allocate some other DefIndices that always must exist. GlobalMetaDataKind::allocate_def_indices(self); @@ -610,9 +590,6 @@ impl Definitions { if node_id != ast::DUMMY_NODE_ID { debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id); self.node_to_def_index.insert(node_id, index); - if let Some(hir_id) = self.node_to_hir_id.get(node_id) { - self.hir_to_def_index.insert(*hir_id, index); - } } if expansion != Mark::root() { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index c8e19c3b49260..977ab05b20932 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -252,8 +252,8 @@ impl<'hir> Map<'hir> { // FIXME(@ljedrz): replace the NodeId variant #[inline] pub fn local_def_id_from_hir_id(&self, hir_id: HirId) -> DefId { - self.opt_local_def_id_from_hir_id(hir_id).unwrap_or_else(|| { - let node_id = self.hir_to_node_id(hir_id); + let node_id = self.hir_to_node_id(hir_id); + self.opt_local_def_id(node_id).unwrap_or_else(|| { bug!("local_def_id_from_hir_id: no entry for `{:?}`, which has a map of `{:?}`", hir_id, self.find_entry(node_id)) }) @@ -262,7 +262,8 @@ impl<'hir> Map<'hir> { // FIXME(@ljedrz): replace the NodeId variant #[inline] pub fn opt_local_def_id_from_hir_id(&self, hir_id: HirId) -> Option { - self.definitions.opt_local_def_id_from_hir_id(hir_id) + let node_id = self.hir_to_node_id(hir_id); + self.definitions.opt_local_def_id(node_id) } #[inline] From d9a4b22d3291913a8f2158a1b7c195bc30c9286e Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Tue, 29 Jan 2019 19:02:42 -0800 Subject: [PATCH 0571/1064] Update the future/task API This change updates the future and task API as discussed in the stabilization RFC at https://github.com/rust-lang/rfcs/pull/2592. Changes: - Replacing UnsafeWake with RawWaker and RawWakerVtable - Removal of LocalWaker - Removal of Arc-based Wake trait --- src/liballoc/boxed.rs | 6 +- src/liballoc/lib.rs | 4 - src/liballoc/task.rs | 130 -------------- src/libcore/future/future.rs | 36 ++-- src/libcore/task/mod.rs | 2 +- src/libcore/task/wake.rs | 316 +++++++++-------------------------- src/libstd/future.rs | 20 +-- src/libstd/lib.rs | 2 - src/libstd/panic.rs | 6 +- 9 files changed, 111 insertions(+), 411 deletions(-) delete mode 100644 src/liballoc/task.rs diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8e01e12e0b8de..51549f92d4dbf 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -71,7 +71,7 @@ use core::ops::{ CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState }; use core::ptr::{self, NonNull, Unique}; -use core::task::{LocalWaker, Poll}; +use core::task::{Waker, Poll}; use crate::vec::Vec; use crate::raw_vec::RawVec; @@ -896,7 +896,7 @@ impl Generator for Pin> { impl Future for Box { type Output = F::Output; - fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { - F::poll(Pin::new(&mut *self), lw) + fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll { + F::poll(Pin::new(&mut *self), waker) } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 80097a128a5f4..cc73e282b6f6f 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -133,10 +133,6 @@ mod macros; pub mod alloc; -#[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] -pub mod task; // Primitive types using the heaps above // Need to conditionally define the mod from `boxed.rs` to avoid diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs deleted file mode 100644 index 2261dabe2779a..0000000000000 --- a/src/liballoc/task.rs +++ /dev/null @@ -1,130 +0,0 @@ -//! Types and Traits for working with asynchronous tasks. - -pub use core::task::*; - -#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] -pub use if_arc::*; - -#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] -mod if_arc { - use super::*; - use core::marker::PhantomData; - use core::mem; - use core::ptr::{self, NonNull}; - use crate::sync::Arc; - - /// A way of waking up a specific task. - /// - /// Any task executor must provide a way of signaling that a task it owns - /// is ready to be `poll`ed again. Executors do so by implementing this trait. - pub trait Wake: Send + Sync { - /// Indicates that the associated task is ready to make progress and should - /// be `poll`ed. - /// - /// Executors generally maintain a queue of "ready" tasks; `wake` should place - /// the associated task onto this queue. - fn wake(arc_self: &Arc); - - /// Indicates that the associated task is ready to make progress and should - /// be `poll`ed. This function is like `wake`, but can only be called from the - /// thread on which this `Wake` was created. - /// - /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place - /// the associated task onto this queue. - #[inline] - unsafe fn wake_local(arc_self: &Arc) { - Self::wake(arc_self); - } - } - - #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] - struct ArcWrapped(PhantomData); - - unsafe impl UnsafeWake for ArcWrapped { - #[inline] - unsafe fn clone_raw(&self) -> Waker { - let me: *const ArcWrapped = self; - let arc = (*(&me as *const *const ArcWrapped as *const Arc)).clone(); - Waker::from(arc) - } - - #[inline] - unsafe fn drop_raw(&self) { - let mut me: *const ArcWrapped = self; - let me = &mut me as *mut *const ArcWrapped as *mut Arc; - ptr::drop_in_place(me); - } - - #[inline] - unsafe fn wake(&self) { - let me: *const ArcWrapped = self; - T::wake(&*(&me as *const *const ArcWrapped as *const Arc)) - } - - #[inline] - unsafe fn wake_local(&self) { - let me: *const ArcWrapped = self; - T::wake_local(&*(&me as *const *const ArcWrapped as *const Arc)) - } - } - - impl From> for Waker - where T: Wake + 'static, - { - fn from(rc: Arc) -> Self { - unsafe { - let ptr = mem::transmute::, NonNull>>(rc); - Waker::new(ptr) - } - } - } - - /// Creates a `LocalWaker` from a local `wake`. - /// - /// This function requires that `wake` is "local" (created on the current thread). - /// The resulting `LocalWaker` will call `wake.wake_local()` when awoken, and - /// will call `wake.wake()` if awoken after being converted to a `Waker`. - #[inline] - pub unsafe fn local_waker(wake: Arc) -> LocalWaker { - let ptr = mem::transmute::, NonNull>>(wake); - LocalWaker::new(ptr) - } - - struct NonLocalAsLocal(ArcWrapped); - - unsafe impl UnsafeWake for NonLocalAsLocal { - #[inline] - unsafe fn clone_raw(&self) -> Waker { - self.0.clone_raw() - } - - #[inline] - unsafe fn drop_raw(&self) { - self.0.drop_raw() - } - - #[inline] - unsafe fn wake(&self) { - self.0.wake() - } - - #[inline] - unsafe fn wake_local(&self) { - // Since we're nonlocal, we can't call wake_local - self.0.wake() - } - } - - /// Creates a `LocalWaker` from a non-local `wake`. - /// - /// This function is similar to `local_waker`, but does not require that `wake` - /// is local to the current thread. The resulting `LocalWaker` will call - /// `wake.wake()` when awoken. - #[inline] - pub fn local_waker_from_nonlocal(wake: Arc) -> LocalWaker { - unsafe { - let ptr = mem::transmute::, NonNull>>(wake); - LocalWaker::new(ptr) - } - } -} diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 539b07fc21eea..c40045245425b 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -5,7 +5,7 @@ use marker::Unpin; use ops; use pin::Pin; -use task::{Poll, LocalWaker}; +use task::{Poll, Waker}; /// A future represents an asynchronous computation. /// @@ -25,7 +25,7 @@ use task::{Poll, LocalWaker}; /// `await!` the value. #[must_use = "futures do nothing unless polled"] pub trait Future { - /// The result of the `Future`. + /// The type of value produced on completion. type Output; /// Attempt to resolve the future to a final value, registering @@ -42,16 +42,16 @@ pub trait Future { /// Once a future has finished, clients should not `poll` it again. /// /// When a future is not ready yet, `poll` returns `Poll::Pending` and - /// stores a clone of the [`LocalWaker`] to be woken once the future can + /// stores a clone of the [`Waker`] to be woken once the future can /// make progress. For example, a future waiting for a socket to become - /// readable would call `.clone()` on the [`LocalWaker`] and store it. + /// readable would call `.clone()` on the [`Waker`] and store it. /// When a signal arrives elsewhere indicating that the socket is readable, - /// `[LocalWaker::wake]` is called and the socket future's task is awoken. + /// `[Waker::wake]` is called and the socket future's task is awoken. /// Once a task has been woken up, it should attempt to `poll` the future /// again, which may or may not produce a final value. /// /// Note that on multiple calls to `poll`, only the most recent - /// [`LocalWaker`] passed to `poll` should be scheduled to receive a + /// [`Waker`] passed to `poll` should be scheduled to receive a /// wakeup. /// /// # Runtime characteristics @@ -74,16 +74,6 @@ pub trait Future { /// thread pool (or something similar) to ensure that `poll` can return /// quickly. /// - /// # [`LocalWaker`], [`Waker`] and thread-safety - /// - /// The `poll` function takes a [`LocalWaker`], an object which knows how to - /// awaken the current task. [`LocalWaker`] is not `Send` nor `Sync`, so in - /// order to make thread-safe futures the [`LocalWaker::into_waker`] method - /// should be used to convert the [`LocalWaker`] into a thread-safe version. - /// [`LocalWaker::wake`] implementations have the ability to be more - /// efficient, however, so when thread safety is not necessary, - /// [`LocalWaker`] should be preferred. - /// /// # Panics /// /// Once a future has completed (returned `Ready` from `poll`), @@ -93,18 +83,16 @@ pub trait Future { /// /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready - /// [`LocalWaker`]: ../task/struct.LocalWaker.html - /// [`LocalWaker::into_waker`]: ../task/struct.LocalWaker.html#method.into_waker - /// [`LocalWaker::wake`]: ../task/struct.LocalWaker.html#method.wake /// [`Waker`]: ../task/struct.Waker.html - fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll; + /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake + fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll; } impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F { type Output = F::Output; - fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { - F::poll(Pin::new(&mut **self), lw) + fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll { + F::poll(Pin::new(&mut **self), waker) } } @@ -115,7 +103,7 @@ where { type Output = <

    ::Target as Future>::Output; - fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { - Pin::get_mut(self).as_mut().poll(lw) + fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { + Pin::get_mut(self).as_mut().poll(waker) } } diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 9552e53ebf849..9b8f598116200 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -8,4 +8,4 @@ mod poll; pub use self::poll::Poll; mod wake; -pub use self::wake::{Waker, LocalWaker, UnsafeWake}; +pub use self::wake::{Waker, RawWaker, RawWakerVTable}; diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 3f7098f1ef934..bb91bf2ecfb44 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -4,16 +4,76 @@ use fmt; use marker::Unpin; -use ptr::NonNull; + +/// A `RawWaker` allows the implementor of a task executor to create a `Waker` +/// which provides customized wakeup behavior. +/// +/// It consists of a data pointer and a virtual function pointer table (vtable) that +/// customizes the behavior of the `RawWaker`. +#[derive(PartialEq)] +pub struct RawWaker { + /// A data pointer, which can be used to store arbitrary data as required + /// by the executor. This could be e.g. a type-erased pointer to an `Arc` + /// that is associated with the task. + /// The value of this field gets passed to all functions that are part of + /// the vtable as first parameter. + pub data: *const (), + /// Virtual function pointer table that customizes the behavior of this waker. + pub vtable: &'static RawWakerVTable, +} + +impl fmt::Debug for RawWaker { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RawWaker") + .finish() + } +} + +/// A virtual function pointer table (vtable) that specifies the behavior +/// of a `RawWaker`. +/// +/// The pointer passed to all functions inside the vtable is the `data` pointer +/// from the enclosing `RawWaker` object. +#[derive(PartialEq, Copy, Clone)] +pub struct RawWakerVTable { + /// This function will be called when the `RawWaker` gets cloned, e.g. when + /// the `Waker` in which the `RawWaker` is stored gets cloned. + /// + /// The implementation of this function must retain all resources that are + /// required for this additional instance of a `RawWaker` and associated + /// task. Calling `wake` on the resulting `RawWaker` should result in a wakeup + /// of the same task that would have been awoken by the original `RawWaker`. + pub clone: unsafe fn(*const ()) -> RawWaker, + + /// This function will be called when `wake` is called on the `Waker`. + /// It must wake up the task associated with this `RawWaker`. + pub wake: unsafe fn(*const ()), + + /// This function gets called when a `RawWaker` gets dropped. + /// + /// The implementation of this function must make sure to release any + /// resources that are associated with this instance of a `RawWaker` and + /// associated task. + pub drop_fn: unsafe fn(*const ()), +} + +impl fmt::Debug for RawWakerVTable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RawWakerVTable") + .finish() + } +} /// A `Waker` is a handle for waking up a task by notifying its executor that it /// is ready to be run. /// -/// This handle contains a trait object pointing to an instance of the `UnsafeWake` -/// trait, allowing notifications to get routed through it. +/// This handle encapsulates a `RawWaker` instance, which defines the +/// executor-specific wakeup behavior. +/// +/// Implements `Clone`, `Send`, and `Sync`. #[repr(transparent)] pub struct Waker { - inner: NonNull, + waker: RawWaker, } impl Unpin for Waker {} @@ -21,264 +81,52 @@ unsafe impl Send for Waker {} unsafe impl Sync for Waker {} impl Waker { - /// Constructs a new `Waker` directly. - /// - /// Note that most code will not need to call this. Implementers of the - /// `UnsafeWake` trait will typically provide a wrapper that calls this - /// but you otherwise shouldn't call it directly. - /// - /// If you're working with the standard library then it's recommended to - /// use the `Waker::from` function instead which works with the safe - /// `Arc` type and the safe `Wake` trait. - #[inline] - pub unsafe fn new(inner: NonNull) -> Self { - Waker { inner } - } - /// Wake up the task associated with this `Waker`. - #[inline] pub fn wake(&self) { - unsafe { self.inner.as_ref().wake() } + // The actual wakeup call is delegated through a virtual function call + // to the implementation which is defined by the executor. + unsafe { (self.waker.vtable.wake)(self.waker.data) } } - /// Returns whether or not this `Waker` and `other` awaken the same task. + /// Returns whether or not this `Waker` and other `Waker` have awaken the same task. /// /// This function works on a best-effort basis, and may return false even /// when the `Waker`s would awaken the same task. However, if this function - /// returns true, it is guaranteed that the `Waker`s will awaken the same - /// task. + /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task. /// /// This function is primarily used for optimization purposes. - #[inline] pub fn will_wake(&self, other: &Waker) -> bool { - self.inner == other.inner + self.waker == other.waker } - /// Returns whether or not this `Waker` and `other` `LocalWaker` awaken - /// the same task. - /// - /// This function works on a best-effort basis, and may return false even - /// when the `Waker`s would awaken the same task. However, if this function - /// returns true, it is guaranteed that the `Waker`s will awaken the same - /// task. + /// Creates a new `Waker` from `RawWaker`. /// - /// This function is primarily used for optimization purposes. - #[inline] - pub fn will_wake_local(&self, other: &LocalWaker) -> bool { - self.will_wake(&other.0) + /// The method cannot check whether `RawWaker` fulfills the required API + /// contract to make it usable for `Waker` and is therefore unsafe. + pub unsafe fn new_unchecked(waker: RawWaker) -> Waker { + Waker { + waker: waker, + } } } impl Clone for Waker { - #[inline] fn clone(&self) -> Self { - unsafe { - self.inner.as_ref().clone_raw() + Waker { + waker: unsafe { (self.waker.vtable.clone)(self.waker.data) }, } } } -impl fmt::Debug for Waker { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Waker") - .finish() - } -} - impl Drop for Waker { - #[inline] fn drop(&mut self) { - unsafe { - self.inner.as_ref().drop_raw() - } + unsafe { (self.waker.vtable.drop_fn)(self.waker.data) } } } -/// A `LocalWaker` is a handle for waking up a task by notifying its executor that it -/// is ready to be run. -/// -/// This is similar to the `Waker` type, but cannot be sent across threads. -/// Task executors can use this type to implement more optimized single-threaded wakeup -/// behavior. -#[repr(transparent)] -#[derive(Clone)] -pub struct LocalWaker(Waker); - -impl Unpin for LocalWaker {} -impl !Send for LocalWaker {} -impl !Sync for LocalWaker {} - -impl LocalWaker { - /// Constructs a new `LocalWaker` directly. - /// - /// Note that most code will not need to call this. Implementers of the - /// `UnsafeWake` trait will typically provide a wrapper that calls this - /// but you otherwise shouldn't call it directly. - /// - /// If you're working with the standard library then it's recommended to - /// use the `local_waker_from_nonlocal` or `local_waker` to convert a `Waker` - /// into a `LocalWaker`. - /// - /// For this function to be used safely, it must be sound to call `inner.wake_local()` - /// on the current thread. - #[inline] - pub unsafe fn new(inner: NonNull) -> Self { - LocalWaker(Waker::new(inner)) - } - - /// Borrows this `LocalWaker` as a `Waker`. - /// - /// `Waker` is nearly identical to `LocalWaker`, but is threadsafe - /// (implements `Send` and `Sync`). - #[inline] - pub fn as_waker(&self) -> &Waker { - &self.0 - } - - /// Converts this `LocalWaker` into a `Waker`. - /// - /// `Waker` is nearly identical to `LocalWaker`, but is threadsafe - /// (implements `Send` and `Sync`). - #[inline] - pub fn into_waker(self) -> Waker { - self.0 - } - - /// Wake up the task associated with this `LocalWaker`. - #[inline] - pub fn wake(&self) { - unsafe { self.0.inner.as_ref().wake_local() } - } - - /// Returns whether or not this `LocalWaker` and `other` `LocalWaker` awaken the same task. - /// - /// This function works on a best-effort basis, and may return false even - /// when the `LocalWaker`s would awaken the same task. However, if this function - /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same - /// task. - /// - /// This function is primarily used for optimization purposes. - #[inline] - pub fn will_wake(&self, other: &LocalWaker) -> bool { - self.0.will_wake(&other.0) - } - - /// Returns whether or not this `LocalWaker` and `other` `Waker` awaken the same task. - /// - /// This function works on a best-effort basis, and may return false even - /// when the `Waker`s would awaken the same task. However, if this function - /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same - /// task. - /// - /// This function is primarily used for optimization purposes. - #[inline] - pub fn will_wake_nonlocal(&self, other: &Waker) -> bool { - self.0.will_wake(other) - } -} - -impl From for Waker { - /// Converts a `LocalWaker` into a `Waker`. - /// - /// This conversion turns a `!Sync` `LocalWaker` into a `Sync` `Waker`, allowing a wakeup - /// object to be sent to another thread, but giving up its ability to do specialized - /// thread-local wakeup behavior. - #[inline] - fn from(local_waker: LocalWaker) -> Self { - local_waker.0 - } -} - -impl fmt::Debug for LocalWaker { +impl fmt::Debug for Waker { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("LocalWaker") + f.debug_struct("Waker") .finish() } } - -/// An unsafe trait for implementing custom memory management for a `Waker` or `LocalWaker`. -/// -/// A `Waker` conceptually is a cloneable trait object for `Wake`, and is -/// most often essentially just `Arc`. However, in some contexts -/// (particularly `no_std`), it's desirable to avoid `Arc` in favor of some -/// custom memory management strategy. This trait is designed to allow for such -/// customization. -/// -/// When using `std`, a default implementation of the `UnsafeWake` trait is provided for -/// `Arc` where `T: Wake`. -pub unsafe trait UnsafeWake: Send + Sync { - /// Creates a clone of this `UnsafeWake` and stores it behind a `Waker`. - /// - /// This function will create a new uniquely owned handle that under the - /// hood references the same notification instance. In other words calls - /// to `wake` on the returned handle should be equivalent to calls to - /// `wake` on this handle. - /// - /// # Unsafety - /// - /// This function is unsafe to call because it's asserting the `UnsafeWake` - /// value is in a consistent state, i.e., hasn't been dropped. - unsafe fn clone_raw(&self) -> Waker; - - /// Drops this instance of `UnsafeWake`, deallocating resources - /// associated with it. - /// - /// FIXME(cramertj) - /// This method is intended to have a signature such as: - /// - /// ```ignore (not-a-doctest) - /// fn drop_raw(self: *mut Self); - /// ``` - /// - /// Unfortunately in Rust today that signature is not object safe. - /// Nevertheless it's recommended to implement this function *as if* that - /// were its signature. As such it is not safe to call on an invalid - /// pointer, nor is the validity of the pointer guaranteed after this - /// function returns. - /// - /// # Unsafety - /// - /// This function is unsafe to call because it's asserting the `UnsafeWake` - /// value is in a consistent state, i.e., hasn't been dropped. - unsafe fn drop_raw(&self); - - /// Indicates that the associated task is ready to make progress and should - /// be `poll`ed. - /// - /// Executors generally maintain a queue of "ready" tasks; `wake` should place - /// the associated task onto this queue. - /// - /// # Panics - /// - /// Implementations should avoid panicking, but clients should also be prepared - /// for panics. - /// - /// # Unsafety - /// - /// This function is unsafe to call because it's asserting the `UnsafeWake` - /// value is in a consistent state, i.e., hasn't been dropped. - unsafe fn wake(&self); - - /// Indicates that the associated task is ready to make progress and should - /// be `poll`ed. This function is the same as `wake`, but can only be called - /// from the thread that this `UnsafeWake` is "local" to. This allows for - /// implementors to provide specialized wakeup behavior specific to the current - /// thread. This function is called by `LocalWaker::wake`. - /// - /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place - /// the associated task onto this queue. - /// - /// # Panics - /// - /// Implementations should avoid panicking, but clients should also be prepared - /// for panics. - /// - /// # Unsafety - /// - /// This function is unsafe to call because it's asserting the `UnsafeWake` - /// value is in a consistent state, i.e., hasn't been dropped, and that the - /// `UnsafeWake` hasn't moved from the thread on which it was created. - unsafe fn wake_local(&self) { - self.wake() - } -} diff --git a/src/libstd/future.rs b/src/libstd/future.rs index d1203be3cf011..aa784746122db 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -5,7 +5,7 @@ use core::marker::Unpin; use core::pin::Pin; use core::option::Option; use core::ptr::NonNull; -use core::task::{LocalWaker, Poll}; +use core::task::{Waker, Poll}; use core::ops::{Drop, Generator, GeneratorState}; #[doc(inline)] @@ -32,10 +32,10 @@ impl> !Unpin for GenFuture {} #[unstable(feature = "gen_future", issue = "50547")] impl> Future for GenFuture { type Output = T::Return; - fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { + fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { // Safe because we're !Unpin + !Drop mapping to a ?Unpin value let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) }; - set_task_waker(lw, || match gen.resume() { + set_task_waker(waker, || match gen.resume() { GeneratorState::Yielded(()) => Poll::Pending, GeneratorState::Complete(x) => Poll::Ready(x), }) @@ -43,10 +43,10 @@ impl> Future for GenFuture { } thread_local! { - static TLS_WAKER: Cell>> = Cell::new(None); + static TLS_WAKER: Cell>> = Cell::new(None); } -struct SetOnDrop(Option>); +struct SetOnDrop(Option>); impl Drop for SetOnDrop { fn drop(&mut self) { @@ -58,12 +58,12 @@ impl Drop for SetOnDrop { #[unstable(feature = "gen_future", issue = "50547")] /// Sets the thread-local task context used by async/await futures. -pub fn set_task_waker(lw: &LocalWaker, f: F) -> R +pub fn set_task_waker(waker: &Waker, f: F) -> R where F: FnOnce() -> R { let old_waker = TLS_WAKER.with(|tls_waker| { - tls_waker.replace(Some(NonNull::from(lw))) + tls_waker.replace(Some(NonNull::from(waker))) }); let _reset_waker = SetOnDrop(old_waker); f() @@ -78,7 +78,7 @@ where /// retrieved by a surrounding call to get_task_waker. pub fn get_task_waker(f: F) -> R where - F: FnOnce(&LocalWaker) -> R + F: FnOnce(&Waker) -> R { let waker_ptr = TLS_WAKER.with(|tls_waker| { // Clear the entry so that nested `get_task_waker` calls @@ -88,7 +88,7 @@ where let _reset_waker = SetOnDrop(waker_ptr); let waker_ptr = waker_ptr.expect( - "TLS LocalWaker not set. This is a rustc bug. \ + "TLS Waker not set. This is a rustc bug. \ Please file an issue on https://github.com/rust-lang/rust."); unsafe { f(waker_ptr.as_ref()) } } @@ -99,5 +99,5 @@ pub fn poll_with_tls_waker(f: Pin<&mut F>) -> Poll where F: Future { - get_task_waker(|lw| F::poll(f, lw)) + get_task_waker(|waker| F::poll(f, waker)) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 244caf28ec7cd..207ba9ae02f05 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -468,8 +468,6 @@ pub mod task { //! Types and Traits for working with asynchronous tasks. #[doc(inline)] pub use core::task::*; - #[doc(inline)] - pub use alloc_crate::task::*; } #[unstable(feature = "futures_api", diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index d27f6ca88c2e9..862fdf051ccd1 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -12,7 +12,7 @@ use panicking; use ptr::{Unique, NonNull}; use rc::Rc; use sync::{Arc, Mutex, RwLock, atomic}; -use task::{LocalWaker, Poll}; +use task::{Waker, Poll}; use thread::Result; #[stable(feature = "panic_hooks", since = "1.10.0")] @@ -323,9 +323,9 @@ impl fmt::Debug for AssertUnwindSafe { impl<'a, F: Future> Future for AssertUnwindSafe { type Output = F::Output; - fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { + fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { let pinned_field = unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) }; - F::poll(pinned_field, lw) + F::poll(pinned_field, waker) } } From 01a704cf3650710a3e3db221759207539de61613 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 3 Feb 2019 12:30:34 -0800 Subject: [PATCH 0572/1064] Apply suggestions from code review Co-Authored-By: Matthias247 --- src/libcore/task/wake.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index bb91bf2ecfb44..adaca50434557 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -8,7 +8,9 @@ use marker::Unpin; /// A `RawWaker` allows the implementor of a task executor to create a `Waker` /// which provides customized wakeup behavior. /// -/// It consists of a data pointer and a virtual function pointer table (vtable) that +/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table +/// +/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that /// customizes the behavior of the `RawWaker`. #[derive(PartialEq)] pub struct RawWaker { @@ -16,7 +18,7 @@ pub struct RawWaker { /// by the executor. This could be e.g. a type-erased pointer to an `Arc` /// that is associated with the task. /// The value of this field gets passed to all functions that are part of - /// the vtable as first parameter. + /// the vtable as the first parameter. pub data: *const (), /// Virtual function pointer table that customizes the behavior of this waker. pub vtable: &'static RawWakerVTable, @@ -30,7 +32,7 @@ impl fmt::Debug for RawWaker { } /// A virtual function pointer table (vtable) that specifies the behavior -/// of a `RawWaker`. +/// of a [`RawWaker`]. /// /// The pointer passed to all functions inside the vtable is the `data` pointer /// from the enclosing `RawWaker` object. @@ -105,7 +107,7 @@ impl Waker { /// contract to make it usable for `Waker` and is therefore unsafe. pub unsafe fn new_unchecked(waker: RawWaker) -> Waker { Waker { - waker: waker, + waker, } } } From 9e6bc3c4386bf5f7f1885fdaab4ef01fdc93007e Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Sun, 3 Feb 2019 12:59:51 -0800 Subject: [PATCH 0573/1064] Apply review suggestions and fix tests --- src/libcore/task/wake.rs | 65 ++++++----- .../compile-fail/must_use-in-stdlib-traits.rs | 4 +- src/test/run-pass/async-await.rs | 69 ++++++++++-- src/test/run-pass/futures-api.rs | 103 ++++++++++++------ 4 files changed, 163 insertions(+), 78 deletions(-) diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index adaca50434557..fe2de61c59446 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -5,14 +5,14 @@ use fmt; use marker::Unpin; -/// A `RawWaker` allows the implementor of a task executor to create a `Waker` +/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`] /// which provides customized wakeup behavior. /// /// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table /// /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that /// customizes the behavior of the `RawWaker`. -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] pub struct RawWaker { /// A data pointer, which can be used to store arbitrary data as required /// by the executor. This could be e.g. a type-erased pointer to an `Arc` @@ -24,55 +24,41 @@ pub struct RawWaker { pub vtable: &'static RawWakerVTable, } -impl fmt::Debug for RawWaker { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("RawWaker") - .finish() - } -} - /// A virtual function pointer table (vtable) that specifies the behavior /// of a [`RawWaker`]. /// /// The pointer passed to all functions inside the vtable is the `data` pointer -/// from the enclosing `RawWaker` object. -#[derive(PartialEq, Copy, Clone)] +/// from the enclosing [`RawWaker`] object. +#[derive(PartialEq, Copy, Clone, Debug)] pub struct RawWakerVTable { - /// This function will be called when the `RawWaker` gets cloned, e.g. when - /// the `Waker` in which the `RawWaker` is stored gets cloned. + /// This function will be called when the [`RawWaker`] gets cloned, e.g. when + /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned. /// /// The implementation of this function must retain all resources that are - /// required for this additional instance of a `RawWaker` and associated - /// task. Calling `wake` on the resulting `RawWaker` should result in a wakeup - /// of the same task that would have been awoken by the original `RawWaker`. + /// required for this additional instance of a [`RawWaker`] and associated + /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup + /// of the same task that would have been awoken by the original [`RawWaker`]. pub clone: unsafe fn(*const ()) -> RawWaker, - /// This function will be called when `wake` is called on the `Waker`. - /// It must wake up the task associated with this `RawWaker`. + /// This function will be called when `wake` is called on the [`Waker`]. + /// It must wake up the task associated with this [`RawWaker`]. pub wake: unsafe fn(*const ()), - /// This function gets called when a `RawWaker` gets dropped. + /// This function gets called when a [`RawWaker`] gets dropped. /// /// The implementation of this function must make sure to release any - /// resources that are associated with this instance of a `RawWaker` and + /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. - pub drop_fn: unsafe fn(*const ()), -} - -impl fmt::Debug for RawWakerVTable { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("RawWakerVTable") - .finish() - } + pub drop: unsafe fn(*const ()), } /// A `Waker` is a handle for waking up a task by notifying its executor that it /// is ready to be run. /// -/// This handle encapsulates a `RawWaker` instance, which defines the +/// This handle encapsulates a [`RawWaker`] instance, which defines the /// executor-specific wakeup behavior. /// -/// Implements `Clone`, `Send`, and `Sync`. +/// Implements [`Clone`], [`Send`], and [`Sync`]. #[repr(transparent)] pub struct Waker { waker: RawWaker, @@ -87,6 +73,10 @@ impl Waker { pub fn wake(&self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. + + // SAFETY: This is safe because `Waker::new_unchecked` is the only way + // to initialize `wake` and `data` requiring the user to acknowledge + // that the contract of `RawWaker` is upheld. unsafe { (self.waker.vtable.wake)(self.waker.data) } } @@ -101,10 +91,11 @@ impl Waker { self.waker == other.waker } - /// Creates a new `Waker` from `RawWaker`. + /// Creates a new `Waker` from [`RawWaker`]. /// - /// The method cannot check whether `RawWaker` fulfills the required API - /// contract to make it usable for `Waker` and is therefore unsafe. + /// The behavior of the returned `Waker` is undefined if the contract defined + /// in [RawWaker]'s documentation is not upheld. Therefore this method is + /// unsafe. pub unsafe fn new_unchecked(waker: RawWaker) -> Waker { Waker { waker, @@ -115,6 +106,9 @@ impl Waker { impl Clone for Waker { fn clone(&self) -> Self { Waker { + // SAFETY: This is safe because `Waker::new_unchecked` is the only way + // to initialize `clone` and `data` requiring the user to acknowledge + // that the contract of [`RawWaker`] is upheld. waker: unsafe { (self.waker.vtable.clone)(self.waker.data) }, } } @@ -122,7 +116,10 @@ impl Clone for Waker { impl Drop for Waker { fn drop(&mut self) { - unsafe { (self.waker.vtable.drop_fn)(self.waker.data) } + // SAFETY: This is safe because `Waker::new_unchecked` is the only way + // to initialize `drop` and `data` requiring the user to acknowledge + // that the contract of `RawWaker` is upheld. + unsafe { (self.waker.vtable.drop)(self.waker.data) } } } diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs index 7e446fdaeaf41..b4f07ab33214c 100644 --- a/src/test/compile-fail/must_use-in-stdlib-traits.rs +++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs @@ -4,7 +4,7 @@ use std::iter::Iterator; use std::future::Future; -use std::task::{Poll, LocalWaker}; +use std::task::{Poll, Waker}; use std::pin::Pin; use std::unimplemented; @@ -13,7 +13,7 @@ struct MyFuture; impl Future for MyFuture { type Output = u32; - fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { + fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { Poll::Pending } } diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 552f38215738b..2def62a6ba60c 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -9,17 +9,70 @@ use std::sync::{ atomic::{self, AtomicUsize}, }; use std::task::{ - LocalWaker, Poll, Wake, - local_waker_from_nonlocal, + Poll, Waker, RawWaker, RawWakerVTable, }; +macro_rules! waker_vtable { + ($ty:ident) => { + &RawWakerVTable { + clone: clone_arc_raw::<$ty>, + drop: drop_arc_raw::<$ty>, + wake: wake_arc_raw::<$ty>, + } + }; +} + +pub trait ArcWake { + fn wake(arc_self: &Arc); + + fn into_waker(wake: Arc) -> Waker where Self: Sized + { + let ptr = Arc::into_raw(wake) as *const(); + + unsafe { + Waker::new_unchecked(RawWaker{ + data: ptr, + vtable: waker_vtable!(Self), + }) + } + } +} + +unsafe fn increase_refcount(data: *const()) { + // Retain Arc by creating a copy + let arc: Arc = Arc::from_raw(data as *const T); + let arc_clone = arc.clone(); + // Forget the Arcs again, so that the refcount isn't decrased + let _ = Arc::into_raw(arc); + let _ = Arc::into_raw(arc_clone); +} + +unsafe fn clone_arc_raw(data: *const()) -> RawWaker { + increase_refcount::(data); + RawWaker { + data: data, + vtable: waker_vtable!(T), + } +} + +unsafe fn drop_arc_raw(data: *const()) { + // Drop Arc + let _: Arc = Arc::from_raw(data as *const T); +} + +unsafe fn wake_arc_raw(data: *const()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake(&arc); + let _ = Arc::into_raw(arc); +} + struct Counter { wakes: AtomicUsize, } -impl Wake for Counter { - fn wake(this: &Arc) { - this.wakes.fetch_add(1, atomic::Ordering::SeqCst); +impl ArcWake for Counter { + fn wake(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); } } @@ -29,11 +82,11 @@ fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } impl Future for WakeOnceThenComplete { type Output = (); - fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<()> { + fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll<()> { if self.0 { Poll::Ready(()) } else { - lw.wake(); + waker.wake(); self.0 = true; Poll::Pending } @@ -130,7 +183,7 @@ where { let mut fut = Box::pin(f(9)); let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); - let waker = local_waker_from_nonlocal(counter.clone()); + let waker = ArcWake::into_waker(counter.clone()); assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); assert_eq!(Poll::Pending, fut.as_mut().poll(&waker)); assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index e3023521100c4..058d09e2420ae 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -3,28 +3,75 @@ use std::future::Future; use std::pin::Pin; -use std::rc::Rc; use std::sync::{ Arc, atomic::{self, AtomicUsize}, }; use std::task::{ - Poll, Wake, Waker, LocalWaker, - local_waker, local_waker_from_nonlocal, + Poll, Waker, RawWaker, RawWakerVTable, }; -struct Counter { - local_wakes: AtomicUsize, - nonlocal_wakes: AtomicUsize, +macro_rules! waker_vtable { + ($ty:ident) => { + &RawWakerVTable { + clone: clone_arc_raw::<$ty>, + drop: drop_arc_raw::<$ty>, + wake: wake_arc_raw::<$ty>, + } + }; } -impl Wake for Counter { - fn wake(this: &Arc) { - this.nonlocal_wakes.fetch_add(1, atomic::Ordering::SeqCst); +pub trait ArcWake { + fn wake(arc_self: &Arc); + + fn into_waker(wake: Arc) -> Waker where Self: Sized + { + let ptr = Arc::into_raw(wake) as *const(); + + unsafe { + Waker::new_unchecked(RawWaker{ + data: ptr, + vtable: waker_vtable!(Self), + }) + } } +} + +unsafe fn increase_refcount(data: *const()) { + // Retain Arc by creating a copy + let arc: Arc = Arc::from_raw(data as *const T); + let arc_clone = arc.clone(); + // Forget the Arcs again, so that the refcount isn't decrased + let _ = Arc::into_raw(arc); + let _ = Arc::into_raw(arc_clone); +} - unsafe fn wake_local(this: &Arc) { - this.local_wakes.fetch_add(1, atomic::Ordering::SeqCst); +unsafe fn clone_arc_raw(data: *const()) -> RawWaker { + increase_refcount::(data); + RawWaker { + data: data, + vtable: waker_vtable!(T), + } +} + +unsafe fn drop_arc_raw(data: *const()) { + // Drop Arc + let _: Arc = Arc::from_raw(data as *const T); +} + +unsafe fn wake_arc_raw(data: *const()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake(&arc); + let _ = Arc::into_raw(arc); +} + +struct Counter { + wakes: AtomicUsize, +} + +impl Wake for Counter { + fn wake(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); } } @@ -32,40 +79,28 @@ struct MyFuture; impl Future for MyFuture { type Output = (); - fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll { - // Wake once locally - lw.wake(); - // Wake twice non-locally - let waker = lw.clone().into_waker(); + fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll { + // Wake twice waker.wake(); waker.wake(); Poll::Ready(()) } } -fn test_local_waker() { +fn test_waker() { let counter = Arc::new(Counter { - local_wakes: AtomicUsize::new(0), - nonlocal_wakes: AtomicUsize::new(0), + wakes: AtomicUsize::new(0), }); - let waker = unsafe { local_waker(counter.clone()) }; - assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&waker)); - assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst)); -} + let waker = ArcWake::into_waker(counter.clone()); + assert_eq!(2, Arc::strong_count(&counter)); -fn test_local_as_nonlocal_waker() { - let counter = Arc::new(Counter { - local_wakes: AtomicUsize::new(0), - nonlocal_wakes: AtomicUsize::new(0), - }); - let waker: LocalWaker = local_waker_from_nonlocal(counter.clone()); assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&waker)); - assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(2, counter.wakes.load(atomic::Ordering::SeqCst)); + + drop(waker); + assert_eq!(1, Arc::strong_count(&counter)); } fn main() { - test_local_waker(); - test_local_as_nonlocal_waker(); + test_waker(); } From f005e1c5d72c775bbb4370e9d8031fbc74efe4eb Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Sun, 3 Feb 2019 14:59:22 -0800 Subject: [PATCH 0574/1064] Fix test --- src/test/run-pass/futures-api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index 058d09e2420ae..8ada7d4fa7416 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -69,7 +69,7 @@ struct Counter { wakes: AtomicUsize, } -impl Wake for Counter { +impl ArcWake for Counter { fn wake(arc_self: &Arc) { arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); } From 4ae8abab9369357a0e5cabd66673ad3d4af307b1 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 00:56:16 +0900 Subject: [PATCH 0575/1064] Transition libtest to 2018 edition --- src/libtest/Cargo.toml | 1 + src/libtest/formatters/json.rs | 2 +- src/libtest/lib.rs | 33 +++++++++++++++++---------------- src/libtest/stats.rs | 6 +++--- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml index aade10ed6c324..10bdd6e877c4f 100644 --- a/src/libtest/Cargo.toml +++ b/src/libtest/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "test" version = "0.0.0" +edition = "2018" [lib] name = "test" diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs index cc1568265c02e..a06497f98626a 100644 --- a/src/libtest/formatters/json.rs +++ b/src/libtest/formatters/json.rs @@ -145,7 +145,7 @@ impl OutputFormatter for JsonFormatter { struct EscapedString>(S); impl> ::std::fmt::Display for EscapedString { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { let mut start = 0; for (i, byte) in self.0.as_ref().bytes().enumerate() { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index c8eceeeaa5a81..b3d719d5c64db 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -17,6 +17,7 @@ // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by // cargo) to detect this crate. +#![deny(rust_2018_idioms)] #![crate_name = "test"] #![unstable(feature = "test", issue = "27812")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", @@ -32,10 +33,10 @@ #![feature(termination_trait_lib)] #![feature(test)] -extern crate getopts; +use getopts; #[cfg(any(unix, target_os = "cloudabi"))] extern crate libc; -extern crate term; +use term; // FIXME(#54291): rustc and/or LLVM don't yet support building with panic-unwind // on aarch64-pc-windows-msvc, so we don't link libtest against @@ -78,7 +79,7 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu // to be used by rustc to compile tests in libtest pub mod test { - pub use {assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, + pub use crate::{assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic, StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}; @@ -87,7 +88,7 @@ pub mod test { pub mod stats; mod formatters; -use formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter}; +use crate::formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter}; /// Whether to execute tests concurrently or not #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -131,7 +132,7 @@ impl TestName { } } impl fmt::Display for TestName { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self.as_slice(), f) } } @@ -185,7 +186,7 @@ impl TestFn { } impl fmt::Debug for TestFn { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match *self { StaticTestFn(..) => "StaticTestFn(..)", StaticBenchFn(..) => "StaticBenchFn(..)", @@ -823,7 +824,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Res let mut nbench = 0; for test in filter_tests(&opts, tests) { - use TestFn::*; + use crate::TestFn::*; let TestDescAndFn { desc: TestDesc { name, .. }, @@ -1454,12 +1455,12 @@ pub fn run_test( match testfn { DynBenchFn(bencher) => { - ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { + crate::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { bencher.run(harness) }); } StaticBenchFn(benchfn) => { - ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { + crate::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { (benchfn.clone())(harness) }); } @@ -1673,7 +1674,7 @@ pub mod bench { use std::cmp; use std::io; use std::sync::{Arc, Mutex}; - use stats; + use crate::stats; use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult}; pub fn benchmark(desc: TestDesc, monitor_ch: Sender, nocapture: bool, f: F) @@ -1749,13 +1750,13 @@ pub mod bench { #[cfg(test)] mod tests { - use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, + use crate::test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, TrIgnored, TrOk}; use std::sync::mpsc::channel; - use bench; - use Bencher; - use Concurrent; + use crate::bench; + use crate::Bencher; + use crate::Concurrent; fn one_ignored_one_unignored_test() -> Vec { @@ -2156,7 +2157,7 @@ mod tests { allow_fail: false, }; - ::bench::benchmark(desc, tx, true, f); + crate::bench::benchmark(desc, tx, true, f); rx.recv().unwrap(); } @@ -2175,7 +2176,7 @@ mod tests { allow_fail: false, }; - ::bench::benchmark(desc, tx, true, f); + crate::bench::benchmark(desc, tx, true, f); rx.recv().unwrap(); } } diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 9fc5f09ba6c92..5c9421d5ea4b0 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -319,8 +319,8 @@ pub fn winsorize(samples: &mut [f64], pct: f64) { #[cfg(test)] mod tests { - use stats::Stats; - use stats::Summary; + use crate::stats::Stats; + use crate::stats::Summary; use std::f64; use std::io::prelude::*; use std::io; @@ -899,7 +899,7 @@ mod tests { mod bench { extern crate test; use self::test::Bencher; - use stats::Stats; + use crate::stats::Stats; #[bench] pub fn sum_three_items(b: &mut Bencher) { From 3c6787306d6b7a45e3b76f18ce543be700fb3c00 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 08:22:30 +0900 Subject: [PATCH 0576/1064] Excute rustfmt for fixing tidy check --- src/libtest/lib.rs | 141 +++++++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 55 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index b3d719d5c64db..cced66f4a22bd 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -20,9 +20,12 @@ #![deny(rust_2018_idioms)] #![crate_name = "test"] #![unstable(feature = "test", issue = "27812")] -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] +#![doc( + html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/", + test(attr(deny(warnings))) +)] #![feature(asm)] #![feature(fnbox)] #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc, rustc_private))] @@ -47,52 +50,57 @@ use term; #[cfg(not(all(windows, target_arch = "aarch64")))] extern crate panic_unwind; -pub use self::TestFn::*; pub use self::ColorConfig::*; -pub use self::TestResult::*; -pub use self::TestName::*; -use self::TestEvent::*; use self::NamePadding::*; use self::OutputLocation::*; +use self::TestEvent::*; +pub use self::TestFn::*; +pub use self::TestName::*; +pub use self::TestResult::*; -use std::panic::{catch_unwind, AssertUnwindSafe}; use std::any::Any; +use std::borrow::Cow; use std::boxed::FnBox; use std::cmp; use std::collections::BTreeMap; use std::env; use std::fmt; use std::fs::File; -use std::io::prelude::*; use std::io; +use std::io::prelude::*; +use std::panic::{catch_unwind, AssertUnwindSafe}; use std::path::PathBuf; +use std::process; use std::process::Termination; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::thread; use std::time::{Duration, Instant}; -use std::borrow::Cow; -use std::process; const TEST_WARN_TIMEOUT_S: u64 = 60; const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in quiet mode // to be used by rustc to compile tests in libtest pub mod test { - pub use crate::{assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, - Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic, - StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, - TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}; + pub use crate::{ + assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, + Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic, + StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, TestOpts, + TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk, + }; } -pub mod stats; mod formatters; +pub mod stats; use crate::formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter}; /// Whether to execute tests concurrently or not #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Concurrent { Yes, No } +pub enum Concurrent { + Yes, + No, +} // The name of a test. By convention this follows the rules for rust // paths; i.e., it should be a series of identifiers separated by double @@ -330,8 +338,7 @@ pub fn test_main_static(tests: &[&TestDescAndFn]) { pub fn assert_test_result(result: T) { let code = result.report(); assert_eq!( - code, - 0, + code, 0, "the test returned a termination value with a non-zero status code ({}) \ which indicates a failure", code @@ -559,14 +566,16 @@ pub fn parse_opts(args: &[String]) -> Option { let include_ignored = matches.opt_present("include-ignored"); if !allow_unstable && include_ignored { return Some(Err( - "The \"include-ignored\" flag is only accepted on the nightly compiler".into() + "The \"include-ignored\" flag is only accepted on the nightly compiler".into(), )); } let run_ignored = match (include_ignored, matches.opt_present("ignored")) { - (true, true) => return Some(Err( - "the options --include-ignored and --ignored are mutually exclusive".into() - )), + (true, true) => { + return Some(Err( + "the options --include-ignored and --ignored are mutually exclusive".into(), + )); + } (true, false) => RunIgnored::Yes, (false, true) => RunIgnored::Only, (false, false) => RunIgnored::No, @@ -598,7 +607,7 @@ pub fn parse_opts(args: &[String]) -> Option { "argument for --test-threads must be a number > 0 \ (error: {})", e - ))) + ))); } }, None => None, @@ -614,7 +623,7 @@ pub fn parse_opts(args: &[String]) -> Option { "argument for --color must be auto, always, or never (was \ {})", v - ))) + ))); } }; @@ -636,7 +645,7 @@ pub fn parse_opts(args: &[String]) -> Option { "argument for --format must be pretty, terse, or json (was \ {})", v - ))) + ))); } }; @@ -1013,10 +1022,12 @@ fn use_color(opts: &TestOpts) -> bool { } } -#[cfg(any(target_os = "cloudabi", - target_os = "redox", - all(target_arch = "wasm32", not(target_os = "emscripten")), - all(target_vendor = "fortanix", target_env = "sgx")))] +#[cfg(any( + target_os = "cloudabi", + target_os = "redox", + all(target_arch = "wasm32", not(target_os = "emscripten")), + all(target_vendor = "fortanix", target_env = "sgx") +))] fn stdout_isatty() -> bool { // FIXME: Implement isatty on Redox and SGX false @@ -1247,21 +1258,34 @@ fn get_concurrency() -> usize { 1 } - #[cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), - all(target_vendor = "fortanix", target_env = "sgx")))] + #[cfg(any( + all(target_arch = "wasm32", not(target_os = "emscripten")), + all(target_vendor = "fortanix", target_env = "sgx") + ))] fn num_cpus() -> usize { 1 } - #[cfg(any(target_os = "android", target_os = "cloudabi", target_os = "emscripten", - target_os = "fuchsia", target_os = "ios", target_os = "linux", - target_os = "macos", target_os = "solaris"))] + #[cfg(any( + target_os = "android", + target_os = "cloudabi", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "solaris" + ))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } } - #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", - target_os = "netbsd"))] + #[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "bitrig", + target_os = "netbsd" + ))] fn num_cpus() -> usize { use std::ptr; @@ -1344,18 +1368,20 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec { - filtered.iter_mut().for_each(|test| test.desc.ignore = false); - }, + filtered + .iter_mut() + .for_each(|test| test.desc.ignore = false); + } RunIgnored::Only => { filtered.retain(|test| test.desc.ignore); - filtered.iter_mut().for_each(|test| test.desc.ignore = false); + filtered + .iter_mut() + .for_each(|test| test.desc.ignore = false); } RunIgnored::No => {} } @@ -1397,7 +1423,8 @@ pub fn run_test( ) { let TestDescAndFn { desc, testfn } = test; - let ignore_because_panic_abort = cfg!(target_arch = "wasm32") && !cfg!(target_os = "emscripten") + let ignore_because_panic_abort = cfg!(target_arch = "wasm32") + && !cfg!(target_os = "emscripten") && desc.should_panic != ShouldPanic::No; if force_ignore || desc.ignore || ignore_because_panic_abort { @@ -1488,7 +1515,8 @@ fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> match (&desc.should_panic, task_result) { (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk, (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { - if err.downcast_ref::() + if err + .downcast_ref::() .map(|e| &**e) .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e)) .map(|e| e.contains(msg)) @@ -1535,7 +1563,8 @@ impl MetricMap { } pub fn fmt_metrics(&self) -> String { - let v = self.0 + let v = self + .0 .iter() .map(|(k, v)| format!("{}: {} (+/- {})", *k, v.value, v.noise)) .collect::>(); @@ -1644,7 +1673,8 @@ where // If we've run for 100ms and seem to have converged to a // stable median. - if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0 + if loop_run > Duration::from_millis(100) + && summ.median_abs_dev_pct < 1.0 && summ.median - summ5.median < summ5.median_abs_dev { return summ5; @@ -1670,12 +1700,12 @@ where } pub mod bench { - use std::panic::{catch_unwind, AssertUnwindSafe}; + use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult}; + use crate::stats; use std::cmp; use std::io; + use std::panic::{catch_unwind, AssertUnwindSafe}; use std::sync::{Arc, Mutex}; - use crate::stats; - use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult}; pub fn benchmark(desc: TestDesc, monitor_ch: Sender, nocapture: bool, f: F) where @@ -1750,14 +1780,15 @@ pub mod bench { #[cfg(test)] mod tests { - use crate::test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, - ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, - TrFailedMsg, TrIgnored, TrOk}; - use std::sync::mpsc::channel; use crate::bench; + use crate::test::{ + filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, + ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, + TrIgnored, TrOk, + }; use crate::Bencher; use crate::Concurrent; - + use std::sync::mpsc::channel; fn one_ignored_one_unignored_test() -> Vec { vec![ From fab032a01dd38693834f54ec424f30f6d9e3aace Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 3 Feb 2019 10:12:47 +0100 Subject: [PATCH 0577/1064] Transition compiletest to Rust 2018 --- src/tools/compiletest/Cargo.toml | 1 + src/tools/compiletest/src/common.rs | 4 ++-- src/tools/compiletest/src/errors.rs | 2 +- src/tools/compiletest/src/header.rs | 6 ++--- src/tools/compiletest/src/json.rs | 4 ++-- src/tools/compiletest/src/main.rs | 22 +++++++----------- src/tools/compiletest/src/read2.rs | 11 ++++----- src/tools/compiletest/src/runtest.rs | 34 ++++++++++++++-------------- src/tools/compiletest/src/util.rs | 2 +- 9 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index edf4aeab1c70f..00e1a53473cda 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "compiletest" version = "0.0.0" +edition = "2018" [dependencies] diff = "0.1.10" diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index f6f8ef1dff485..42afb72c91f39 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use test::ColorConfig; -use util::PathBufExt; +use crate::util::PathBufExt; #[derive(Clone, Copy, PartialEq, Debug)] pub enum Mode { @@ -66,7 +66,7 @@ impl FromStr for Mode { } impl fmt::Display for Mode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match *self { CompileFail => "compile-fail", RunFail => "run-fail", diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index fd3f002fb6682..0329fb0db1422 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -33,7 +33,7 @@ impl FromStr for ErrorKind { } impl fmt::Display for ErrorKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { ErrorKind::Help => write!(f, "help message"), ErrorKind::Error => write!(f, "error"), diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 591d92f0cfa14..80a015d7aea56 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -4,10 +4,10 @@ use std::io::prelude::*; use std::io::BufReader; use std::path::{Path, PathBuf}; -use common::{self, CompareMode, Config, Mode}; -use util; +use crate::common::{self, CompareMode, Config, Mode}; +use crate::util; -use extract_gdb_version; +use crate::extract_gdb_version; /// Whether to ignore the test. #[derive(Clone, Copy, PartialEq, Debug)] diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 106aa67157a42..12aae303f29aa 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -1,5 +1,5 @@ -use errors::{Error, ErrorKind}; -use runtest::ProcRes; +use crate::errors::{Error, ErrorKind}; +use crate::runtest::ProcRes; use serde_json; use std::path::Path; use std::str::FromStr; diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 15d53f1e3755c..1f9b4b2ad4363 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,29 +1,21 @@ #![crate_name = "compiletest"] #![feature(test)] -#![deny(warnings)] +#![deny(warnings, rust_2018_idioms)] -extern crate diff; -extern crate env_logger; -extern crate filetime; -extern crate getopts; #[cfg(unix)] extern crate libc; #[macro_use] extern crate log; -extern crate regex; #[macro_use] extern crate lazy_static; #[macro_use] extern crate serde_derive; -extern crate serde_json; extern crate test; -extern crate rustfix; -extern crate walkdir; -use common::CompareMode; -use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS}; -use common::{Config, TestPaths}; -use common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; +use crate::common::CompareMode; +use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS}; +use crate::common::{Config, TestPaths}; +use crate::common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; use filetime::FileTime; use getopts::Options; use std::env; @@ -33,8 +25,10 @@ use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::Command; use test::ColorConfig; -use util::logv; +use crate::util::logv; use walkdir::WalkDir; +use env_logger; +use getopts; use self::header::{EarlyProps, Ignore}; diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs index 5a4caddcdd319..6dfd8e97c636d 100644 --- a/src/tools/compiletest/src/read2.rs +++ b/src/tools/compiletest/src/read2.rs @@ -100,18 +100,15 @@ mod imp { #[cfg(windows)] mod imp { - extern crate miow; - extern crate winapi; - use std::io; use std::os::windows::prelude::*; use std::process::{ChildStderr, ChildStdout}; use std::slice; - use self::miow::iocp::{CompletionPort, CompletionStatus}; - use self::miow::pipe::NamedPipe; - use self::miow::Overlapped; - use self::winapi::shared::winerror::ERROR_BROKEN_PIPE; + use miow::iocp::{CompletionPort, CompletionStatus}; + use miow::pipe::NamedPipe; + use miow::Overlapped; + use winapi::shared::winerror::ERROR_BROKEN_PIPE; struct Pipe<'a> { dst: &'a mut Vec, diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ff201b03a0bdc..31529810a04db 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,18 +1,18 @@ -use common::CompareMode; -use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; -use common::{output_base_dir, output_base_name, output_testname_unique}; -use common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc}; -use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind}; -use common::{Config, TestPaths}; -use common::{Incremental, MirOpt, RunMake, Ui}; +use crate::common::CompareMode; +use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; +use crate::common::{output_base_dir, output_base_name, output_testname_unique}; +use crate::common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc}; +use crate::common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind}; +use crate::common::{Config, TestPaths}; +use crate::common::{Incremental, MirOpt, RunMake, Ui}; use diff; -use errors::{self, Error, ErrorKind}; +use crate::errors::{self, Error, ErrorKind}; use filetime::FileTime; -use header::TestProps; -use json; +use crate::header::TestProps; +use crate::json; use regex::Regex; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; -use util::{logv, PathBufExt}; +use crate::util::{logv, PathBufExt}; use std::collections::hash_map::DefaultHasher; use std::collections::{HashMap, HashSet, VecDeque}; @@ -27,8 +27,8 @@ use std::path::{Path, PathBuf}; use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; -use extract_gdb_version; -use is_android_gdb_target; +use crate::extract_gdb_version; +use crate::is_android_gdb_target; #[cfg(windows)] fn disable_error_reporting R, R>(f: F) -> R { @@ -1937,7 +1937,7 @@ impl<'test> TestCx<'test> { } fn make_cmdline(&self, command: &Command, libpath: &str) -> String { - use util; + use crate::util; // Linux and mac don't require adjusting the library search path if cfg!(unix) { @@ -3255,7 +3255,7 @@ impl<'test> TestCx<'test> { } fn create_stamp(&self) { - let stamp = ::stamp(&self.config, self.testpaths, self.revision); + let stamp = crate::stamp(&self.config, self.testpaths, self.revision); fs::write(&stamp, compute_stamp_hash(&self.config)).unwrap(); } } @@ -3311,7 +3311,7 @@ impl fmt::Debug for ExpectedLine where T: AsRef + fmt::Debug, { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { if let &ExpectedLine::Text(ref t) = self { write!(formatter, "{:?}", t) } else { @@ -3334,7 +3334,7 @@ fn nocomment_mir_line(line: &str) -> &str { } fn read2_abbreviated(mut child: Child) -> io::Result { - use read2::read2; + use crate::read2::read2; use std::mem::replace; const HEAD_LEN: usize = 160 * 1024; diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 90dfadeee4612..85be2fed07567 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -1,7 +1,7 @@ use std::ffi::OsStr; use std::env; use std::path::PathBuf; -use common::Config; +use crate::common::Config; /// Conversion table from triple OS name to Rust SYSNAME const OS_TABLE: &'static [(&'static str, &'static str)] = &[ From 27c8dfddac4c69a6fd399abe537e1007306c58cf Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Sun, 3 Feb 2019 22:38:43 -0800 Subject: [PATCH 0578/1064] Improve error message and docs for non-UTF-8 bytes in stdio on Windows cc #23344 --- src/libstd/io/stdio.rs | 45 +++++++++++++++++++++++++++++++++ src/libstd/sys/windows/stdio.rs | 4 ++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index d249469323063..4068c0f9c7de5 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -131,6 +131,11 @@ fn handle_ebadf(r: io::Result, default: T) -> io::Result { /// /// [`io::stdin`]: fn.stdin.html /// [`BufRead`]: trait.BufRead.html +/// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return +/// an error. #[stable(feature = "rust1", since = "1.0.0")] pub struct Stdin { inner: Arc>>>, @@ -144,6 +149,11 @@ pub struct Stdin { /// [`Read`]: trait.Read.html /// [`BufRead`]: trait.BufRead.html /// [`Stdin::lock`]: struct.Stdin.html#method.lock +/// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return +/// an error. #[stable(feature = "rust1", since = "1.0.0")] pub struct StdinLock<'a> { inner: MutexGuard<'a, BufReader>>, @@ -157,6 +167,11 @@ pub struct StdinLock<'a> { /// /// [lock]: struct.Stdin.html#method.lock /// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return +/// an error. +/// /// # Examples /// /// Using implicit synchronization: @@ -328,6 +343,11 @@ impl<'a> fmt::Debug for StdinLock<'a> { /// /// Created by the [`io::stdout`] method. /// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return +/// an error. +/// /// [`lock`]: #method.lock /// [`io::stdout`]: fn.stdout.html #[stable(feature = "rust1", since = "1.0.0")] @@ -343,6 +363,11 @@ pub struct Stdout { /// This handle implements the [`Write`] trait, and is constructed via /// the [`Stdout::lock`] method. /// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return +/// an error. +/// /// [`Write`]: trait.Write.html /// [`Stdout::lock`]: struct.Stdout.html#method.lock #[stable(feature = "rust1", since = "1.0.0")] @@ -358,6 +383,11 @@ pub struct StdoutLock<'a> { /// /// [Stdout::lock]: struct.Stdout.html#method.lock /// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return +/// an error. +/// /// # Examples /// /// Using implicit synchronization: @@ -476,6 +506,11 @@ impl<'a> fmt::Debug for StdoutLock<'a> { /// For more information, see the [`io::stderr`] method. /// /// [`io::stderr`]: fn.stderr.html +/// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return +/// an error. #[stable(feature = "rust1", since = "1.0.0")] pub struct Stderr { inner: Arc>>>, @@ -487,6 +522,11 @@ pub struct Stderr { /// the [`Stderr::lock`] method. /// /// [`Stderr::lock`]: struct.Stderr.html#method.lock +/// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return +/// an error. #[stable(feature = "rust1", since = "1.0.0")] pub struct StderrLock<'a> { inner: ReentrantMutexGuard<'a, RefCell>>, @@ -496,6 +536,11 @@ pub struct StderrLock<'a> { /// /// This handle is not buffered. /// +/// ### Note: Windows Portability Consideration +/// When operating in a console, the Windows implementation of this stream does not support +/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return +/// an error. +/// /// # Examples /// /// Using implicit synchronization: diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs index a4f4bd22cd921..0ea19a855257b 100644 --- a/src/libstd/sys/windows/stdio.rs +++ b/src/libstd/sys/windows/stdio.rs @@ -188,7 +188,9 @@ impl Output { } fn invalid_encoding() -> io::Error { - io::Error::new(io::ErrorKind::InvalidData, "text was not valid unicode") + io::Error::new(io::ErrorKind::InvalidData, + "Windows stdio in console mode does not support non-UTF-8 byte sequences; \ + see https://github.com/rust-lang/rust/issues/23344") } fn readconsole_input_control(wakeup_mask: c::ULONG) -> c::CONSOLE_READCONSOLE_CONTROL { From 526a398c77e7be8b437ea4b7cae06e0f3a026155 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Mon, 4 Feb 2019 18:04:33 +0900 Subject: [PATCH 0579/1064] Fix #58101 --- src/librustc/middle/stability.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 3717ee7143c55..c726885337ea8 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -765,7 +765,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } EvalResult::Unmarked => { - span_bug!(span, "encountered unmarked API: {:?}", def_id); + // The API could be uncallable for other reasons, for example when a private module + // was referenced. + self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id)); } } } From 789b4d1a4f9a4c0cfbce51f0939b5ec322abca0c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 4 Feb 2019 11:11:39 +0100 Subject: [PATCH 0580/1064] typos --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 4712df1fa7cd2..68f985ce65202 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1047,7 +1047,7 @@ impl DerefMut for ManuallyDrop { /// /// let x: &i32 = mem::zeroed(); // undefined behavior! /// ``` -/// This is exploitet by the compiler for various optimizations, such as eliding +/// This is exploited by the compiler for various optimizations, such as eliding /// run-time checks and optimizing `enum` layout. /// /// Not initializing memory at all (instead of 0-initializing it) causes the same @@ -1055,7 +1055,7 @@ impl DerefMut for ManuallyDrop { /// one that violates the invariant. /// /// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data: -/// it is a signal to the compiler indicating that the data here may *not* +/// it is a signal to the compiler indicating that the data here might *not* /// be initialized: /// ```rust /// use std::mem::MaybeUninit; From 606e5e07f6bf73297472c41a181672133bf21f16 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sat, 19 Jan 2019 04:52:39 +0100 Subject: [PATCH 0581/1064] Add embedded book --- .gitmodules | 3 +++ src/bootstrap/builder.rs | 1 + src/bootstrap/doc.rs | 5 +---- src/ci/docker/x86_64-gnu-tools/checktools.sh | 1 + src/doc/embedded-book | 1 + src/doc/index.md | 16 ++++++++++++++++ 6 files changed, 23 insertions(+), 4 deletions(-) create mode 160000 src/doc/embedded-book diff --git a/.gitmodules b/.gitmodules index 4e368c3ebafd8..d603e4575159d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -44,3 +44,6 @@ path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git branch = rustc/8.0-2019-01-16 +[submodule "src/doc/embedded-book"] + path = src/doc/embedded-book + url = https://github.com/rust-embedded/book.git \ No newline at end of file diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 716774632a01c..b0d15e6a5df5f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -430,6 +430,7 @@ impl<'a> Builder<'a> { doc::RustByExample, doc::RustcBook, doc::CargoBook, + doc::EmbeddedBook, doc::EditionGuide, ), Kind::Dist => describe!( diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 08e97396fd68b..f1d8fca71cdf7 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -61,6 +61,7 @@ macro_rules! book { // adding a build step in `src/bootstrap/builder.rs`! book!( EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::MdBook1; + EmbeddedBook, "src/doc/embedded-book", "embedded-book", RustbookVersion::MdBook2; Nomicon, "src/doc/nomicon", "nomicon", RustbookVersion::MdBook1; Reference, "src/doc/reference", "reference", RustbookVersion::MdBook1; RustByExample, "src/doc/rust-by-example", "rust-by-example", RustbookVersion::MdBook1; @@ -71,10 +72,6 @@ book!( #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] enum RustbookVersion { MdBook1, - - /// Note: Currently no books use mdBook v2, but we want the option - /// to be available - #[allow(dead_code)] MdBook2, } diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 2e5b335950166..3343716419ff4 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -23,6 +23,7 @@ python2.7 "$X_PY" test --no-fail-fast \ src/doc/nomicon \ src/doc/reference \ src/doc/rust-by-example \ + src/doc/embedded-book \ src/tools/clippy \ src/tools/rls \ src/tools/rustfmt \ diff --git a/src/doc/embedded-book b/src/doc/embedded-book new file mode 160000 index 0000000000000..36bc507044a95 --- /dev/null +++ b/src/doc/embedded-book @@ -0,0 +1 @@ +Subproject commit 36bc507044a9596df426e67e2e1685a3ed6e3c60 diff --git a/src/doc/index.md b/src/doc/index.md index 7bd1854d86f40..7a240ac0a42a5 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -117,3 +117,19 @@ Rust. It's also sometimes called "the 'nomicon." [The `rustc` Guide](https://rust-lang.github.io/rustc-guide/) documents how the compiler works and how to contribute to it. This is useful if you want to build or modify the Rust compiler from source (e.g. to target something non-standard). + +# Specialize Rust + +When using Rust in specific domain areas, consider using the following resources tailored to each domain. + +## Embedded Systems + +When developing for Bare Metal or Embedded Linux systems, you may find these resources maintained by the [Embedded Working Group] useful. + +[Embedded Working Group]: https://github.com/rust-embedded + +### The Embedded Rust Book + +[The Embedded Rust Book] is targeted at developers familiar with embedded development and familiar with Rust, but have not used Rust for embedded development. + +[The Embedded Rust Book]: embedded-book/index.html From e3bbd67110e977a0f17b5d9009b86563826e5df4 Mon Sep 17 00:00:00 2001 From: lukaslueg Date: Mon, 4 Feb 2019 11:21:39 +0100 Subject: [PATCH 0582/1064] Remove weasel word in docs for iter's take_while() The phrase "... or some similar thing." is very vague and contributes nothing to understanding the example. Simply removed. --- src/libcore/iter/traits/iterator.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 9dfa83f473baf..218c7199f35a6 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -952,8 +952,7 @@ pub trait Iterator { /// ``` /// /// The `3` is no longer there, because it was consumed in order to see if - /// the iteration should stop, but wasn't placed back into the iterator or - /// some similar thing. + /// the iteration should stop, but wasn't placed back into the iterator. #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take_while

    {}
    ", ret)); +
    {}
    ", ret.join(""))); } } @@ -4502,40 +4504,47 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { impl_.inner_impl().trait_.as_ref().unwrap())), Escape(&format!("{:#}", target)))); out.push_str(""); - let ret = impls.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(|i| get_methods(i.inner_impl(), - true, - &mut used_links)) - .collect::(); - out.push_str(&format!("
    {}
    ", ret)); + let mut ret = impls.iter() + .filter(|i| i.inner_impl().trait_.is_none()) + .flat_map(|i| get_methods(i.inner_impl(), + true, + &mut used_links)) + .collect::>(); + // We want links' order to be reproducible so we don't use unstable sort. + ret.sort(); + if !ret.is_empty() { + out.push_str(&format!("
    {}
    ", + ret.join(""))); + } } } } let format_impls = |impls: Vec<&Impl>| { let mut links = FxHashSet::default(); - impls.iter() - .filter_map(|i| { - let is_negative_impl = is_negative_impl(i.inner_impl()); - if let Some(ref i) = i.inner_impl().trait_ { - let i_display = format!("{:#}", i); - let out = Escape(&i_display); - let encoded = small_url_encode(&format!("{:#}", i)); - let generated = format!("{}{}", - encoded, - if is_negative_impl { "!" } else { "" }, - out); - if links.insert(generated.clone()) { - Some(generated) - } else { - None - } - } else { - None - } - }) - .collect::() + let mut ret = impls.iter() + .filter_map(|i| { + let is_negative_impl = is_negative_impl(i.inner_impl()); + if let Some(ref i) = i.inner_impl().trait_ { + let i_display = format!("{:#}", i); + let out = Escape(&i_display); + let encoded = small_url_encode(&format!("{:#}", i)); + let generated = format!("{}{}", + encoded, + if is_negative_impl { "!" } else { "" }, + out); + if links.insert(generated.clone()) { + Some(generated) + } else { + None + } + } else { + None + } + }) + .collect::>(); + ret.sort(); + ret.join("") }; let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v @@ -4637,29 +4646,29 @@ fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item, } }) .collect::(); - let required = t.items - .iter() - .filter_map(|m| { - match m.name { - Some(ref name) if m.is_ty_method() => { - Some(format!("{name}", - name=name)) + let mut required = t.items + .iter() + .filter_map(|m| { + match m.name { + Some(ref name) if m.is_ty_method() => { + Some(format!("{name}", + name=name)) + } + _ => None, } - _ => None, - } - }) - .collect::(); - let provided = t.items - .iter() - .filter_map(|m| { - match m.name { - Some(ref name) if m.is_method() => { - Some(format!("{name}", name=name)) + }) + .collect::>(); + let mut provided = t.items + .iter() + .filter_map(|m| { + match m.name { + Some(ref name) if m.is_method() => { + Some(format!("{0}", name)) + } + _ => None, } - _ => None, - } - }) - .collect::(); + }) + .collect::>(); if !types.is_empty() { sidebar.push_str(&format!("\ @@ -4672,38 +4681,41 @@ fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item, consts)); } if !required.is_empty() { + required.sort(); sidebar.push_str(&format!("\ Required Methods
    {}
    ", - required)); + required.join(""))); } if !provided.is_empty() { + provided.sort(); sidebar.push_str(&format!("\ Provided Methods
    {}
    ", - provided)); + provided.join(""))); } let c = cache(); if let Some(implementors) = c.implementors.get(&it.def_id) { - let res = implementors.iter() - .filter(|i| i.inner_impl().for_.def_id() - .map_or(false, |d| !c.paths.contains_key(&d))) - .filter_map(|i| { - match extract_for_impl_name(&i.impl_item) { - Some((ref name, ref url)) => { - Some(format!("{}", - small_url_encode(url), - Escape(name))) + let mut res = implementors.iter() + .filter(|i| i.inner_impl().for_.def_id() + .map_or(false, |d| !c.paths.contains_key(&d))) + .filter_map(|i| { + match extract_for_impl_name(&i.impl_item) { + Some((ref name, ref url)) => { + Some(format!("{}", + small_url_encode(url), + Escape(name))) + } + _ => None, } - _ => None, - } - }) - .collect::(); + }) + .collect::>(); if !res.is_empty() { + res.sort(); sidebar.push_str(&format!("\ Implementations on Foreign Types
    {}
    ", - res)); + res.join(""))); } } From 94f121ff3f47fecdcf458b691f1bf87f8b1f1f1d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 4 Feb 2019 21:49:54 +0900 Subject: [PATCH 0587/1064] libsyntax_ext => 2018 --- src/libsyntax_ext/Cargo.toml | 1 + src/libsyntax_ext/asm.rs | 11 +- src/libsyntax_ext/assert.rs | 5 +- src/libsyntax_ext/cfg.rs | 8 +- src/libsyntax_ext/compile_error.rs | 5 +- src/libsyntax_ext/concat.rs | 3 +- src/libsyntax_ext/concat_idents.rs | 5 +- src/libsyntax_ext/deriving/bounds.rs | 11 +- src/libsyntax_ext/deriving/clone.rs | 25 ++-- src/libsyntax_ext/deriving/cmp/eq.rs | 19 +-- src/libsyntax_ext/deriving/cmp/ord.rs | 12 +- src/libsyntax_ext/deriving/cmp/partial_eq.rs | 18 +-- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 22 ++-- src/libsyntax_ext/deriving/custom.rs | 15 +-- src/libsyntax_ext/deriving/debug.rs | 12 +- src/libsyntax_ext/deriving/decodable.rs | 22 ++-- src/libsyntax_ext/deriving/default.rs | 14 ++- src/libsyntax_ext/deriving/encodable.rs | 18 +-- src/libsyntax_ext/deriving/generic/mod.rs | 108 +++++++++--------- src/libsyntax_ext/deriving/generic/ty.rs | 29 +++-- src/libsyntax_ext/deriving/hash.rs | 10 +- src/libsyntax_ext/deriving/mod.rs | 4 +- src/libsyntax_ext/diagnostics.rs | 2 + src/libsyntax_ext/env.rs | 7 +- src/libsyntax_ext/format.rs | 33 +++--- src/libsyntax_ext/format_foreign.rs | 30 +++-- src/libsyntax_ext/global_asm.rs | 9 +- src/libsyntax_ext/lib.rs | 16 +-- src/libsyntax_ext/log_syntax.rs | 2 +- src/libsyntax_ext/proc_macro_decls.rs | 7 +- src/libsyntax_ext/proc_macro_impl.rs | 26 ++--- src/libsyntax_ext/proc_macro_server.rs | 7 +- src/libsyntax_ext/test.rs | 14 +-- src/libsyntax_ext/test_case.rs | 2 +- src/libsyntax_ext/trace_macros.rs | 5 +- 35 files changed, 269 insertions(+), 268 deletions(-) diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml index 7ad08f75e8bdd..c22b55b8c13a0 100644 --- a/src/libsyntax_ext/Cargo.toml +++ b/src/libsyntax_ext/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "syntax_ext" version = "0.0.0" +edition = "2018" [lib] name = "syntax_ext" diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 41ee6e91b3dc9..ebcdceea7c5a9 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -1,13 +1,13 @@ // Inline assembly support. // -use self::State::*; +use State::*; use rustc_data_structures::thin_vec::ThinVec; -use errors::DiagnosticBuilder; +use crate::errors::DiagnosticBuilder; + use syntax::ast; -use syntax::ext::base; -use syntax::ext::base::*; +use syntax::ext::base::{self, *}; use syntax::feature_gate; use syntax::parse::{self, token}; use syntax::ptr::P; @@ -15,6 +15,7 @@ use syntax::symbol::Symbol; use syntax::ast::AsmDialect; use syntax_pos::Span; use syntax::tokenstream; +use syntax::{span_err, struct_span_err}; enum State { Asm, @@ -40,7 +41,7 @@ impl State { const OPTIONS: &[&str] = &["volatile", "alignstack", "intel"]; -pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, +pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index b27f495322a42..984ef26f5ab8b 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -1,4 +1,5 @@ -use errors::DiagnosticBuilder; +use crate::errors::DiagnosticBuilder; + use syntax::ast::{self, *}; use syntax::source_map::Spanned; use syntax::ext::base::*; @@ -11,7 +12,7 @@ use syntax::tokenstream::{TokenStream, TokenTree}; use syntax_pos::{Span, DUMMY_SP}; pub fn expand_assert<'cx>( - cx: &'cx mut ExtCtxt, + cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[TokenTree], ) -> Box { diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs index 3b47b03cbe8dc..e2104550878ec 100644 --- a/src/libsyntax_ext/cfg.rs +++ b/src/libsyntax_ext/cfg.rs @@ -2,17 +2,17 @@ /// a literal `true` or `false` based on whether the given cfg matches the /// current compilation environment. -use errors::DiagnosticBuilder; +use crate::errors::DiagnosticBuilder; + use syntax::ast; -use syntax::ext::base::*; -use syntax::ext::base; +use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; use syntax::attr; use syntax::tokenstream; use syntax::parse::token; use syntax_pos::Span; -pub fn expand_cfg<'cx>(cx: &mut ExtCtxt, +pub fn expand_cfg<'cx>(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { diff --git a/src/libsyntax_ext/compile_error.rs b/src/libsyntax_ext/compile_error.rs index 8f7f5deb091ac..59d3f2c9c7813 100644 --- a/src/libsyntax_ext/compile_error.rs +++ b/src/libsyntax_ext/compile_error.rs @@ -1,11 +1,10 @@ // The compiler code necessary to support the compile_error! extension. -use syntax::ext::base::*; -use syntax::ext::base; +use syntax::ext::base::{self, *}; use syntax_pos::Span; use syntax::tokenstream; -pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt, +pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index f148f8e003df3..230b00c0f8f55 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -3,12 +3,11 @@ use syntax::ext::base; use syntax::ext::build::AstBuilder; use syntax::symbol::Symbol; use syntax::tokenstream; -use syntax_pos; use std::string::String; pub fn expand_syntax_ext( - cx: &mut base::ExtCtxt, + cx: &mut base::ExtCtxt<'_>, sp: syntax_pos::Span, tts: &[tokenstream::TokenTree], ) -> Box { diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index de96de4bdc2bc..8c9eb4bf2d8ff 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -1,8 +1,7 @@ use rustc_data_structures::thin_vec::ThinVec; use syntax::ast; -use syntax::ext::base::*; -use syntax::ext::base; +use syntax::ext::base::{self, *}; use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; @@ -10,7 +9,7 @@ use syntax_pos::Span; use syntax_pos::symbol::Symbol; use syntax::tokenstream::TokenTree; -pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, +pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[TokenTree]) -> Box { diff --git a/src/libsyntax_ext/deriving/bounds.rs b/src/libsyntax_ext/deriving/bounds.rs index dcfc6ab0391b8..c7b805e0bdca6 100644 --- a/src/libsyntax_ext/deriving/bounds.rs +++ b/src/libsyntax_ext/deriving/bounds.rs @@ -1,11 +1,12 @@ -use deriving::path_std; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::path_std; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; + use syntax::ast::MetaItem; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax_pos::Span; -pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt, +pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt<'_>, span: Span, _: &MetaItem, _: &Annotatable, @@ -13,7 +14,7 @@ pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt, cx.span_err(span, "this unsafe trait should be implemented explicitly"); } -pub fn expand_deriving_copy(cx: &mut ExtCtxt, +pub fn expand_deriving_copy(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 38d433e842cd7..b347092e1bc4c 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -1,9 +1,8 @@ -use deriving::path_std; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::path_std; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; -use syntax::ast::{self, Expr, Generics, ItemKind, MetaItem, VariantData}; -use syntax::ast::GenericArg; +use syntax::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; @@ -11,7 +10,7 @@ use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; use syntax_pos::Span; -pub fn expand_deriving_clone(cx: &mut ExtCtxt, +pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -105,12 +104,12 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt, } fn cs_clone_shallow(name: &str, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, trait_span: Span, - substr: &Substructure, + substr: &Substructure<'_>, is_union: bool) -> P { - fn assert_ty_bounds(cx: &mut ExtCtxt, stmts: &mut Vec, + fn assert_ty_bounds(cx: &mut ExtCtxt<'_>, stmts: &mut Vec, ty: P, span: Span, helper_name: &str) { // Generate statement `let _: helper_name;`, // set the expn ID so we can use the unstable struct. @@ -120,7 +119,7 @@ fn cs_clone_shallow(name: &str, vec![GenericArg::Type(ty)], vec![]); stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path))); } - fn process_variant(cx: &mut ExtCtxt, stmts: &mut Vec, variant: &VariantData) { + fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec, variant: &VariantData) { for field in variant.fields() { // let _: AssertParamIsClone; assert_ty_bounds(cx, stmts, field.ty.clone(), field.span, "AssertParamIsClone"); @@ -151,14 +150,14 @@ fn cs_clone_shallow(name: &str, } fn cs_clone(name: &str, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, trait_span: Span, - substr: &Substructure) + substr: &Substructure<'_>) -> P { let ctor_path; let all_fields; let fn_path = cx.std_path(&["clone", "Clone", "clone"]); - let subcall = |cx: &mut ExtCtxt, field: &FieldInfo| { + let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo<'_>| { let args = vec![cx.expr_addr_of(field.span, field.self_.clone())]; cx.expr_call_global(field.span, fn_path.clone(), args) }; diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index dbba8c3b7a006..a1035ff641fa1 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -1,6 +1,6 @@ -use deriving::path_std; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::path_std; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem, GenericArg}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -9,7 +9,7 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; -pub fn expand_deriving_eq(cx: &mut ExtCtxt, +pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -44,8 +44,11 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt, trait_def.expand_ext(cx, mitem, item, push, true) } -fn cs_total_eq_assert(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { - fn assert_ty_bounds(cx: &mut ExtCtxt, stmts: &mut Vec, +fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>, + trait_span: Span, + substr: &Substructure<'_>) + -> P { + fn assert_ty_bounds(cx: &mut ExtCtxt<'_>, stmts: &mut Vec, ty: P, span: Span, helper_name: &str) { // Generate statement `let _: helper_name;`, // set the expn ID so we can use the unstable struct. @@ -55,7 +58,9 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) vec![GenericArg::Type(ty)], vec![]); stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path))); } - fn process_variant(cx: &mut ExtCtxt, stmts: &mut Vec, variant: &ast::VariantData) { + fn process_variant(cx: &mut ExtCtxt<'_>, + stmts: &mut Vec, + variant: &ast::VariantData) { for field in variant.fields() { // let _: AssertParamIsEq; assert_ty_bounds(cx, stmts, field.ty.clone(), field.span, "AssertParamIsEq"); diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs index 21bd56710ac9b..e4f939c151f3e 100644 --- a/src/libsyntax_ext/deriving/cmp/ord.rs +++ b/src/libsyntax_ext/deriving/cmp/ord.rs @@ -1,6 +1,6 @@ -use deriving::path_std; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::path_std; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -9,7 +9,7 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; -pub fn expand_deriving_ord(cx: &mut ExtCtxt, +pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -44,7 +44,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt, } -pub fn ordering_collapsed(cx: &mut ExtCtxt, +pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>, span: Span, self_arg_tags: &[ast::Ident]) -> P { @@ -53,7 +53,7 @@ pub fn ordering_collapsed(cx: &mut ExtCtxt, cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt]) } -pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { +pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P { let test_id = cx.ident_of("cmp").gensym(); let equals_path = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"])); diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 4ec24bce4cd48..07026ae373919 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -1,6 +1,6 @@ -use deriving::{path_local, path_std}; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::{path_local, path_std}; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use syntax::ast::{BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -9,22 +9,22 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; -pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt, +pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different - fn cs_op(cx: &mut ExtCtxt, + fn cs_op(cx: &mut ExtCtxt<'_>, span: Span, - substr: &Substructure, + substr: &Substructure<'_>, op: BinOpKind, combiner: BinOpKind, base: bool) -> P { - let op = |cx: &mut ExtCtxt, span: Span, self_f: P, other_fs: &[P]| { + let op = |cx: &mut ExtCtxt<'_>, span: Span, self_f: P, other_fs: &[P]| { let other_f = match (other_fs.len(), other_fs.get(0)) { (1, Some(o_f)) => o_f, _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`"), @@ -53,10 +53,10 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt, substr) } - fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { + fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P { cs_op(cx, span, substr, BinOpKind::Eq, BinOpKind::And, true) } - fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { + fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P { cs_op(cx, span, substr, BinOpKind::Ne, BinOpKind::Or, false) } diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index 9ef481edf51ca..e99abeb118ea2 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -1,8 +1,8 @@ -pub use self::OrderingOp::*; +pub use OrderingOp::*; -use deriving::{path_local, pathvec_std, path_std}; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::{path_local, pathvec_std, path_std}; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use syntax::ast::{self, BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -11,7 +11,7 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; -pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt, +pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -95,7 +95,7 @@ pub enum OrderingOp { GeOp, } -pub fn some_ordering_collapsed(cx: &mut ExtCtxt, +pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>, span: Span, op: OrderingOp, self_arg_tags: &[ast::Ident]) @@ -112,7 +112,7 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt, cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt]) } -pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { +pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P { let test_id = cx.ident_of("cmp").gensym(); let ordering = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"])); let ordering_expr = cx.expr_path(ordering.clone()); @@ -184,14 +184,14 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P< /// Strict inequality. fn cs_op(less: bool, inclusive: bool, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, span: Span, - substr: &Substructure) -> P { - let ordering_path = |cx: &mut ExtCtxt, name: &str| { + substr: &Substructure<'_>) -> P { + let ordering_path = |cx: &mut ExtCtxt<'_>, name: &str| { cx.expr_path(cx.path_global(span, cx.std_path(&["cmp", "Ordering", name]))) }; - let par_cmp = |cx: &mut ExtCtxt, span, self_f: P, other_fs: &[P], default| { + let par_cmp = |cx: &mut ExtCtxt<'_>, span, self_f: P, other_fs: &[P], default| { let other_f = match (other_fs.len(), other_fs.get(0)) { (1, Some(o_f)) => o_f, _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"), diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 2f20814ef3efd..7d9b8402cac3f 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -1,4 +1,7 @@ -use errors::FatalError; +use crate::errors::FatalError; +use crate::proc_macro_impl::EXEC_STRATEGY; +use crate::proc_macro_server; + use syntax::ast::{self, ItemKind, Attribute, Mac}; use syntax::attr::{mark_used, mark_known}; use syntax::source_map::Span; @@ -9,8 +12,6 @@ use syntax::tokenstream; use syntax::visit::Visitor; use syntax_pos::DUMMY_SP; -use proc_macro_impl::EXEC_STRATEGY; - struct MarkAttrs<'a>(&'a [ast::Name]); impl<'a> Visitor<'a> for MarkAttrs<'a> { @@ -25,15 +26,15 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> { } pub struct ProcMacroDerive { - pub client: ::proc_macro::bridge::client::Client< - fn(::proc_macro::TokenStream) -> ::proc_macro::TokenStream, + pub client: proc_macro::bridge::client::Client< + fn(proc_macro::TokenStream) -> proc_macro::TokenStream, >, pub attrs: Vec, } impl MultiItemModifier for ProcMacroDerive { fn expand(&self, - ecx: &mut ExtCtxt, + ecx: &mut ExtCtxt<'_>, span: Span, _meta_item: &ast::MetaItem, item: Annotatable) @@ -67,7 +68,7 @@ impl MultiItemModifier for ProcMacroDerive { let token = Token::interpolated(token::NtItem(item)); let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); - let server = ::proc_macro_server::Rustc::new(ecx); + let server = proc_macro_server::Rustc::new(ecx); let stream = match self.client.run(&EXEC_STRATEGY, server, input) { Ok(stream) => stream, Err(e) => { diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index b3e5bd9283ef6..7dc2d007d73d6 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -1,6 +1,6 @@ -use deriving::path_std; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::path_std; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use rustc_data_structures::thin_vec::ThinVec; @@ -11,7 +11,7 @@ use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax_pos::{DUMMY_SP, Span}; -pub fn expand_deriving_debug(cx: &mut ExtCtxt, +pub fn expand_deriving_debug(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -47,7 +47,7 @@ pub fn expand_deriving_debug(cx: &mut ExtCtxt, } /// We use the debug builders to do the heavy lifting here -fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { +fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P { // build fmt.debug_struct().field(, &)....build() // or fmt.debug_tuple().field(&)....build() // based on the "shape". @@ -124,7 +124,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P) -> ast::Stmt { +fn stmt_let_undescore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P) -> ast::Stmt { let local = P(ast::Local { pat: cx.pat_wild(sp), ty: None, diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs index 89c630e991530..b082351d5f684 100644 --- a/src/libsyntax_ext/deriving/decodable.rs +++ b/src/libsyntax_ext/deriving/decodable.rs @@ -1,9 +1,9 @@ //! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more. -use deriving::{self, pathvec_std}; -use deriving::generic::*; -use deriving::generic::ty::*; -use deriving::warn_if_deprecated; +use crate::deriving::{self, pathvec_std}; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; +use crate::deriving::warn_if_deprecated; use syntax::ast; use syntax::ast::{Expr, MetaItem, Mutability}; @@ -13,7 +13,7 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; -pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt, +pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -21,7 +21,7 @@ pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt, expand_deriving_decodable_imp(cx, span, mitem, item, push, "rustc_serialize") } -pub fn expand_deriving_decodable(cx: &mut ExtCtxt, +pub fn expand_deriving_decodable(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -30,7 +30,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt, expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize") } -fn expand_deriving_decodable_imp(cx: &mut ExtCtxt, +fn expand_deriving_decodable_imp(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -79,9 +79,9 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt, trait_def.expand(cx, mitem, item, push) } -fn decodable_substructure(cx: &mut ExtCtxt, +fn decodable_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, - substr: &Substructure, + substr: &Substructure<'_>, krate: &str) -> P { let decoder = substr.nonself_args[0].clone(); @@ -168,13 +168,13 @@ fn decodable_substructure(cx: &mut ExtCtxt, /// Create a decoder for a single enum variant/struct: /// - `outer_pat_path` is the path to this enum variant/struct /// - `getarg` should retrieve the `usize`-th field with name `@str`. -fn decode_static_fields(cx: &mut ExtCtxt, +fn decode_static_fields(cx: &mut ExtCtxt<'_>, trait_span: Span, outer_pat_path: ast::Path, fields: &StaticFields, mut getarg: F) -> P - where F: FnMut(&mut ExtCtxt, Span, Symbol, usize) -> P + where F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P { match *fields { Unnamed(ref fields, is_tuple) => { diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index 32d02bec7989b..6db0a29165a4a 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -1,15 +1,16 @@ -use deriving::path_std; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::path_std; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use syntax::ast::{Expr, MetaItem}; use syntax::ext::base::{Annotatable, DummyResult, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::Symbol; +use syntax::span_err; use syntax_pos::Span; -pub fn expand_deriving_default(cx: &mut ExtCtxt, +pub fn expand_deriving_default(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -42,7 +43,10 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt, trait_def.expand(cx, mitem, item, push) } -fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { +fn default_substructure(cx: &mut ExtCtxt<'_>, + trait_span: Span, + substr: &Substructure<'_>) + -> P { let default_ident = cx.std_path(&["default", "Default", "default"]); let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new()); diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index c8935874158a2..dd5646342b362 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -82,10 +82,10 @@ //! } //! ``` -use deriving::{self, pathvec_std}; -use deriving::generic::*; -use deriving::generic::ty::*; -use deriving::warn_if_deprecated; +use crate::deriving::{self, pathvec_std}; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; +use crate::deriving::warn_if_deprecated; use syntax::ast::{Expr, ExprKind, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -94,7 +94,7 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; -pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt, +pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -102,7 +102,7 @@ pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt, expand_deriving_encodable_imp(cx, span, mitem, item, push, "rustc_serialize") } -pub fn expand_deriving_encodable(cx: &mut ExtCtxt, +pub fn expand_deriving_encodable(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -111,7 +111,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt, expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize") } -fn expand_deriving_encodable_imp(cx: &mut ExtCtxt, +fn expand_deriving_encodable_imp(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -162,9 +162,9 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt, trait_def.expand(cx, mitem, item, push) } -fn encodable_substructure(cx: &mut ExtCtxt, +fn encodable_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, - substr: &Substructure, + substr: &Substructure<'_>, krate: &'static str) -> P { let encoder = substr.nonself_args[0].clone(); diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 22643db501693..0c88ae0311d52 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -174,8 +174,8 @@ //! (, , Named(vec![(, )]))]) //! ``` -pub use self::StaticFields::*; -pub use self::SubstructureFields::*; +pub use StaticFields::*; +pub use SubstructureFields::*; use std::cell::RefCell; use std::iter; @@ -195,9 +195,9 @@ use syntax::symbol::{Symbol, keywords}; use syntax::parse::ParseSess; use syntax_pos::{DUMMY_SP, Span}; -use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty}; +use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty}; -use deriving; +use crate::deriving; pub mod ty; @@ -321,7 +321,7 @@ pub enum SubstructureFields<'a> { /// Combine the values of all the fields together. The last argument is /// all the fields of all the structures. pub type CombineSubstructureFunc<'a> = - Box P + 'a>; + Box, Span, &Substructure<'_>) -> P + 'a>; /// Deal with non-matching enum variants. The tuple is a list of /// identifiers (one for each `Self` argument, which could be any of the @@ -329,7 +329,7 @@ pub type CombineSubstructureFunc<'a> = /// holding the variant index value for each of the `Self` arguments. The /// last argument is all the non-`Self` args of the method being derived. pub type EnumNonMatchCollapsedFunc<'a> = - Box]) -> P + 'a>; + Box, Span, (&[Ident], &[Ident]), &[P]) -> P + 'a>; pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) -> RefCell> { @@ -342,7 +342,7 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name], span: Span, - cx: &ExtCtxt) + cx: &ExtCtxt<'_>) -> Vec> { use syntax::visit; @@ -386,7 +386,7 @@ fn find_type_parameters(ty: &ast::Ty, impl<'a> TraitDef<'a> { pub fn expand(self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, mitem: &ast::MetaItem, item: &'a Annotatable, push: &mut dyn FnMut(Annotatable)) { @@ -394,7 +394,7 @@ impl<'a> TraitDef<'a> { } pub fn expand_ext(self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, mitem: &ast::MetaItem, item: &'a Annotatable, push: &mut dyn FnMut(Annotatable), @@ -513,7 +513,7 @@ impl<'a> TraitDef<'a> { /// where B1, ..., BN are the bounds given by `bounds_paths`.'. Z is a phantom type, and /// therefore does not get bound by the derived trait. fn create_derived_impl(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, type_ident: Ident, generics: &Generics, field_tys: Vec>, @@ -696,7 +696,7 @@ impl<'a> TraitDef<'a> { } fn expand_struct_def(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, struct_def: &'a VariantData, type_ident: Ident, generics: &Generics, @@ -746,7 +746,7 @@ impl<'a> TraitDef<'a> { } fn expand_enum_def(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, enum_def: &'a EnumDef, type_attrs: &[ast::Attribute], type_ident: Ident, @@ -832,12 +832,12 @@ fn find_repr_type_name(sess: &ParseSess, type_attrs: &[ast::Attribute]) -> &'sta impl<'a> MethodDef<'a> { fn call_substructure_method(&self, - cx: &mut ExtCtxt, - trait_: &TraitDef, + cx: &mut ExtCtxt<'_>, + trait_: &TraitDef<'_>, type_ident: Ident, self_args: &[P], nonself_args: &[P], - fields: &SubstructureFields) + fields: &SubstructureFields<'_>) -> P { let substructure = Substructure { type_ident, @@ -847,13 +847,13 @@ impl<'a> MethodDef<'a> { fields, }; let mut f = self.combine_substructure.borrow_mut(); - let f: &mut CombineSubstructureFunc = &mut *f; + let f: &mut CombineSubstructureFunc<'_> = &mut *f; f(cx, trait_.span, &substructure) } fn get_ret_ty(&self, - cx: &mut ExtCtxt, - trait_: &TraitDef, + cx: &mut ExtCtxt<'_>, + trait_: &TraitDef<'_>, generics: &Generics, type_ident: Ident) -> P { @@ -866,8 +866,8 @@ impl<'a> MethodDef<'a> { fn split_self_nonself_args (&self, - cx: &mut ExtCtxt, - trait_: &TraitDef, + cx: &mut ExtCtxt<'_>, + trait_: &TraitDef<'_>, type_ident: Ident, generics: &Generics) -> (Option, Vec>, Vec>, Vec<(Ident, P)>) { @@ -912,8 +912,8 @@ impl<'a> MethodDef<'a> { } fn create_method(&self, - cx: &mut ExtCtxt, - trait_: &TraitDef, + cx: &mut ExtCtxt<'_>, + trait_: &TraitDef<'_>, type_ident: Ident, generics: &Generics, abi: Abi, @@ -1005,7 +1005,7 @@ impl<'a> MethodDef<'a> { /// } /// ``` fn expand_struct_method_body<'b>(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, trait_: &TraitDef<'b>, struct_def: &'b VariantData, type_ident: Ident, @@ -1077,8 +1077,8 @@ impl<'a> MethodDef<'a> { } fn expand_static_struct_method_body(&self, - cx: &mut ExtCtxt, - trait_: &TraitDef, + cx: &mut ExtCtxt<'_>, + trait_: &TraitDef<'_>, struct_def: &VariantData, type_ident: Ident, self_args: &[P], @@ -1125,7 +1125,7 @@ impl<'a> MethodDef<'a> { /// as their results are unused. The point of `__self_vi` and /// `__arg_1_vi` is for `PartialOrd`; see #15503.) fn expand_enum_method_body<'b>(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, trait_: &TraitDef<'b>, enum_def: &'b EnumDef, type_attrs: &[ast::Attribute], @@ -1179,7 +1179,7 @@ impl<'a> MethodDef<'a> { /// } /// ``` fn build_enum_match_tuple<'b>(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, trait_: &TraitDef<'b>, enum_def: &'b EnumDef, type_attrs: &[ast::Attribute], @@ -1230,7 +1230,7 @@ impl<'a> MethodDef<'a> { .enumerate() .filter(|&(_, v)| !(self.unify_fieldless_variants && v.node.data.fields().is_empty())) .map(|(index, variant)| { - let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| { + let mk_self_pat = |cx: &mut ExtCtxt<'_>, self_arg_name: &str| { let (p, idents) = trait_.create_enum_variant_pattern(cx, type_ident, variant, @@ -1296,7 +1296,7 @@ impl<'a> MethodDef<'a> { other: others, attrs, } - }).collect::>(); + }).collect::>>(); // Now, for some given VariantK, we have built up // expressions for referencing every field of every @@ -1501,8 +1501,8 @@ impl<'a> MethodDef<'a> { } fn expand_static_enum_method_body(&self, - cx: &mut ExtCtxt, - trait_: &TraitDef, + cx: &mut ExtCtxt<'_>, + trait_: &TraitDef<'_>, enum_def: &EnumDef, type_ident: Ident, self_args: &[P], @@ -1527,7 +1527,7 @@ impl<'a> MethodDef<'a> { // general helper methods. impl<'a> TraitDef<'a> { - fn summarise_struct(&self, cx: &mut ExtCtxt, struct_def: &VariantData) -> StaticFields { + fn summarise_struct(&self, cx: &mut ExtCtxt<'_>, struct_def: &VariantData) -> StaticFields { let mut named_idents = Vec::new(); let mut just_spans = Vec::new(); for field in struct_def.fields() { @@ -1553,7 +1553,7 @@ impl<'a> TraitDef<'a> { } fn create_subpatterns(&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, field_paths: Vec, mutbl: ast::Mutability, use_temporaries: bool) @@ -1573,7 +1573,7 @@ impl<'a> TraitDef<'a> { fn create_struct_pattern (&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, struct_path: ast::Path, struct_def: &'a VariantData, prefix: &str, @@ -1633,7 +1633,7 @@ impl<'a> TraitDef<'a> { fn create_enum_variant_pattern (&self, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, enum_ident: ast::Ident, variant: &'a ast::Variant, prefix: &str, @@ -1652,10 +1652,10 @@ impl<'a> TraitDef<'a> { pub fn cs_fold_fields<'a, F>(use_foldl: bool, mut f: F, base: P, - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, all_fields: &[FieldInfo<'a>]) -> P - where F: FnMut(&mut ExtCtxt, Span, P, P, &[P]) -> P + where F: FnMut(&mut ExtCtxt<'_>, Span, P, P, &[P]) -> P { if use_foldl { all_fields.iter().fold(base, |old, field| { @@ -1668,10 +1668,10 @@ pub fn cs_fold_fields<'a, F>(use_foldl: bool, } } -pub fn cs_fold_enumnonmatch(mut enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, +pub fn cs_fold_enumnonmatch(mut enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>, + cx: &mut ExtCtxt<'_>, trait_span: Span, - substructure: &Substructure) + substructure: &Substructure<'_>) -> P { match *substructure.fields { @@ -1685,7 +1685,7 @@ pub fn cs_fold_enumnonmatch(mut enum_nonmatch_f: EnumNonMatchCollapsedFunc, } } -pub fn cs_fold_static(cx: &mut ExtCtxt, +pub fn cs_fold_static(cx: &mut ExtCtxt<'_>, trait_span: Span) -> P { @@ -1697,12 +1697,12 @@ pub fn cs_fold_static(cx: &mut ExtCtxt, pub fn cs_fold(use_foldl: bool, f: F, base: P, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, + enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>, + cx: &mut ExtCtxt<'_>, trait_span: Span, - substructure: &Substructure) + substructure: &Substructure<'_>) -> P - where F: FnMut(&mut ExtCtxt, Span, P, P, &[P]) -> P + where F: FnMut(&mut ExtCtxt<'_>, Span, P, P, &[P]) -> P { match *substructure.fields { EnumMatching(.., ref all_fields) | @@ -1730,13 +1730,13 @@ pub fn cs_fold(use_foldl: bool, pub fn cs_fold1(use_foldl: bool, f: F, mut b: B, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, + enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>, + cx: &mut ExtCtxt<'_>, trait_span: Span, - substructure: &Substructure) + substructure: &Substructure<'_>) -> P - where F: FnMut(&mut ExtCtxt, Span, P, P, &[P]) -> P, - B: FnMut(&mut ExtCtxt, Option<(Span, P, &[P])>) -> P + where F: FnMut(&mut ExtCtxt<'_>, Span, P, P, &[P]) -> P, + B: FnMut(&mut ExtCtxt<'_>, Option<(Span, P, &[P])>) -> P { match *substructure.fields { EnumMatching(.., ref all_fields) | @@ -1776,12 +1776,12 @@ pub fn cs_fold1(use_foldl: bool, /// ``` #[inline] pub fn cs_same_method(f: F, - mut enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, + mut enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>, + cx: &mut ExtCtxt<'_>, trait_span: Span, - substructure: &Substructure) + substructure: &Substructure<'_>) -> P - where F: FnOnce(&mut ExtCtxt, Span, Vec>) -> P + where F: FnOnce(&mut ExtCtxt<'_>, Span, Vec>) -> P { match *substructure.fields { EnumMatching(.., ref all_fields) | diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 83ec99b3573b4..ea6e07922b2b3 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -1,11 +1,10 @@ //! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use //! when specifying impls to be derived. -pub use self::PtrTy::*; -pub use self::Ty::*; +pub use PtrTy::*; +pub use Ty::*; -use syntax::ast; -use syntax::ast::{Expr, GenericParamKind, Generics, Ident, SelfKind, GenericArg}; +use syntax::ast::{self, Expr, GenericParamKind, Generics, Ident, SelfKind, GenericArg}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::source_map::{respan, DUMMY_SP}; @@ -60,7 +59,7 @@ impl<'a> Path<'a> { } pub fn to_ty(&self, - cx: &ExtCtxt, + cx: &ExtCtxt<'_>, span: Span, self_ty: Ident, self_generics: &Generics) @@ -68,7 +67,7 @@ impl<'a> Path<'a> { cx.ty_path(self.to_path(cx, span, self_ty, self_generics)) } pub fn to_path(&self, - cx: &ExtCtxt, + cx: &ExtCtxt<'_>, span: Span, self_ty: Ident, self_generics: &Generics) @@ -127,19 +126,19 @@ pub fn nil_ty<'r>() -> Ty<'r> { Tuple(Vec::new()) } -fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option { +fn mk_lifetime(cx: &ExtCtxt<'_>, span: Span, lt: &Option<&str>) -> Option { lt.map(|s| cx.lifetime(span, Ident::from_str(s)) ) } -fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec { +fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<&str>) -> Vec { mk_lifetime(cx, span, lt).into_iter().collect() } impl<'a> Ty<'a> { pub fn to_ty(&self, - cx: &ExtCtxt, + cx: &ExtCtxt<'_>, span: Span, self_ty: Ident, self_generics: &Generics) @@ -167,7 +166,7 @@ impl<'a> Ty<'a> { } pub fn to_path(&self, - cx: &ExtCtxt, + cx: &ExtCtxt<'_>, span: Span, self_ty: Ident, generics: &Generics) @@ -193,11 +192,11 @@ impl<'a> Ty<'a> { } -fn mk_ty_param(cx: &ExtCtxt, +fn mk_ty_param(cx: &ExtCtxt<'_>, span: Span, name: &str, attrs: &[ast::Attribute], - bounds: &[Path], + bounds: &[Path<'_>], self_ident: Ident, self_generics: &Generics) -> ast::GenericParam { @@ -237,7 +236,7 @@ impl<'a> LifetimeBounds<'a> { } } pub fn to_generics(&self, - cx: &ExtCtxt, + cx: &ExtCtxt<'_>, span: Span, self_ty: Ident, self_generics: &Generics) @@ -262,9 +261,9 @@ impl<'a> LifetimeBounds<'a> { } } -pub fn get_explicit_self(cx: &ExtCtxt, +pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span, - self_ptr: &Option) + self_ptr: &Option>) -> (P, ast::ExplicitSelf) { // this constructs a fresh `self` path let self_path = cx.expr_self(span); diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs index 4af2bd57b00e2..0d4f2ddc3be7b 100644 --- a/src/libsyntax_ext/deriving/hash.rs +++ b/src/libsyntax_ext/deriving/hash.rs @@ -1,6 +1,6 @@ -use deriving::{self, pathvec_std, path_std}; -use deriving::generic::*; -use deriving::generic::ty::*; +use crate::deriving::{self, pathvec_std, path_std}; +use crate::deriving::generic::*; +use crate::deriving::generic::ty::*; use syntax::ast::{Expr, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -8,7 +8,7 @@ use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax_pos::Span; -pub fn expand_deriving_hash(cx: &mut ExtCtxt, +pub fn expand_deriving_hash(cx: &mut ExtCtxt<'_>, span: Span, mitem: &MetaItem, item: &Annotatable, @@ -50,7 +50,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, hash_trait_def.expand(cx, mitem, item, push); } -fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { +fn hash_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>) -> P { let state_expr = match (substr.nonself_args.len(), substr.nonself_args.get(0)) { (1, Some(o_f)) => o_f, _ => { diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 7548d43f18444..2c8a996cdb0cb 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -90,7 +90,7 @@ derive_traits! { } #[inline] // because `name` is a compile-time constant -fn warn_if_deprecated(ecx: &mut ExtCtxt, sp: Span, name: &str) { +fn warn_if_deprecated(ecx: &mut ExtCtxt<'_>, sp: Span, name: &str) { if let Some(replacement) = match name { "Encodable" => Some("RustcEncodable"), "Decodable" => Some("RustcDecodable"), @@ -131,7 +131,7 @@ fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String { } /// Constructs an expression that calls an intrinsic -fn call_intrinsic(cx: &ExtCtxt, +fn call_intrinsic(cx: &ExtCtxt<'_>, mut span: Span, intrinsic: &str, args: Vec>) diff --git a/src/libsyntax_ext/diagnostics.rs b/src/libsyntax_ext/diagnostics.rs index e8ad4af68508e..9bbd9fdec17d6 100644 --- a/src/libsyntax_ext/diagnostics.rs +++ b/src/libsyntax_ext/diagnostics.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use syntax::{register_diagnostic, register_long_diagnostics}; + // Error messages for EXXXX errors. // Each message should start and end with a new line, and be wrapped to 80 characters. // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 16fb64a5f3912..ccff4aec2c8c7 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -4,8 +4,7 @@ // use syntax::ast::{self, Ident, GenericArg}; -use syntax::ext::base::*; -use syntax::ext::base; +use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; use syntax::symbol::{keywords, Symbol}; use syntax_pos::Span; @@ -13,7 +12,7 @@ use syntax::tokenstream; use std::env; -pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, +pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { @@ -44,7 +43,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, MacEager::expr(e) } -pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, +pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 4c473fe7612af..6bb7ee1d5ddfd 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -1,9 +1,11 @@ -use self::ArgumentType::*; -use self::Position::*; +use ArgumentType::*; +use Position::*; use fmt_macros as parse; -use errors::DiagnosticBuilder; +use crate::errors::DiagnosticBuilder; +use crate::errors::Applicability; + use syntax::ast; use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; @@ -13,7 +15,6 @@ use syntax::ptr::P; use syntax::symbol::Symbol; use syntax::tokenstream; use syntax_pos::{MultiSpan, Span, DUMMY_SP}; -use errors::Applicability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::borrow::Cow; @@ -184,7 +185,7 @@ fn parse_args<'a>( } impl<'a, 'b> Context<'a, 'b> { - fn resolve_name_inplace(&self, p: &mut parse::Piece) { + fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) { // NOTE: the `unwrap_or` branch is needed in case of invalid format // arguments, e.g., `format_args!("{foo}")`. let lookup = |s| *self.names.get(s).unwrap_or(&0); @@ -208,7 +209,7 @@ impl<'a, 'b> Context<'a, 'b> { /// Verifies one piece of a parse string, and remembers it if valid. /// All errors are not emitted as fatal so we can continue giving errors /// about this and possibly other format strings. - fn verify_piece(&mut self, p: &parse::Piece) { + fn verify_piece(&mut self, p: &parse::Piece<'_>) { match *p { parse::String(..) => {} parse::NextArgument(ref arg) => { @@ -231,7 +232,7 @@ impl<'a, 'b> Context<'a, 'b> { } } - fn verify_count(&mut self, c: parse::Count) { + fn verify_count(&mut self, c: parse::Count<'_>) { match c { parse::CountImplied | parse::CountIs(..) => {} @@ -244,7 +245,7 @@ impl<'a, 'b> Context<'a, 'b> { } } - fn describe_num_args(&self) -> Cow { + fn describe_num_args(&self) -> Cow<'_, str> { match self.args.len() { 0 => "no arguments were given".into(), 1 => "there is 1 argument".into(), @@ -385,11 +386,11 @@ impl<'a, 'b> Context<'a, 'b> { self.count_args_index_offset = sofar; } - fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec { + fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec { ecx.std_path(&["fmt", "rt", "v1", s]) } - fn build_count(&self, c: parse::Count) -> P { + fn build_count(&self, c: parse::Count<'_>) -> P { let sp = self.macsp; let count = |c, arg| { let mut path = Context::rtpath(self.ecx, "Count"); @@ -426,7 +427,7 @@ impl<'a, 'b> Context<'a, 'b> { /// Build a static `rt::Argument` from a `parse::Piece` or append /// to the `literal` string. fn build_piece(&mut self, - piece: &parse::Piece, + piece: &parse::Piece<'_>, arg_index_consumed: &mut Vec) -> Option> { let sp = self.macsp; @@ -647,7 +648,7 @@ impl<'a, 'b> Context<'a, 'b> { self.ecx.expr_call_global(self.macsp, path, fn_args) } - fn format_arg(ecx: &ExtCtxt, + fn format_arg(ecx: &ExtCtxt<'_>, macsp: Span, mut sp: Span, ty: &ArgumentType, @@ -686,7 +687,7 @@ impl<'a, 'b> Context<'a, 'b> { } } -pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, +pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt<'_>, mut sp: Span, tts: &[tokenstream::TokenTree]) -> Box { @@ -703,7 +704,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, } pub fn expand_format_args_nl<'cx>( - ecx: &'cx mut ExtCtxt, + ecx: &'cx mut ExtCtxt<'_>, mut sp: Span, tts: &[tokenstream::TokenTree], ) -> Box { @@ -734,7 +735,7 @@ pub fn expand_format_args_nl<'cx>( /// Take the various parts of `format_args!(efmt, args..., name=names...)` /// and construct the appropriate formatting expression. -pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, +pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt<'_>, sp: Span, efmt: P, args: Vec>, @@ -952,7 +953,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, piece }).collect::>(); - let numbered_position_args = pieces.iter().any(|arg: &parse::Piece| { + let numbered_position_args = pieces.iter().any(|arg: &parse::Piece<'_>| { match *arg { parse::String(_) => false, parse::NextArgument(arg) => { diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index 8ac6d460ec3d9..381325b2963ef 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -68,7 +68,7 @@ pub mod printf { pub position: (usize, usize), } - impl<'a> Format<'a> { + impl Format<'_> { /// Translate this directive into an equivalent Rust formatting directive. /// /// Returns `None` in cases where the `printf` directive does not have an exact Rust @@ -249,12 +249,12 @@ pub mod printf { } } - fn translate(&self, s: &mut String) -> ::std::fmt::Result { + fn translate(&self, s: &mut String) -> std::fmt::Result { use std::fmt::Write; match *self { Num::Num(n) => write!(s, "{}", n), Num::Arg(n) => { - let n = n.checked_sub(1).ok_or(::std::fmt::Error)?; + let n = n.checked_sub(1).ok_or(std::fmt::Error)?; write!(s, "{}$", n) }, Num::Next => write!(s, "*"), @@ -263,7 +263,7 @@ pub mod printf { } /// Returns an iterator over all substitutions in a given string. - pub fn iter_subs(s: &str) -> Substitutions { + pub fn iter_subs(s: &str) -> Substitutions<'_> { Substitutions { s, pos: 0, @@ -309,7 +309,7 @@ pub mod printf { } /// Parse the next substitution from the input string. - pub fn parse_next_substitution(s: &str) -> Option<(Substitution, &str)> { + pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> { use self::State::*; let at = { @@ -389,7 +389,7 @@ pub mod printf { let mut precision: Option = None; let mut length: Option<&str> = None; let mut type_: &str = ""; - let end: Cur; + let end: Cur<'_>; if let Start = state { match c { @@ -575,7 +575,7 @@ pub mod printf { Some((Substitution::Format(f), end.slice_after())) } - fn at_next_cp_while(mut cur: Cur, mut pred: F) -> Cur + fn at_next_cp_while(mut cur: Cur<'_>, mut pred: F) -> Cur<'_> where F: FnMut(char) -> bool { loop { match cur.next_cp() { @@ -769,7 +769,7 @@ pub mod shell { Escape((usize, usize)), } - impl<'a> Substitution<'a> { + impl Substitution<'_> { pub fn as_str(&self) -> String { match self { Substitution::Ordinal(n, _) => format!("${}", n), @@ -804,7 +804,7 @@ pub mod shell { } /// Returns an iterator over all substitutions in a given string. - pub fn iter_subs(s: &str) -> Substitutions { + pub fn iter_subs(s: &str) -> Substitutions<'_> { Substitutions { s, pos: 0, @@ -839,7 +839,7 @@ pub mod shell { } /// Parse the next substitution from the input string. - pub fn parse_next_substitution(s: &str) -> Option<(Substitution, &str)> { + pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> { let at = { let start = s.find('$')?; match s[start+1..].chars().next()? { @@ -868,7 +868,7 @@ pub mod shell { } } - fn at_next_cp_while(mut cur: Cur, mut pred: F) -> Cur + fn at_next_cp_while(mut cur: Cur<'_>, mut pred: F) -> Cur<'_> where F: FnMut(char) -> bool { loop { match cur.next_cp() { @@ -962,8 +962,6 @@ pub mod shell { } mod strcursor { - use std; - pub struct StrCursor<'a> { s: &'a str, pub at: usize, @@ -1028,7 +1026,7 @@ mod strcursor { } } - impl<'a> Copy for StrCursor<'a> {} + impl Copy for StrCursor<'_> {} impl<'a> Clone for StrCursor<'a> { fn clone(&self) -> StrCursor<'a> { @@ -1036,8 +1034,8 @@ mod strcursor { } } - impl<'a> std::fmt::Debug for StrCursor<'a> { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + impl std::fmt::Debug for StrCursor<'_> { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(fmt, "StrCursor({:?} | {:?})", self.slice_before(), self.slice_after()) } } diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 0a12e27c4fc21..14dbd9300232b 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -8,21 +8,22 @@ /// LLVM's `module asm "some assembly here"`. All of LLVM's caveats /// therefore apply. -use errors::DiagnosticBuilder; +use crate::errors::DiagnosticBuilder; + use syntax::ast; use syntax::source_map::respan; -use syntax::ext::base; -use syntax::ext::base::*; +use syntax::ext::base::{self, *}; use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; use syntax::tokenstream; +use smallvec::smallvec; pub const MACRO: &str = "global_asm"; -pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt, +pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { if !cx.ecfg.enable_global_asm() { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 5e767d237cc0e..9308cfb3a4f2e 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -4,29 +4,21 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![deny(rust_2018_idioms)] + #![feature(in_band_lifetimes)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] #![feature(proc_macro_span)] #![feature(decl_macro)] -#![feature(nll)] #![feature(str_escape)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] -extern crate fmt_macros; -#[macro_use] -extern crate syntax; -extern crate syntax_pos; extern crate proc_macro; -extern crate rustc_data_structures; -extern crate rustc_errors as errors; -extern crate rustc_target; -#[macro_use] -extern crate smallvec; -#[macro_use] -extern crate log; + +use rustc_errors as errors; mod diagnostics; diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index a143186b9451f..658ce98d26884 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -4,7 +4,7 @@ use syntax::print; use syntax::tokenstream; use syntax_pos; -pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt, +pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>, sp: syntax_pos::Span, tts: &[tokenstream::TokenTree]) -> Box { diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 46c502965eea8..fbc4d8990742c 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -1,6 +1,7 @@ use std::mem; -use errors; +use crate::deriving; +use crate::errors; use syntax::ast::{self, Ident}; use syntax::attr; @@ -18,8 +19,6 @@ use syntax::visit::{self, Visitor}; use syntax_pos::{Span, DUMMY_SP}; -use deriving; - const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"]; struct ProcMacroDerive { @@ -324,7 +323,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // ]; // } fn mk_decls( - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, custom_derives: &[ProcMacroDerive], custom_attrs: &[ProcMacroDef], custom_macros: &[ProcMacroDef], diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index 60d167d01eebe..88e20e3dc7c9e 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -1,27 +1,27 @@ -use errors::FatalError; +use crate::errors::FatalError; +use crate::proc_macro_server; use syntax::source_map::Span; -use syntax::ext::base::*; +use syntax::ext::base::{self, *}; use syntax::tokenstream::TokenStream; -use syntax::ext::base; -pub const EXEC_STRATEGY: ::proc_macro::bridge::server::SameThread = - ::proc_macro::bridge::server::SameThread; +pub const EXEC_STRATEGY: proc_macro::bridge::server::SameThread = + proc_macro::bridge::server::SameThread; pub struct AttrProcMacro { - pub client: ::proc_macro::bridge::client::Client< - fn(::proc_macro::TokenStream, ::proc_macro::TokenStream) -> ::proc_macro::TokenStream, + pub client: proc_macro::bridge::client::Client< + fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream, >, } impl base::AttrProcMacro for AttrProcMacro { fn expand<'cx>(&self, - ecx: &'cx mut ExtCtxt, + ecx: &'cx mut ExtCtxt<'_>, span: Span, annotation: TokenStream, annotated: TokenStream) -> TokenStream { - let server = ::proc_macro_server::Rustc::new(ecx); + let server = proc_macro_server::Rustc::new(ecx); match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) { Ok(stream) => stream, Err(e) => { @@ -39,18 +39,18 @@ impl base::AttrProcMacro for AttrProcMacro { } pub struct BangProcMacro { - pub client: ::proc_macro::bridge::client::Client< - fn(::proc_macro::TokenStream) -> ::proc_macro::TokenStream, + pub client: proc_macro::bridge::client::Client< + fn(proc_macro::TokenStream) -> proc_macro::TokenStream, >, } impl base::ProcMacro for BangProcMacro { fn expand<'cx>(&self, - ecx: &'cx mut ExtCtxt, + ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream) -> TokenStream { - let server = ::proc_macro_server::Rustc::new(ecx); + let server = proc_macro_server::Rustc::new(ecx); match self.client.run(&EXEC_STRATEGY, server, input) { Ok(stream) => stream, Err(e) => { diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index 7de9b9343a8fa..730262683c0b7 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -1,4 +1,5 @@ -use errors::{self, Diagnostic, DiagnosticBuilder}; +use crate::errors::{self, Diagnostic, DiagnosticBuilder}; + use std::panic; use proc_macro::bridge::{server, TokenTree}; @@ -369,7 +370,7 @@ pub(crate) struct Rustc<'a> { } impl<'a> Rustc<'a> { - pub fn new(cx: &'a ExtCtxt) -> Self { + pub fn new(cx: &'a ExtCtxt<'_>) -> Self { // No way to determine def location for a proc macro right now, so use call location. let location = cx.current_expansion.mark.expn_info().unwrap().call_site; let to_span = |transparency| { @@ -650,7 +651,7 @@ impl server::Literal for Rustc<'_> { } } -impl<'a> server::SourceFile for Rustc<'a> { +impl server::SourceFile for Rustc<'_> { fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool { Lrc::ptr_eq(file1, file2) } diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 11c734b299c1e..832bebb6113e9 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -13,7 +13,7 @@ use syntax::source_map::{ExpnInfo, MacroAttribute}; use std::iter; pub fn expand_test( - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, attr_sp: Span, _meta_item: &ast::MetaItem, item: Annotatable, @@ -22,7 +22,7 @@ pub fn expand_test( } pub fn expand_bench( - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, attr_sp: Span, _meta_item: &ast::MetaItem, item: Annotatable, @@ -31,7 +31,7 @@ pub fn expand_bench( } pub fn expand_test_or_bench( - cx: &mut ExtCtxt, + cx: &mut ExtCtxt<'_>, attr_sp: Span, item: Annotatable, is_bench: bool @@ -180,7 +180,7 @@ pub fn expand_test_or_bench( ast::ItemKind::ExternCrate(Some(Symbol::intern("test"))) ); - debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); + log::debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); vec![ // Access to libtest under a gensymed name @@ -210,7 +210,7 @@ fn should_fail(i: &ast::Item) -> bool { attr::contains_name(&i.attrs, "allow_fail") } -fn should_panic(cx: &ExtCtxt, i: &ast::Item) -> ShouldPanic { +fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { match attr::find_by_name(&i.attrs, "should_panic") { Some(attr) => { let ref sd = cx.parse_sess.span_diagnostic; @@ -243,7 +243,7 @@ fn should_panic(cx: &ExtCtxt, i: &ast::Item) -> ShouldPanic { } } -fn has_test_signature(cx: &ExtCtxt, i: &ast::Item) -> bool { +fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic"); let ref sd = cx.parse_sess.span_diagnostic; if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node { @@ -296,7 +296,7 @@ fn has_test_signature(cx: &ExtCtxt, i: &ast::Item) -> bool { } } -fn has_bench_signature(cx: &ExtCtxt, i: &ast::Item) -> bool { +fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.node { // N.B., inadequate check, but we're running // well before resolve, can't get too deep. diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 04e33671872f5..63417b702d569 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -20,7 +20,7 @@ use syntax::source_map::{ExpnInfo, MacroAttribute}; use syntax::feature_gate; pub fn expand( - ecx: &mut ExtCtxt, + ecx: &mut ExtCtxt<'_>, attr_sp: Span, _meta_item: &ast::MetaItem, anno_item: Annotatable diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index 638d7b5568bfb..4d35daf3de998 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -1,11 +1,10 @@ -use syntax::ext::base::ExtCtxt; -use syntax::ext::base; +use syntax::ext::base::{self, ExtCtxt}; use syntax::feature_gate; use syntax::symbol::keywords; use syntax_pos::Span; use syntax::tokenstream::TokenTree; -pub fn expand_trace_macros(cx: &mut ExtCtxt, +pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>, sp: Span, tt: &[TokenTree]) -> Box { From 4847c097b46265963bbf9cd8006456b3ff31169b Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 4 Feb 2019 22:41:39 +0900 Subject: [PATCH 0588/1064] Add #[must_use] to core::task::Poll --- src/libcore/task/poll.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs index 27b1139e15c79..ac656153519e1 100644 --- a/src/libcore/task/poll.rs +++ b/src/libcore/task/poll.rs @@ -7,6 +7,7 @@ use result::Result; /// Indicates whether a value is available or if the current task has been /// scheduled to receive a wakeup instead. +#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum Poll { /// Represents that a value is immediately ready. From 927614ff3ea38014549e24152fd3198532919b2c Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 4 Feb 2019 11:09:32 +0100 Subject: [PATCH 0589/1064] hir: more HirId methods --- src/librustc/hir/map/mod.rs | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 977ab05b20932..d35306ba353a3 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -401,6 +401,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn describe_def_by_hir_id(&self, hir_id: HirId) -> Option { + let node_id = self.hir_to_node_id(hir_id); + self.describe_def(node_id) + } + fn entry_count(&self) -> usize { self.map.len() } @@ -445,6 +451,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option { + let node_id = self.hir_to_node_id(hir_id); + self.fn_decl(node_id) + } + /// Returns the `NodeId` that corresponds to the definition of /// which this is the body of, i.e., a `fn`, `const` or `static` /// item (possibly associated), a closure, or a `hir::AnonConst`. @@ -855,6 +867,12 @@ impl<'hir> Map<'hir> { self.local_def_id(self.get_parent(id)) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_parent_did_by_hir_id(&self, id: HirId) -> DefId { + let node_id = self.hir_to_node_id(id); + self.get_parent_did(node_id) + } + pub fn get_foreign_abi(&self, id: NodeId) -> Abi { let parent = self.get_parent(id); if let Some(entry) = self.find_entry(parent) { @@ -868,6 +886,12 @@ impl<'hir> Map<'hir> { bug!("expected foreign mod or inlined parent, found {}", self.node_to_string(parent)) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_foreign_abi_by_hir_id(&self, id: HirId) -> Abi { + let node_id = self.hir_to_node_id(id); + self.get_foreign_abi(node_id) + } + pub fn expect_item(&self, id: NodeId) -> &'hir Item { match self.find(id) { // read recorded by `find` Some(Node::Item(item)) => item, @@ -888,6 +912,18 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn expect_impl_item_by_hir_id(&self, id: HirId) -> &'hir ImplItem { + let node_id = self.hir_to_node_id(id); + self.expect_impl_item(node_id) + } + + // FIXME(@ljedrz): replace the NodeId variant + pub fn expect_trait_item_by_hir_id(&self, id: HirId) -> &'hir TraitItem { + let node_id = self.hir_to_node_id(id); + self.expect_trait_item(node_id) + } + pub fn expect_trait_item(&self, id: NodeId) -> &'hir TraitItem { match self.find(id) { Some(Node::TraitItem(item)) => item, @@ -931,6 +967,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn expect_expr_by_hir_id(&self, id: HirId) -> &'hir Expr { + let node_id = self.hir_to_node_id(id); + self.expect_expr(node_id) + } + /// Returns the name associated with the given NodeId's AST. pub fn name(&self, id: NodeId) -> Name { match self.get(id) { @@ -948,6 +990,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn name_by_hir_id(&self, id: HirId) -> Name { + let node_id = self.hir_to_node_id(id); + self.name(node_id) + } + /// Given a node ID, get a list of attributes associated with the AST /// corresponding to the Node ID pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] { @@ -970,6 +1018,12 @@ impl<'hir> Map<'hir> { attrs.unwrap_or(&[]) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn attrs_by_hir_id(&self, id: HirId) -> &'hir [ast::Attribute] { + let node_id = self.hir_to_node_id(id); + self.attrs(node_id) + } + /// Returns an iterator that yields the node id's with paths that /// match `parts`. (Requires `parts` is non-empty.) /// @@ -1019,6 +1073,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn span_by_hir_id(&self, id: HirId) -> Span { + let node_id = self.hir_to_node_id(id); + self.span(node_id) + } + pub fn span_if_local(&self, id: DefId) -> Option { self.as_local_node_id(id).map(|id| self.span(id)) } From d0f88c4da31b3a3ff2a0b62342b3d36e0c0bd6cf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 4 Feb 2019 14:59:06 +0100 Subject: [PATCH 0590/1064] Prevent automatic collapse of methods impl blocks --- src/librustdoc/html/static/main.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 82604cc7ad8bb..631d8236464ae 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1887,12 +1887,30 @@ if (!DOMTokenList.prototype.remove) { updateLocalStorage("rustdoc-collapse", "true"); addClass(innerToggle, "will-expand"); onEveryMatchingChild(innerToggle, "inner", function(e) { - e.innerHTML = labelForToggleButton(true); + var parent = e.parentNode; + var superParent = null; + + if (parent) { + superParent = parent.parentNode; + } + if (!parent || !superParent || superParent.id !== "main" || + hasClass(parent, "impl") === false) { + e.innerHTML = labelForToggleButton(true); + } }); innerToggle.title = "expand all docs"; if (fromAutoCollapse !== true) { onEachLazy(document.getElementsByClassName("collapse-toggle"), function(e) { - collapseDocs(e, "hide", pageId); + var parent = e.parentNode; + var superParent = null; + + if (parent) { + superParent = parent.parentNode; + } + if (!parent || !superParent || superParent.id !== "main" || + hasClass(parent, "impl") === false) { + collapseDocs(e, "hide", pageId); + } }); } } From 4ca3c7b156f0ecb18c15e91800b6933a5c0f47b4 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Tue, 5 Feb 2019 01:21:07 +0900 Subject: [PATCH 0591/1064] update rust-installer from 27dec6c to ccdc47b --- src/tools/rust-installer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-installer b/src/tools/rust-installer index 27dec6cae3a81..ccdc47b657a76 160000 --- a/src/tools/rust-installer +++ b/src/tools/rust-installer @@ -1 +1 @@ -Subproject commit 27dec6cae3a8132d8a073aad6775425c85095c99 +Subproject commit ccdc47b657a7600cbd0c2858eb52a8d712cfce18 From bd4df0c6dd95b93a2157922970b8c7b97b9db086 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Tue, 5 Feb 2019 01:31:48 +0900 Subject: [PATCH 0592/1064] Add Cargo.lock automatically adding message --- Cargo.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b52f2094584ce..6121ee0ccf75a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "adler32" version = "1.0.3" From 59ea75b51ce3100d8e176551b41ec99330b8e011 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 4 Feb 2019 19:27:43 +0100 Subject: [PATCH 0593/1064] add more debugging code to track down appveyor 259 exit code --- appveyor.yml | 5 ++++- src/ci/run.sh | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d70ad54b1c812..0ec4210af98b2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -207,7 +207,10 @@ test_script: - sh src/ci/init_repo.sh . /c/cache/rustsrc - set SRC=. - set NO_CCACHE=1 - - sh src/ci/run.sh + # Added this debugging code to try tracking down https://github.com/rust-lang/rust/issues/58160 + # Replace it with the commented line below after the issue with AppVeyor is fixed + - "sh src/ci/run.sh & set ret=%errorlevel% & echo exit code in appveyor.yml: %ret% & exit %ret%" +# - sh src/ci/run.sh on_failure: # Dump crash log diff --git a/src/ci/run.sh b/src/ci/run.sh index 0f2517c7d1f55..b8b1052c41c12 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -127,7 +127,7 @@ if [ ! -z "$SCRIPT" ]; then set +e sh -x -c "$SCRIPT" ret=$? - echo "script exited with $ret" + echo "exit code in src/ci/run.sh: $ret" exit $ret else do_make() { From 57c4c2863d4e1a18d668fdd79cab210105deb13c Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Mon, 4 Feb 2019 14:43:30 -0700 Subject: [PATCH 0594/1064] Update contributor name in .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index a928606b693e5..d265f45c5cafa 100644 --- a/.mailmap +++ b/.mailmap @@ -155,6 +155,7 @@ Matt Brubeck Matthew Auld Matthew McPherrin Matthijs Hofstra +Melody Horn Michael Williams Michael Woerister Mickaël Raybaud-Roig m-r-r From 75b19579fb22b91ded35cdda3c381b17faa63798 Mon Sep 17 00:00:00 2001 From: garyemerson Date: Mon, 4 Feb 2019 15:26:33 -0800 Subject: [PATCH 0595/1064] update split docs Some confusion about split popped up at https://news.ycombinator.com/item?id=19080931 since the docs sorta sound like `&str`, `char` and closures are the only types that can be patterns. cc @steveklabnik --- src/libcore/str/mod.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 130142103a9ba..e9190cc3ddf1b 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2961,8 +2961,8 @@ impl str { /// An iterator over substrings of this string slice, separated by /// characters matched by a pattern. /// - /// The pattern can be a `&str`, [`char`], or a closure that determines the - /// split. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// /// # Iterator behavior /// @@ -3078,8 +3078,8 @@ impl str { /// An iterator over substrings of the given string slice, separated by /// characters matched by a pattern and yielded in reverse order. /// - /// The pattern can be a `&str`, [`char`], or a closure that determines the - /// split. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// /// # Iterator behavior /// @@ -3128,8 +3128,8 @@ impl str { /// An iterator over substrings of the given string slice, separated by /// characters matched by a pattern. /// - /// The pattern can be a `&str`, [`char`], or a closure that determines the - /// split. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// /// Equivalent to [`split`], except that the trailing substring /// is skipped if empty. @@ -3175,8 +3175,8 @@ impl str { /// An iterator over substrings of `self`, separated by characters /// matched by a pattern and yielded in reverse order. /// - /// The pattern can be a simple `&str`, [`char`], or a closure that - /// determines the split. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// Additional libraries might provide more complex patterns like /// regular expressions. /// @@ -3222,8 +3222,8 @@ impl str { /// If `n` substrings are returned, the last substring (the `n`th substring) /// will contain the remainder of the string. /// - /// The pattern can be a `&str`, [`char`], or a closure that determines the - /// split. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// /// # Iterator behavior /// @@ -3275,8 +3275,8 @@ impl str { /// If `n` substrings are returned, the last substring (the `n`th substring) /// will contain the remainder of the string. /// - /// The pattern can be a `&str`, [`char`], or a closure that - /// determines the split. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// /// # Iterator behavior /// @@ -3319,8 +3319,8 @@ impl str { /// An iterator over the disjoint matches of a pattern within the given string /// slice. /// - /// The pattern can be a `&str`, [`char`], or a closure that - /// determines if a character matches. + /// The pattern can be any type that implements the Pattern trait. Notable + /// examples are `&str`, [`char`], and closures that determines the split. /// /// # Iterator behavior /// From 5d9eed4191c3edae4704737a95706dcf714334f8 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 00:05:53 +0900 Subject: [PATCH 0596/1064] Transition build-manifest to 2018 edition --- src/tools/build-manifest/Cargo.toml | 1 + src/tools/build-manifest/src/main.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 844b7aad72fde..0fda887ea61fe 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -2,6 +2,7 @@ name = "build-manifest" version = "0.1.0" authors = ["Alex Crichton "] +edition = "2018" [dependencies] toml = "0.4" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 4ca285b9b1db1..5e8559725f134 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -1,4 +1,6 @@ -extern crate toml; +#![deny(rust_2018_idioms)] + +use toml; #[macro_use] extern crate serde_derive; From 212533afbe352e74c6c8bb64c2d8b526cfa15350 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Tue, 5 Feb 2019 01:11:08 +0900 Subject: [PATCH 0597/1064] Remove macro_use --- src/tools/build-manifest/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 5e8559725f134..9d88ac8dd0498 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -1,8 +1,7 @@ #![deny(rust_2018_idioms)] use toml; -#[macro_use] -extern crate serde_derive; +use serde_derive::Serialize; use std::collections::BTreeMap; use std::env; From 6904fac6d915b9bb3538ac2e6fbd31ad301a64c8 Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Tue, 5 Feb 2019 10:51:47 +0900 Subject: [PATCH 0598/1064] Use derive feature of serde --- src/tools/build-manifest/Cargo.toml | 2 +- src/tools/build-manifest/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 0fda887ea61fe..93d0f61e1d9f0 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -6,5 +6,5 @@ edition = "2018" [dependencies] toml = "0.4" -serde = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_derive = "1.0" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 9d88ac8dd0498..335cd617759a9 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -1,7 +1,7 @@ #![deny(rust_2018_idioms)] use toml; -use serde_derive::Serialize; +use serde::Serialize; use std::collections::BTreeMap; use std::env; From 47a587fb2b8f654aa165e2f87e533bc99b1546fd Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Tue, 5 Feb 2019 10:59:18 +0900 Subject: [PATCH 0599/1064] Remove unncessary return statement --- src/tools/build-manifest/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 335cd617759a9..a51eb4b4a10ad 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -469,7 +469,7 @@ impl Builder { } manifest.pkg.insert("rust".to_string(), pkg); - return manifest; + manifest } fn profile(&mut self, From b9686416c63117db3832e8015b609cbc83f11e4b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:09:23 +1100 Subject: [PATCH 0600/1064] Remove some unnecessary `ast::` and `fold::` qualifiers. --- src/libsyntax/ext/expand.rs | 7 ++-- src/libsyntax/fold.rs | 76 +++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 46 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 1b4b44270ad06..957187ec71c61 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -9,7 +9,6 @@ use ext::derive::{add_derived_markers, collect_derives}; use ext::hygiene::{self, Mark, SyntaxContext}; use ext::placeholders::{placeholder, PlaceholderExpander}; use feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; -use fold; use fold::*; use parse::{DirectoryOwnership, PResult, ParseSess}; use parse::token::{self, Token}; @@ -1395,7 +1394,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { self.check_attributes(&attrs); self.collect_bang(mac, span, AstFragmentKind::TraitItems).make_trait_items() } - _ => fold::noop_fold_trait_item(item, self), + _ => noop_fold_trait_item(item, self), } } @@ -1414,14 +1413,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { self.check_attributes(&attrs); self.collect_bang(mac, span, AstFragmentKind::ImplItems).make_impl_items() } - _ => fold::noop_fold_impl_item(item, self), + _ => noop_fold_impl_item(item, self), } } fn fold_ty(&mut self, ty: P) -> P { let ty = match ty.node { ast::TyKind::Mac(_) => ty.into_inner(), - _ => return fold::noop_fold_ty(ty, self), + _ => return noop_fold_ty(ty, self), }; match ty.node { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index fdcbbb939a6cf..d8afad5e37912 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -9,7 +9,6 @@ //! that are created by the expansion of a macro. use ast::*; -use ast; use syntax_pos::Span; use source_map::{Spanned, respan}; use parse::token::{self, Token}; @@ -785,31 +784,26 @@ pub fn noop_fold_where_predicate( fld: &mut T) -> WherePredicate { match pred { - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_generic_params, - bounded_ty, - bounds, - span}) => { - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { + WherePredicate::BoundPredicate(WhereBoundPredicate { bound_generic_params, + bounded_ty, + bounds, + span }) => { + WherePredicate::BoundPredicate(WhereBoundPredicate { bound_generic_params: fld.fold_generic_params(bound_generic_params), bounded_ty: fld.fold_ty(bounded_ty), bounds: bounds.move_map(|x| fld.fold_param_bound(x)), span: fld.new_span(span) }) } - ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{lifetime, - bounds, - span}) => { - ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { + WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => { + WherePredicate::RegionPredicate(WhereRegionPredicate { span: fld.new_span(span), lifetime: noop_fold_lifetime(lifetime, fld), bounds: bounds.move_map(|bound| noop_fold_param_bound(bound, fld)) }) } - ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id, - lhs_ty, - rhs_ty, - span}) => { - ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ + WherePredicate::EqPredicate(WhereEqPredicate { id, lhs_ty, rhs_ty, span }) => { + WherePredicate::EqPredicate(WhereEqPredicate{ id: fld.new_id(id), lhs_ty: fld.fold_ty(lhs_ty), rhs_ty: fld.fold_ty(rhs_ty), @@ -821,15 +815,13 @@ pub fn noop_fold_where_predicate( pub fn noop_fold_variant_data(vdata: VariantData, fld: &mut T) -> VariantData { match vdata { - ast::VariantData::Struct(fields, id) => { - ast::VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)), - fld.new_id(id)) + VariantData::Struct(fields, id) => { + VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)), fld.new_id(id)) } - ast::VariantData::Tuple(fields, id) => { - ast::VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)), - fld.new_id(id)) + VariantData::Tuple(fields, id) => { + VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)), fld.new_id(id)) } - ast::VariantData::Unit(id) => ast::VariantData::Unit(fld.new_id(id)) + VariantData::Unit(id) => VariantData::Unit(fld.new_id(id)) } } @@ -839,14 +831,14 @@ pub fn noop_fold_trait_ref(p: TraitRef, fld: &mut T) -> TraitRef { path, ref_id: _, } = p; - ast::TraitRef { + TraitRef { path: fld.fold_path(path), ref_id: id, } } pub fn noop_fold_poly_trait_ref(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef { - ast::PolyTraitRef { + PolyTraitRef { bound_generic_params: fld.fold_generic_params(p.bound_generic_params), trait_ref: fld.fold_trait_ref(p.trait_ref), span: fld.new_span(p.span), @@ -932,7 +924,7 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { ItemKind::Enum(enum_definition, generics) => { let generics = folder.fold_generics(generics); let variants = enum_definition.variants.move_map(|x| folder.fold_variant(x)); - ItemKind::Enum(ast::EnumDef { variants }, generics) + ItemKind::Enum(EnumDef { variants }, generics) } ItemKind::Struct(struct_def, generics) => { let generics = folder.fold_generics(generics); @@ -991,7 +983,7 @@ pub fn noop_fold_trait_item(i: TraitItem, folder: &mut T) -> SmallVec TraitItemKind::Type(folder.fold_bounds(bounds), default.map(|x| folder.fold_ty(x))) } - ast::TraitItemKind::Macro(mac) => { + TraitItemKind::Macro(mac) => { TraitItemKind::Macro(folder.fold_mac(mac)) } }, @@ -1009,18 +1001,18 @@ pub fn noop_fold_impl_item(i: ImplItem, folder: &mut T)-> SmallVec<[I generics: folder.fold_generics(i.generics), defaultness: i.defaultness, node: match i.node { - ast::ImplItemKind::Const(ty, expr) => { - ast::ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr)) + ImplItemKind::Const(ty, expr) => { + ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr)) } - ast::ImplItemKind::Method(sig, body) => { - ast::ImplItemKind::Method(noop_fold_method_sig(sig, folder), + ImplItemKind::Method(sig, body) => { + ImplItemKind::Method(noop_fold_method_sig(sig, folder), folder.fold_block(body)) } - ast::ImplItemKind::Type(ty) => ast::ImplItemKind::Type(folder.fold_ty(ty)), - ast::ImplItemKind::Existential(bounds) => { - ast::ImplItemKind::Existential(folder.fold_bounds(bounds)) + ImplItemKind::Type(ty) => ImplItemKind::Type(folder.fold_ty(ty)), + ImplItemKind::Existential(bounds) => { + ImplItemKind::Existential(folder.fold_bounds(bounds)) }, - ast::ImplItemKind::Macro(mac) => ast::ImplItemKind::Macro(folder.fold_mac(mac)) + ImplItemKind::Macro(mac) => ImplItemKind::Macro(folder.fold_mac(mac)) }, span: folder.new_span(i.span), tokens: i.tokens, @@ -1042,13 +1034,13 @@ pub fn noop_fold_mod(Mod {inner, items, inline}: Mod, folder: &mut T) pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, folder: &mut T) -> Crate { - let mut items = folder.fold_item(P(ast::Item { + let mut items = folder.fold_item(P(Item { ident: keywords::Invalid.ident(), attrs, - id: ast::DUMMY_NODE_ID, - vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Public), + id: DUMMY_NODE_ID, + vis: respan(span.shrink_to_lo(), VisibilityKind::Public), span, - node: ast::ItemKind::Mod(module), + node: ItemKind::Mod(module), tokens: None, })).into_iter(); @@ -1056,14 +1048,14 @@ pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, Some(item) => { assert!(items.next().is_none(), "a crate cannot expand to more than one item"); - item.and_then(|ast::Item { attrs, span, node, .. }| { + item.and_then(|Item { attrs, span, node, .. }| { match node { - ast::ItemKind::Mod(m) => (m, attrs, span), + ItemKind::Mod(m) => (m, attrs, span), _ => panic!("fold converted a module to not a module"), } }) } - None => (ast::Mod { + None => (Mod { inner: span, items: vec![], inline: true, @@ -1155,7 +1147,7 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P { let pth = folder.fold_path(pth); let fs = fields.move_map(|f| { Spanned { span: folder.new_span(f.span), - node: ast::FieldPat { + node: FieldPat { ident: folder.fold_ident(f.node.ident), pat: folder.fold_pat(f.node.pat), is_shorthand: f.node.is_shorthand, From faa82eb46c800857756ddc5458623a906a9f103e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:10:04 +1100 Subject: [PATCH 0601/1064] Streamline `Folder`. Specifically: - Remove dead methods: fold_usize, fold_meta_items, fold_opt_bounds. - Remove useless methods: fold_global_asm, fold_range_end. - Inline and remove unnecessary methods: fold_item_simple, fold_foreign_item_simple. --- src/libsyntax/fold.rs | 97 +++++++++---------------------------------- 1 file changed, 20 insertions(+), 77 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d8afad5e37912..6f856f63d6c7f 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -45,10 +45,6 @@ pub trait Folder : Sized { noop_fold_crate(c, self) } - fn fold_meta_items(&mut self, meta_items: Vec) -> Vec { - noop_fold_meta_items(meta_items, self) - } - fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem { noop_fold_meta_list_item(list_item, self) } @@ -65,18 +61,10 @@ pub trait Folder : Sized { noop_fold_foreign_item(ni, self) } - fn fold_foreign_item_simple(&mut self, ni: ForeignItem) -> ForeignItem { - noop_fold_foreign_item_simple(ni, self) - } - fn fold_item(&mut self, i: P) -> SmallVec<[P; 1]> { noop_fold_item(i, self) } - fn fold_item_simple(&mut self, i: Item) -> Item { - noop_fold_item_simple(i, self) - } - fn fold_fn_header(&mut self, header: FnHeader) -> FnHeader { noop_fold_fn_header(header, self) } @@ -133,10 +121,6 @@ pub trait Folder : Sized { e.map(|e| noop_fold_expr(e, self)) } - fn fold_range_end(&mut self, re: RangeEnd) -> RangeEnd { - noop_fold_range_end(re, self) - } - fn fold_opt_expr(&mut self, e: P) -> Option> { noop_fold_opt_expr(e, self) } @@ -172,10 +156,6 @@ pub trait Folder : Sized { noop_fold_foreign_mod(nm, self) } - fn fold_global_asm(&mut self, ga: P) -> P { - noop_fold_global_asm(ga, self) - } - fn fold_variant(&mut self, v: Variant) -> Variant { noop_fold_variant(v, self) } @@ -184,10 +164,6 @@ pub trait Folder : Sized { noop_fold_ident(i, self) } - fn fold_usize(&mut self, i: usize) -> usize { - noop_fold_usize(i, self) - } - fn fold_path(&mut self, p: Path) -> Path { noop_fold_path(p, self) } @@ -281,10 +257,6 @@ pub trait Folder : Sized { noop_fold_interpolated(nt, self) } - fn fold_opt_bounds(&mut self, b: Option) -> Option { - noop_fold_opt_bounds(b, self) - } - fn fold_bounds(&mut self, b: GenericBounds) -> GenericBounds { noop_fold_bounds(b, self) } @@ -324,10 +296,6 @@ pub trait Folder : Sized { } } -pub fn noop_fold_meta_items(meta_items: Vec, fld: &mut T) -> Vec { - meta_items.move_map(|x| fld.fold_meta_item(x)) -} - pub fn noop_fold_use_tree(use_tree: UseTree, fld: &mut T) -> UseTree { UseTree { span: fld.new_span(use_tree.span), @@ -430,11 +398,6 @@ pub fn noop_fold_foreign_mod(ForeignMod {abi, items}: ForeignMod, } } -pub fn noop_fold_global_asm(ga: P, - _: &mut T) -> P { - ga -} - pub fn noop_fold_variant(v: Variant, fld: &mut T) -> Variant { Spanned { node: Variant_ { @@ -451,10 +414,6 @@ pub fn noop_fold_ident(ident: Ident, fld: &mut T) -> Ident { Ident::new(ident.name, fld.new_span(ident.span)) } -pub fn noop_fold_usize(i: usize, _: &mut T) -> usize { - i -} - pub fn noop_fold_path(Path { segments, span }: Path, fld: &mut T) -> Path { Path { segments: segments.move_map(|PathSegment { ident, id, args }| PathSegment { @@ -873,11 +832,6 @@ pub fn noop_fold_mt(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutT } } -pub fn noop_fold_opt_bounds(b: Option, folder: &mut T) - -> Option { - b.map(|bounds| folder.fold_bounds(bounds)) -} - fn noop_fold_bounds(bounds: GenericBounds, folder: &mut T) -> GenericBounds { bounds.move_map(|bound| folder.fold_param_bound(bound)) @@ -913,7 +867,7 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { } ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)), ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)), - ItemKind::GlobalAsm(ga) => ItemKind::GlobalAsm(folder.fold_global_asm(ga)), + ItemKind::GlobalAsm(ga) => ItemKind::GlobalAsm(ga), ItemKind::Ty(t, generics) => { ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics)) } @@ -1071,34 +1025,27 @@ pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, // fold one item into possibly many items pub fn noop_fold_item(i: P, folder: &mut T) -> SmallVec<[P; 1]> { - smallvec![i.map(|i| folder.fold_item_simple(i))] -} - -// fold one item into exactly one item -pub fn noop_fold_item_simple(Item {id, ident, attrs, node, vis, span, tokens}: Item, - folder: &mut T) -> Item { - Item { - id: folder.new_id(id), - vis: folder.fold_vis(vis), - ident: folder.fold_ident(ident), - attrs: fold_attrs(attrs, folder), - node: folder.fold_item_kind(node), - span: folder.new_span(span), - - // FIXME: if this is replaced with a call to `folder.fold_tts` it causes - // an ICE during resolve... odd! - tokens, - } + smallvec![i.map(|i| { + let Item {id, ident, attrs, node, vis, span, tokens} = i; + Item { + id: folder.new_id(id), + vis: folder.fold_vis(vis), + ident: folder.fold_ident(ident), + attrs: fold_attrs(attrs, folder), + node: folder.fold_item_kind(node), + span: folder.new_span(span), + + // FIXME: if this is replaced with a call to `folder.fold_tts` it causes + // an ICE during resolve... odd! + tokens, + } + })] } pub fn noop_fold_foreign_item(ni: ForeignItem, folder: &mut T) -> SmallVec<[ForeignItem; 1]> { - smallvec![folder.fold_foreign_item_simple(ni)] -} - -pub fn noop_fold_foreign_item_simple(ni: ForeignItem, folder: &mut T) -> ForeignItem { - ForeignItem { + smallvec![ForeignItem { id: folder.new_id(ni.id), vis: folder.fold_vis(ni.vis), ident: folder.fold_ident(ni.ident), @@ -1114,7 +1061,7 @@ pub fn noop_fold_foreign_item_simple(ni: ForeignItem, folder: &mut T) ForeignItemKind::Macro(mac) => ForeignItemKind::Macro(folder.fold_mac(mac)), }, span: folder.new_span(ni.span) - } + }] } pub fn noop_fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { @@ -1161,10 +1108,10 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P { } PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)), PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl), - PatKind::Range(e1, e2, Spanned { span, node: end }) => { + PatKind::Range(e1, e2, Spanned { span, node }) => { PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2), - Spanned { span, node: folder.fold_range_end(end) }) + Spanned { span, node }) }, PatKind::Slice(before, slice, after) => { PatKind::Slice(before.move_map(|x| folder.fold_pat(x)), @@ -1178,10 +1125,6 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P { }) } -pub fn noop_fold_range_end(end: RangeEnd, _folder: &mut T) -> RangeEnd { - end -} - pub fn noop_fold_anon_const(constant: AnonConst, folder: &mut T) -> AnonConst { let AnonConst {id, value} = constant; AnonConst { From eea2dfe76f7afea0df3ae99fcdd30f1afbf4402d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:11:10 +1100 Subject: [PATCH 0602/1064] Fold some overlooked spans. --- src/libsyntax/fold.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6f856f63d6c7f..c01ac3107b6d8 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -734,7 +734,7 @@ pub fn noop_fold_where_clause( predicates: predicates.move_map(|predicate| { fld.fold_where_predicate(predicate) }), - span, + span: fld.new_span(span), } } @@ -1111,7 +1111,7 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P { PatKind::Range(e1, e2, Spanned { span, node }) => { PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2), - Spanned { span, node }) + Spanned { node, span: folder.new_span(span) }) }, PatKind::Slice(before, slice, after) => { PatKind::Slice(before.move_map(|x| folder.fold_pat(x)), @@ -1342,15 +1342,20 @@ pub fn noop_fold_stmt_kind(node: StmtKind, folder: &mut T) -> SmallVe } } -pub fn noop_fold_vis(vis: Visibility, folder: &mut T) -> Visibility { - match vis.node { - VisibilityKind::Restricted { path, id } => { - respan(vis.span, VisibilityKind::Restricted { - path: path.map(|path| folder.fold_path(path)), - id: folder.new_id(id), - }) - } - _ => vis, +pub fn noop_fold_vis(Spanned { node, span }: Visibility, folder: &mut T) -> Visibility { + Visibility { + node: match node { + VisibilityKind::Public => VisibilityKind::Public, + VisibilityKind::Crate(sugar) => VisibilityKind::Crate(sugar), + VisibilityKind::Restricted { path, id } => { + VisibilityKind::Restricted { + path: path.map(|path| folder.fold_path(path)), + id: folder.new_id(id), + } + } + VisibilityKind::Inherited => VisibilityKind::Inherited, + }, + span: folder.new_span(span), } } From f97e896fd669b61051027d76d6dccb89c72c4c52 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:11:27 +1100 Subject: [PATCH 0603/1064] Simplify `fold_attribute`. It doesn't need to return an `Option`. --- src/libsyntax/ext/expand.rs | 8 +++----- src/libsyntax/fold.rs | 16 ++++++---------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 957187ec71c61..72e0a86bf5909 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1465,7 +1465,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { noop_fold_generic_param(param, self) } - fn fold_attribute(&mut self, at: ast::Attribute) -> Option { + fn fold_attribute(&mut self, at: ast::Attribute) -> ast::Attribute { // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename", // contents="file contents")]` attributes if !at.check_name("doc") { @@ -1585,10 +1585,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let meta = attr::mk_list_item(DUMMY_SP, Ident::from_str("doc"), items); match at.style { - ast::AttrStyle::Inner => - Some(attr::mk_spanned_attr_inner(at.span, at.id, meta)), - ast::AttrStyle::Outer => - Some(attr::mk_spanned_attr_outer(at.span, at.id, meta)), + ast::AttrStyle::Inner => attr::mk_spanned_attr_inner(at.span, at.id, meta), + ast::AttrStyle::Outer => attr::mk_spanned_attr_outer(at.span, at.id, meta), } } else { noop_fold_attribute(at, self) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c01ac3107b6d8..1ab1de1ba5c33 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -209,7 +209,7 @@ pub trait Folder : Sized { noop_fold_label(label, self) } - fn fold_attribute(&mut self, at: Attribute) -> Option { + fn fold_attribute(&mut self, at: Attribute) -> Attribute { noop_fold_attribute(at, self) } @@ -313,7 +313,7 @@ pub fn noop_fold_use_tree(use_tree: UseTree, fld: &mut T) -> UseTree } pub fn fold_attrs(attrs: Vec, fld: &mut T) -> Vec { - attrs.move_flat_map(|x| fld.fold_attribute(x)) + attrs.move_map(|x| fld.fold_attribute(x)) } pub fn fold_thin_attrs(attrs: ThinVec, fld: &mut T) -> ThinVec { @@ -485,15 +485,15 @@ pub fn noop_fold_local(l: P, fld: &mut T) -> P { }) } -pub fn noop_fold_attribute(attr: Attribute, fld: &mut T) -> Option { - Some(Attribute { +pub fn noop_fold_attribute(attr: Attribute, fld: &mut T) -> Attribute { + Attribute { id: attr.id, style: attr.style, path: fld.fold_path(attr.path), tokens: fld.fold_tts(attr.tokens), is_sugared_doc: attr.is_sugared_doc, span: fld.new_span(attr.span), - }) + } } pub fn noop_fold_mac(Spanned {node, span}: Mac, fld: &mut T) -> Mac { @@ -678,14 +678,10 @@ pub fn noop_fold_param_bound(pb: GenericBound, fld: &mut T) -> GenericBound w } pub fn noop_fold_generic_param(param: GenericParam, fld: &mut T) -> GenericParam { - let attrs: Vec<_> = param.attrs.into(); GenericParam { ident: fld.fold_ident(param.ident), id: fld.new_id(param.id), - attrs: attrs.into_iter() - .flat_map(|x| fld.fold_attribute(x).into_iter()) - .collect::>() - .into(), + attrs: fold_thin_attrs(param.attrs, fld), bounds: param.bounds.move_map(|l| noop_fold_param_bound(l, fld)), kind: match param.kind { GenericParamKind::Lifetime => GenericParamKind::Lifetime, From 8909f70a3249f61be10627fc6b6634dedf66f77a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:11:52 +1100 Subject: [PATCH 0604/1064] Change `fold_qpath` to `fold_qself`. It's simpler that way. --- src/libsyntax/fold.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1ab1de1ba5c33..a7e835fbd45f2 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -168,8 +168,8 @@ pub trait Folder : Sized { noop_fold_path(p, self) } - fn fold_qpath(&mut self, qs: Option, p: Path) -> (Option, Path) { - noop_fold_qpath(qs, p, self) + fn fold_qself(&mut self, qs: Option) -> Option { + noop_fold_qself(qs, self) } fn fold_generic_args(&mut self, p: GenericArgs) -> GenericArgs { @@ -367,8 +367,7 @@ pub fn noop_fold_ty(t: P, fld: &mut T) -> P { TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))), TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)), TyKind::Path(qself, path) => { - let (qself, path) = fld.fold_qpath(qself, path); - TyKind::Path(qself, path) + TyKind::Path(fld.fold_qself(qself), fld.fold_path(path)) } TyKind::Array(ty, length) => { TyKind::Array(fld.fold_ty(ty), fld.fold_anon_const(length)) @@ -425,17 +424,14 @@ pub fn noop_fold_path(Path { segments, span }: Path, fld: &mut T) -> } } -pub fn noop_fold_qpath(qself: Option, - path: Path, - fld: &mut T) -> (Option, Path) { - let qself = qself.map(|QSelf { ty, path_span, position }| { +pub fn noop_fold_qself(qself: Option, fld: &mut T) -> Option { + qself.map(|QSelf { ty, path_span, position }| { QSelf { ty: fld.fold_ty(ty), path_span: fld.new_span(path_span), position, } - }); - (qself, fld.fold_path(path)) + }) } pub fn noop_fold_generic_args(generic_args: GenericArgs, fld: &mut T) -> GenericArgs @@ -1083,8 +1079,7 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P { pats.move_map(|x| folder.fold_pat(x)), ddpos) } PatKind::Path(qself, pth) => { - let (qself, pth) = folder.fold_qpath(qself, pth); - PatKind::Path(qself, pth) + PatKind::Path(folder.fold_qself(qself), folder.fold_path(pth)) } PatKind::Struct(pth, fields, etc) => { let pth = folder.fold_path(pth); @@ -1251,8 +1246,7 @@ pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mu lim) } ExprKind::Path(qself, path) => { - let (qself, path) = folder.fold_qpath(qself, path); - ExprKind::Path(qself, path) + ExprKind::Path(folder.fold_qself(qself), folder.fold_path(path)) } ExprKind::Break(opt_label, opt_expr) => { ExprKind::Break(opt_label.map(|label| folder.fold_label(label)), From 473095345b74b4d6b836d3ab2e3ace0c6719b20f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:12:15 +1100 Subject: [PATCH 0605/1064] Neaten up `fold_crate`. --- src/libsyntax/fold.rs | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index a7e835fbd45f2..567175b84df1a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -980,7 +980,7 @@ pub fn noop_fold_mod(Mod {inner, items, inline}: Mod, folder: &mut T) pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, folder: &mut T) -> Crate { - let mut items = folder.fold_item(P(Item { + let item = P(Item { ident: keywords::Invalid.ident(), attrs, id: DUMMY_NODE_ID, @@ -988,30 +988,21 @@ pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, span, node: ItemKind::Mod(module), tokens: None, - })).into_iter(); - - let (module, attrs, span) = match items.next() { - Some(item) => { - assert!(items.next().is_none(), - "a crate cannot expand to more than one item"); - item.and_then(|Item { attrs, span, node, .. }| { - match node { - ItemKind::Mod(m) => (m, attrs, span), - _ => panic!("fold converted a module to not a module"), - } - }) + }); + let items = folder.fold_item(item); + + let len = items.len(); + if len == 0 { + let module = Mod { inner: span, items: vec![], inline: true }; + Crate { module, attrs: vec![], span } + } else if len == 1 { + let Item { attrs, span, node, .. } = items.into_iter().next().unwrap().into_inner(); + match node { + ItemKind::Mod(module) => Crate { module, attrs, span }, + _ => panic!("fold converted a module to not a module"), } - None => (Mod { - inner: span, - items: vec![], - inline: true, - }, vec![], span) - }; - - Crate { - module, - attrs, - span, + } else { + panic!("a crate cannot expand to more than one item"); } } From 372fe84a8349ab4a8693d656bd786a5a47e22a56 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:13:12 +1100 Subject: [PATCH 0606/1064] Streamline `Folder` some more. By eliminating some unnecessary methods, and moving/renaming some functions that look like they might be methods but aren't. --- src/libsyntax/fold.rs | 82 ++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 567175b84df1a..5fb0132ad4566 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -125,10 +125,6 @@ pub trait Folder : Sized { noop_fold_opt_expr(e, self) } - fn fold_exprs(&mut self, es: Vec>) -> Vec> { - noop_fold_exprs(es, self) - } - fn fold_generic_arg(&mut self, arg: GenericArg) -> GenericArg { match arg { GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.fold_lifetime(lt)), @@ -257,10 +253,6 @@ pub trait Folder : Sized { noop_fold_interpolated(nt, self) } - fn fold_bounds(&mut self, b: GenericBounds) -> GenericBounds { - noop_fold_bounds(b, self) - } - fn fold_param_bound(&mut self, tpb: GenericBound) -> GenericBound { noop_fold_param_bound(tpb, self) } @@ -296,6 +288,34 @@ pub trait Folder : Sized { } } +// No `noop_` prefix because there isn't a corresponding method in `Folder`. +fn fold_attrs(attrs: Vec, fld: &mut T) -> Vec { + attrs.move_map(|x| fld.fold_attribute(x)) +} + +// No `noop_` prefix because there isn't a corresponding method in `Folder`. +fn fold_thin_attrs(attrs: ThinVec, fld: &mut T) -> ThinVec { + fold_attrs(attrs.into(), fld).into() +} + +// No `noop_` prefix because there isn't a corresponding method in `Folder`. +fn fold_exprs(es: Vec>, fld: &mut T) -> Vec> { + es.move_flat_map(|e| fld.fold_opt_expr(e)) +} + +// No `noop_` prefix because there isn't a corresponding method in `Folder`. +fn fold_bounds(bounds: GenericBounds, folder: &mut T) -> GenericBounds { + bounds.move_map(|bound| folder.fold_param_bound(bound)) +} + +// No `noop_` prefix because there isn't a corresponding method in `Folder`. +fn fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { + MethodSig { + header: folder.fold_fn_header(sig.header), + decl: folder.fold_fn_decl(sig.decl) + } +} + pub fn noop_fold_use_tree(use_tree: UseTree, fld: &mut T) -> UseTree { UseTree { span: fld.new_span(use_tree.span), @@ -312,14 +332,6 @@ pub fn noop_fold_use_tree(use_tree: UseTree, fld: &mut T) -> UseTree } } -pub fn fold_attrs(attrs: Vec, fld: &mut T) -> Vec { - attrs.move_map(|x| fld.fold_attribute(x)) -} - -pub fn fold_thin_attrs(attrs: ThinVec, fld: &mut T) -> ThinVec { - fold_attrs(attrs.into(), fld).into() -} - pub fn noop_fold_arm(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm { Arm { @@ -824,11 +836,6 @@ pub fn noop_fold_mt(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutT } } -fn noop_fold_bounds(bounds: GenericBounds, folder: &mut T) - -> GenericBounds { - bounds.move_map(|bound| folder.fold_param_bound(bound)) -} - pub fn noop_fold_block(b: P, folder: &mut T) -> P { b.map(|Block {id, stmts, rules, span}| Block { id: folder.new_id(id), @@ -864,7 +871,7 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics)) } ItemKind::Existential(bounds, generics) => ItemKind::Existential( - folder.fold_bounds(bounds), + fold_bounds(bounds, folder), folder.fold_generics(generics), ), ItemKind::Enum(enum_definition, generics) => { @@ -899,12 +906,12 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { is_auto, unsafety, folder.fold_generics(generics), - folder.fold_bounds(bounds), + fold_bounds(bounds, folder), items.move_flat_map(|item| folder.fold_trait_item(item)), ), ItemKind::TraitAlias(generics, bounds) => ItemKind::TraitAlias( folder.fold_generics(generics), - folder.fold_bounds(bounds)), + fold_bounds(bounds, folder)), ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)), ItemKind::MacroDef(def) => ItemKind::MacroDef(folder.fold_macro_def(def)), } @@ -922,11 +929,11 @@ pub fn noop_fold_trait_item(i: TraitItem, folder: &mut T) -> SmallVec default.map(|x| folder.fold_expr(x))) } TraitItemKind::Method(sig, body) => { - TraitItemKind::Method(noop_fold_method_sig(sig, folder), + TraitItemKind::Method(fold_method_sig(sig, folder), body.map(|x| folder.fold_block(x))) } TraitItemKind::Type(bounds, default) => { - TraitItemKind::Type(folder.fold_bounds(bounds), + TraitItemKind::Type(fold_bounds(bounds, folder), default.map(|x| folder.fold_ty(x))) } TraitItemKind::Macro(mac) => { @@ -951,12 +958,12 @@ pub fn noop_fold_impl_item(i: ImplItem, folder: &mut T)-> SmallVec<[I ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr)) } ImplItemKind::Method(sig, body) => { - ImplItemKind::Method(noop_fold_method_sig(sig, folder), + ImplItemKind::Method(fold_method_sig(sig, folder), folder.fold_block(body)) } ImplItemKind::Type(ty) => ImplItemKind::Type(folder.fold_ty(ty)), ImplItemKind::Existential(bounds) => { - ImplItemKind::Existential(folder.fold_bounds(bounds)) + ImplItemKind::Existential(fold_bounds(bounds, folder)) }, ImplItemKind::Macro(mac) => ImplItemKind::Macro(folder.fold_mac(mac)) }, @@ -1047,13 +1054,6 @@ pub fn noop_fold_foreign_item(ni: ForeignItem, folder: &mut T) }] } -pub fn noop_fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { - MethodSig { - header: folder.fold_fn_header(sig.header), - decl: folder.fold_fn_decl(sig.decl) - } -} - pub fn noop_fold_pat(p: P, folder: &mut T) -> P { p.map(|Pat {id, node, span}| Pat { id: folder.new_id(id), @@ -1125,15 +1125,15 @@ pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mu ExprKind::ObsoleteInPlace(folder.fold_expr(a), folder.fold_expr(b)) } ExprKind::Array(exprs) => { - ExprKind::Array(folder.fold_exprs(exprs)) + ExprKind::Array(fold_exprs(exprs, folder)) } ExprKind::Repeat(expr, count) => { ExprKind::Repeat(folder.fold_expr(expr), folder.fold_anon_const(count)) } - ExprKind::Tup(exprs) => ExprKind::Tup(folder.fold_exprs(exprs)), + ExprKind::Tup(exprs) => ExprKind::Tup(fold_exprs(exprs, folder)), ExprKind::Call(f, args) => { ExprKind::Call(folder.fold_expr(f), - folder.fold_exprs(args)) + fold_exprs(args, folder)) } ExprKind::MethodCall(seg, args) => { ExprKind::MethodCall( @@ -1144,7 +1144,7 @@ pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mu args.map(|args| folder.fold_generic_args(args)) }), }, - folder.fold_exprs(args)) + fold_exprs(args, folder)) } ExprKind::Binary(binop, lhs, rhs) => { ExprKind::Binary(binop, @@ -1294,10 +1294,6 @@ pub fn noop_fold_opt_expr(e: P, folder: &mut T) -> Option(es: Vec>, folder: &mut T) -> Vec> { - es.move_flat_map(|e| folder.fold_opt_expr(e)) -} - pub fn noop_fold_stmt(Stmt {node, span, id}: Stmt, folder: &mut T) -> SmallVec<[Stmt; 1]> { let id = folder.new_id(id); From 970b5d189af48dd6ec26e90bb8d6d236824edf4b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:18:29 +1100 Subject: [PATCH 0607/1064] Various improvements in `Folder` impls. --- src/libsyntax/config.rs | 44 +++++++++---------------------- src/libsyntax/ext/expand.rs | 5 +--- src/libsyntax/ext/placeholders.rs | 15 ++++------- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 2930ce079c848..b35730bf2381b 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -13,6 +13,7 @@ use edition::Edition; use parse::{token, ParseSess}; use smallvec::SmallVec; use errors::Applicability; +use util::move_map::MoveMap; use ptr::P; @@ -220,19 +221,19 @@ impl<'a> StripUnconfigured<'a> { pub fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod { ast::ForeignMod { abi: foreign_mod.abi, - items: foreign_mod.items.into_iter().filter_map(|item| self.configure(item)).collect(), + items: foreign_mod.items.move_flat_map(|item| self.configure(item)), } } fn configure_variant_data(&mut self, vdata: ast::VariantData) -> ast::VariantData { match vdata { ast::VariantData::Struct(fields, id) => { - let fields = fields.into_iter().filter_map(|field| self.configure(field)); - ast::VariantData::Struct(fields.collect(), id) + let fields = fields.move_flat_map(|field| self.configure(field)); + ast::VariantData::Struct(fields, id) } ast::VariantData::Tuple(fields, id) => { - let fields = fields.into_iter().filter_map(|field| self.configure(field)); - ast::VariantData::Tuple(fields.collect(), id) + let fields = fields.move_flat_map(|field| self.configure(field)); + ast::VariantData::Tuple(fields, id) } ast::VariantData::Unit(id) => ast::VariantData::Unit(id) } @@ -247,7 +248,7 @@ impl<'a> StripUnconfigured<'a> { ast::ItemKind::Union(self.configure_variant_data(def), generics) } ast::ItemKind::Enum(def, generics) => { - let variants = def.variants.into_iter().filter_map(|v| { + let variants = def.variants.move_flat_map(|v| { self.configure(v).map(|v| { Spanned { node: ast::Variant_ { @@ -260,9 +261,7 @@ impl<'a> StripUnconfigured<'a> { } }) }); - ast::ItemKind::Enum(ast::EnumDef { - variants: variants.collect(), - }, generics) + ast::ItemKind::Enum(ast::EnumDef { variants }, generics) } item => item, } @@ -271,15 +270,11 @@ impl<'a> StripUnconfigured<'a> { pub fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind { match expr_kind { ast::ExprKind::Match(m, arms) => { - let arms = arms.into_iter().filter_map(|a| self.configure(a)).collect(); + let arms = arms.move_flat_map(|a| self.configure(a)); ast::ExprKind::Match(m, arms) } ast::ExprKind::Struct(path, fields, base) => { - let fields = fields.into_iter() - .filter_map(|field| { - self.configure(field) - }) - .collect(); + let fields = fields.move_flat_map(|field| self.configure(field)); ast::ExprKind::Struct(path, fields, base) } _ => expr_kind, @@ -304,22 +299,10 @@ impl<'a> StripUnconfigured<'a> { self.process_cfg_attrs(expr) } - pub fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option { - self.configure(stmt) - } - - pub fn configure_struct_expr_field(&mut self, field: ast::Field) -> Option { - self.configure(field) - } - pub fn configure_pat(&mut self, pattern: P) -> P { pattern.map(|mut pattern| { if let ast::PatKind::Struct(path, fields, etc) = pattern.node { - let fields = fields.into_iter() - .filter_map(|field| { - self.configure(field) - }) - .collect(); + let fields = fields.move_flat_map(|field| self.configure(field)); pattern.node = ast::PatKind::Struct(path, fields, etc); } pattern @@ -367,10 +350,7 @@ impl<'a> fold::Folder for StripUnconfigured<'a> { } fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { - match self.configure_stmt(stmt) { - Some(stmt) => fold::noop_fold_stmt(stmt, self), - None => return SmallVec::new(), - } + fold::noop_fold_stmt(configure!(self, stmt), self) } fn fold_item(&mut self, item: P) -> SmallVec<[P; 1]> { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 72e0a86bf5909..2effd910e8545 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1247,10 +1247,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { - let mut stmt = match self.cfg.configure_stmt(stmt) { - Some(stmt) => stmt, - None => return SmallVec::new(), - }; + let mut stmt = configure!(self, stmt); // we'll expand attributes on expressions separately if !stmt.is_expr() { diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 3b0402d910a85..0928bc804041d 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -181,17 +181,12 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { fn fold_block(&mut self, block: P) -> P { noop_fold_block(block, self).map(|mut block| { - let mut remaining_stmts = block.stmts.len(); - - block.stmts = block.stmts.move_flat_map(|mut stmt| { - remaining_stmts -= 1; - + block.stmts = block.stmts.move_map(|mut stmt| { if self.monotonic { assert_eq!(stmt.id, ast::DUMMY_NODE_ID); stmt.id = self.cx.resolver.next_node_id(); } - - Some(stmt) + stmt }); block @@ -200,9 +195,9 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod { let mut module = noop_fold_mod(module, self); - module.items = module.items.move_flat_map(|item| match item.node { - ast::ItemKind::Mac(_) if !self.cx.ecfg.keep_macs => None, // remove macro definitions - _ => Some(item), + module.items.retain(|item| match item.node { + ast::ItemKind::Mac(_) if !self.cx.ecfg.keep_macs => false, // remove macro definitions + _ => true, }); module } From 2bfb4b336fc8fcd499c36dbc997dd18c7a5e62cf Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 5 Feb 2019 08:47:52 +0100 Subject: [PATCH 0608/1064] add even more debugging code to track down appveyor 259 exit code --- src/ci/run.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ci/run.sh b/src/ci/run.sh index b8b1052c41c12..0841e70a6ed29 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -128,6 +128,12 @@ if [ ! -z "$SCRIPT" ]; then sh -x -c "$SCRIPT" ret=$? echo "exit code in src/ci/run.sh: $ret" + + echo "tasklist:" + tasklist + echo -n "location of sh: " + where sh + exit $ret else do_make() { From e1ec81459da4ba8e0633d90ddf440522a1587f35 Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Tue, 5 Feb 2019 01:14:09 -0800 Subject: [PATCH 0609/1064] Apply more review suggestions --- src/libcore/future/future.rs | 8 +++++--- src/libcore/task/wake.rs | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index c40045245425b..470143d797afc 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -19,7 +19,8 @@ use task::{Poll, Waker}; /// final value. This method does not block if the value is not ready. Instead, /// the current task is scheduled to be woken up when it's possible to make /// further progress by `poll`ing again. The wake up is performed using -/// `cx.waker()`, a handle for waking up the current task. +/// the `waker` argument of the `poll()` method, which is a handle for waking +/// up the current task. /// /// When using a future, you generally won't call `poll` directly, but instead /// `await!` the value. @@ -78,8 +79,9 @@ pub trait Future { /// /// Once a future has completed (returned `Ready` from `poll`), /// then any future calls to `poll` may panic, block forever, or otherwise - /// cause bad behavior. The `Future` trait itself provides no guarantees - /// about the behavior of `poll` after a future has completed. + /// cause any kind of bad behavior expect causing memory unsafety. + /// The `Future` trait itself provides no guarantees about the behavior + /// of `poll` after a future has completed. /// /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index fe2de61c59446..1f42d3e2690f6 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -42,6 +42,9 @@ pub struct RawWakerVTable { /// This function will be called when `wake` is called on the [`Waker`]. /// It must wake up the task associated with this [`RawWaker`]. + /// + /// The implemention of this function must not consume the provided data + /// pointer. pub wake: unsafe fn(*const ()), /// This function gets called when a [`RawWaker`] gets dropped. @@ -125,7 +128,10 @@ impl Drop for Waker { impl fmt::Debug for Waker { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let vtable_ptr = self.waker.vtable as *const RawWakerVTable; f.debug_struct("Waker") + .field("data", &self.waker.data) + .field("vtable", &vtable_ptr) .finish() } } From 363e992b9885e2ce55b389ab274f9cd88598104d Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Tue, 5 Feb 2019 01:30:00 -0800 Subject: [PATCH 0610/1064] review suggestions --- src/libcore/future/future.rs | 6 ++++-- src/libcore/task/wake.rs | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 470143d797afc..459e8a927e757 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -68,13 +68,15 @@ pub trait Future { /// typically do *not* suffer the same problems of "all wakeups must poll /// all events"; they are more like `epoll(4)`. /// - /// An implementation of `poll` should strive to return quickly, and must - /// *never* block. Returning quickly prevents unnecessarily clogging up + /// An implementation of `poll` should strive to return quickly, and should + /// not block. Returning quickly prevents unnecessarily clogging up /// threads or event loops. If it is known ahead of time that a call to /// `poll` may end up taking awhile, the work should be offloaded to a /// thread pool (or something similar) to ensure that `poll` can return /// quickly. /// + /// An implementation of `poll` may also never cause memory unsafety. + /// /// # Panics /// /// Once a future has completed (returned `Ready` from `poll`), diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 1f42d3e2690f6..a877e033bc63b 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -29,6 +29,11 @@ pub struct RawWaker { /// /// The pointer passed to all functions inside the vtable is the `data` pointer /// from the enclosing [`RawWaker`] object. +/// +/// The functions inside this struct are only intended be called on the `data` +/// pointer of a properly constructed [`RawWaker`] object from inside the +/// [`RawWaker`] implementation. Calling one of the contained functions using +/// any other `data` pointer will cause undefined behavior. #[derive(PartialEq, Copy, Clone, Debug)] pub struct RawWakerVTable { /// This function will be called when the [`RawWaker`] gets cloned, e.g. when From b377d0b14ce141b8ce6c9bb22c22b1fb12d8232f Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 5 Feb 2019 09:03:39 +0100 Subject: [PATCH 0611/1064] Fix span for closure return type when annotated. This commit adjusts the span used to label closure return types so that if the user specifies the return type, i.e. `|_| -> X {}` instead of `|_| {}`, we correctly highlight all of it and not just the last character. --- .../error_reporting/region_name.rs | 7 +++++-- src/test/ui/nll/issue-58053.rs | 14 +++++++++++++ src/test/ui/nll/issue-58053.stderr | 20 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/nll/issue-58053.rs create mode 100644 src/test/ui/nll/issue-58053.stderr diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index bff8015511242..6adab3128d707 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -681,10 +681,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { let (return_span, mir_description) = match tcx.hir().get(mir_node_id) { hir::Node::Expr(hir::Expr { - node: hir::ExprKind::Closure(_, _, _, span, gen_move), + node: hir::ExprKind::Closure(_, return_ty, _, span, gen_move), .. }) => ( - tcx.sess.source_map().end_point(*span), + match return_ty.output { + hir::FunctionRetTy::DefaultReturn(_) => tcx.sess.source_map().end_point(*span), + hir::FunctionRetTy::Return(_) => return_ty.output.span(), + }, if gen_move.is_some() { " of generator" } else { diff --git a/src/test/ui/nll/issue-58053.rs b/src/test/ui/nll/issue-58053.rs new file mode 100644 index 0000000000000..d4338905ed2df --- /dev/null +++ b/src/test/ui/nll/issue-58053.rs @@ -0,0 +1,14 @@ +#![allow(warnings)] +#![feature(nll)] + +fn main() { + let i = &3; + + let f = |x: &i32| -> &i32 { x }; + //~^ ERROR lifetime may not live long enough + let j = f(i); + + let g = |x: &i32| { x }; + //~^ ERROR lifetime may not live long enough + let k = g(i); +} diff --git a/src/test/ui/nll/issue-58053.stderr b/src/test/ui/nll/issue-58053.stderr new file mode 100644 index 0000000000000..9048983318b36 --- /dev/null +++ b/src/test/ui/nll/issue-58053.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/issue-58053.rs:7:33 + | +LL | let f = |x: &i32| -> &i32 { x }; + | - ---- ^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is &'2 i32 + | let's call the lifetime of this reference `'1` + +error: lifetime may not live long enough + --> $DIR/issue-58053.rs:11:25 + | +LL | let g = |x: &i32| { x }; + | - - ^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is &'2 i32 + | let's call the lifetime of this reference `'1` + +error: aborting due to 2 previous errors + From 4c8c0fc1e2145b520ef31d1bf5e4d3fa1050c579 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 5 Feb 2019 16:19:05 +0530 Subject: [PATCH 0612/1064] SGX target: handle empty user buffers correctly --- src/libstd/sys/sgx/abi/usercalls/alloc.rs | 7 ++++++- src/libstd/sys/sgx/abi/usercalls/mod.rs | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs index 8d0013a235ac7..2efbaa9b1487a 100644 --- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs +++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs @@ -537,7 +537,12 @@ impl UserRef { pub fn copy_user_buffer(&self) -> Vec { unsafe { let buf = self.to_enclave(); - User::from_raw_parts(buf.data as _, buf.len).to_enclave() + if buf.len > 0 { + User::from_raw_parts(buf.data as _, buf.len).to_enclave() + } else { + // Mustn't look at `data` or call `free` if `len` is `0`. + Vec::with_capacity(0) + } } } } diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index 58903761ebe40..511d6e9e9273a 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -22,7 +22,8 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult { #[unstable(feature = "sgx_platform", issue = "56975")] pub fn read_alloc(fd: Fd) -> IoResult> { unsafe { - let mut userbuf = alloc::User::::uninitialized(); + let userbuf = ByteBuffer { data: ::ptr::null_mut(), len: 0 }; + let mut userbuf = alloc::User::new_from_enclave(&userbuf); raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?; Ok(userbuf.copy_user_buffer()) } From d89ebdd475ceaa35173e7d39dfdf23f8b7318745 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 5 Feb 2019 16:19:20 +0530 Subject: [PATCH 0613/1064] Expose correct items in `os::fortanix_sgx::usercalls::alloc` --- src/libstd/os/fortanix_sgx/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs index 810965fc1b85a..f536c5d04e6ee 100644 --- a/src/libstd/os/fortanix_sgx/mod.rs +++ b/src/libstd/os/fortanix_sgx/mod.rs @@ -16,7 +16,7 @@ pub mod usercalls { /// Primitives for allocating memory in userspace as well as copying data /// to and from user memory. pub mod alloc { - pub use sys::abi::usercalls::alloc; + pub use sys::abi::usercalls::alloc::*; } /// Lowest-level interfaces to usercalls and usercall ABI type definitions. From c93bce85e5e085274febf1ca71b551de3f51429c Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 5 Feb 2019 14:18:09 +0100 Subject: [PATCH 0614/1064] Add more tests --- .../generic_duplicate_param_use8.rs | 16 ++++++++ .../generic_duplicate_param_use8.stderr | 19 +++++++++ .../existential_types/not_a_defining_use.rs | 39 +++++++++++++++++++ .../not_a_defining_use.stderr | 18 +++++++++ 4 files changed, 92 insertions(+) create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use8.rs create mode 100644 src/test/ui/existential_types/generic_duplicate_param_use8.stderr create mode 100644 src/test/ui/existential_types/not_a_defining_use.rs create mode 100644 src/test/ui/existential_types/not_a_defining_use.stderr diff --git a/src/test/ui/existential_types/generic_duplicate_param_use8.rs b/src/test/ui/existential_types/generic_duplicate_param_use8.rs new file mode 100644 index 0000000000000..83501ad8c41a7 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use8.rs @@ -0,0 +1,16 @@ +#![feature(existential_type)] + +use std::fmt::Debug; + +fn main() {} + +existential type Two: Debug; + +fn two(t: T, _: U) -> Two { + (t, 4u32) +} + +fn three(_: T, u: U) -> Two { +//~^ concrete type differs from previous + (u, 4u32) +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use8.stderr b/src/test/ui/existential_types/generic_duplicate_param_use8.stderr new file mode 100644 index 0000000000000..80c7441c857d1 --- /dev/null +++ b/src/test/ui/existential_types/generic_duplicate_param_use8.stderr @@ -0,0 +1,19 @@ +error: concrete type differs from previous defining existential type use + --> $DIR/generic_duplicate_param_use8.rs:13:1 + | +LL | / fn three(_: T, u: U) -> Two { +LL | | //~^ concrete type differs from previous +LL | | (u, 4u32) +LL | | } + | |_^ expected `(T, u32)`, got `(U, u32)` + | +note: previous use here + --> $DIR/generic_duplicate_param_use8.rs:9:1 + | +LL | / fn two(t: T, _: U) -> Two { +LL | | (t, 4u32) +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/not_a_defining_use.rs b/src/test/ui/existential_types/not_a_defining_use.rs new file mode 100644 index 0000000000000..413cc6788c281 --- /dev/null +++ b/src/test/ui/existential_types/not_a_defining_use.rs @@ -0,0 +1,39 @@ +#![feature(existential_type)] + +use std::fmt::Debug; + +fn main() {} + +existential type Two: Debug; + +fn two(t: T) -> Two { + (t, 4i8) +} + +fn three(t: T) -> Two { + (t, 5i8) +} + +trait Bar { + type Blub: Debug; + const FOO: Self::Blub; +} + +impl Bar for u32 { + type Blub = i32; + const FOO: i32 = 42; +} + +// this should work! But it requires `two` and `three` not to be defining uses, +// just restricting uses +fn four(t: T) -> Two { //~ concrete type differs from previous + (t, ::FOO) +} + +fn is_sync() {} + +fn asdfl() { + //FIXME(oli-obk): these currently cause cycle errors + //is_sync::>(); + //is_sync::>(); +} diff --git a/src/test/ui/existential_types/not_a_defining_use.stderr b/src/test/ui/existential_types/not_a_defining_use.stderr new file mode 100644 index 0000000000000..a6ed5dbe0a9dd --- /dev/null +++ b/src/test/ui/existential_types/not_a_defining_use.stderr @@ -0,0 +1,18 @@ +error: concrete type differs from previous defining existential type use + --> $DIR/not_a_defining_use.rs:29:1 + | +LL | / fn four(t: T) -> Two { //~ concrete type differs from previous +LL | | (t, ::FOO) +LL | | } + | |_^ expected `(T, i8)`, got `(T, ::Blub)` + | +note: previous use here + --> $DIR/not_a_defining_use.rs:9:1 + | +LL | / fn two(t: T) -> Two { +LL | | (t, 4i8) +LL | | } + | |_^ + +error: aborting due to previous error + From a6f2f7f15e4c4c24f9091bbbb8c56952c15ab70a Mon Sep 17 00:00:00 2001 From: Hirokazu Hata Date: Mon, 4 Feb 2019 00:39:37 +0900 Subject: [PATCH 0615/1064] Transition rustdoc to 2018 edition --- src/tools/rustdoc/Cargo.toml | 1 + src/tools/rustdoc/main.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml index d38815004418c..36aa5916da733 100644 --- a/src/tools/rustdoc/Cargo.toml +++ b/src/tools/rustdoc/Cargo.toml @@ -2,6 +2,7 @@ name = "rustdoc-tool" version = "0.0.0" authors = ["The Rust Project Developers"] +edition = "2018" # Cargo adds a number of paths to the dylib search path on windows, which results in # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs index df9d2c6ba96db..8bdc365c4ca68 100644 --- a/src/tools/rustdoc/main.rs +++ b/src/tools/rustdoc/main.rs @@ -1,3 +1,5 @@ +#![deny(rust_2018_idioms)] + #![feature(link_args)] #[allow(unused_attributes)] @@ -10,6 +12,4 @@ // See src/rustc/rustc.rs for the corresponding rustc settings. extern {} -extern crate rustdoc; - fn main() { rustdoc::main() } From 014ffa3ac9e499fc0c3f03b7e902be6d819d02f3 Mon Sep 17 00:00:00 2001 From: liv Date: Tue, 5 Feb 2019 15:32:59 +0100 Subject: [PATCH 0616/1064] Add Rustlings to the doc index --- src/doc/index.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/index.md b/src/doc/index.md index 7a240ac0a42a5..0a2a80e8fd6e2 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -52,6 +52,12 @@ If reading multiple hundreds of pages about a language isn't your style, then a lot of words, RBE shows off a bunch of code, and keeps the talking to a minimum. It also includes exercises! +## Rustlings + +[Rustlings](https://github.com/rust-lang/rustlings) guides you through downloading and setting up the Rust toolchain, +and teaches you the basics of reading and writing Rust syntax. It's an +alternative to Rust by Example that works with your own environment. + # Use Rust Once you've gotten familiar with the language, these resources can help you From aaafc3c7fa1846b952b1a479ed69420b9b3f86bb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Feb 2019 17:22:46 +0100 Subject: [PATCH 0617/1064] fix doctest --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 68f985ce65202..18302e36ff762 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1042,7 +1042,7 @@ impl DerefMut for ManuallyDrop { /// even in unsafe code. As a consequence, 0-initializing a variable of reference /// type causes instantaneous undefined behavior, no matter whether that reference /// ever gets used to access memory: -/// ```rust,ignore +/// ```rust,no_run /// use std::mem; /// /// let x: &i32 = mem::zeroed(); // undefined behavior! @@ -1065,7 +1065,7 @@ impl DerefMut for ManuallyDrop { /// // Set it to a valid value. /// x.set(&0); /// // Extract the initialized data -- this is only allowed *after* properly -/// initializing `x`! +/// // initializing `x`! /// let x = unsafe { x.into_initialized() }; /// ``` /// The compiler then knows to not optimize this code. From e957ed9d10ec589bdd523b88b4b44c41b1ecf763 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 5 Feb 2019 11:20:45 -0600 Subject: [PATCH 0618/1064] move librustc to 2018 --- src/librustc/Cargo.toml | 1 + src/librustc/cfg/construct.rs | 10 +- src/librustc/cfg/graphviz.rs | 6 +- src/librustc/cfg/mod.rs | 6 +- src/librustc/dep_graph/cgu_reuse_tracker.rs | 2 +- src/librustc/dep_graph/dep_node.rs | 22 ++-- src/librustc/dep_graph/dep_tracking_map.rs | 2 +- src/librustc/dep_graph/graph.rs | 10 +- src/librustc/dep_graph/prev.rs | 2 +- src/librustc/dep_graph/safe.rs | 6 +- src/librustc/dep_graph/serialized.rs | 4 +- src/librustc/hir/check_attr.rs | 10 +- src/librustc/hir/def.rs | 8 +- src/librustc/hir/def_id.rs | 6 +- src/librustc/hir/intravisit.rs | 6 +- src/librustc/hir/lowering.rs | 28 ++--- src/librustc/hir/map/blocks.rs | 8 +- src/librustc/hir/map/collector.rs | 20 ++-- src/librustc/hir/map/def_collector.rs | 8 +- src/librustc/hir/map/definitions.rs | 10 +- src/librustc/hir/map/hir_id_validator.rs | 6 +- src/librustc/hir/map/mod.rs | 24 ++--- src/librustc/hir/mod.rs | 14 +-- src/librustc/hir/pat_util.rs | 6 +- src/librustc/hir/print.rs | 8 +- src/librustc/ich/hcx.rs | 18 ++-- src/librustc/ich/impls_cstore.rs | 18 ++-- src/librustc/ich/impls_hir.rs | 16 +-- src/librustc/ich/impls_mir.rs | 4 +- src/librustc/ich/impls_misc.rs | 2 +- src/librustc/ich/impls_syntax.rs | 4 +- src/librustc/ich/impls_ty.rs | 54 +++++----- src/librustc/infer/at.rs | 2 +- src/librustc/infer/canonical/canonicalizer.rs | 10 +- src/librustc/infer/canonical/mod.rs | 18 ++-- .../infer/canonical/query_response.rs | 24 ++--- src/librustc/infer/canonical/substitute.rs | 8 +- src/librustc/infer/combine.rs | 14 +-- src/librustc/infer/equate.rs | 10 +- src/librustc/infer/error_reporting/mod.rs | 22 ++-- .../infer/error_reporting/need_type_info.rs | 12 +-- .../nice_region_error/different_lifetimes.rs | 6 +- .../nice_region_error/find_anon_type.rs | 12 +-- .../error_reporting/nice_region_error/mod.rs | 10 +- .../nice_region_error/named_anon_conflict.rs | 8 +- .../nice_region_error/outlives_closure.rs | 14 +-- .../nice_region_error/placeholder_error.rs | 24 ++--- .../nice_region_error/static_impl_trait.rs | 10 +- .../error_reporting/nice_region_error/util.rs | 8 +- src/librustc/infer/error_reporting/note.rs | 10 +- src/librustc/infer/freshen.rs | 6 +- src/librustc/infer/fudge.rs | 6 +- src/librustc/infer/glb.rs | 6 +- src/librustc/infer/higher_ranked/mod.rs | 4 +- src/librustc/infer/lattice.rs | 8 +- .../infer/lexical_region_resolve/graphviz.rs | 14 +-- .../infer/lexical_region_resolve/mod.rs | 26 ++--- src/librustc/infer/lub.rs | 6 +- src/librustc/infer/mod.rs | 36 +++---- src/librustc/infer/opaque_types/mod.rs | 22 ++-- src/librustc/infer/outlives/env.rs | 8 +- .../infer/outlives/free_region_map.rs | 2 +- src/librustc/infer/outlives/obligations.rs | 12 +-- src/librustc/infer/outlives/verify.rs | 14 +-- src/librustc/infer/region_constraints/mod.rs | 8 +- src/librustc/infer/resolve.rs | 4 +- src/librustc/infer/sub.rs | 10 +- src/librustc/infer/type_variable.rs | 2 +- src/librustc/infer/unify_key.rs | 2 +- src/librustc/lib.rs | 38 +++---- src/librustc/lint/builtin.rs | 6 +- src/librustc/lint/context.rs | 30 +++--- src/librustc/lint/levels.rs | 16 +-- src/librustc/lint/mod.rs | 24 ++--- src/librustc/middle/borrowck.rs | 6 +- src/librustc/middle/cstore.rs | 12 +-- src/librustc/middle/dead.rs | 24 ++--- src/librustc/middle/dependency_format.rs | 12 +-- src/librustc/middle/entry.rs | 16 +-- src/librustc/middle/exported_symbols.rs | 8 +- src/librustc/middle/expr_use_visitor.rs | 18 ++-- src/librustc/middle/free_region.rs | 8 +- src/librustc/middle/intrinsicck.rs | 14 +-- src/librustc/middle/lang_items.rs | 14 +-- src/librustc/middle/lib_features.rs | 6 +- src/librustc/middle/liveness.rs | 24 ++--- src/librustc/middle/mem_categorization.rs | 28 ++--- src/librustc/middle/privacy.rs | 2 +- src/librustc/middle/reachable.rs | 28 ++--- src/librustc/middle/recursion_limit.rs | 2 +- src/librustc/middle/region.rs | 24 ++--- src/librustc/middle/resolve_lifetime.rs | 26 ++--- src/librustc/middle/stability.rs | 20 ++-- src/librustc/middle/weak_lang_items.rs | 14 +-- src/librustc/mir/cache.rs | 6 +- src/librustc/mir/interpret/allocation.rs | 4 +- src/librustc/mir/interpret/error.rs | 16 +-- src/librustc/mir/interpret/mod.rs | 16 +-- src/librustc/mir/interpret/pointer.rs | 4 +- src/librustc/mir/interpret/value.rs | 2 +- src/librustc/mir/mod.rs | 42 ++++---- src/librustc/mir/mono.rs | 8 +- src/librustc/mir/tcx.rs | 12 +-- src/librustc/mir/visit.rs | 10 +- src/librustc/session/config.rs | 30 +++--- src/librustc/session/filesearch.rs | 2 +- src/librustc/session/mod.rs | 28 ++--- src/librustc/session/search_paths.rs | 4 +- src/librustc/traits/auto_trait.rs | 8 +- src/librustc/traits/chalk_fulfill.rs | 10 +- src/librustc/traits/codegen/mod.rs | 12 +-- src/librustc/traits/coherence.rs | 20 ++-- src/librustc/traits/engine.rs | 8 +- src/librustc/traits/error_reporting.rs | 30 +++--- src/librustc/traits/fulfill.rs | 8 +- src/librustc/traits/mod.rs | 22 ++-- src/librustc/traits/object_safety.rs | 12 +-- src/librustc/traits/on_unimplemented.rs | 8 +- src/librustc/traits/project.rs | 16 +-- src/librustc/traits/query/dropck_outlives.rs | 10 +- .../traits/query/evaluate_obligation.rs | 6 +- src/librustc/traits/query/method_autoderef.rs | 4 +- src/librustc/traits/query/mod.rs | 6 +- src/librustc/traits/query/normalize.rs | 18 ++-- .../traits/query/normalize_erasing_regions.rs | 4 +- src/librustc/traits/query/outlives_bounds.rs | 12 +-- .../traits/query/type_op/ascribe_user_type.rs | 10 +- src/librustc/traits/query/type_op/custom.rs | 10 +- src/librustc/traits/query/type_op/eq.rs | 6 +- .../query/type_op/implied_outlives_bounds.rs | 8 +- src/librustc/traits/query/type_op/mod.rs | 12 +-- .../traits/query/type_op/normalize.rs | 8 +- src/librustc/traits/query/type_op/outlives.rs | 10 +- .../traits/query/type_op/prove_predicate.rs | 6 +- src/librustc/traits/query/type_op/subtype.rs | 6 +- src/librustc/traits/select.rs | 26 ++--- src/librustc/traits/specialize/mod.rs | 14 +-- .../traits/specialize/specialization_graph.rs | 16 +-- src/librustc/traits/structural_impls.rs | 22 ++-- src/librustc/traits/util.rs | 14 +-- src/librustc/ty/_match.rs | 6 +- src/librustc/ty/adjustment.rs | 8 +- src/librustc/ty/binding.rs | 6 +- src/librustc/ty/cast.rs | 2 +- src/librustc/ty/codec.rs | 14 +-- src/librustc/ty/constness.rs | 10 +- src/librustc/ty/context.rs | 100 +++++++++--------- src/librustc/ty/erase_regions.rs | 4 +- src/librustc/ty/error.rs | 8 +- src/librustc/ty/fast_reject.rs | 6 +- src/librustc/ty/flags.rs | 4 +- src/librustc/ty/fold.rs | 6 +- .../ty/inhabitedness/def_id_forest.rs | 4 +- src/librustc/ty/inhabitedness/mod.rs | 10 +- src/librustc/ty/instance.rs | 12 +-- src/librustc/ty/item_path.rs | 10 +- src/librustc/ty/layout.rs | 22 ++-- src/librustc/ty/mod.rs | 50 ++++----- src/librustc/ty/outlives.rs | 2 +- src/librustc/ty/query/config.rs | 28 ++--- src/librustc/ty/query/job.rs | 24 +++-- src/librustc/ty/query/keys.rs | 14 +-- src/librustc/ty/query/mod.rs | 78 +++++++------- src/librustc/ty/query/on_disk_cache.rs | 36 +++---- src/librustc/ty/query/plumbing.rs | 48 ++++----- src/librustc/ty/query/values.rs | 2 +- src/librustc/ty/relate.rs | 30 +++--- src/librustc/ty/structural_impls.rs | 54 +++++----- src/librustc/ty/sty.rs | 22 ++-- src/librustc/ty/subst.rs | 8 +- src/librustc/ty/trait_def.rs | 16 +-- src/librustc/ty/util.rs | 26 ++--- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 12 +-- src/librustc/util/bug.rs | 2 +- src/librustc/util/common.rs | 6 +- src/librustc/util/nodemap.rs | 4 +- src/librustc/util/ppaux.rs | 26 ++--- src/librustc/util/profiling.rs | 2 +- 179 files changed, 1234 insertions(+), 1243 deletions(-) diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index a5521effc7d8d..c9a04f4c6834d 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc" version = "0.0.0" +edition = "2018" [lib] name = "rustc" diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 669c2998d1cb2..f7ffbe8c65833 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -1,11 +1,11 @@ -use cfg::*; -use middle::region; +use crate::cfg::*; +use crate::middle::region; use rustc_data_structures::graph::implementation as graph; use syntax::ptr::P; -use ty::{self, TyCtxt}; +use crate::ty::{self, TyCtxt}; -use hir::{self, PatKind}; -use hir::def_id::DefId; +use crate::hir::{self, PatKind}; +use crate::hir::def_id::DefId; struct CFGBuilder<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc/cfg/graphviz.rs index 6dec421760899..969c38bd66329 100644 --- a/src/librustc/cfg/graphviz.rs +++ b/src/librustc/cfg/graphviz.rs @@ -4,9 +4,9 @@ // For clarity, rename the graphviz crate locally to dot. use graphviz as dot; -use cfg; -use hir; -use ty::TyCtxt; +use crate::cfg; +use crate::hir; +use crate::ty::TyCtxt; pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode); pub type Edge<'a> = &'a cfg::CFGEdge; diff --git a/src/librustc/cfg/mod.rs b/src/librustc/cfg/mod.rs index e58557839f9b9..345dff88b5f0b 100644 --- a/src/librustc/cfg/mod.rs +++ b/src/librustc/cfg/mod.rs @@ -2,9 +2,9 @@ //! Uses `Graph` as the underlying representation. use rustc_data_structures::graph::implementation as graph; -use ty::TyCtxt; -use hir; -use hir::def_id::DefId; +use crate::ty::TyCtxt; +use crate::hir; +use crate::hir::def_id::DefId; mod construct; pub mod graphviz; diff --git a/src/librustc/dep_graph/cgu_reuse_tracker.rs b/src/librustc/dep_graph/cgu_reuse_tracker.rs index e8d1b71048705..13f6f95332973 100644 --- a/src/librustc/dep_graph/cgu_reuse_tracker.rs +++ b/src/librustc/dep_graph/cgu_reuse_tracker.rs @@ -2,7 +2,7 @@ //! compilation. This is used for incremental compilation tests and debug //! output. -use session::Session; +use crate::session::Session; use rustc_data_structures::fx::FxHashMap; use std::sync::{Arc, Mutex}; use syntax_pos::Span; diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index cda469657ed87..58087b76266b5 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -49,25 +49,25 @@ //! user of the `DepNode` API of having to know how to compute the expected //! fingerprint for a given set of node parameters. -use mir::interpret::GlobalId; -use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; -use hir::map::DefPathHash; -use hir::HirId; +use crate::mir::interpret::GlobalId; +use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; +use crate::hir::map::DefPathHash; +use crate::hir::HirId; -use ich::{Fingerprint, StableHashingContext}; +use crate::ich::{Fingerprint, StableHashingContext}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use std::fmt; use std::hash::Hash; use syntax_pos::symbol::InternedString; -use traits; -use traits::query::{ +use crate::traits; +use crate::traits::query::{ CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, }; -use ty::{TyCtxt, FnSig, Instance, InstanceDef, +use crate::ty::{TyCtxt, FnSig, Instance, InstanceDef, ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty}; -use ty::subst::Substs; +use crate::ty::subst::Substs; // erase!() just makes tokens go away. It's used to specify which macro argument // is repeated (i.e., which sub-expression of the macro we are in) but don't need @@ -389,7 +389,7 @@ impl fmt::Debug for DepNode { write!(f, "(")?; - ::ty::tls::with_opt(|opt_tcx| { + crate::ty::tls::with_opt(|opt_tcx| { if let Some(tcx) = opt_tcx { if let Some(def_id) = self.extract_def_id(tcx) { write!(f, "{}", tcx.def_path_debug_str(def_id))?; @@ -825,6 +825,6 @@ impl WorkProductId { } } -impl_stable_hash_for!(struct ::dep_graph::WorkProductId { +impl_stable_hash_for!(struct crate::dep_graph::WorkProductId { hash }); diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs index 331a9c6109c4c..a296a3379c2ac 100644 --- a/src/librustc/dep_graph/dep_tracking_map.rs +++ b/src/librustc/dep_graph/dep_tracking_map.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use std::cell::RefCell; use std::hash::Hash; use std::marker::PhantomData; -use util::common::MemoizationMap; +use crate::util::common::MemoizationMap; use super::{DepKind, DepNodeIndex, DepGraph}; diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index c9353a451e2cd..663c408ac22fd 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -1,4 +1,4 @@ -use errors::{Diagnostic, DiagnosticBuilder}; +use crate::errors::{Diagnostic, DiagnosticBuilder}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -7,11 +7,11 @@ use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering}; use std::env; use std::hash::Hash; use std::collections::hash_map::Entry; -use ty::{self, TyCtxt}; -use util::common::{ProfileQueriesMsg, profq_msg}; +use crate::ty::{self, TyCtxt}; +use crate::util::common::{ProfileQueriesMsg, profq_msg}; use parking_lot::{Mutex, Condvar}; -use ich::{StableHashingContext, StableHashingContextProvider, Fingerprint}; +use crate::ich::{StableHashingContext, StableHashingContextProvider, Fingerprint}; use super::debug::EdgeFilter; use super::dep_node::{DepNode, DepKind, WorkProductId}; @@ -669,7 +669,7 @@ impl DepGraph { // We failed to mark it green, so we try to force the query. debug!("try_mark_previous_green({:?}) --- trying to force \ dependency {:?}", dep_node, dep_dep_node); - if ::ty::query::force_from_dep_node(tcx, dep_dep_node) { + if crate::ty::query::force_from_dep_node(tcx, dep_dep_node) { let dep_dep_node_color = data.colors.get(dep_dep_node_index); match dep_dep_node_color { diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index ea5350ac97fee..d971690bbe317 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -1,4 +1,4 @@ -use ich::Fingerprint; +use crate::ich::Fingerprint; use rustc_data_structures::fx::FxHashMap; use super::dep_node::DepNode; use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex}; diff --git a/src/librustc/dep_graph/safe.rs b/src/librustc/dep_graph/safe.rs index f1e8224a70d14..fc767defe9c71 100644 --- a/src/librustc/dep_graph/safe.rs +++ b/src/librustc/dep_graph/safe.rs @@ -1,9 +1,9 @@ //! The `DepGraphSafe` trait -use hir::BodyId; -use hir::def_id::DefId; +use crate::hir::BodyId; +use crate::hir::def_id::DefId; use syntax::ast::NodeId; -use ty::TyCtxt; +use crate::ty::TyCtxt; /// The `DepGraphSafe` trait is used to specify what kinds of values /// are safe to "leak" into a task. The idea is that this should be diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs index 3c04f01a5e1eb..b64f71ed908d8 100644 --- a/src/librustc/dep_graph/serialized.rs +++ b/src/librustc/dep_graph/serialized.rs @@ -1,7 +1,7 @@ //! The data that we will serialize and deserialize. -use dep_graph::DepNode; -use ich::Fingerprint; +use crate::dep_graph::DepNode; +use crate::ich::Fingerprint; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; newtype_index! { diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 4ce41fec18240..75710210d7722 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -5,12 +5,12 @@ //! item. -use ty::TyCtxt; -use ty::query::Providers; +use crate::ty::TyCtxt; +use crate::ty::query::Providers; -use hir; -use hir::def_id::DefId; -use hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use std::fmt::{self, Display}; use syntax_pos::Span; diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index f8f27992b3ea8..6566c6041b6e5 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -1,10 +1,10 @@ -use hir::def_id::DefId; -use util::nodemap::{NodeMap, DefIdMap}; +use crate::hir::def_id::DefId; +use crate::util::nodemap::{NodeMap, DefIdMap}; use syntax::ast; use syntax::ext::base::MacroKind; use syntax_pos::Span; -use hir; -use ty; +use crate::hir; +use crate::ty; use self::Namespace::*; diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index 9181076740ba0..e06f09e21cbf3 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -1,6 +1,6 @@ -use ty; -use ty::TyCtxt; -use hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX; +use crate::ty; +use crate::ty::TyCtxt; +use crate::hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX; use rustc_data_structures::indexed_vec::Idx; use serialize; use std::fmt; diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 5f85e33fb87ee..86c3fb9e4fcd7 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -33,9 +33,9 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, Ident, Name, Attribute}; use syntax_pos::Span; -use hir::*; -use hir::def::Def; -use hir::map::Map; +use crate::hir::*; +use crate::hir::def::Def; +use crate::hir::map::Map; use super::itemlikevisit::DeepVisitor; #[derive(Copy, Clone)] diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e3c913313adee..d0fd5bd6844b0 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -30,24 +30,24 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. -use dep_graph::DepGraph; -use errors::Applicability; -use hir::{self, ParamName}; -use hir::HirVec; -use hir::map::{DefKey, DefPathData, Definitions}; -use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX}; -use hir::def::{Def, PathResolution, PerNS}; -use hir::GenericArg; -use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, +use crate::dep_graph::DepGraph; +use crate::errors::Applicability; +use crate::hir::{self, ParamName}; +use crate::hir::HirVec; +use crate::hir::map::{DefKey, DefPathData, Definitions}; +use crate::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX}; +use crate::hir::def::{Def, PathResolution, PerNS}; +use crate::hir::GenericArg; +use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, ELIDED_LIFETIMES_IN_PATHS}; -use middle::cstore::CrateStore; +use crate::middle::cstore::CrateStore; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::thin_vec::ThinVec; -use session::Session; -use session::config::nightly_options; -use util::common::FN_OUTPUT_NAME; -use util::nodemap::{DefIdMap, NodeMap}; +use crate::session::Session; +use crate::session::config::nightly_options; +use crate::util::common::FN_OUTPUT_NAME; +use crate::util::nodemap::{DefIdMap, NodeMap}; use std::collections::{BTreeSet, BTreeMap}; use std::fmt::Debug; diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index f61b8551927bb..d5fb578d8d492 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -11,10 +11,10 @@ //! nested within a uniquely determined `FnLike`), and users can ask //! for the `Code` associated with a particular NodeId. -use hir as ast; -use hir::map; -use hir::{Expr, FnDecl, Node}; -use hir::intravisit::FnKind; +use crate::hir as ast; +use crate::hir::map; +use crate::hir::{Expr, FnDecl, Node}; +use crate::hir::intravisit::FnKind; use syntax::ast::{Attribute, Ident, NodeId}; use syntax_pos::Span; diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 9c4fa9e127287..f84bb77e29b27 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -1,19 +1,19 @@ use super::*; -use dep_graph::{DepGraph, DepKind, DepNodeIndex}; -use hir; -use hir::def_id::{LOCAL_CRATE, CrateNum}; -use hir::intravisit::{Visitor, NestedVisitorMap}; +use crate::dep_graph::{DepGraph, DepKind, DepNodeIndex}; +use crate::hir; +use crate::hir::def_id::{LOCAL_CRATE, CrateNum}; +use crate::hir::intravisit::{Visitor, NestedVisitorMap}; use rustc_data_structures::svh::Svh; -use ich::Fingerprint; -use middle::cstore::CrateStore; -use session::CrateDisambiguator; -use session::Session; +use crate::ich::Fingerprint; +use crate::middle::cstore::CrateStore; +use crate::session::CrateDisambiguator; +use crate::session::Session; use std::iter::repeat; use syntax::ast::{NodeId, CRATE_NODE_ID}; use syntax::source_map::SourceMap; use syntax_pos::Span; -use ich::StableHashingContext; +use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; /// A Visitor that walks over the HIR and collects Nodes into a HIR map @@ -253,7 +253,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { None => format!("{:?}", node) }; - let forgot_str = if hir_id == ::hir::DUMMY_HIR_ID { + let forgot_str = if hir_id == crate::hir::DUMMY_HIR_ID { format!("\nMaybe you forgot to lower the node id {:?}?", id) } else { String::new() diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index c9b4b2bb99717..710170674f761 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -1,6 +1,6 @@ -use hir::map::definitions::*; -use hir::def_id::{CRATE_DEF_INDEX, DefIndex, DefIndexAddressSpace}; -use session::CrateDisambiguator; +use crate::hir::map::definitions::*; +use crate::hir::def_id::{CRATE_DEF_INDEX, DefIndex, DefIndexAddressSpace}; +use crate::session::CrateDisambiguator; use syntax::ast::*; use syntax::ext::hygiene::Mark; @@ -10,7 +10,7 @@ use syntax::symbol::Symbol; use syntax::parse::token::{self, Token}; use syntax_pos::Span; -use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE}; +use crate::hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE}; /// Creates def ids for nodes in the AST. pub struct DefCollector<'a> { diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 4c622adefbdb1..a8193e1d34837 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -4,15 +4,15 @@ //! There are also some rather random cases (like const initializer //! expressions) that are mostly just leftovers. -use hir; -use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace, +use crate::hir; +use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace, CRATE_DEF_INDEX}; -use ich::Fingerprint; +use crate::ich::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; use rustc_data_structures::stable_hasher::StableHasher; use serialize::{Encodable, Decodable, Encoder, Decoder}; -use session::CrateDisambiguator; +use crate::session::CrateDisambiguator; use std::borrow::Borrow; use std::fmt::Write; use std::hash::Hash; @@ -20,7 +20,7 @@ use syntax::ast; use syntax::ext::hygiene::Mark; use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{Span, DUMMY_SP}; -use util::nodemap::NodeMap; +use crate::util::nodemap::NodeMap; /// The DefPathTable maps DefIndexes to DefKeys and vice versa. /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 91c8c29144406..2c3ff4c9b5c05 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -1,7 +1,7 @@ -use hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; -use hir::{self, intravisit, HirId, ItemLocalId}; +use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; +use crate::hir::{self, intravisit, HirId, ItemLocalId}; use syntax::ast::NodeId; -use hir::itemlikevisit::ItemLikeVisitor; +use crate::hir::itemlikevisit::ItemLikeVisitor; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter}; diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 977ab05b20932..6db1ec3e99b53 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -3,11 +3,11 @@ pub use self::def_collector::{DefCollector, MacroInvocationData}; pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, DefPathHash}; -use dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex}; +use crate::dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex}; -use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace}; +use crate::hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace}; -use middle::cstore::CrateStoreDyn; +use crate::middle::cstore::CrateStoreDyn; use rustc_target::spec::abi::Abi; use rustc_data_structures::svh::Svh; @@ -17,15 +17,15 @@ use syntax::source_map::Spanned; use syntax::ext::base::MacroKind; use syntax_pos::{Span, DUMMY_SP}; -use hir::*; -use hir::itemlikevisit::ItemLikeVisitor; -use hir::print::Nested; -use util::nodemap::FxHashMap; -use util::common::time; +use crate::hir::*; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use crate::hir::print::Nested; +use crate::util::nodemap::FxHashMap; +use crate::util::common::time; use std::io; use std::result::Result::Err; -use ty::TyCtxt; +use crate::ty::TyCtxt; pub mod blocks; mod collector; @@ -1152,13 +1152,13 @@ impl Named for StructField { fn name(&self) -> Name { self.ident.name } } impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } } impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } } -pub fn map_crate<'hir>(sess: &::session::Session, +pub fn map_crate<'hir>(sess: &crate::session::Session, cstore: &CrateStoreDyn, forest: &'hir Forest, definitions: &'hir Definitions) -> Map<'hir> { let ((map, crate_hash), hir_to_node_id) = join(|| { - let hcx = ::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore); + let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore); let mut collector = NodeCollector::root(sess, &forest.krate, @@ -1269,7 +1269,7 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { let path_str = || { // This functionality is used for debugging, try to use TyCtxt to get // the user-friendly path, otherwise fall back to stringifying DefPath. - ::ty::tls::with_opt(|tcx| { + crate::ty::tls::with_opt(|tcx| { if let Some(tcx) = tcx { tcx.node_path_str(id) } else if let Some(path) = map.def_path_from_id(id) { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 924b044da5fc3..f8fb2b88e2750 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -10,11 +10,11 @@ pub use self::PrimTy::*; pub use self::UnOp::*; pub use self::UnsafeSource::*; -use errors::FatalError; -use hir::def::Def; -use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; -use util::nodemap::{NodeMap, FxHashSet}; -use mir::mono::Linkage; +use crate::errors::FatalError; +use crate::hir::def::Def; +use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; +use crate::util::nodemap::{NodeMap, FxHashSet}; +use crate::mir::mono::Linkage; use syntax_pos::{Span, DUMMY_SP, symbol::InternedString}; use syntax::source_map::Spanned; @@ -27,8 +27,8 @@ use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; use syntax::tokenstream::TokenStream; use syntax::util::parser::ExprPrecedence; -use ty::AdtKind; -use ty::query::Providers; +use crate::ty::AdtKind; +use crate::ty::query::Providers; use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope}; use rustc_data_structures::thin_vec::ThinVec; diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index e2a03c638764d..c92cbc9b96c93 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -1,6 +1,6 @@ -use hir::def::Def; -use hir::def_id::DefId; -use hir::{self, HirId, PatKind}; +use crate::hir::def::Def; +use crate::hir::def_id::DefId; +use crate::hir::{self, HirId, PatKind}; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 89b5b7a190df6..9b6fcf259be14 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -11,9 +11,9 @@ use syntax::symbol::keywords; use syntax::util::parser::{self, AssocOp, Fixity}; use syntax_pos::{self, BytePos, FileName}; -use hir; -use hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; -use hir::{GenericParam, GenericParamKind, GenericArg}; +use crate::hir; +use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; +use crate::hir::{GenericParam, GenericParamKind, GenericArg}; use std::borrow::Cow; use std::cell::Cell; @@ -2401,7 +2401,7 @@ fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool { } fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp { - use hir::BinOpKind::*; + use crate::hir::BinOpKind::*; match op { Add => AssocOp::Add, Sub => AssocOp::Subtract, diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index d5c9d9ff16dcb..e60fdd62debd1 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -1,11 +1,11 @@ -use hir; -use hir::def_id::{DefId, DefIndex}; -use hir::map::DefPathHash; -use hir::map::definitions::Definitions; -use ich::{self, CachingSourceMapView, Fingerprint}; -use middle::cstore::CrateStore; -use ty::{TyCtxt, fast_reject}; -use session::Session; +use crate::hir; +use crate::hir::def_id::{DefId, DefIndex}; +use crate::hir::map::DefPathHash; +use crate::hir::map::definitions::Definitions; +use crate::ich::{self, CachingSourceMapView, Fingerprint}; +use crate::middle::cstore::CrateStore; +use crate::ty::{TyCtxt, fast_reject}; +use crate::session::Session; use std::cmp::Ord; use std::hash as std_hash; @@ -218,7 +218,7 @@ impl<'a> StableHashingContextProvider<'a> for StableHashingContext<'a> { } } -impl<'a> ::dep_graph::DepGraphSafe for StableHashingContext<'a> { +impl<'a> crate::dep_graph::DepGraphSafe for StableHashingContext<'a> { } diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs index fdea62a1dd8f6..17ed1a79d45e0 100644 --- a/src/librustc/ich/impls_cstore.rs +++ b/src/librustc/ich/impls_cstore.rs @@ -1,23 +1,21 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::middle::cstore in no particular order. -use middle; - -impl_stable_hash_for!(enum middle::cstore::DepKind { +impl_stable_hash_for!(enum crate::middle::cstore::DepKind { UnexportedMacrosOnly, MacrosOnly, Implicit, Explicit }); -impl_stable_hash_for!(enum middle::cstore::NativeLibraryKind { +impl_stable_hash_for!(enum crate::middle::cstore::NativeLibraryKind { NativeStatic, NativeStaticNobundle, NativeFramework, NativeUnknown }); -impl_stable_hash_for!(struct middle::cstore::NativeLibrary { +impl_stable_hash_for!(struct crate::middle::cstore::NativeLibrary { kind, name, cfg, @@ -25,30 +23,30 @@ impl_stable_hash_for!(struct middle::cstore::NativeLibrary { wasm_import_module }); -impl_stable_hash_for!(struct middle::cstore::ForeignModule { +impl_stable_hash_for!(struct crate::middle::cstore::ForeignModule { foreign_items, def_id }); -impl_stable_hash_for!(enum middle::cstore::LinkagePreference { +impl_stable_hash_for!(enum crate::middle::cstore::LinkagePreference { RequireDynamic, RequireStatic }); -impl_stable_hash_for!(struct middle::cstore::ExternCrate { +impl_stable_hash_for!(struct crate::middle::cstore::ExternCrate { src, span, path_len, direct }); -impl_stable_hash_for!(enum middle::cstore::ExternCrateSource { +impl_stable_hash_for!(enum crate::middle::cstore::ExternCrateSource { Extern(def_id), Use, Path, }); -impl_stable_hash_for!(struct middle::cstore::CrateSource { +impl_stable_hash_for!(struct crate::middle::cstore::CrateSource { dylib, rlib, rmeta diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 1061ea752af11..2b359428b1fa1 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1,10 +1,10 @@ //! This module contains `HashStable` implementations for various HIR data //! types in no particular order. -use hir; -use hir::map::DefPathHash; -use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX}; -use ich::{StableHashingContext, NodeIdHashingMode, Fingerprint}; +use crate::hir; +use crate::hir::map::DefPathHash; +use crate::hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX}; +use crate::ich::{StableHashingContext, NodeIdHashingMode, Fingerprint}; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher, StableHasherResult}; use std::mem; @@ -619,7 +619,7 @@ impl<'a> HashStable> for hir::MatchSource { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use hir::MatchSource; + use crate::hir::MatchSource; mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -1116,12 +1116,12 @@ impl_stable_hash_for!(struct hir::def::Export { span }); -impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures { +impl_stable_hash_for!(struct crate::middle::lib_features::LibFeatures { stable, unstable }); -impl<'a> HashStable> for ::middle::lang_items::LangItem { +impl<'a> HashStable> for crate::middle::lang_items::LangItem { fn hash_stable(&self, _: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { @@ -1129,7 +1129,7 @@ impl<'a> HashStable> for ::middle::lang_items::LangItem } } -impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems { +impl_stable_hash_for!(struct crate::middle::lang_items::LanguageItems { items, missing }); diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 002ac7cc7a9bb..51fc78ffc8669 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -1,8 +1,8 @@ //! This module contains `HashStable` implementations for various MIR data //! types in no particular order. -use ich::StableHashingContext; -use mir; +use crate::ich::StableHashingContext; +use crate::mir; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use std::mem; diff --git a/src/librustc/ich/impls_misc.rs b/src/librustc/ich/impls_misc.rs index f79adc8109a7f..8a388fafce5e8 100644 --- a/src/librustc/ich/impls_misc.rs +++ b/src/librustc/ich/impls_misc.rs @@ -1,7 +1,7 @@ //! This module contains `HashStable` implementations for various data types //! that don't fit into any of the other impls_xxx modules. -impl_stable_hash_for!(enum ::session::search_paths::PathKind { +impl_stable_hash_for!(enum crate::session::search_paths::PathKind { Native, Crate, Dependency, diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index e10359636f749..f34423ccca655 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -1,7 +1,7 @@ //! This module contains `HashStable` implementations for various data types //! from libsyntax in no particular order. -use ich::StableHashingContext; +use crate::ich::StableHashingContext; use std::hash as std_hash; use std::mem; @@ -13,7 +13,7 @@ use syntax::symbol::{InternedString, LocalInternedString}; use syntax::tokenstream; use syntax_pos::SourceFile; -use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; +use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index bd2349161f74a..1e1dbd0b621ec 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1,18 +1,18 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::ty in no particular order. -use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; +use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher, StableHasherResult}; use std::cell::RefCell; use std::hash as std_hash; use std::mem; -use middle::region; -use infer; -use traits; -use ty; -use mir; +use crate::middle::region; +use crate::infer; +use crate::traits; +use crate::ty; +use crate::mir; impl<'a, 'gcx, T> HashStable> for &'gcx ty::List @@ -306,7 +306,7 @@ impl_stable_hash_for!( ByRef(id, alloc, offset), } ); -impl_stable_hash_for!(struct ::mir::interpret::RawConst<'tcx> { +impl_stable_hash_for!(struct crate::mir::interpret::RawConst<'tcx> { alloc_id, ty, }); @@ -512,20 +512,22 @@ impl_stable_hash_for!(enum ty::GenericParamDefKind { }); impl_stable_hash_for!( - impl for enum ::middle::resolve_lifetime::Set1 [ ::middle::resolve_lifetime::Set1 ] { + impl for enum crate::middle::resolve_lifetime::Set1 + [ crate::middle::resolve_lifetime::Set1 ] + { Empty, Many, One(value), } ); -impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin { +impl_stable_hash_for!(enum crate::middle::resolve_lifetime::LifetimeDefOrigin { ExplicitOrElided, InBand, Error, }); -impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region { +impl_stable_hash_for!(enum crate::middle::resolve_lifetime::Region { Static, EarlyBound(index, decl, is_in_band), LateBound(db_index, decl, is_in_band), @@ -547,9 +549,9 @@ impl_stable_hash_for!(enum ty::cast::CastKind { FnPtrAddrCast }); -impl_stable_hash_for!(struct ::middle::region::Scope { id, data }); +impl_stable_hash_for!(struct crate::middle::region::Scope { id, data }); -impl_stable_hash_for!(enum ::middle::region::ScopeData { +impl_stable_hash_for!(enum crate::middle::region::ScopeData { Node, CallSite, Arguments, @@ -588,7 +590,7 @@ for ty::TyKind<'gcx> fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use ty::TyKind::*; + use crate::ty::TyKind::*; mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -882,7 +884,7 @@ impl_stable_hash_for!(enum traits::Reveal { All }); -impl_stable_hash_for!(enum ::middle::privacy::AccessLevel { +impl_stable_hash_for!(enum crate::middle::privacy::AccessLevel { ReachableFromImplTrait, Reachable, Exported, @@ -890,12 +892,12 @@ impl_stable_hash_for!(enum ::middle::privacy::AccessLevel { }); impl<'a> HashStable> -for ::middle::privacy::AccessLevels { +for crate::middle::privacy::AccessLevels { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - let ::middle::privacy::AccessLevels { + let crate::middle::privacy::AccessLevels { ref map } = *self; @@ -908,14 +910,14 @@ impl_stable_hash_for!(struct ty::CrateInherentImpls { inherent_impls }); -impl_stable_hash_for!(enum ::session::CompileIncomplete { +impl_stable_hash_for!(enum crate::session::CompileIncomplete { Stopped, Errored(error_reported) }); -impl_stable_hash_for!(struct ::util::common::ErrorReported {}); +impl_stable_hash_for!(struct crate::util::common::ErrorReported {}); -impl_stable_hash_for!(tuple_struct ::middle::reachable::ReachableSet { +impl_stable_hash_for!(tuple_struct crate::middle::reachable::ReachableSet { reachable_set }); @@ -924,7 +926,7 @@ for traits::Vtable<'gcx, N> where N: HashStable> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::Vtable::*; + use crate::traits::Vtable::*; mem::discriminant(self).hash_stable(hcx, hasher); @@ -1105,7 +1107,7 @@ impl<'a, 'tcx> HashStable> for traits::WhereClause<'tcx fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::WhereClause::*; + use crate::traits::WhereClause::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { @@ -1121,7 +1123,7 @@ impl<'a, 'tcx> HashStable> for traits::WellFormed<'tcx> fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::WellFormed::*; + use crate::traits::WellFormed::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { @@ -1135,7 +1137,7 @@ impl<'a, 'tcx> HashStable> for traits::FromEnv<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::FromEnv::*; + use crate::traits::FromEnv::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { @@ -1149,7 +1151,7 @@ impl<'a, 'tcx> HashStable> for traits::DomainGoal<'tcx> fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::DomainGoal::*; + use crate::traits::DomainGoal::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { @@ -1165,7 +1167,7 @@ impl<'a, 'tcx> HashStable> for traits::Goal<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::GoalKind::*; + use crate::traits::GoalKind::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { @@ -1208,7 +1210,7 @@ impl<'a, 'tcx> HashStable> for traits::Clause<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::Clause::*; + use crate::traits::Clause::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index 328d518ca66aa..7b2b1184a6336 100644 --- a/src/librustc/infer/at.rs +++ b/src/librustc/infer/at.rs @@ -27,7 +27,7 @@ use super::*; -use ty::relate::{Relate, TypeRelation}; +use crate::ty::relate::{Relate, TypeRelation}; pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> { pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 408cba42ae04b..4e1c797a2c72a 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -5,15 +5,15 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html -use infer::canonical::{ +use crate::infer::canonical::{ Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized, OriginalQueryValues, }; -use infer::InferCtxt; +use crate::infer::InferCtxt; use std::sync::atomic::Ordering; -use ty::fold::{TypeFoldable, TypeFolder}; -use ty::subst::Kind; -use ty::{self, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::subst::Kind; +use crate::ty::{self, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index eaf72f5a68710..6f28c0b131f61 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -21,16 +21,16 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html -use infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; +use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::Lrc; use serialize::UseSpecializedDecodable; use smallvec::SmallVec; use std::ops::Index; use syntax::source_map::Span; -use ty::fold::TypeFoldable; -use ty::subst::Kind; -use ty::{self, BoundVar, Lift, List, Region, TyCtxt}; +use crate::ty::fold::TypeFoldable; +use crate::ty::subst::Kind; +use crate::ty::{self, BoundVar, Lift, List, Region, TyCtxt}; mod canonicalizer; @@ -393,14 +393,14 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { } CloneTypeFoldableAndLiftImpls! { - ::infer::canonical::Certainty, - ::infer::canonical::CanonicalVarInfo, - ::infer::canonical::CanonicalVarKind, + crate::infer::canonical::Certainty, + crate::infer::canonical::CanonicalVarInfo, + crate::infer::canonical::CanonicalVarKind, } CloneTypeFoldableImpls! { for <'tcx> { - ::infer::canonical::CanonicalVarInfos<'tcx>, + crate::infer::canonical::CanonicalVarInfos<'tcx>, } } @@ -431,7 +431,7 @@ impl<'tcx> CanonicalVarValues<'tcx> { /// we'll return a substitution `subst` with: /// `subst.var_values == [Type(^0), Lifetime(^1), Type(^2)]`. pub fn make_identity<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { - use ty::subst::UnpackedKind; + use crate::ty::subst::UnpackedKind; CanonicalVarValues { var_values: self.var_values.iter() diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 7f113f07276d8..409afca43203d 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -7,26 +7,26 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html -use infer::canonical::substitute::substitute_value; -use infer::canonical::{ +use crate::infer::canonical::substitute::substitute_value; +use crate::infer::canonical::{ Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty, OriginalQueryValues, QueryRegionConstraint, QueryResponse, }; -use infer::region_constraints::{Constraint, RegionConstraintData}; -use infer::InferCtxtBuilder; -use infer::{InferCtxt, InferOk, InferResult}; +use crate::infer::region_constraints::{Constraint, RegionConstraintData}; +use crate::infer::InferCtxtBuilder; +use crate::infer::{InferCtxt, InferOk, InferResult}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::Lrc; use std::fmt::Debug; use syntax_pos::DUMMY_SP; -use traits::query::{Fallible, NoSolution}; -use traits::TraitEngine; -use traits::{Obligation, ObligationCause, PredicateObligation}; -use ty::fold::TypeFoldable; -use ty::subst::{Kind, UnpackedKind}; -use ty::{self, BoundVar, Lift, Ty, TyCtxt}; -use util::captures::Captures; +use crate::traits::query::{Fallible, NoSolution}; +use crate::traits::TraitEngine; +use crate::traits::{Obligation, ObligationCause, PredicateObligation}; +use crate::ty::fold::TypeFoldable; +use crate::ty::subst::{Kind, UnpackedKind}; +use crate::ty::{self, BoundVar, Lift, Ty, TyCtxt}; +use crate::util::captures::Captures; impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> { /// The "main method" for a canonicalized trait query. Given the diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs index d3ed00481dcee..5af4e8366818b 100644 --- a/src/librustc/infer/canonical/substitute.rs +++ b/src/librustc/infer/canonical/substitute.rs @@ -6,10 +6,10 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html -use infer::canonical::{Canonical, CanonicalVarValues}; -use ty::fold::TypeFoldable; -use ty::subst::UnpackedKind; -use ty::{self, TyCtxt}; +use crate::infer::canonical::{Canonical, CanonicalVarValues}; +use crate::ty::fold::TypeFoldable; +use crate::ty::subst::UnpackedKind; +use crate::ty::{self, TyCtxt}; impl<'tcx, V> Canonical<'tcx, V> { /// Instantiate the wrapped value, replacing each canonical value diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 40c11695d51e2..7e22521473491 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -29,13 +29,13 @@ use super::lub::Lub; use super::sub::Sub; use super::type_variable::TypeVariableValue; -use hir::def_id::DefId; -use ty::{IntType, UintType}; -use ty::{self, Ty, TyCtxt}; -use ty::error::TypeError; -use ty::relate::{self, Relate, RelateResult, TypeRelation}; -use ty::subst::Substs; -use traits::{Obligation, PredicateObligations}; +use crate::hir::def_id::DefId; +use crate::ty::{IntType, UintType}; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::error::TypeError; +use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use crate::ty::subst::Substs; +use crate::traits::{Obligation, PredicateObligations}; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 60a7eb0d54f8b..a4b62307a60b8 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -1,12 +1,12 @@ use super::combine::{CombineFields, RelationDir}; use super::{Subtype}; -use hir::def_id::DefId; +use crate::hir::def_id::DefId; -use ty::{self, Ty, TyCtxt}; -use ty::TyVar; -use ty::subst::Substs; -use ty::relate::{self, Relate, RelateResult, TypeRelation}; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::TyVar; +use crate::ty::subst::Substs; +use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; /// Ensures `a` is made equal to `b`. Returns `a` on success. pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 66e4cd49c807f..8510533391287 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -48,19 +48,19 @@ use super::lexical_region_resolve::RegionResolutionError; use super::region_constraints::GenericKind; use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs}; -use infer::{self, SuppressRegionErrors}; +use crate::infer::{self, SuppressRegionErrors}; -use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use hir; -use hir::def_id::DefId; -use hir::Node; -use middle::region; +use crate::errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::hir::Node; +use crate::middle::region; use std::{cmp, fmt}; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; -use traits::{ObligationCause, ObligationCauseCode}; -use ty::error::TypeError; -use ty::{self, subst::Subst, Region, Ty, TyCtxt, TyKind, TypeFoldable}; +use crate::traits::{ObligationCause, ObligationCauseCode}; +use crate::ty::error::TypeError; +use crate::ty::{self, subst::Subst, Region, Ty, TyCtxt, TyKind, TypeFoldable}; mod note; @@ -1479,7 +1479,7 @@ enum FailureCode { impl<'tcx> ObligationCause<'tcx> { fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode { use self::FailureCode::*; - use traits::ObligationCauseCode::*; + use crate::traits::ObligationCauseCode::*; match self.code { CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"), MatchExpressionArm { source, .. } => Error0308(match source { @@ -1509,7 +1509,7 @@ impl<'tcx> ObligationCause<'tcx> { } fn as_requirement_str(&self) -> &'static str { - use traits::ObligationCauseCode::*; + use crate::traits::ObligationCauseCode::*; match self.code { CompareImplMethodObligation { .. } => "method type is compatible with trait", ExprAssignable => "expression is assignable", diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 8ee367c87c3ea..fac498bd6dd78 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -1,11 +1,11 @@ -use hir::{self, Local, Pat, Body, HirId}; -use hir::intravisit::{self, Visitor, NestedVisitorMap}; -use infer::InferCtxt; -use infer::type_variable::TypeVariableOrigin; -use ty::{self, Ty, Infer, TyVar}; +use crate::hir::{self, Local, Pat, Body, HirId}; +use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::infer::InferCtxt; +use crate::infer::type_variable::TypeVariableOrigin; +use crate::ty::{self, Ty, Infer, TyVar}; use syntax::source_map::CompilerDesugaringKind; use syntax_pos::Span; -use errors::DiagnosticBuilder; +use crate::errors::DiagnosticBuilder; struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index 8be49b2792441..0f4401517792c 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -1,9 +1,9 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where both the regions are anonymous. -use infer::error_reporting::nice_region_error::NiceRegionError; -use infer::error_reporting::nice_region_error::util::AnonymousArgInfo; -use util::common::ErrorReported; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::infer::error_reporting::nice_region_error::util::AnonymousArgInfo; +use crate::util::common::ErrorReported; impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// Print the error message for lifetime errors when both the concerned regions are anonymous. diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs index ebaef4977f400..ea748874fc4e2 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,9 +1,9 @@ -use hir; -use ty::{self, Region, TyCtxt}; -use hir::Node; -use middle::resolve_lifetime as rl; -use hir::intravisit::{self, NestedVisitorMap, Visitor}; -use infer::error_reporting::nice_region_error::NiceRegionError; +use crate::hir; +use crate::ty::{self, Region, TyCtxt}; +use crate::hir::Node; +use crate::middle::resolve_lifetime as rl; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// This function calls the `visit_ty` method for the parameters diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index d34b71c33f4b4..dad1e3ba80da3 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -1,9 +1,9 @@ -use infer::InferCtxt; -use infer::lexical_region_resolve::RegionResolutionError; -use infer::lexical_region_resolve::RegionResolutionError::*; +use crate::infer::InferCtxt; +use crate::infer::lexical_region_resolve::RegionResolutionError; +use crate::infer::lexical_region_resolve::RegionResolutionError::*; use syntax::source_map::Span; -use ty::{self, TyCtxt}; -use util::common::ErrorReported; +use crate::ty::{self, TyCtxt}; +use crate::util::common::ErrorReported; mod different_lifetimes; mod find_anon_type; diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 05333f4337336..d66bb274b34ce 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -1,9 +1,9 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where one region is named and the other is anonymous. -use infer::error_reporting::nice_region_error::NiceRegionError; -use ty; -use util::common::ErrorReported; -use errors::Applicability; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::ty; +use crate::util::common::ErrorReported; +use crate::errors::Applicability; impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs index cbd36a8b2db8a..6432780de0670 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs @@ -1,13 +1,13 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where both the regions are anonymous. -use infer::error_reporting::nice_region_error::NiceRegionError; -use infer::SubregionOrigin; -use ty::RegionKind; -use hir::{Expr, ExprKind::Closure}; -use hir::Node; -use util::common::ErrorReported; -use infer::lexical_region_resolve::RegionResolutionError::SubSupConflict; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::infer::SubregionOrigin; +use crate::ty::RegionKind; +use crate::hir::{Expr, ExprKind::Closure}; +use crate::hir::Node; +use crate::util::common::ErrorReported; +use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict; impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// Print the error message for lifetime errors when binding escapes a closure. diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index ebac5a0c2a69e..6893a1fb168b8 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,15 +1,15 @@ -use errors::DiagnosticBuilder; -use hir::def_id::DefId; -use infer::error_reporting::nice_region_error::NiceRegionError; -use infer::lexical_region_resolve::RegionResolutionError; -use infer::ValuePairs; -use infer::{SubregionOrigin, TypeTrace}; -use traits::{ObligationCause, ObligationCauseCode}; -use ty; -use ty::error::ExpectedFound; -use ty::subst::Substs; -use util::common::ErrorReported; -use util::ppaux::RegionHighlightMode; +use crate::errors::DiagnosticBuilder; +use crate::hir::def_id::DefId; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::infer::lexical_region_resolve::RegionResolutionError; +use crate::infer::ValuePairs; +use crate::infer::{SubregionOrigin, TypeTrace}; +use crate::traits::{ObligationCause, ObligationCauseCode}; +use crate::ty; +use crate::ty::error::ExpectedFound; +use crate::ty::subst::Substs; +use crate::util::common::ErrorReported; +use crate::util::ppaux::RegionHighlightMode; impl NiceRegionError<'me, 'gcx, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs index 4331518d403dd..3f0297952278a 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -1,10 +1,10 @@ //! Error Reporting for static impl Traits. -use infer::error_reporting::nice_region_error::NiceRegionError; -use infer::lexical_region_resolve::RegionResolutionError; -use ty::{BoundRegion, FreeRegion, RegionKind}; -use util::common::ErrorReported; -use errors::Applicability; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::infer::lexical_region_resolve::RegionResolutionError; +use crate::ty::{BoundRegion, FreeRegion, RegionKind}; +use crate::util::common::ErrorReported; +use crate::errors::Applicability; impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// Print the error message for lifetime errors when the return type is a static impl Trait. diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index dd8a33829eb53..f73f8d8bb82be 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -1,10 +1,10 @@ //! Helper functions corresponding to lifetime errors due to //! anonymous regions. -use hir; -use infer::error_reporting::nice_region_error::NiceRegionError; -use ty::{self, Region, Ty}; -use hir::def_id::DefId; +use crate::hir; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::ty::{self, Region, Ty}; +use crate::hir::def_id::DefId; use syntax_pos::Span; // The struct contains the information about the anonymous region diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index e45a4b17cdd9c..efd7f3c55e900 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -1,8 +1,8 @@ -use infer::{self, InferCtxt, SubregionOrigin}; -use middle::region; -use ty::{self, Region}; -use ty::error::TypeError; -use errors::DiagnosticBuilder; +use crate::infer::{self, InferCtxt, SubregionOrigin}; +use crate::middle::region; +use crate::ty::{self, Region}; +use crate::ty::error::TypeError; +use crate::errors::DiagnosticBuilder; impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub(super) fn note_region_origin(&self, diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 74abcf82529cb..201717b34ee41 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -31,9 +31,9 @@ //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". -use ty::{self, Ty, TyCtxt, TypeFoldable}; -use ty::fold::TypeFolder; -use util::nodemap::FxHashMap; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +use crate::ty::fold::TypeFolder; +use crate::util::nodemap::FxHashMap; use std::collections::hash_map::Entry; diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index a38db5d210f7b..d205cfcf73b7e 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -1,6 +1,6 @@ -use infer::type_variable::TypeVariableMap; -use ty::{self, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder}; +use crate::infer::type_variable::TypeVariableMap; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; use super::InferCtxt; use super::RegionVariableOrigin; diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index 635a6d00270b7..910c6571853dc 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -3,9 +3,9 @@ use super::InferCtxt; use super::lattice::{self, LatticeDir}; use super::Subtype; -use traits::ObligationCause; -use ty::{self, Ty, TyCtxt}; -use ty::relate::{Relate, RelateResult, TypeRelation}; +use crate::traits::ObligationCause; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::relate::{Relate, RelateResult, TypeRelation}; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 709e8c0ba9b24..c7fc446b9787b 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -4,8 +4,8 @@ use super::combine::CombineFields; use super::{HigherRankedType, InferCtxt, PlaceholderMap}; -use ty::relate::{Relate, RelateResult, TypeRelation}; -use ty::{self, Binder, TypeFoldable}; +use crate::ty::relate::{Relate, RelateResult, TypeRelation}; +use crate::ty::{self, Binder, TypeFoldable}; impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { pub fn higher_ranked_sub( diff --git a/src/librustc/infer/lattice.rs b/src/librustc/infer/lattice.rs index a8794b4076a9d..dfa086a64de61 100644 --- a/src/librustc/infer/lattice.rs +++ b/src/librustc/infer/lattice.rs @@ -22,10 +22,10 @@ use super::InferCtxt; use super::type_variable::TypeVariableOrigin; -use traits::ObligationCause; -use ty::TyVar; -use ty::{self, Ty}; -use ty::relate::{RelateResult, TypeRelation}; +use crate::traits::ObligationCause; +use crate::ty::TyVar; +use crate::ty::{self, Ty}; +use crate::ty::relate::{RelateResult, TypeRelation}; pub trait LatticeDir<'f, 'gcx: 'f+'tcx, 'tcx: 'f> : TypeRelation<'f, 'gcx, 'tcx> { fn infcx(&self) -> &'f InferCtxt<'f, 'gcx, 'tcx>; diff --git a/src/librustc/infer/lexical_region_resolve/graphviz.rs b/src/librustc/infer/lexical_region_resolve/graphviz.rs index 7ce2aba54f5cc..073a3f74422c6 100644 --- a/src/librustc/infer/lexical_region_resolve/graphviz.rs +++ b/src/librustc/infer/lexical_region_resolve/graphviz.rs @@ -8,14 +8,14 @@ /// For clarity, rename the graphviz crate locally to dot. use graphviz as dot; -use hir::def_id::DefIndex; -use ty; -use middle::free_region::RegionRelations; -use middle::region; +use crate::hir::def_id::DefIndex; +use crate::ty; +use crate::middle::free_region::RegionRelations; +use crate::middle::region; use super::Constraint; -use infer::SubregionOrigin; -use infer::region_constraints::RegionConstraintData; -use util::nodemap::{FxHashMap, FxHashSet}; +use crate::infer::SubregionOrigin; +use crate::infer::region_constraints::RegionConstraintData; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use std::borrow::Cow; use std::collections::hash_map::Entry::Vacant; diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index c0952fefac0e1..7add8a26ede09 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -1,13 +1,13 @@ //! The code to do lexical region resolution. -use infer::region_constraints::Constraint; -use infer::region_constraints::GenericKind; -use infer::region_constraints::RegionConstraintData; -use infer::region_constraints::VarInfos; -use infer::region_constraints::VerifyBound; -use infer::RegionVariableOrigin; -use infer::SubregionOrigin; -use middle::free_region::RegionRelations; +use crate::infer::region_constraints::Constraint; +use crate::infer::region_constraints::GenericKind; +use crate::infer::region_constraints::RegionConstraintData; +use crate::infer::region_constraints::VarInfos; +use crate::infer::region_constraints::VerifyBound; +use crate::infer::RegionVariableOrigin; +use crate::infer::SubregionOrigin; +use crate::middle::free_region::RegionRelations; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, @@ -16,11 +16,11 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; use std::u32; -use ty::fold::TypeFoldable; -use ty::{self, Ty, TyCtxt}; -use ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; -use ty::{ReLateBound, ReScope, RePlaceholder, ReVar}; -use ty::{Region, RegionVid}; +use crate::ty::fold::TypeFoldable; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; +use crate::ty::{ReLateBound, ReScope, RePlaceholder, ReVar}; +use crate::ty::{Region, RegionVid}; mod graphviz; diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index 0b9839f69fa2a..f9eb60d82d17b 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -3,9 +3,9 @@ use super::InferCtxt; use super::lattice::{self, LatticeDir}; use super::Subtype; -use traits::ObligationCause; -use ty::{self, Ty, TyCtxt}; -use ty::relate::{Relate, RelateResult, TypeRelation}; +use crate::traits::ObligationCause; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::relate::{Relate, RelateResult, TypeRelation}; /// "Least upper bound" (common supertype) pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 958982545750f..06c94d133344c 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -5,31 +5,31 @@ pub use self::LateBoundRegionConversionTime::*; pub use self::RegionVariableOrigin::*; pub use self::SubregionOrigin::*; pub use self::ValuePairs::*; -pub use ty::IntVarValue; +pub use crate::ty::IntVarValue; use arena::SyncDroplessArena; -use errors::DiagnosticBuilder; -use hir::def_id::DefId; -use infer::canonical::{Canonical, CanonicalVarValues}; -use middle::free_region::RegionRelations; -use middle::lang_items; -use middle::region; +use crate::errors::DiagnosticBuilder; +use crate::hir::def_id::DefId; +use crate::infer::canonical::{Canonical, CanonicalVarValues}; +use crate::middle::free_region::RegionRelations; +use crate::middle::lang_items; +use crate::middle::region; use rustc_data_structures::unify as ut; -use session::config::BorrowckMode; +use crate::session::config::BorrowckMode; use std::cell::{Cell, Ref, RefCell, RefMut}; use std::collections::BTreeMap; use std::fmt; use syntax::ast; use syntax_pos::symbol::InternedString; use syntax_pos::{self, Span}; -use traits::{self, ObligationCause, PredicateObligations, TraitEngine}; -use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; -use ty::fold::TypeFoldable; -use ty::relate::RelateResult; -use ty::subst::{Kind, Substs}; -use ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners}; -use ty::{FloatVid, IntVid, TyVid}; -use util::nodemap::FxHashMap; +use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine}; +use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; +use crate::ty::fold::TypeFoldable; +use crate::ty::relate::RelateResult; +use crate::ty::subst::{Kind, Substs}; +use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners}; +use crate::ty::{FloatVid, IntVid, TyVid}; +use crate::util::nodemap::FxHashMap; use self::combine::CombineFields; use self::lexical_region_resolve::LexicalRegionResolutions; @@ -617,8 +617,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn type_is_unconstrained_numeric(&'a self, ty: Ty<'_>) -> UnconstrainedNumeric { - use ty::error::UnconstrainedNumeric::Neither; - use ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt}; + use crate::ty::error::UnconstrainedNumeric::Neither; + use crate::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt}; match ty.sty { ty::Infer(ty::IntVar(vid)) => { if self.int_unification_table diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 5e94bb1f877fb..e28157f05f15f 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -1,16 +1,16 @@ -use hir::def_id::DefId; -use hir; -use hir::Node; -use infer::{self, InferCtxt, InferOk, TypeVariableOrigin}; -use infer::outlives::free_region_map::FreeRegionRelations; +use crate::hir::def_id::DefId; +use crate::hir; +use crate::hir::Node; +use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin}; +use crate::infer::outlives::free_region_map::FreeRegionRelations; use rustc_data_structures::fx::FxHashMap; use syntax::ast; -use traits::{self, PredicateObligation}; -use ty::{self, Ty, TyCtxt, GenericParamDefKind}; -use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; -use ty::outlives::Component; -use ty::subst::{Kind, Substs, UnpackedKind}; -use util::nodemap::DefIdMap; +use crate::traits::{self, PredicateObligation}; +use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind}; +use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; +use crate::ty::outlives::Component; +use crate::ty::subst::{Kind, Substs, UnpackedKind}; +use crate::util::nodemap::DefIdMap; pub type OpaqueTypeMap<'tcx> = DefIdMap>; diff --git a/src/librustc/infer/outlives/env.rs b/src/librustc/infer/outlives/env.rs index 677b6136ea03b..20d03f3c6edb5 100644 --- a/src/librustc/infer/outlives/env.rs +++ b/src/librustc/infer/outlives/env.rs @@ -1,10 +1,10 @@ -use infer::outlives::free_region_map::FreeRegionMap; -use infer::{GenericKind, InferCtxt}; +use crate::infer::outlives::free_region_map::FreeRegionMap; +use crate::infer::{GenericKind, InferCtxt}; use rustc_data_structures::fx::FxHashMap; use syntax::ast; use syntax_pos::Span; -use traits::query::outlives_bounds::{self, OutlivesBound}; -use ty::{self, Ty}; +use crate::traits::query::outlives_bounds::{self, OutlivesBound}; +use crate::ty::{self, Ty}; /// The `OutlivesEnvironment` collects information about what outlives /// what in a given type-checking setting. For example, if we have a diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index a6703c9d679da..7daf6d71980f6 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -1,4 +1,4 @@ -use ty::{self, Lift, TyCtxt, Region}; +use crate::ty::{self, Lift, TyCtxt, Region}; use rustc_data_structures::transitive_relation::TransitiveRelation; #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index abe835c9211a5..884bd58b4023b 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -59,14 +59,14 @@ //! might later infer `?U` to something like `&'b u32`, which would //! imply that `'b: 'a`. -use infer::outlives::env::RegionBoundPairs; -use infer::outlives::verify::VerifyBoundCx; -use infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound}; +use crate::infer::outlives::env::RegionBoundPairs; +use crate::infer::outlives::verify::VerifyBoundCx; +use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound}; use rustc_data_structures::fx::FxHashMap; use syntax::ast; -use traits::ObligationCause; -use ty::outlives::Component; -use ty::{self, Region, Ty, TyCtxt, TypeFoldable}; +use crate::traits::ObligationCause; +use crate::ty::outlives::Component; +use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable}; impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// Registers that the given region obligation must be resolved diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 4e9a8e9ded899..0457e7179461c 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -1,10 +1,10 @@ -use hir::def_id::DefId; -use infer::outlives::env::RegionBoundPairs; -use infer::{GenericKind, VerifyBound}; -use traits; -use ty::subst::{Subst, Substs}; -use ty::{self, Ty, TyCtxt}; -use util::captures::Captures; +use crate::hir::def_id::DefId; +use crate::infer::outlives::env::RegionBoundPairs; +use crate::infer::{GenericKind, VerifyBound}; +use crate::traits; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::{self, Ty, TyCtxt}; +use crate::util::captures::Captures; /// The `TypeOutlives` struct has the job of "lowering" a `T: 'a` /// obligation into a series of `'a: 'b` constraints and "verifys", as diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 56ae850226c91..500497dc011e1 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -9,10 +9,10 @@ use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::unify as ut; -use ty::ReStatic; -use ty::{self, Ty, TyCtxt}; -use ty::{BrFresh, ReLateBound, ReVar}; -use ty::{Region, RegionVid}; +use crate::ty::ReStatic; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{BrFresh, ReLateBound, ReVar}; +use crate::ty::{Region, RegionVid}; use std::collections::BTreeMap; use std::{cmp, fmt, mem, u32}; diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index f6131c01b372f..4a8f0c34ead11 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -1,6 +1,6 @@ use super::{InferCtxt, FixupError, FixupResult}; -use ty::{self, Ty, TyCtxt, TypeFoldable}; -use ty::fold::{TypeFolder, TypeVisitor}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +use crate::ty::fold::{TypeFolder, TypeVisitor}; /////////////////////////////////////////////////////////////////////////// // OPPORTUNISTIC TYPE RESOLVER diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index df76d1d3afb34..0cff42742c30a 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -1,11 +1,11 @@ use super::SubregionOrigin; use super::combine::{CombineFields, RelationDir}; -use traits::Obligation; -use ty::{self, Ty, TyCtxt}; -use ty::TyVar; -use ty::fold::TypeFoldable; -use ty::relate::{Cause, Relate, RelateResult, TypeRelation}; +use crate::traits::Obligation; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::TyVar; +use crate::ty::fold::TypeFoldable; +use crate::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use std::mem; /// Ensures `a` is made a subtype of `b`. Returns `a` on success. diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 3ec27bdcf1bcd..14f3261bfc203 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -1,6 +1,6 @@ use syntax::symbol::InternedString; use syntax_pos::Span; -use ty::{self, Ty}; +use crate::ty::{self, Ty}; use std::cmp; use std::marker::PhantomData; diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index 068ff0c90e7fc..09f800d9f9bfc 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -1,4 +1,4 @@ -use ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt}; +use crate::ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt}; use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue}; pub trait ToType { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index f886e50246ac0..d19513515201e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -30,6 +30,9 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![deny(rust_2018_idioms)] +#![allow(explicit_outlives_requirements)] + #![feature(box_patterns)] #![feature(box_syntax)] #![feature(core_intrinsics)] @@ -64,41 +67,24 @@ #![warn(elided_lifetimes_in_paths)] -extern crate arena; #[macro_use] extern crate bitflags; -extern crate core; -extern crate fmt_macros; extern crate getopts; -extern crate graphviz; -extern crate num_cpus; #[macro_use] extern crate lazy_static; #[macro_use] extern crate scoped_tls; #[cfg(windows)] extern crate libc; -extern crate polonius_engine; -extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; -extern crate serialize; -extern crate parking_lot; -extern crate rustc_errors as errors; -extern crate rustc_rayon as rayon; -extern crate rustc_rayon_core as rayon_core; + #[macro_use] extern crate log; #[macro_use] extern crate syntax; -extern crate syntax_pos; -extern crate jobserver; -extern crate proc_macro; -extern crate chalk_engine; -extern crate rustc_fs_util; -extern crate serialize as rustc_serialize; // used by deriving +// FIXME: This import is used by deriving `RustcDecodable` and `RustcEncodable`. Removing this +// results in a bunch of "failed to resolve" errors. Hopefully, the compiler moves to serde or +// something, and we can get rid of this. +#[allow(rust_2018_idioms)] +extern crate serialize as rustc_serialize; -extern crate rustc_apfloat; -extern crate byteorder; -extern crate backtrace; - -#[macro_use] -extern crate smallvec; +#[macro_use] extern crate smallvec; // Note that librustc doesn't actually depend on these crates, see the note in // `Cargo.toml` for this crate about why these are here. @@ -166,9 +152,11 @@ pub mod util { // `libstd` uses the same trick. #[doc(hidden)] mod rustc { - pub use lint; + pub use crate::lint; } +use rustc_errors as errors; + // FIXME(#27438): right now the unit tests of librustc don't refer to any actual // functions generated in librustc_data_structures (all // references are through generic functions), but statics are diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3fe544d690640..6ae7448645a20 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,9 +4,9 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use errors::{Applicability, DiagnosticBuilder}; -use lint::{LintPass, LateLintPass, LintArray}; -use session::Session; +use crate::errors::{Applicability, DiagnosticBuilder}; +use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::session::Session; use syntax::ast; use syntax::source_map::Span; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 394e404fb881f..27ead805d5dbd 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -18,26 +18,26 @@ use self::TargetLint::*; use std::slice; use rustc_data_structures::sync::ReadGuard; -use lint::{EarlyLintPass, EarlyLintPassObject, LateLintPassObject}; -use lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; -use lint::builtin::BuiltinLintDiagnostics; -use lint::levels::{LintLevelSets, LintLevelsBuilder}; -use middle::privacy::AccessLevels; -use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; -use session::{config, early_error, Session}; -use ty::{self, TyCtxt, Ty}; -use ty::layout::{LayoutError, LayoutOf, TyLayout}; -use util::nodemap::FxHashMap; -use util::common::time; +use crate::lint::{EarlyLintPass, EarlyLintPassObject, LateLintPassObject}; +use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::builtin::BuiltinLintDiagnostics; +use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; +use crate::middle::privacy::AccessLevels; +use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; +use crate::session::{config, early_error, Session}; +use crate::ty::{self, TyCtxt, Ty}; +use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; +use crate::util::nodemap::FxHashMap; +use crate::util::common::time; use std::default::Default as StdDefault; use syntax::ast; use syntax::edition; use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}}; -use errors::DiagnosticBuilder; -use hir; -use hir::def_id::LOCAL_CRATE; -use hir::intravisit as hir_visit; +use crate::errors::DiagnosticBuilder; +use crate::hir; +use crate::hir::def_id::LOCAL_CRATE; +use crate::hir::intravisit as hir_visit; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 616915769435d..62bd54de7c929 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -1,20 +1,20 @@ use std::cmp; -use errors::{Applicability, DiagnosticBuilder}; -use hir::HirId; -use ich::StableHashingContext; -use lint::builtin; -use lint::context::CheckLintNameResult; -use lint::{self, Lint, LintId, Level, LintSource}; +use crate::errors::{Applicability, DiagnosticBuilder}; +use crate::hir::HirId; +use crate::ich::StableHashingContext; +use crate::lint::builtin; +use crate::lint::context::CheckLintNameResult; +use crate::lint::{self, Lint, LintId, Level, LintSource}; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher, StableHasherResult}; -use session::Session; +use crate::session::Session; use syntax::ast; use syntax::attr; use syntax::feature_gate; use syntax::source_map::MultiSpan; use syntax::symbol::Symbol; -use util::nodemap::FxHashMap; +use crate::util::nodemap::FxHashMap; pub struct LintLevelSets { list: Vec, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index a95fa350bf1c3..4e6bf753b01aa 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -23,13 +23,13 @@ pub use self::LintSource::*; use rustc_data_structures::sync::{self, Lrc}; -use errors::{DiagnosticBuilder, DiagnosticId}; -use hir::def_id::{CrateNum, LOCAL_CRATE}; -use hir::intravisit; -use hir; -use lint::builtin::BuiltinLintDiagnostics; -use lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT}; -use session::{Session, DiagnosticMessageId}; +use crate::errors::{DiagnosticBuilder, DiagnosticId}; +use crate::hir::def_id::{CrateNum, LOCAL_CRATE}; +use crate::hir::intravisit; +use crate::hir; +use crate::lint::builtin::BuiltinLintDiagnostics; +use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT}; +use crate::session::{Session, DiagnosticMessageId}; use std::{hash, ptr}; use syntax::ast; use syntax::source_map::{MultiSpan, ExpnFormat}; @@ -37,11 +37,11 @@ use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; use syntax::symbol::Symbol; use syntax_pos::Span; -use ty::TyCtxt; -use ty::query::Providers; -use util::nodemap::NodeMap; +use crate::ty::TyCtxt; +use crate::ty::query::Providers; +use crate::util::nodemap::NodeMap; -pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore, +pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore, check_crate, check_ast_crate, CheckLintNameResult, FutureIncompatibleInfo, BufferedEarlyLint}; @@ -678,7 +678,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, "this was previously accepted by the compiler but is being phased out; \ it will become a hard error"; - let explanation = if lint_id == LintId::of(::lint::builtin::UNSTABLE_NAME_COLLISIONS) { + let explanation = if lint_id == LintId::of(crate::lint::builtin::UNSTABLE_NAME_COLLISIONS) { "once this method is added to the standard library, \ the ambiguity may cause an error or change in behavior!" .to_owned() diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index 120ba6b1d4e9f..2799f9424d919 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -1,6 +1,6 @@ -use ich::StableHashingContext; -use hir::HirId; -use util::nodemap::FxHashSet; +use crate::ich::StableHashingContext; +use crate::hir::HirId; +use crate::util::nodemap::FxHashSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 9168bbf907f1e..6e9552a1e9209 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -2,13 +2,13 @@ //! are *mostly* used as a part of that interface, but these should //! probably get a better home if someone can find one. -use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use hir::map as hir_map; -use hir::map::definitions::{DefKey, DefPathTable}; +use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use crate::hir::map as hir_map; +use crate::hir::map::definitions::{DefKey, DefPathTable}; use rustc_data_structures::svh::Svh; -use ty::{self, TyCtxt}; -use session::{Session, CrateDisambiguator}; -use session::search_paths::PathKind; +use crate::ty::{self, TyCtxt}; +use crate::session::{Session, CrateDisambiguator}; +use crate::session::search_paths::PathKind; use std::any::Any; use std::path::{Path, PathBuf}; diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index abbf0ae210c25..6dffe8efba612 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -2,18 +2,18 @@ // closely. The idea is that all reachable symbols are live, codes called // from live codes are live, and everything else is dead. -use hir::Node; -use hir::{self, PatKind}; -use hir::intravisit::{self, Visitor, NestedVisitorMap}; -use hir::itemlikevisit::ItemLikeVisitor; - -use hir::def::Def; -use hir::CodegenFnAttrFlags; -use hir::def_id::{DefId, LOCAL_CRATE}; -use lint; -use middle::privacy; -use ty::{self, TyCtxt}; -use util::nodemap::FxHashSet; +use crate::hir::Node; +use crate::hir::{self, PatKind}; +use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::hir::itemlikevisit::ItemLikeVisitor; + +use crate::hir::def::Def; +use crate::hir::CodegenFnAttrFlags; +use crate::hir::def_id::{DefId, LOCAL_CRATE}; +use crate::lint; +use crate::middle::privacy; +use crate::ty::{self, TyCtxt}; +use crate::util::nodemap::FxHashSet; use rustc_data_structures::fx::FxHashMap; diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 16c9344a03722..a24d25cba1184 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -51,13 +51,13 @@ //! Additionally, the algorithm is geared towards finding *any* solution rather //! than finding a number of solutions (there are normally quite a few). -use hir::def_id::CrateNum; +use crate::hir::def_id::CrateNum; -use session::config; -use ty::TyCtxt; -use middle::cstore::{self, DepKind}; -use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; -use util::nodemap::FxHashMap; +use crate::session::config; +use crate::ty::TyCtxt; +use crate::middle::cstore::{self, DepKind}; +use crate::middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; +use crate::util::nodemap::FxHashMap; use rustc_target::spec::PanicStrategy; /// A list of dependencies for a certain crate type. diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 218ca3b7553c0..2d0e6c3917bb8 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -1,15 +1,15 @@ -use hir::map as hir_map; -use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; -use session::{config, Session}; -use session::config::EntryFnType; +use crate::hir::map as hir_map; +use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; +use crate::session::{config, Session}; +use crate::session::config::EntryFnType; use syntax::ast::NodeId; use syntax::attr; use syntax::entry::EntryPointType; use syntax_pos::Span; -use hir::{Item, ItemKind, ImplItem, TraitItem}; -use hir::itemlikevisit::ItemLikeVisitor; -use ty::TyCtxt; -use ty::query::Providers; +use crate::hir::{Item, ItemKind, ImplItem, TraitItem}; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use crate::ty::TyCtxt; +use crate::ty::query::Providers; struct EntryContext<'a, 'tcx: 'a> { session: &'a Session, diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index a0a73ea0b81fb..6c43068a22772 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -1,11 +1,11 @@ -use hir::def_id::{DefId, LOCAL_CRATE}; -use ich::StableHashingContext; +use crate::hir::def_id::{DefId, LOCAL_CRATE}; +use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{StableHasher, HashStable, StableHasherResult}; use std::cmp; use std::mem; -use ty; -use ty::subst::Substs; +use crate::ty; +use crate::ty::subst::Substs; /// The SymbolExportLevel of a symbols specifies from which kinds of crates /// the symbol will be exported. `C` symbols will be exported from any diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 08210c3f075ce..0939f07f43bb3 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -9,20 +9,20 @@ pub use self::MatchMode::*; use self::TrackMatchMode::*; use self::OverloadedCallType::*; -use hir::def::Def; -use hir::def_id::DefId; -use infer::InferCtxt; -use middle::mem_categorization as mc; -use middle::region; -use ty::{self, TyCtxt, adjustment}; - -use hir::{self, PatKind}; +use crate::hir::def::Def; +use crate::hir::def_id::DefId; +use crate::infer::InferCtxt; +use crate::middle::mem_categorization as mc; +use crate::middle::region; +use crate::ty::{self, TyCtxt, adjustment}; + +use crate::hir::{self, PatKind}; use rustc_data_structures::sync::Lrc; use std::rc::Rc; use syntax::ast; use syntax::ptr::P; use syntax_pos::Span; -use util::nodemap::ItemLocalSet; +use crate::util::nodemap::ItemLocalSet; /////////////////////////////////////////////////////////////////////////// // The Delegate trait diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 6e9eadca6a521..e752643e842aa 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -5,10 +5,10 @@ //! `TransitiveRelation` type and use that to decide when one free //! region outlives another and so forth. -use infer::outlives::free_region_map::{FreeRegionMap, FreeRegionRelations}; -use hir::def_id::DefId; -use middle::region; -use ty::{self, TyCtxt, Region}; +use crate::infer::outlives::free_region_map::{FreeRegionMap, FreeRegionRelations}; +use crate::hir::def_id::DefId; +use crate::middle::region; +use crate::ty::{self, TyCtxt, Region}; /// Combines a `region::ScopeTree` (which governs relationships between /// scopes) and a `FreeRegionMap` (which governs relationships between diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 29d3713900ad9..ee361e9776313 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -1,14 +1,14 @@ -use hir::def::Def; -use hir::def_id::DefId; -use ty::{self, Ty, TyCtxt}; -use ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; -use ty::query::Providers; +use crate::hir::def::Def; +use crate::hir::def_id::DefId; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; +use crate::ty::query::Providers; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; -use hir::intravisit::{self, Visitor, NestedVisitorMap}; -use hir; +use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { for &module in tcx.hir().krate().modules.keys() { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 87107f727a05d..3f9230ab551d5 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -11,17 +11,17 @@ pub use self::LangItem::*; -use hir::def_id::DefId; -use hir::check_attr::Target; -use ty::{self, TyCtxt}; -use middle::weak_lang_items; -use util::nodemap::FxHashMap; +use crate::hir::def_id::DefId; +use crate::hir::check_attr::Target; +use crate::ty::{self, TyCtxt}; +use crate::middle::weak_lang_items; +use crate::util::nodemap::FxHashMap; use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; -use hir::itemlikevisit::ItemLikeVisitor; -use hir; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use crate::hir; // The actual lang items defined come at the end of this file in one handy table. // So you probably just want to nip down to the end. diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 8c23377324f1f..45095d9bc986b 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -4,13 +4,13 @@ // and `#[unstable (..)]`), but are not declared in one single location // (unlike lang features), which means we need to collect them instead. -use ty::TyCtxt; +use crate::ty::TyCtxt; use syntax::symbol::Symbol; use syntax::ast::{Attribute, MetaItem, MetaItemKind}; use syntax_pos::Span; -use hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; -use errors::DiagnosticId; +use crate::errors::DiagnosticId; pub struct LibFeatures { // A map from feature to stabilisation version. diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d47ad009c1db6..ce4a0f69c2864 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -97,13 +97,13 @@ use self::LoopKind::*; use self::LiveNodeKind::*; use self::VarKind::*; -use hir::def::*; -use hir::Node; -use ty::{self, TyCtxt}; -use ty::query::Providers; -use lint; -use errors::Applicability; -use util::nodemap::{NodeMap, HirIdMap, HirIdSet}; +use crate::hir::def::*; +use crate::hir::Node; +use crate::ty::{self, TyCtxt}; +use crate::ty::query::Providers; +use crate::lint; +use crate::errors::Applicability; +use crate::util::nodemap::{NodeMap, HirIdMap, HirIdSet}; use std::collections::{BTreeMap, VecDeque}; use std::{fmt, u32}; @@ -115,10 +115,10 @@ use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::Span; -use hir; -use hir::{Expr, HirId}; -use hir::def_id::DefId; -use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; +use crate::hir; +use crate::hir::{Expr, HirId}; +use crate::hir::def_id::DefId; +use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; /// For use with `propagate_through_loop`. enum LoopKind<'a> { @@ -406,7 +406,7 @@ fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P) { let mut pats = VecDeque::new(); pats.push_back(pat); while let Some(pat) = pats.pop_front() { - use hir::PatKind::*; + use crate::hir::PatKind::*; match pat.node { Binding(_, _, _, _, ref inner_pat) => { pats.extend(inner_pat.iter()); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 370f0d1a6c6d7..04e4a0b39a2ca 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -58,19 +58,19 @@ pub use self::Note::*; use self::Aliasability::*; -use middle::region; -use hir::def_id::{DefId, LocalDefId}; -use hir::Node; -use infer::InferCtxt; -use hir::def::{Def, CtorKind}; -use ty::adjustment; -use ty::{self, Ty, TyCtxt}; -use ty::fold::TypeFoldable; -use ty::layout::VariantIdx; - -use hir::{MutImmutable, MutMutable, PatKind}; -use hir::pat_util::EnumerateAndAdjustIterator; -use hir; +use crate::middle::region; +use crate::hir::def_id::{DefId, LocalDefId}; +use crate::hir::Node; +use crate::infer::InferCtxt; +use crate::hir::def::{Def, CtorKind}; +use crate::ty::adjustment; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::fold::TypeFoldable; +use crate::ty::layout::VariantIdx; + +use crate::hir::{MutImmutable, MutMutable, PatKind}; +use crate::hir::pat_util::EnumerateAndAdjustIterator; +use crate::hir; use syntax::ast::{self, Name}; use syntax_pos::Span; @@ -80,7 +80,7 @@ use std::hash::{Hash, Hasher}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::indexed_vec::Idx; use std::rc::Rc; -use util::nodemap::ItemLocalSet; +use crate::util::nodemap::ItemLocalSet; #[derive(Clone, Debug, PartialEq)] pub enum Categorization<'tcx> { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 3baf0f0ea39ff..1655d8356a5a7 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -2,7 +2,7 @@ //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. -use util::nodemap::{DefIdSet, FxHashMap}; +use crate::util::nodemap::{DefIdSet, FxHashMap}; use std::hash::Hash; use std::fmt; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 10deca836fff3..73ba47d411915 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -5,24 +5,24 @@ // makes all other generics or inline functions that it references // reachable as well. -use hir::{CodegenFnAttrs, CodegenFnAttrFlags}; -use hir::Node; -use hir::def::Def; -use hir::def_id::{DefId, CrateNum}; +use crate::hir::{CodegenFnAttrs, CodegenFnAttrFlags}; +use crate::hir::Node; +use crate::hir::def::Def; +use crate::hir::def_id::{DefId, CrateNum}; use rustc_data_structures::sync::Lrc; -use ty::{self, TyCtxt}; -use ty::query::Providers; -use middle::privacy; -use session::config; -use util::nodemap::{NodeSet, FxHashSet}; +use crate::ty::{self, TyCtxt}; +use crate::ty::query::Providers; +use crate::middle::privacy; +use crate::session::config; +use crate::util::nodemap::{NodeSet, FxHashSet}; use rustc_target::spec::abi::Abi; use syntax::ast; -use hir; -use hir::def_id::LOCAL_CRATE; -use hir::intravisit::{Visitor, NestedVisitorMap}; -use hir::itemlikevisit::ItemLikeVisitor; -use hir::intravisit; +use crate::hir; +use crate::hir::def_id::LOCAL_CRATE; +use crate::hir::intravisit::{Visitor, NestedVisitorMap}; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use crate::hir::intravisit; // Returns true if the given item must be inlined because it may be // monomorphized or it was marked with `#[inline]`. This will only return diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs index 1eabd7f59e689..ea077220e0be3 100644 --- a/src/librustc/middle/recursion_limit.rs +++ b/src/librustc/middle/recursion_limit.rs @@ -5,7 +5,7 @@ // this via an attribute on the crate like `#![recursion_limit="22"]`. This pass // just peeks and looks for that attribute. -use session::Session; +use crate::session::Session; use syntax::ast; use rustc_data_structures::sync::Once; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index db52cc3074b9a..788d2185d6da2 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -6,9 +6,9 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html -use ich::{StableHashingContext, NodeIdHashingMode}; -use util::nodemap::{FxHashMap, FxHashSet}; -use ty; +use crate::ich::{StableHashingContext, NodeIdHashingMode}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; +use crate::ty; use std::mem; use std::fmt; @@ -16,14 +16,14 @@ use rustc_data_structures::sync::Lrc; use syntax::source_map; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -use ty::TyCtxt; -use ty::query::Providers; - -use hir; -use hir::Node; -use hir::def_id::DefId; -use hir::intravisit::{self, Visitor, NestedVisitorMap}; -use hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local}; +use crate::ty::TyCtxt; +use crate::ty::query::Providers; + +use crate::hir; +use crate::hir::Node; +use crate::hir::def_id::DefId; +use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; @@ -154,7 +154,7 @@ newtype_index! { pub struct FirstStatementIndex { .. } } -impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { private }); +impl_stable_hash_for!(struct crate::middle::region::FirstStatementIndex { private }); // compilation error if size of `ScopeData` is not the same as a `u32` static_assert!(ASSERT_SCOPE_DATA: mem::size_of::() == 4); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 34db30a1706b9..f7cd241236498 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -5,16 +5,16 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore we break lifetime name resolution into a separate pass. -use hir::def::Def; -use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; -use hir::map::Map; -use hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName}; -use ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; - -use errors::{Applicability, DiagnosticBuilder}; -use rustc::lint; +use crate::hir::def::Def; +use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; +use crate::hir::map::Map; +use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName}; +use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; + +use crate::errors::{Applicability, DiagnosticBuilder}; +use crate::rustc::lint; use rustc_data_structures::sync::Lrc; -use session::Session; +use crate::session::Session; use std::borrow::Cow; use std::cell::Cell; use std::mem::replace; @@ -23,10 +23,10 @@ use syntax::attr; use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::Span; -use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet}; +use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet}; -use hir::intravisit::{self, NestedVisitorMap, Visitor}; -use hir::{self, GenericParamKind, LifetimeParamKind}; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::{self, GenericParamKind, LifetimeParamKind}; /// The origin of a named lifetime definition. /// @@ -216,7 +216,7 @@ pub struct ResolveLifetimes { FxHashMap>>>>, } -impl_stable_hash_for!(struct ::middle::resolve_lifetime::ResolveLifetimes { +impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes { defs, late_bound, object_lifetime_defaults diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 3717ee7143c55..85b5409465a8d 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,14 +3,14 @@ pub use self::StabilityLevel::*; -use lint::{self, Lint}; -use hir::{self, Item, Generics, StructField, Variant, HirId}; -use hir::def::Def; -use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; -use hir::intravisit::{self, Visitor, NestedVisitorMap}; -use ty::query::Providers; -use middle::privacy::AccessLevels; -use session::{DiagnosticMessageId, Session}; +use crate::lint::{self, Lint}; +use crate::hir::{self, Item, Generics, StructField, Variant, HirId}; +use crate::hir::def::Def; +use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; +use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::ty::query::Providers; +use crate::middle::privacy::AccessLevels; +use crate::session::{DiagnosticMessageId, Session}; use syntax::symbol::Symbol; use syntax_pos::{Span, MultiSpan}; use syntax::ast; @@ -18,8 +18,8 @@ use syntax::ast::{NodeId, Attribute}; use syntax::errors::Applicability; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::attr::{self, Stability, Deprecation}; -use ty::{self, TyCtxt}; -use util::nodemap::{FxHashSet, FxHashMap}; +use crate::ty::{self, TyCtxt}; +use crate::util::nodemap::{FxHashSet, FxHashMap}; use std::mem::replace; use std::cmp::Ordering; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 82f19cbb82a19..119e855c58551 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -1,18 +1,18 @@ //! Validity checking for weak lang items -use session::config; -use middle::lang_items; +use crate::session::config; +use crate::middle::lang_items; use rustc_data_structures::fx::FxHashSet; use rustc_target::spec::PanicStrategy; use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; -use hir::def_id::DefId; -use hir::intravisit::{Visitor, NestedVisitorMap}; -use hir::intravisit; -use hir; -use ty::TyCtxt; +use crate::hir::def_id::DefId; +use crate::hir::intravisit::{Visitor, NestedVisitorMap}; +use crate::hir::intravisit; +use crate::hir; +use crate::ty::TyCtxt; macro_rules! weak_lang_items { ($($name:ident, $item:ident, $sym:ident;)*) => ( diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 56ab263c47740..1cc927b1f720f 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -2,10 +2,10 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::{RwLock, MappedReadGuard, ReadGuard}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use ich::StableHashingContext; -use mir::{Mir, BasicBlock}; +use crate::ich::StableHashingContext; +use crate::mir::{Mir, BasicBlock}; -use rustc_serialize as serialize; +use crate::rustc_serialize as serialize; #[derive(Clone, Debug)] pub struct Cache { diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 7ed29c5afd03f..7761e1fdafac5 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -5,10 +5,10 @@ use super::{ truncate, }; -use ty::layout::{Size, Align}; +use crate::ty::layout::{Size, Align}; use syntax::ast::Mutability; use std::iter; -use mir; +use crate::mir; use std::ops::{Deref, DerefMut}; use rustc_data_structures::sorted_map::SortedMap; use rustc_target::abi::HasDataLayout; diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index c3fe5d773ab16..870a51f95df1c 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -1,17 +1,17 @@ use std::{fmt, env}; -use hir::map::definitions::DefPathData; -use mir; -use ty::{self, Ty, layout}; -use ty::layout::{Size, Align, LayoutError}; +use crate::hir::map::definitions::DefPathData; +use crate::mir; +use crate::ty::{self, Ty, layout}; +use crate::ty::layout::{Size, Align, LayoutError}; use rustc_target::spec::abi::Abi; use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef}; use backtrace::Backtrace; -use ty::query::TyCtxtAt; -use errors::DiagnosticBuilder; +use crate::ty::query::TyCtxtAt; +use crate::errors::DiagnosticBuilder; use syntax_pos::{Pos, Span}; use syntax::ast; @@ -42,7 +42,7 @@ pub type ConstEvalResult<'tcx> = Result, ErrorHandled>; #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub error: ::mir::interpret::EvalErrorKind<'tcx, u64>, + pub error: crate::mir::interpret::EvalErrorKind<'tcx, u64>, pub stacktrace: Vec>, } @@ -136,7 +136,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { .next() .unwrap_or(lint_root); tcx.struct_span_lint_node( - ::rustc::lint::builtin::CONST_ERR, + crate::rustc::lint::builtin::CONST_ERR, node_id, tcx.span, message, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index e6a560b2ad7b6..efd233f1f3854 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -25,17 +25,17 @@ pub use self::allocation::{ pub use self::pointer::{Pointer, PointerArithmetic}; use std::fmt; -use mir; -use hir::def_id::DefId; -use ty::{self, TyCtxt, Instance}; -use ty::layout::{self, Size}; +use crate::mir; +use crate::hir::def_id::DefId; +use crate::ty::{self, TyCtxt, Instance}; +use crate::ty::layout::{self, Size}; use std::io; -use rustc_serialize::{Encoder, Decodable, Encodable}; +use crate::rustc_serialize::{Encoder, Decodable, Encodable}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{Lock as Mutex, HashMapExt}; use rustc_data_structures::tiny_list::TinyList; use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian, BigEndian}; -use ty::codec::TyDecoder; +use crate::ty::codec::TyDecoder; use std::sync::atomic::{AtomicU32, Ordering}; use std::num::NonZeroU32; @@ -53,8 +53,8 @@ pub struct GlobalId<'tcx> { #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] pub struct AllocId(pub u64); -impl ::rustc_serialize::UseSpecializedEncodable for AllocId {} -impl ::rustc_serialize::UseSpecializedDecodable for AllocId {} +impl crate::rustc_serialize::UseSpecializedEncodable for AllocId {} +impl crate::rustc_serialize::UseSpecializedDecodable for AllocId {} #[derive(RustcDecodable, RustcEncodable)] enum AllocDiscriminant { diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 498c0b5b917e9..551e7b2fd41ec 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -1,5 +1,5 @@ -use mir; -use ty::layout::{self, HasDataLayout, Size}; +use crate::mir; +use crate::ty::layout::{self, HasDataLayout, Size}; use super::{ AllocId, EvalResult, InboundsCheck, diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 1328a1aeeab96..73917342814de 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -515,7 +515,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { } } -impl_stable_hash_for!(enum ::mir::interpret::ScalarMaybeUndef { +impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef { Scalar(v), Undef }); diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 82083b4f69964..009997bfcf2c4 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2,11 +2,11 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html -use hir::def::CtorKind; -use hir::def_id::DefId; -use hir::{self, HirId, InlineAsm}; -use mir::interpret::{ConstValue, EvalErrorKind, Scalar}; -use mir::visit::MirVisitable; +use crate::hir::def::CtorKind; +use crate::hir::def_id::DefId; +use crate::hir::{self, HirId, InlineAsm}; +use crate::mir::interpret::{ConstValue, EvalErrorKind, Scalar}; +use crate::mir::visit::MirVisitable; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_data_structures::fx::FxHashSet; @@ -15,7 +15,7 @@ use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::MappedReadGuard; -use rustc_serialize::{self as serialize}; +use crate::rustc_serialize::{self as serialize}; use smallvec::SmallVec; use std::borrow::Cow; use std::fmt::{self, Debug, Formatter, Write}; @@ -26,16 +26,16 @@ use std::{iter, mem, option, u32}; use syntax::ast::{self, Name}; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use ty::subst::{Subst, Substs}; -use ty::layout::VariantIdx; -use ty::{ +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::layout::VariantIdx; +use crate::ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, UserTypeAnnotationIndex, }; -use util::ppaux; +use crate::util::ppaux; -pub use mir::interpret::AssertMessage; +pub use crate::mir::interpret::AssertMessage; mod cache; pub mod interpret; @@ -676,7 +676,7 @@ impl_stable_hash_for!(enum self::MirPhase { }); mod binding_form_impl { - use ich::StableHashingContext; + use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; impl<'a, 'tcx> HashStable> for super::BindingForm<'tcx> { @@ -2625,7 +2625,7 @@ CloneTypeFoldableAndLiftImpls! { ProjectionKind<'tcx>, } impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use mir::ProjectionElem::*; + use crate::mir::ProjectionElem::*; let base = self.base.fold_with(folder); let projs: Vec<_> = self.projs @@ -2671,7 +2671,7 @@ pub fn fmt_lazy_const_val(f: &mut impl Write, const_val: &ty::LazyConst<'_>) -> /// Write a `ConstValue` in a way closer to the original source code than the `Debug` output. pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Result { - use ty::TyKind::*; + use crate::ty::TyKind::*; let value = const_val.val; let ty = const_val.ty; // print some primitives @@ -3116,7 +3116,7 @@ EnumTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use mir::TerminatorKind::*; + use crate::mir::TerminatorKind::*; let kind = match self.kind { Goto { target } => Goto { target }, @@ -3229,7 +3229,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } fn super_visit_with>(&self, visitor: &mut V) -> bool { - use mir::TerminatorKind::*; + use crate::mir::TerminatorKind::*; match self.kind { SwitchInt { @@ -3301,7 +3301,7 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use mir::Rvalue::*; + use crate::mir::Rvalue::*; match *self { Use(ref op) => Use(op.fold_with(folder)), Repeat(ref op, len) => Repeat(op.fold_with(folder), len), @@ -3343,7 +3343,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { } fn super_visit_with>(&self, visitor: &mut V) -> bool { - use mir::Rvalue::*; + use crate::mir::Rvalue::*; match *self { Use(ref op) => op.visit_with(visitor), Repeat(ref op, _) => op.visit_with(visitor), @@ -3395,7 +3395,7 @@ where T: TypeFoldable<'tcx>, { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use mir::ProjectionElem::*; + use crate::mir::ProjectionElem::*; let base = self.base.fold_with(folder); let elem = match self.elem { @@ -3409,7 +3409,7 @@ where } fn super_visit_with>(&self, visitor: &mut Vs) -> bool { - use mir::ProjectionElem::*; + use crate::mir::ProjectionElem::*; self.base.visit_with(visitor) || match self.elem { Field(_, ref ty) => ty.visit_with(visitor), diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 55f5c36cde66d..affa9f9fdd4d7 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,12 +1,12 @@ -use hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; +use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use syntax::ast::NodeId; use syntax::symbol::{Symbol, InternedString}; -use ty::{Instance, TyCtxt}; -use util::nodemap::FxHashMap; +use crate::ty::{Instance, TyCtxt}; +use crate::util::nodemap::FxHashMap; use rustc_data_structures::base_n; use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult, StableHasher}; -use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; +use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; use std::fmt; use std::hash::Hash; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 649370059f0ea..ac3a97898b405 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -3,12 +3,12 @@ * building is complete. */ -use mir::*; -use ty::subst::{Subst, Substs}; -use ty::{self, AdtDef, Ty, TyCtxt}; -use ty::layout::VariantIdx; -use hir; -use ty::util::IntTypeExt; +use crate::mir::*; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::{self, AdtDef, Ty, TyCtxt}; +use crate::ty::layout::VariantIdx; +use crate::hir; +use crate::ty::util::IntTypeExt; #[derive(Copy, Clone, Debug)] pub enum PlaceTy<'tcx> { diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 598303f29328f..0180256661630 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -1,7 +1,7 @@ -use hir::def_id::DefId; -use ty::subst::Substs; -use ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, Region, Ty}; -use mir::*; +use crate::hir::def_id::DefId; +use crate::ty::subst::Substs; +use crate::ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, Region, Ty}; +use crate::mir::*; use syntax_pos::Span; // # The MIR Visitor @@ -567,7 +567,7 @@ macro_rules! make_mir_visitor { fn super_assert_message(&mut self, msg: & $($mutability)* AssertMessage<'tcx>, location: Location) { - use mir::interpret::EvalErrorKind::*; + use crate::mir::interpret::EvalErrorKind::*; if let BoundsCheck { ref $($mutability)* len, ref $($mutability)* index diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 86f676fbf888a..f8de61f146337 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -3,13 +3,13 @@ use std::str::FromStr; -use session::{early_error, early_warn, Session}; -use session::search_paths::SearchPath; +use crate::session::{early_error, early_warn, Session}; +use crate::session::search_paths::SearchPath; use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel}; use rustc_target::spec::{Target, TargetTriple}; -use lint; -use middle::cstore; +use crate::lint; +use crate::middle::cstore; use syntax::ast::{self, IntTy, UintTy, MetaItemKind}; use syntax::source_map::{FileName, FilePathMapping}; @@ -19,7 +19,7 @@ use syntax::parse; use syntax::symbol::Symbol; use syntax::feature_gate::UnstableFeatures; -use errors::{ColorConfig, FatalError, Handler}; +use crate::errors::{ColorConfig, FatalError, Handler}; use getopts; use std::collections::{BTreeMap, BTreeSet}; @@ -2342,7 +2342,7 @@ pub mod nightly_options { use getopts; use syntax::feature_gate::UnstableFeatures; use super::{ErrorOutputType, OptionStability, RustcOptGroup}; - use session::early_error; + use crate::session::early_error; pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool { is_nightly_build() @@ -2431,8 +2431,8 @@ impl fmt::Display for CrateType { /// we have an opt-in scheme here, so one is hopefully forced to think about /// how the hash should be calculated when adding a new command-line argument. mod dep_tracking { - use lint; - use middle::cstore; + use crate::lint; + use crate::middle::cstore; use std::collections::BTreeMap; use std::hash::Hash; use std::path::PathBuf; @@ -2565,14 +2565,14 @@ mod dep_tracking { #[cfg(test)] mod tests { - use errors; + use crate::errors; use getopts; - use lint; - use middle::cstore; - use session::config::{build_configuration, build_session_options_and_crate_config}; - use session::config::{LtoCli, CrossLangLto}; - use session::build_session; - use session::search_paths::SearchPath; + use crate::lint; + use crate::middle::cstore; + use crate::session::config::{build_configuration, build_session_options_and_crate_config}; + use crate::session::config::{LtoCli, CrossLangLto}; + use crate::session::build_session; + use crate::session::search_paths::SearchPath; use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; use std::path::PathBuf; diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index 19f1c7a18fad1..77f190e281229 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -7,7 +7,7 @@ use std::env; use std::fs; use std::path::{Path, PathBuf}; -use session::search_paths::{SearchPath, PathKind}; +use crate::session::search_paths::{SearchPath, PathKind}; use rustc_fs_util::fix_windows_verbatim_for_gcc; #[derive(Copy, Clone)] diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index c5034415d6ffb..d2beb64b38861 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1,19 +1,19 @@ pub use self::code_stats::{DataTypeKind, SizeKind, FieldInfo, VariantInfo}; use self::code_stats::CodeStats; -use dep_graph::cgu_reuse_tracker::CguReuseTracker; -use hir::def_id::CrateNum; +use crate::dep_graph::cgu_reuse_tracker::CguReuseTracker; +use crate::hir::def_id::CrateNum; use rustc_data_structures::fingerprint::Fingerprint; -use lint; -use lint::builtin::BuiltinLintDiagnostics; -use middle::allocator::AllocatorKind; -use middle::dependency_format; -use session::config::{OutputType, Lto}; -use session::search_paths::{PathKind, SearchPath}; -use util::nodemap::{FxHashMap, FxHashSet}; -use util::common::{duration_to_secs_str, ErrorReported}; -use util::common::ProfileQueriesMsg; +use crate::lint; +use crate::lint::builtin::BuiltinLintDiagnostics; +use crate::middle::allocator::AllocatorKind; +use crate::middle::dependency_format; +use crate::session::config::{OutputType, Lto}; +use crate::session::search_paths::{PathKind, SearchPath}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; +use crate::util::common::{duration_to_secs_str, ErrorReported}; +use crate::util::common::ProfileQueriesMsg; use rustc_data_structures::base_n; use rustc_data_structures::sync::{ @@ -21,8 +21,8 @@ use rustc_data_structures::sync::{ Ordering::SeqCst, }; -use errors::{self, DiagnosticBuilder, DiagnosticId, Applicability}; -use errors::emitter::{Emitter, EmitterWriter}; +use crate::errors::{self, DiagnosticBuilder, DiagnosticId, Applicability}; +use crate::errors::emitter::{Emitter, EmitterWriter}; use syntax::ast::{self, NodeId}; use syntax::edition::Edition; use syntax::feature_gate::{self, AttributeType}; @@ -30,7 +30,7 @@ use syntax::json::JsonEmitter; use syntax::source_map; use syntax::parse::{self, ParseSess}; use syntax_pos::{MultiSpan, Span}; -use util::profiling::SelfProfiler; +use crate::util::profiling::SelfProfiler; use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple}; use rustc_data_structures::flock; diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 85d64b1571266..a950258cefd0c 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; -use session::{early_error, config}; -use session::filesearch::make_target_lib_path; +use crate::session::{early_error, config}; +use crate::session::filesearch::make_target_lib_path; #[derive(Clone, Debug)] pub struct SearchPath { diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index 92004ece26d00..d1db49e05f190 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -6,12 +6,12 @@ use super::*; use std::collections::hash_map::Entry; use std::collections::VecDeque; -use infer::region_constraints::{Constraint, RegionConstraintData}; -use infer::InferCtxt; +use crate::infer::region_constraints::{Constraint, RegionConstraintData}; +use crate::infer::InferCtxt; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use ty::fold::TypeFolder; -use ty::{Region, RegionVid}; +use crate::ty::fold::TypeFolder; +use crate::ty::{Region, RegionVid}; // FIXME(twk): this is obviously not nice to duplicate like that #[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)] diff --git a/src/librustc/traits/chalk_fulfill.rs b/src/librustc/traits/chalk_fulfill.rs index df4e08e0eb5f3..d9eb6d8157dfb 100644 --- a/src/librustc/traits/chalk_fulfill.rs +++ b/src/librustc/traits/chalk_fulfill.rs @@ -1,4 +1,4 @@ -use traits::{ +use crate::traits::{ Environment, InEnvironment, TraitEngine, @@ -8,10 +8,10 @@ use traits::{ FulfillmentErrorCode, SelectionError, }; -use traits::query::NoSolution; -use infer::InferCtxt; -use infer::canonical::{Canonical, OriginalQueryValues}; -use ty::{self, Ty}; +use crate::traits::query::NoSolution; +use crate::infer::InferCtxt; +use crate::infer::canonical::{Canonical, OriginalQueryValues}; +use crate::ty::{self, Ty}; use rustc_data_structures::fx::FxHashSet; pub type CanonicalGoal<'tcx> = Canonical<'tcx, InEnvironment<'tcx, ty::Predicate<'tcx>>>; diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs index 94d56c2cbfc88..eed9345afae16 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -3,16 +3,16 @@ // seems likely that they should eventually be merged into more // general routines. -use dep_graph::{DepKind, DepTrackingMapConfig}; +use crate::dep_graph::{DepKind, DepTrackingMapConfig}; use std::marker::PhantomData; use syntax_pos::DUMMY_SP; -use infer::InferCtxt; +use crate::infer::InferCtxt; use syntax_pos::Span; -use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, +use crate::traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable}; -use ty::{self, Ty, TyCtxt}; -use ty::subst::{Subst, Substs}; -use ty::fold::TypeFoldable; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::fold::TypeFoldable; /// Attempts to resolve an obligation to a vtable.. The result is /// a shallow vtable resolution -- meaning that we do not diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 4c7049c366207..4fe7a1507f737 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -4,17 +4,17 @@ //! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html //! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html -use infer::CombinedSnapshot; -use hir::def_id::{DefId, LOCAL_CRATE}; +use crate::infer::CombinedSnapshot; +use crate::hir::def_id::{DefId, LOCAL_CRATE}; use syntax_pos::DUMMY_SP; -use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause}; -use traits::IntercrateMode; -use traits::select::IntercrateAmbiguityCause; -use ty::{self, Ty, TyCtxt}; -use ty::fold::TypeFoldable; -use ty::subst::Subst; +use crate::traits::{self, Normalized, SelectionContext, Obligation, ObligationCause}; +use crate::traits::IntercrateMode; +use crate::traits::select::IntercrateAmbiguityCause; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::fold::TypeFoldable; +use crate::ty::subst::Subst; -use infer::{InferOk}; +use crate::infer::{InferOk}; /// Whether we do the orphan check relative to this crate or /// to some remote crate. @@ -39,7 +39,7 @@ pub struct OverlapResult<'tcx> { pub involves_placeholder: bool, } -pub fn add_placeholder_note(err: &mut ::errors::DiagnosticBuilder<'_>) { +pub fn add_placeholder_note(err: &mut crate::errors::DiagnosticBuilder<'_>) { err.note(&format!( "this behavior recently changed as a result of a bug fix; \ see rust-lang/rust#56105 for details" diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index c759a9ddf2ce6..2f019d823ff5d 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -1,7 +1,7 @@ -use infer::InferCtxt; -use ty::{self, Ty, TyCtxt, ToPredicate}; -use traits::Obligation; -use hir::def_id::DefId; +use crate::infer::InferCtxt; +use crate::ty::{self, Ty, TyCtxt, ToPredicate}; +use crate::traits::Obligation; +use crate::hir::def_id::DefId; use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError}; use super::{ObligationCause, PredicateObligation}; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index ea3ea59c7613f..79afc593a4676 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -17,23 +17,23 @@ use super::{ Overflow, }; -use errors::{Applicability, DiagnosticBuilder}; -use hir; -use hir::Node; -use hir::def_id::DefId; -use infer::{self, InferCtxt}; -use infer::type_variable::TypeVariableOrigin; +use crate::errors::{Applicability, DiagnosticBuilder}; +use crate::hir; +use crate::hir::Node; +use crate::hir::def_id::DefId; +use crate::infer::{self, InferCtxt}; +use crate::infer::type_variable::TypeVariableOrigin; use std::fmt; use syntax::ast; -use session::DiagnosticMessageId; -use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; -use ty::GenericParamDefKind; -use ty::error::ExpectedFound; -use ty::fast_reject; -use ty::fold::TypeFolder; -use ty::subst::Subst; -use ty::SubtypePredicate; -use util::nodemap::{FxHashMap, FxHashSet}; +use crate::session::DiagnosticMessageId; +use crate::ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; +use crate::ty::GenericParamDefKind; +use crate::ty::error::ExpectedFound; +use crate::ty::fast_reject; +use crate::ty::fold::TypeFolder; +use crate::ty::subst::Subst; +use crate::ty::SubtypePredicate; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat}; diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 2e00d4d4b7c3b..98784bccb6f82 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -1,7 +1,7 @@ -use infer::InferCtxt; -use mir::interpret::{GlobalId, ErrorHandled}; -use ty::{self, Ty, TypeFoldable, ToPolyTraitRef}; -use ty::error::ExpectedFound; +use crate::infer::InferCtxt; +use crate::mir::interpret::{GlobalId, ErrorHandled}; +use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef}; +use crate::ty::error::ExpectedFound; use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; use rustc_data_structures::obligation_forest::{ProcessResult}; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 68383bef37a6a..d1be8d377a84d 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -20,20 +20,20 @@ mod util; pub mod query; use chalk_engine; -use hir; -use hir::def_id::DefId; -use infer::{InferCtxt, SuppressRegionErrors}; -use infer::outlives::env::OutlivesEnvironment; -use middle::region; -use mir::interpret::ErrorHandled; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::infer::{InferCtxt, SuppressRegionErrors}; +use crate::infer::outlives::env::OutlivesEnvironment; +use crate::middle::region; +use crate::mir::interpret::ErrorHandled; use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -use ty::subst::Substs; -use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate}; -use ty::error::{ExpectedFound, TypeError}; -use ty::fold::{TypeFolder, TypeFoldable, TypeVisitor}; -use util::common::ErrorReported; +use crate::ty::subst::Substs; +use crate::ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate}; +use crate::ty::error::{ExpectedFound, TypeError}; +use crate::ty::fold::{TypeFolder, TypeFoldable, TypeVisitor}; +use crate::util::common::ErrorReported; use std::fmt::Debug; use std::rc::Rc; diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index c37dc2a855ed0..75eaa67e767c2 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -10,11 +10,11 @@ use super::elaborate_predicates; -use hir::def_id::DefId; -use lint; -use traits::{self, Obligation, ObligationCause}; -use ty::{self, Ty, TyCtxt, TypeFoldable, Predicate, ToPredicate}; -use ty::subst::{Subst, Substs}; +use crate::hir::def_id::DefId; +use crate::lint; +use crate::traits::{self, Obligation, ObligationCause}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable, Predicate, ToPredicate}; +use crate::ty::subst::{Subst, Substs}; use std::borrow::Cow; use std::iter::{self}; use syntax::ast::{self, Name}; @@ -341,7 +341,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } else { // sanity check to make sure the receiver actually has the layout of a pointer - use ty::layout::Abi; + use crate::ty::layout::Abi; let param_env = self.param_env(method.def_id); diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 3ec901f50e4cc..f61c32614cc93 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -1,9 +1,9 @@ use fmt_macros::{Parser, Piece, Position}; -use hir::def_id::DefId; -use ty::{self, TyCtxt, GenericParamDefKind}; -use util::common::ErrorReported; -use util::nodemap::FxHashMap; +use crate::hir::def_id::DefId; +use crate::ty::{self, TyCtxt, GenericParamDefKind}; +use crate::util::common::ErrorReported; +use crate::util::nodemap::FxHashMap; use syntax::ast::{MetaItem, NestedMetaItem}; use syntax::attr; diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index bec45046cb93e..99107a1a6d4e1 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -12,16 +12,16 @@ use super::SelectionError; use super::{VtableImplData, VtableClosureData, VtableGeneratorData, VtableFnPointerData}; use super::util; -use hir::def_id::DefId; -use infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; -use infer::type_variable::TypeVariableOrigin; -use mir::interpret::{GlobalId}; +use crate::hir::def_id::DefId; +use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; +use crate::infer::type_variable::TypeVariableOrigin; +use crate::mir::interpret::{GlobalId}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use syntax::ast::Ident; -use ty::subst::{Subst, Substs}; -use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder}; -use util::common::FN_OUTPUT_NAME; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::util::common::FN_OUTPUT_NAME; /// Depending on the stage of compilation, we want projection to be /// more or less conservative. diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1fd2172212d3c..47ca416e6b5aa 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -1,10 +1,10 @@ -use infer::at::At; -use infer::InferOk; -use infer::canonical::OriginalQueryValues; +use crate::infer::at::At; +use crate::infer::InferOk; +use crate::infer::canonical::OriginalQueryValues; use std::iter::FromIterator; use syntax::source_map::Span; -use ty::subst::Kind; -use ty::{self, Ty, TyCtxt}; +use crate::ty::subst::Kind; +use crate::ty::{self, Ty, TyCtxt}; impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs index fdae7d833734e..d5230f15c2565 100644 --- a/src/librustc/traits/query/evaluate_obligation.rs +++ b/src/librustc/traits/query/evaluate_obligation.rs @@ -1,6 +1,6 @@ -use infer::InferCtxt; -use infer::canonical::OriginalQueryValues; -use traits::{EvaluationResult, PredicateObligation, SelectionContext, +use crate::infer::InferCtxt; +use crate::infer::canonical::OriginalQueryValues; +use crate::traits::{EvaluationResult, PredicateObligation, SelectionContext, TraitQueryMode, OverflowError}; impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { diff --git a/src/librustc/traits/query/method_autoderef.rs b/src/librustc/traits/query/method_autoderef.rs index b4984e1237857..6b9bdfd63f4d0 100644 --- a/src/librustc/traits/query/method_autoderef.rs +++ b/src/librustc/traits/query/method_autoderef.rs @@ -1,6 +1,6 @@ use rustc_data_structures::sync::Lrc; -use infer::canonical::{Canonical, QueryResponse}; -use ty::Ty; +use crate::infer::canonical::{Canonical, QueryResponse}; +use crate::ty::Ty; #[derive(Debug)] pub struct CandidateStep<'tcx> { diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index 59f786025b224..112a1d0e09c94 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -5,9 +5,9 @@ //! The providers for the queries defined here can be found in //! `librustc_traits`. -use infer::canonical::Canonical; -use ty::error::TypeError; -use ty::{self, Ty}; +use crate::infer::canonical::Canonical; +use crate::ty::error::TypeError; +use crate::ty::{self, Ty}; pub mod dropck_outlives; pub mod evaluate_obligation; diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index be05445cfc61a..f477f161bbb32 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -2,15 +2,15 @@ //! which folds deeply, invoking the underlying //! `normalize_projection_ty` query when it encounters projections. -use infer::at::At; -use infer::canonical::OriginalQueryValues; -use infer::{InferCtxt, InferOk}; -use mir::interpret::GlobalId; -use traits::project::Normalized; -use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; -use ty::fold::{TypeFoldable, TypeFolder}; -use ty::subst::{Subst, Substs}; -use ty::{self, Ty, TyCtxt}; +use crate::infer::at::At; +use crate::infer::canonical::OriginalQueryValues; +use crate::infer::{InferCtxt, InferOk}; +use crate::mir::interpret::GlobalId; +use crate::traits::project::Normalized; +use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::{self, Ty, TyCtxt}; use super::NoSolution; diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs index e7034065bdf2e..4fc61077e268a 100644 --- a/src/librustc/traits/query/normalize_erasing_regions.rs +++ b/src/librustc/traits/query/normalize_erasing_regions.rs @@ -7,8 +7,8 @@ //! `normalize_ty_after_erasing_regions` query for each type found //! within. (This underlying query is what is cached.) -use ty::{self, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; impl<'cx, 'tcx> TyCtxt<'cx, 'tcx, 'tcx> { /// Erase the regions in `value` and then fully normalize all the diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs index 1134cb1b2f5d0..e57236b999bab 100644 --- a/src/librustc/traits/query/outlives_bounds.rs +++ b/src/librustc/traits/query/outlives_bounds.rs @@ -1,12 +1,12 @@ -use infer::InferCtxt; -use infer::canonical::OriginalQueryValues; +use crate::infer::InferCtxt; +use crate::infer::canonical::OriginalQueryValues; use syntax::ast; use syntax::source_map::Span; -use traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt}; -use traits::query::NoSolution; -use ty::{self, Ty, TyCtxt}; +use crate::traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt}; +use crate::traits::query::NoSolution; +use crate::ty::{self, Ty, TyCtxt}; -use ich::StableHashingContext; +use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use std::mem; diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index 15f627b3ee8c4..d9f573eb7e291 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -1,8 +1,8 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; -use traits::query::Fallible; -use hir::def_id::DefId; -use ty::{ParamEnvAnd, Ty, TyCtxt}; -use ty::subst::UserSubsts; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::traits::query::Fallible; +use crate::hir::def_id::DefId; +use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::subst::UserSubsts; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct AscribeUserType<'tcx> { diff --git a/src/librustc/traits/query/type_op/custom.rs b/src/librustc/traits/query/type_op/custom.rs index 0756d2eed8aea..7e38282cc1adc 100644 --- a/src/librustc/traits/query/type_op/custom.rs +++ b/src/librustc/traits/query/type_op/custom.rs @@ -1,12 +1,12 @@ -use infer::{InferCtxt, InferOk}; +use crate::infer::{InferCtxt, InferOk}; use std::fmt; -use traits::query::Fallible; +use crate::traits::query::Fallible; -use infer::canonical::query_response; -use infer::canonical::QueryRegionConstraint; +use crate::infer::canonical::query_response; +use crate::infer::canonical::QueryRegionConstraint; use std::rc::Rc; use syntax::source_map::DUMMY_SP; -use traits::{ObligationCause, TraitEngine, TraitEngineExt}; +use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt}; pub struct CustomTypeOp { closure: F, diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index 7acb8ccb0d319..5c3ccc9a99537 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -1,6 +1,6 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; -use traits::query::Fallible; -use ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::traits::query::Fallible; +use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Eq<'tcx> { diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs index f4a825a669b48..c48ca33b13fbc 100644 --- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs +++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs @@ -1,7 +1,7 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; -use traits::query::outlives_bounds::OutlivesBound; -use traits::query::Fallible; -use ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::traits::query::outlives_bounds::OutlivesBound; +use crate::traits::query::Fallible; +use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ImpliedOutlivesBounds<'tcx> { diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index 6e5a6080976c0..fd13acc7796f8 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -1,14 +1,14 @@ -use infer::canonical::{ +use crate::infer::canonical::{ Canonical, Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues, QueryRegionConstraint, QueryResponse, }; -use infer::{InferCtxt, InferOk}; +use crate::infer::{InferCtxt, InferOk}; use std::fmt; use std::rc::Rc; -use traits::query::Fallible; -use traits::ObligationCause; -use ty::fold::TypeFoldable; -use ty::{Lift, ParamEnvAnd, TyCtxt}; +use crate::traits::query::Fallible; +use crate::traits::ObligationCause; +use crate::ty::fold::TypeFoldable; +use crate::ty::{Lift, ParamEnvAnd, TyCtxt}; pub mod ascribe_user_type; pub mod custom; diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index 98afe2abdbf05..346c18516234c 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -1,8 +1,8 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; use std::fmt; -use traits::query::Fallible; -use ty::fold::TypeFoldable; -use ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; +use crate::traits::query::Fallible; +use crate::ty::fold::TypeFoldable; +use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Normalize { diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index 108aa373e039c..fc0c1c022fc80 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -1,8 +1,8 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; -use traits::query::dropck_outlives::trivial_dropck_outlives; -use traits::query::dropck_outlives::DropckOutlivesResult; -use traits::query::Fallible; -use ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::traits::query::dropck_outlives::trivial_dropck_outlives; +use crate::traits::query::dropck_outlives::DropckOutlivesResult; +use crate::traits::query::Fallible; +use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug)] pub struct DropckOutlives<'tcx> { diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index d9eb89c9fc7c8..50dedf6e87f40 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -1,6 +1,6 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; -use traits::query::Fallible; -use ty::{ParamEnvAnd, Predicate, TyCtxt}; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::traits::query::Fallible; +use crate::ty::{ParamEnvAnd, Predicate, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ProvePredicate<'tcx> { diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index f001c7ea10a17..c45fb06313e16 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -1,6 +1,6 @@ -use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; -use traits::query::Fallible; -use ty::{ParamEnvAnd, Ty, TyCtxt}; +use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::traits::query::Fallible; +use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Subtype<'tcx> { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 6fe4a7a52be86..1e4cd145e1760 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -27,17 +27,17 @@ use super::{ VtableGeneratorData, VtableImplData, VtableObjectData, VtableTraitAliasData, }; -use dep_graph::{DepKind, DepNodeIndex}; -use hir::def_id::DefId; -use infer::{InferCtxt, InferOk, TypeFreshener}; -use middle::lang_items; -use mir::interpret::GlobalId; -use ty::fast_reject; -use ty::relate::TypeRelation; -use ty::subst::{Subst, Substs}; -use ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; - -use hir; +use crate::dep_graph::{DepKind, DepNodeIndex}; +use crate::hir::def_id::DefId; +use crate::infer::{InferCtxt, InferOk, TypeFreshener}; +use crate::middle::lang_items; +use crate::mir::interpret::GlobalId; +use crate::ty::fast_reject; +use crate::ty::relate::TypeRelation; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; + +use crate::hir; use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; @@ -45,7 +45,7 @@ use std::cmp; use std::fmt::{self, Display}; use std::iter; use std::rc::Rc; -use util::nodemap::{FxHashMap, FxHashSet}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; pub struct SelectionContext<'cx, 'gcx: 'cx + 'tcx, 'tcx: 'cx> { infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, @@ -103,7 +103,7 @@ impl IntercrateAmbiguityCause { /// See #23980 for details. pub fn add_intercrate_ambiguity_hint<'a, 'tcx>( &self, - err: &mut ::errors::DiagnosticBuilder<'_>, + err: &mut crate::errors::DiagnosticBuilder<'_>, ) { err.note(&self.intercrate_ambiguity_hint()); } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index e5ed16e755860..e7187005c132a 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -11,16 +11,16 @@ pub mod specialization_graph; -use hir::def_id::DefId; -use infer::{InferCtxt, InferOk}; -use lint; -use traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; +use crate::hir::def_id::DefId; +use crate::infer::{InferCtxt, InferOk}; +use crate::lint; +use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use syntax_pos::DUMMY_SP; -use traits::select::IntercrateAmbiguityCause; -use ty::{self, TyCtxt, TypeFoldable}; -use ty::subst::{Subst, Substs}; +use crate::traits::select::IntercrateAmbiguityCause; +use crate::ty::{self, TyCtxt, TypeFoldable}; +use crate::ty::subst::{Subst, Substs}; use super::{SelectionContext, FulfillmentContext}; use super::util::impl_trait_ref_and_oblig; diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index e5780a26a1918..010555744b6c3 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -1,16 +1,16 @@ use super::OverlapError; -use hir::def_id::DefId; -use ich::{self, StableHashingContext}; +use crate::hir::def_id::DefId; +use crate::ich::{self, StableHashingContext}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use traits; -use ty::{self, TyCtxt, TypeFoldable}; -use ty::fast_reject::{self, SimplifiedType}; +use crate::traits; +use crate::ty::{self, TyCtxt, TypeFoldable}; +use crate::ty::fast_reject::{self, SimplifiedType}; use rustc_data_structures::sync::Lrc; use syntax::ast::Ident; -use util::captures::Captures; -use util::nodemap::{DefIdMap, FxHashMap}; +use crate::util::captures::Captures; +use crate::util::nodemap::{DefIdMap, FxHashMap}; /// A per-trait graph of impls in specialization order. At the moment, this /// graph forms a tree rooted with the trait itself, with all other nodes @@ -489,7 +489,7 @@ impl<'a, 'gcx, 'tcx> Ancestors { trait_def_id: DefId, ) -> impl Iterator> + Captures<'gcx> + Captures<'tcx> + 'a { self.flat_map(move |node| { - use ty::AssociatedKind::*; + use crate::ty::AssociatedKind::*; node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) { | (Const, Const) | (Method, Method) diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 2f5df022218fe..c5cc9e8b40182 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -1,9 +1,9 @@ use chalk_engine; use smallvec::SmallVec; -use traits; -use traits::project::Normalized; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use ty::{self, Lift, TyCtxt}; +use crate::traits; +use crate::traits::project::Normalized; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::{self, Lift, TyCtxt}; use syntax::symbol::InternedString; use std::fmt; @@ -163,7 +163,7 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::WhereClause::*; + use crate::traits::WhereClause::*; // Bypass ppaux because it does not print out anonymous regions. fn write_region_name<'tcx>( @@ -206,7 +206,7 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { impl<'tcx> fmt::Display for traits::WellFormed<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::WellFormed::*; + use crate::traits::WellFormed::*; match self { Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref), @@ -217,7 +217,7 @@ impl<'tcx> fmt::Display for traits::WellFormed<'tcx> { impl<'tcx> fmt::Display for traits::FromEnv<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::FromEnv::*; + use crate::traits::FromEnv::*; match self { Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref), @@ -228,7 +228,7 @@ impl<'tcx> fmt::Display for traits::FromEnv<'tcx> { impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::DomainGoal::*; + use crate::traits::DomainGoal::*; match self { Holds(wc) => write!(fmt, "{}", wc), @@ -246,7 +246,7 @@ impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { impl fmt::Display for traits::QuantifierKind { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::QuantifierKind::*; + use crate::traits::QuantifierKind::*; match self { Universal => write!(fmt, "forall"), @@ -361,7 +361,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { impl<'tcx> fmt::Display for traits::Goal<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::GoalKind::*; + use crate::traits::GoalKind::*; match self { Implies(hypotheses, goal) => { @@ -420,7 +420,7 @@ impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> { impl<'tcx> fmt::Display for traits::Clause<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::Clause::*; + use crate::traits::Clause::*; match self { Implies(clause) => write!(fmt, "{}", clause), diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 5b7ba5386725e..67c919ac91610 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -1,10 +1,10 @@ -use hir; -use hir::def_id::DefId; -use traits::specialize::specialization_graph::NodeItem; -use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; -use ty::outlives::Component; -use ty::subst::{Kind, Subst, Substs}; -use util::nodemap::FxHashSet; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::traits::specialize::specialization_graph::NodeItem; +use crate::ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; +use crate::ty::outlives::Component; +use crate::ty::subst::{Kind, Subst, Substs}; +use crate::util::nodemap::FxHashSet; use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized}; diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs index 34b94d4217d8b..07fa441bb8076 100644 --- a/src/librustc/ty/_match.rs +++ b/src/librustc/ty/_match.rs @@ -1,6 +1,6 @@ -use ty::{self, Ty, TyCtxt}; -use ty::error::TypeError; -use ty::relate::{self, Relate, TypeRelation, RelateResult}; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::error::TypeError; +use crate::ty::relate::{self, Relate, TypeRelation, RelateResult}; /// A type "A" *matches* "B" if the fresh types in B could be /// substituted with values so as to make it equal to A. Matching is diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 117112c0c75f4..68e7bd6e16abe 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -1,7 +1,7 @@ -use hir; -use hir::def_id::DefId; -use ty::{self, Ty, TyCtxt}; -use ty::subst::Substs; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::subst::Substs; /// Represents coercing a value to a different type of value. diff --git a/src/librustc/ty/binding.rs b/src/librustc/ty/binding.rs index 2ab14642406b1..1290141b0a6b0 100644 --- a/src/librustc/ty/binding.rs +++ b/src/librustc/ty/binding.rs @@ -1,6 +1,6 @@ -use hir::BindingAnnotation::*; -use hir::BindingAnnotation; -use hir::Mutability; +use crate::hir::BindingAnnotation::*; +use crate::hir::BindingAnnotation; +use crate::hir::Mutability; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum BindingMode { diff --git a/src/librustc/ty/cast.rs b/src/librustc/ty/cast.rs index 0f067de3649bf..0b2112f42d595 100644 --- a/src/librustc/ty/cast.rs +++ b/src/librustc/ty/cast.rs @@ -1,7 +1,7 @@ // Helpers for handling cast expressions, used in both // typeck and codegen. -use ty::{self, Ty}; +use crate::ty::{self, Ty}; use syntax::ast; diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index e0e4d9c362a6c..c9775b1029315 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -6,15 +6,15 @@ // The functionality in here is shared between persisting to crate metadata and // persisting to incr. comp. caches. -use hir::def_id::{DefId, CrateNum}; -use infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; +use crate::hir::def_id::{DefId, CrateNum}; +use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use rustc_data_structures::fx::FxHashMap; -use rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; +use crate::rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; use std::hash::Hash; use std::intrinsics; -use ty::{self, Ty, TyCtxt}; -use ty::subst::Substs; -use mir::interpret::Allocation; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::subst::Substs; +use crate::mir::interpret::Allocation; /// The shorthand encoding uses an enum's variant index `usize` /// and is offset by this value so it never matches a real variant. @@ -283,7 +283,7 @@ macro_rules! implement_ty_decoder { use $crate::ty::codec::*; use $crate::ty::subst::Substs; use $crate::hir::def_id::{CrateNum}; - use rustc_serialize::{Decoder, SpecializedDecoder}; + use crate::rustc_serialize::{Decoder, SpecializedDecoder}; use std::borrow::Cow; impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> { diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs index 3741f4051b896..1bb6386728917 100644 --- a/src/librustc/ty/constness.rs +++ b/src/librustc/ty/constness.rs @@ -1,9 +1,9 @@ -use ty::query::Providers; -use hir::def_id::DefId; -use hir; -use ty::TyCtxt; +use crate::ty::query::Providers; +use crate::hir::def_id::DefId; +use crate::hir; +use crate::ty::TyCtxt; use syntax_pos::symbol::Symbol; -use hir::map::blocks::FnLikeNode; +use crate::hir::map::blocks::FnLikeNode; use syntax::attr; impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b379b5ba02494..140c772256d3f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1,48 +1,48 @@ //! type context book-keeping -use dep_graph::DepGraph; -use dep_graph::{DepNode, DepConstructor}; -use errors::DiagnosticBuilder; -use session::Session; -use session::config::{BorrowckMode, OutputFilenames}; -use session::config::CrateType; -use middle; -use hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node}; -use hir::def::{Def, Export}; -use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; -use hir::map as hir_map; -use hir::map::DefPathHash; -use lint::{self, Lint}; -use ich::{StableHashingContext, NodeIdHashingMode}; -use infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; -use infer::outlives::free_region_map::FreeRegionMap; -use middle::cstore::CrateStoreDyn; -use middle::cstore::EncodedMetadata; -use middle::lang_items; -use middle::resolve_lifetime::{self, ObjectLifetimeDefault}; -use middle::stability; -use mir::{self, Mir, interpret, ProjectionKind}; -use mir::interpret::Allocation; -use ty::subst::{Kind, Substs, Subst}; -use ty::ReprOptions; -use traits; -use traits::{Clause, Clauses, GoalKind, Goal, Goals}; -use ty::{self, Ty, TypeAndMut}; -use ty::{TyS, TyKind, List}; -use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst}; -use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}; -use ty::RegionKind; -use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; -use ty::TyKind::*; -use ty::GenericParamDefKind; -use ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx}; -use ty::query; -use ty::steal::Steal; -use ty::subst::{UserSubsts, UnpackedKind}; -use ty::{BoundVar, BindingMode}; -use ty::CanonicalPolyFnSig; -use util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap}; -use util::nodemap::{FxHashMap, FxHashSet}; +use crate::dep_graph::DepGraph; +use crate::dep_graph::{DepNode, DepConstructor}; +use crate::errors::DiagnosticBuilder; +use crate::session::Session; +use crate::session::config::{BorrowckMode, OutputFilenames}; +use crate::session::config::CrateType; +use crate::middle; +use crate::hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node}; +use crate::hir::def::{Def, Export}; +use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; +use crate::hir::map as hir_map; +use crate::hir::map::DefPathHash; +use crate::lint::{self, Lint}; +use crate::ich::{StableHashingContext, NodeIdHashingMode}; +use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; +use crate::infer::outlives::free_region_map::FreeRegionMap; +use crate::middle::cstore::CrateStoreDyn; +use crate::middle::cstore::EncodedMetadata; +use crate::middle::lang_items; +use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; +use crate::middle::stability; +use crate::mir::{self, Mir, interpret, ProjectionKind}; +use crate::mir::interpret::Allocation; +use crate::ty::subst::{Kind, Substs, Subst}; +use crate::ty::ReprOptions; +use crate::traits; +use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals}; +use crate::ty::{self, Ty, TypeAndMut}; +use crate::ty::{TyS, TyKind, List}; +use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst}; +use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}; +use crate::ty::RegionKind; +use crate::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; +use crate::ty::TyKind::*; +use crate::ty::GenericParamDefKind; +use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx}; +use crate::ty::query; +use crate::ty::steal::Steal; +use crate::ty::subst::{UserSubsts, UnpackedKind}; +use crate::ty::{BoundVar, BindingMode}; +use crate::ty::CanonicalPolyFnSig; +use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::interner::HashInterner; use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, @@ -73,7 +73,7 @@ use syntax::feature_gate; use syntax::symbol::{Symbol, keywords, InternedString}; use syntax_pos::Span; -use hir; +use crate::hir; pub struct AllArenas<'tcx> { pub global: WorkerLocal>, @@ -1822,18 +1822,18 @@ pub mod tls { use std::marker::PhantomData; use std::ptr; use syntax_pos; - use ty::query; - use errors::{Diagnostic, TRACK_DIAGNOSTICS}; + use crate::ty::query; + use crate::errors::{Diagnostic, TRACK_DIAGNOSTICS}; use rustc_data_structures::OnDrop; use rustc_data_structures::sync::{self, Lrc, Lock}; use rustc_data_structures::thin_vec::ThinVec; - use dep_graph::TaskDeps; + use crate::dep_graph::TaskDeps; #[cfg(not(parallel_compiler))] use std::cell::Cell; #[cfg(parallel_compiler)] - use rayon_core; + use rustc_rayon_core as rayon_core; /// This is the implicit state of rustc. It contains the current /// TyCtxt and query. It is updated when creating a local interner or @@ -2114,8 +2114,8 @@ macro_rules! sty_debug_print { // variable names. #[allow(non_snake_case)] mod inner { - use ty::{self, TyCtxt}; - use ty::context::Interned; + use crate::ty::{self, TyCtxt}; + use crate::ty::context::Interned; #[derive(Copy, Clone)] struct DebugStat { diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs index da7e021b2d54b..0431afcc76c9e 100644 --- a/src/librustc/ty/erase_regions.rs +++ b/src/librustc/ty/erase_regions.rs @@ -1,5 +1,5 @@ -use ty::{self, Ty, TyCtxt, TypeFlags}; -use ty::fold::{TypeFolder, TypeFoldable}; +use crate::ty::{self, Ty, TyCtxt, TypeFlags}; +use crate::ty::fold::{TypeFolder, TypeFoldable}; pub(super) fn provide(providers: &mut ty::query::Providers<'_>) { *providers = ty::query::Providers { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index f444013e2a3bd..d0c9677ea6ecb 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -1,13 +1,13 @@ -use hir::def_id::DefId; -use ty::{self, Region, Ty, TyCtxt}; +use crate::hir::def_id::DefId; +use crate::ty::{self, Region, Ty, TyCtxt}; use std::borrow::Cow; use std::fmt; use rustc_target::spec::abi; use syntax::ast; -use errors::{Applicability, DiagnosticBuilder}; +use crate::errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; -use hir; +use crate::hir; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct ExpectedFound { diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 2b41fc4fe341f..59ab4561f2c87 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -1,12 +1,12 @@ -use hir::def_id::DefId; -use ich::StableHashingContext; +use crate::hir::def_id::DefId; +use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, HashStable}; use std::fmt::Debug; use std::hash::Hash; use std::mem; use syntax::ast; -use ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt}; use self::SimplifiedTypeGen::*; diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 4fa13a01d5a92..25ec3e49cdf67 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -1,5 +1,5 @@ -use ty::subst::Substs; -use ty::{self, Ty, TypeFlags, TypeFoldable}; +use crate::ty::subst::Substs; +use crate::ty::{self, Ty, TypeFlags, TypeFoldable}; #[derive(Debug)] pub struct FlagComputation { diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 28b6f010ce09c..306c69666e596 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -29,12 +29,12 @@ //! These methods return true to indicate that the visitor has found what it is looking for //! and does not need to visit anything else. -use hir::def_id::DefId; -use ty::{self, Binder, Ty, TyCtxt, TypeFlags}; +use crate::hir::def_id::DefId; +use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags}; use std::collections::BTreeMap; use std::fmt; -use util::nodemap::FxHashSet; +use crate::util::nodemap::FxHashSet; /// The TypeFoldable trait is implemented for every type that can be folded. /// Basically, every type that has a corresponding method in TypeFolder. diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs index 41fd88607e893..73b7d74d9dafe 100644 --- a/src/librustc/ty/inhabitedness/def_id_forest.rs +++ b/src/librustc/ty/inhabitedness/def_id_forest.rs @@ -1,8 +1,8 @@ use std::mem; use smallvec::SmallVec; use syntax::ast::CRATE_NODE_ID; -use ty::context::TyCtxt; -use ty::{DefId, DefIdTree}; +use crate::ty::context::TyCtxt; +use crate::ty::{DefId, DefIdTree}; /// Represents a forest of DefIds closed under the ancestor relation. That is, /// if a DefId representing a module is contained in the forest then all diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 6dfc9681cfd86..601ffe70eec18 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -1,8 +1,8 @@ -use ty::context::TyCtxt; -use ty::{AdtDef, VariantDef, FieldDef, Ty, TyS}; -use ty::{self, DefId, Substs}; -use ty::{AdtKind, Visibility}; -use ty::TyKind::*; +use crate::ty::context::TyCtxt; +use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS}; +use crate::ty::{self, DefId, Substs}; +use crate::ty::{AdtKind, Visibility}; +use crate::ty::TyKind::*; pub use self::def_id_forest::DefIdForest; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index bc43fedef0f34..e4fe93d5deaea 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -1,9 +1,9 @@ -use hir::Unsafety; -use hir::def_id::DefId; -use ty::{self, Ty, PolyFnSig, TypeFoldable, Substs, TyCtxt}; -use traits; +use crate::hir::Unsafety; +use crate::hir::def_id::DefId; +use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, Substs, TyCtxt}; +use crate::traits; use rustc_target::spec::abi::Abi; -use util::ppaux; +use crate::util::ppaux; use std::fmt; use std::iter; @@ -141,7 +141,7 @@ impl<'tcx> InstanceDef<'tcx> { &self, tcx: TyCtxt<'a, 'tcx, 'tcx> ) -> bool { - use hir::map::DefPathData; + use crate::hir::map::DefPathData; let def_id = match *self { ty::InstanceDef::Item(def_id) => def_id, ty::InstanceDef::DropGlue(_, Some(_)) => return false, diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index adb7e1fb3e322..f89e50d696945 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -1,8 +1,8 @@ -use hir; -use hir::map::DefPathData; -use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use ty::{self, DefIdTree, Ty, TyCtxt}; -use middle::cstore::{ExternCrate, ExternCrateSource}; +use crate::hir; +use crate::hir::map::DefPathData; +use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; +use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use syntax::ast; use syntax::symbol::{keywords, LocalInternedString, Symbol}; diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 1162bff852cbb..8401d0861cad2 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1,5 +1,5 @@ -use session::{self, DataTypeKind}; -use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions}; +use crate::session::{self, DataTypeKind}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions}; use syntax::ast::{self, Ident, IntTy, UintTy}; use syntax::attr; @@ -12,7 +12,7 @@ use std::iter; use std::mem; use std::ops::Bound; -use ich::StableHashingContext; +use crate::ich::StableHashingContext; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; @@ -1872,7 +1872,7 @@ impl<'a> HashStable> for Variants { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use ty::layout::Variants::*; + use crate::ty::layout::Variants::*; mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -1908,7 +1908,7 @@ impl<'a> HashStable> for FieldPlacement { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use ty::layout::FieldPlacement::*; + use crate::ty::layout::FieldPlacement::*; mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -1941,7 +1941,7 @@ impl<'a> HashStable> for Abi { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use ty::layout::Abi::*; + use crate::ty::layout::Abi::*; mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -1975,7 +1975,7 @@ impl<'a> HashStable> for Scalar { } } -impl_stable_hash_for!(struct ::ty::layout::LayoutDetails { +impl_stable_hash_for!(struct crate::ty::layout::LayoutDetails { variants, fields, abi, @@ -1983,7 +1983,7 @@ impl_stable_hash_for!(struct ::ty::layout::LayoutDetails { align }); -impl_stable_hash_for!(enum ::ty::layout::Integer { +impl_stable_hash_for!(enum crate::ty::layout::Integer { I8, I16, I32, @@ -1991,13 +1991,13 @@ impl_stable_hash_for!(enum ::ty::layout::Integer { I128 }); -impl_stable_hash_for!(enum ::ty::layout::Primitive { +impl_stable_hash_for!(enum crate::ty::layout::Primitive { Int(integer, signed), Float(fty), Pointer }); -impl_stable_hash_for!(struct ::ty::layout::AbiAndPrefAlign { +impl_stable_hash_for!(struct crate::ty::layout::AbiAndPrefAlign { abi, pref }); @@ -2023,7 +2023,7 @@ impl<'a, 'gcx> HashStable> for LayoutError<'gcx> fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use ty::layout::LayoutError::*; + use crate::ty::layout::LayoutError::*; mem::discriminant(self).hash_stable(hcx, hasher); match *self { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c9089428b2324..60e3ac673a0a0 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -4,31 +4,31 @@ pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::fold::TypeFoldable; -use hir::{map as hir_map, FreevarMap, GlobMap, TraitMap}; -use hir::Node; -use hir::def::{Def, CtorKind, ExportMap}; -use hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use hir::map::DefPathData; +use crate::hir::{map as hir_map, FreevarMap, GlobMap, TraitMap}; +use crate::hir::Node; +use crate::hir::def::{Def, CtorKind, ExportMap}; +use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::hir::map::DefPathData; use rustc_data_structures::svh::Svh; -use ich::Fingerprint; -use ich::StableHashingContext; -use infer::canonical::Canonical; -use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; -use middle::resolve_lifetime::ObjectLifetimeDefault; -use mir::Mir; -use mir::interpret::{GlobalId, ErrorHandled}; -use mir::GeneratorLayout; -use session::CrateDisambiguator; -use traits::{self, Reveal}; -use ty; -use ty::layout::VariantIdx; -use ty::subst::{Subst, Substs}; -use ty::util::{IntTypeExt, Discr}; -use ty::walk::TypeWalker; -use util::captures::Captures; -use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; +use crate::ich::Fingerprint; +use crate::ich::StableHashingContext; +use crate::infer::canonical::Canonical; +use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; +use crate::middle::resolve_lifetime::ObjectLifetimeDefault; +use crate::mir::Mir; +use crate::mir::interpret::{GlobalId, ErrorHandled}; +use crate::mir::GeneratorLayout; +use crate::session::CrateDisambiguator; +use crate::traits::{self, Reveal}; +use crate::ty; +use crate::ty::layout::VariantIdx; +use crate::ty::subst::{Subst, Substs}; +use crate::ty::util::{IntTypeExt, Discr}; +use crate::ty::walk::TypeWalker; +use crate::util::captures::Captures; +use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use arena::SyncDroplessArena; -use session::DataTypeKind; +use crate::session::DataTypeKind; use serialize::{self, Encodable, Encoder}; use std::cell::RefCell; @@ -50,7 +50,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, HashStable}; -use hir; +use crate::hir; pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST}; pub use self::sty::{FnSig, GenSig, CanonicalPolyFnSig, PolyFnSig, PolyGenSig}; @@ -2277,7 +2277,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { }) } else { info!("invalid enum discriminant: {:#?}", val); - ::mir::interpret::struct_error( + crate::mir::interpret::struct_error( tcx.at(tcx.def_span(expr_did)), "constant evaluation of enum discriminant resulted in non-integer", ).emit(); diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index ca2d5cd718c64..5b21ed5abd77b 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -3,7 +3,7 @@ // RFC for reference. use smallvec::SmallVec; -use ty::{self, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; #[derive(Debug)] pub enum Component<'tcx> { diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 495cce4d2feac..255e39eaccd6d 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -1,19 +1,19 @@ -use dep_graph::SerializedDepNodeIndex; -use dep_graph::DepNode; -use hir::def_id::{CrateNum, DefId, DefIndex}; -use mir::interpret::GlobalId; -use traits; -use traits::query::{ +use crate::dep_graph::SerializedDepNodeIndex; +use crate::dep_graph::DepNode; +use crate::hir::def_id::{CrateNum, DefId, DefIndex}; +use crate::mir::interpret::GlobalId; +use crate::traits; +use crate::traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, }; -use ty::{self, ParamEnvAnd, Ty, TyCtxt}; -use ty::subst::Substs; -use ty::query::queries; -use ty::query::Query; -use ty::query::QueryCache; -use util::profiling::ProfileCategory; +use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::subst::Substs; +use crate::ty::query::queries; +use crate::ty::query::Query; +use crate::ty::query::QueryCache; +use crate::util::profiling::ProfileCategory; use std::borrow::Cow; use std::hash::Hash; @@ -21,7 +21,7 @@ use std::fmt::Debug; use syntax_pos::symbol::InternedString; use rustc_data_structures::sync::Lock; use rustc_data_structures::stable_hasher::HashStable; -use ich::StableHashingContext; +use crate::ich::StableHashingContext; // Query configuration and description traits. @@ -901,7 +901,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: SerializedDepNodeIndex) -> Option { - let mir: Option<::mir::Mir<'tcx>> = tcx.queries.on_disk_cache + let mir: Option> = tcx.queries.on_disk_cache .try_load_query_result(tcx, id); mir.map(|x| tcx.alloc_mir(x)) } diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index abbf74a7761ef..0793366e6d479 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -1,25 +1,27 @@ #![allow(warnings)] use std::mem; +use std::process; +use std::{fmt, ptr}; + use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak}; use rustc_data_structures::OnDrop; use syntax_pos::Span; -use ty::tls; -use ty::query::Query; -use ty::query::plumbing::CycleError; + +use crate::ty::tls; +use crate::ty::query::Query; +use crate::ty::query::plumbing::CycleError; #[cfg(not(parallel_compiler))] -use ty::query::{ +use crate::ty::query::{ plumbing::TryGetJob, config::QueryDescription, }; -use ty::context::TyCtxt; -use std::process; -use std::{fmt, ptr}; +use crate::ty::context::TyCtxt; #[cfg(parallel_compiler)] use { - rayon_core, + rustc_rayon_core as rayon_core, parking_lot::{Mutex, Condvar}, std::sync::atomic::Ordering, std::thread, @@ -89,7 +91,7 @@ impl<'tcx> QueryJob<'tcx> { /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any /// query that means that there is a query cycle, thus this always running a cycle error. #[cfg(parallel_compiler)] - pub(super) fn await<'lcx>( + pub(super) fn r#await<'lcx>( &self, tcx: TyCtxt<'_, 'tcx, 'lcx>, span: Span, @@ -101,7 +103,7 @@ impl<'tcx> QueryJob<'tcx> { cycle: Lock::new(None), condvar: Condvar::new(), }); - self.latch.await(&waiter); + self.latch.r#await(&waiter); // FIXME: Get rid of this lock. We have ownership of the QueryWaiter // although another thread may still have a Lrc reference so we cannot // use Lrc::get_mut @@ -200,7 +202,7 @@ impl<'tcx> QueryLatch<'tcx> { } /// Awaits the caller on this latch by blocking the current thread. - fn await(&self, waiter: &Lrc>) { + fn r#await(&self, waiter: &Lrc>) { let mut info = self.info.lock(); if !info.complete { // We push the waiter on to the `waiters` list. It can be accessed inside diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index af6f5a00dee5c..f5eb7374cc19b 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -1,12 +1,12 @@ //! Defines the set of legal keys that can be used in queries. -use infer::canonical::Canonical; -use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; -use traits; -use ty::{self, Ty, TyCtxt}; -use ty::subst::Substs; -use ty::fast_reject::SimplifiedType; -use mir; +use crate::infer::canonical::Canonical; +use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; +use crate::traits; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::subst::Substs; +use crate::ty::fast_reject::SimplifiedType; +use crate::mir; use std::fmt::Debug; use std::hash::Hash; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index d4884e712b860..20a700bb58dd1 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -1,48 +1,48 @@ -use dep_graph::{DepConstructor, DepNode}; -use errors::DiagnosticBuilder; -use hir::def_id::{CrateNum, DefId, DefIndex}; -use hir::def::{Def, Export}; -use hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs}; +use crate::dep_graph::{DepConstructor, DepNode}; +use crate::errors::DiagnosticBuilder; +use crate::hir::def_id::{CrateNum, DefId, DefIndex}; +use crate::hir::def::{Def, Export}; +use crate::hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs}; use rustc_data_structures::svh::Svh; -use infer::canonical::{self, Canonical}; -use lint; -use middle::borrowck::BorrowCheckResult; -use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, ForeignModule}; -use middle::cstore::{NativeLibraryKind, DepKind, CrateSource}; -use middle::privacy::AccessLevels; -use middle::reachable::ReachableSet; -use middle::region; -use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault}; -use middle::stability::{self, DeprecationEntry}; -use middle::lib_features::LibFeatures; -use middle::lang_items::{LanguageItems, LangItem}; -use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; -use mir::interpret::{ConstEvalRawResult, ConstEvalResult}; -use mir::mono::CodegenUnit; -use mir; -use mir::interpret::GlobalId; -use session::{CompileResult, CrateDisambiguator}; -use session::config::{EntryFnType, OutputFilenames, OptLevel}; -use traits::{self, Vtable}; -use traits::query::{ +use crate::infer::canonical::{self, Canonical}; +use crate::lint; +use crate::middle::borrowck::BorrowCheckResult; +use crate::middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, ForeignModule}; +use crate::middle::cstore::{NativeLibraryKind, DepKind, CrateSource}; +use crate::middle::privacy::AccessLevels; +use crate::middle::reachable::ReachableSet; +use crate::middle::region; +use crate::middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault}; +use crate::middle::stability::{self, DeprecationEntry}; +use crate::middle::lib_features::LibFeatures; +use crate::middle::lang_items::{LanguageItems, LangItem}; +use crate::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; +use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult}; +use crate::mir::mono::CodegenUnit; +use crate::mir; +use crate::mir::interpret::GlobalId; +use crate::session::{CompileResult, CrateDisambiguator}; +use crate::session::config::{EntryFnType, OutputFilenames, OptLevel}; +use crate::traits::{self, Vtable}; +use crate::traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, NoSolution, }; -use traits::query::method_autoderef::MethodAutoderefStepsResult; -use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; -use traits::query::normalize::NormalizationResult; -use traits::query::outlives_bounds::OutlivesBound; -use traits::specialization_graph; -use traits::Clauses; -use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; -use ty::steal::Steal; -use ty::subst::Substs; -use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet}; -use util::common::{ErrorReported}; -use util::profiling::ProfileCategory::*; -use session::Session; +use crate::traits::query::method_autoderef::MethodAutoderefStepsResult; +use crate::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; +use crate::traits::query::normalize::NormalizationResult; +use crate::traits::query::outlives_bounds::OutlivesBound; +use crate::traits::specialization_graph; +use crate::traits::Clauses; +use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::steal::Steal; +use crate::ty::subst::Substs; +use crate::util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet}; +use crate::util::common::{ErrorReported}; +use crate::util::profiling::ProfileCategory::*; +use crate::session::Session; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::indexed_vec::IndexVec; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index a3f49de0d078b..9c9bc0f6aa11c 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -1,28 +1,28 @@ -use dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; -use errors::Diagnostic; -use hir; -use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; -use hir::map::definitions::DefPathHash; -use ich::{CachingSourceMapView, Fingerprint}; -use mir::{self, interpret}; -use mir::interpret::{AllocDecodingSession, AllocDecodingState}; +use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; +use crate::errors::Diagnostic; +use crate::hir; +use crate::hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; +use crate::hir::map::definitions::DefPathHash; +use crate::ich::{CachingSourceMapView, Fingerprint}; +use crate::mir::{self, interpret}; +use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, +use crate::rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, SpecializedDecoder, SpecializedEncoder, UseSpecializedDecodable, UseSpecializedEncodable}; -use session::{CrateDisambiguator, Session}; +use crate::session::{CrateDisambiguator, Session}; use std::mem; use syntax::ast::NodeId; use syntax::source_map::{SourceMap, StableSourceFileId}; use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile}; use syntax_pos::hygiene::{Mark, SyntaxContext, ExpnInfo}; -use ty; -use ty::codec::{self as ty_codec, TyDecoder, TyEncoder}; -use ty::context::TyCtxt; -use util::common::time; +use crate::ty; +use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder}; +use crate::ty::context::TyCtxt; +use crate::util::common::time; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; @@ -202,7 +202,7 @@ impl<'sess> OnDiskCache<'sess> { let mut query_result_index = EncodedQueryResultIndex::new(); time(tcx.sess, "encode query results", || { - use ty::query::queries::*; + use crate::ty::query::queries::*; let enc = &mut encoder; let qri = &mut query_result_index; @@ -225,11 +225,11 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::, _>(tcx, enc, qri)?; // const eval is special, it only encodes successfully evaluated constants - use ty::query::QueryAccessors; + use crate::ty::query::QueryAccessors; let cache = const_eval::query_cache(tcx).borrow(); assert!(cache.active.is_empty()); for (key, entry) in cache.results.iter() { - use ty::query::config::QueryDescription; + use crate::ty::query::config::QueryDescription; if const_eval::cache_on_disk(tcx, key.clone()) { if let Ok(ref value) = entry.value { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); @@ -777,7 +777,7 @@ impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E> value: &V) -> Result<(), E::Error> { - use ty::codec::TyEncoder; + use crate::ty::codec::TyEncoder; let start_pos = self.position(); tag.encode(self)?; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 69bff8d25b024..a26b21a1059fe 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -2,19 +2,19 @@ //! that generate the actual methods on tcx which find and execute the //! provider, manage the caches, and so forth. -use dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; -use errors::DiagnosticBuilder; -use errors::Level; -use errors::Diagnostic; -use errors::FatalError; -use ty::tls; -use ty::{TyCtxt}; -use ty::query::Query; -use ty::query::config::{QueryConfig, QueryDescription}; -use ty::query::job::{QueryJob, QueryResult, QueryInfo}; -use ty::item_path; - -use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg}; +use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; +use crate::errors::DiagnosticBuilder; +use crate::errors::Level; +use crate::errors::Diagnostic; +use crate::errors::FatalError; +use crate::ty::tls; +use crate::ty::{TyCtxt}; +use crate::ty::query::Query; +use crate::ty::query::config::{QueryConfig, QueryDescription}; +use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo}; +use crate::ty::item_path; + +use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg}; use rustc_data_structures::fx::{FxHashMap}; use rustc_data_structures::sync::{Lrc, Lock}; @@ -160,7 +160,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { // thread #[cfg(parallel_compiler)] { - if let Err(cycle) = job.await(tcx, span) { + if let Err(cycle) = job.r#await(tcx, span) { return TryGetJob::JobCompleted(Err(cycle)); } } @@ -367,7 +367,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Fast path for when incr. comp. is off. `to_dep_node` is // expensive for some DepKinds. if !self.dep_graph.is_fully_enabled() { - let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null); + let null_dep_node = DepNode::new_no_params(crate::dep_graph::DepKind::Null); return Ok(self.force_query_with_job::(key, job, null_dep_node).0); } @@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { dep_node_index: DepNodeIndex, ) { use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; - use ich::Fingerprint; + use crate::ich::Fingerprint; assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) == self.dep_graph.prev_fingerprint_of(dep_node), @@ -566,7 +566,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.dep_graph.mark_loaded_from_cache(dep_node_index, false); } - if dep_node.kind != ::dep_graph::DepKind::Null { + if dep_node.kind != crate::dep_graph::DepKind::Null { if unlikely!(!diagnostics.is_empty()) { self.queries.on_disk_cache .store_diagnostics(dep_node_index, diagnostics); @@ -698,13 +698,13 @@ macro_rules! define_queries_inner { #[cfg(parallel_compiler)] use ty::query::job::QueryResult; use rustc_data_structures::sync::Lock; - use { + use crate::{ rustc_data_structures::stable_hasher::HashStable, rustc_data_structures::stable_hasher::StableHasherResult, rustc_data_structures::stable_hasher::StableHasher, ich::StableHashingContext }; - use util::profiling::ProfileCategory; + use crate::util::profiling::ProfileCategory; define_queries_struct! { tcx: $tcx, @@ -947,7 +947,7 @@ macro_rules! define_queries_inner { #[allow(unused)] #[inline(always)] fn to_dep_node(tcx: TyCtxt<'_, $tcx, '_>, key: &Self::Key) -> DepNode { - use dep_graph::DepConstructor::*; + use crate::dep_graph::DepConstructor::*; DepNode::new(tcx, $node(*key)) } @@ -1127,7 +1127,7 @@ macro_rules! define_provider_struct { pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, dep_node: &DepNode) -> bool { - use hir::def_id::LOCAL_CRATE; + use crate::hir::def_id::LOCAL_CRATE; // We must avoid ever having to call force_from_dep_node() for a // DepNode::CodegenUnit: @@ -1167,7 +1167,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, macro_rules! force { ($query:ident, $key:expr) => { { - tcx.force_query::<::ty::query::queries::$query<'_>>($key, DUMMY_SP, *dep_node); + tcx.force_query::>($key, DUMMY_SP, *dep_node); } } }; @@ -1437,8 +1437,8 @@ macro_rules! impl_load_from_cache { // Check whether the query invocation corresponding to the given // DepNode is eligible for on-disk-caching. pub fn cache_on_disk(&self, tcx: TyCtxt<'_, '_, '_>) -> bool { - use ty::query::queries; - use ty::query::QueryDescription; + use crate::ty::query::queries; + use crate::ty::query::QueryDescription; match self.kind { $(DepKind::$dep_kind => { diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index 3f84f1bc78972..11f55208d6e48 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -1,4 +1,4 @@ -use ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt}; use syntax::symbol::Symbol; diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index a16d6fea74c0b..3dbd0dc1d97f7 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -4,18 +4,18 @@ //! types or regions but can be other things. Examples of type relations are //! subtyping, type equality, etc. -use hir::def_id::DefId; -use ty::subst::{Kind, UnpackedKind, Substs}; -use ty::{self, Ty, TyCtxt, TypeFoldable}; -use ty::error::{ExpectedFound, TypeError}; -use mir::interpret::GlobalId; -use util::common::ErrorReported; +use crate::hir::def_id::DefId; +use crate::ty::subst::{Kind, UnpackedKind, Substs}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +use crate::ty::error::{ExpectedFound, TypeError}; +use crate::mir::interpret::GlobalId; +use crate::util::common::ErrorReported; use syntax_pos::DUMMY_SP; use std::rc::Rc; use std::iter; use rustc_target::spec::abi; -use hir as ast; -use traits; +use crate::hir as ast; +use crate::traits; pub type RelateResult<'tcx, T> = Result>; @@ -588,7 +588,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { let tcx = relation.tcx(); let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| { - use ty::ExistentialPredicate::*; + use crate::ty::ExistentialPredicate::*; match (*ep_a, *ep_b) { (Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)), (Projection(ref a), Projection(ref b)) => Ok(Projection(relation.relate(a, b)?)), @@ -746,7 +746,7 @@ impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> { ) -> RelateResult<'tcx, traits::WhereClause<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a { - use traits::WhereClause::*; + use crate::traits::WhereClause::*; match (a, b) { (Implemented(a_pred), Implemented(b_pred)) => { Ok(Implemented(relation.relate(a_pred, b_pred)?)) @@ -783,7 +783,7 @@ impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> { ) -> RelateResult<'tcx, traits::WellFormed<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a { - use traits::WellFormed::*; + use crate::traits::WellFormed::*; match (a, b) { (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)), (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)), @@ -800,7 +800,7 @@ impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> { ) -> RelateResult<'tcx, traits::FromEnv<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a { - use traits::FromEnv::*; + use crate::traits::FromEnv::*; match (a, b) { (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)), (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)), @@ -817,7 +817,7 @@ impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> { ) -> RelateResult<'tcx, traits::DomainGoal<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a { - use traits::DomainGoal::*; + use crate::traits::DomainGoal::*; match (a, b) { (Holds(a_wc), Holds(b_wc)) => Ok(Holds(relation.relate(a_wc, b_wc)?)), (WellFormed(a_wf), WellFormed(b_wf)) => Ok(WellFormed(relation.relate(a_wf, b_wf)?)), @@ -840,7 +840,7 @@ impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> { ) -> RelateResult<'tcx, traits::Goal<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a { - use traits::GoalKind::*; + use crate::traits::GoalKind::*; match (a, b) { (Implies(a_clauses, a_goal), Implies(b_clauses, b_goal)) => { let clauses = relation.relate(a_clauses, b_clauses)?; @@ -904,7 +904,7 @@ impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> { ) -> RelateResult<'tcx, traits::Clause<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a { - use traits::Clause::*; + use crate::traits::Clause::*; match (a, b) { (Implies(a_clause), Implies(b_clause)) => { let clause = relation.relate(a_clause, b_clause)?; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 28f5a65374d98..62a49238ebf3d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -3,13 +3,13 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. -use mir::ProjectionKind; -use mir::interpret::ConstValue; -use ty::{self, Lift, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::mir::ProjectionKind; +use crate::mir::interpret::ConstValue; +use crate::ty::{self, Lift, Ty, TyCtxt}; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use smallvec::SmallVec; -use mir::interpret; +use crate::mir::interpret; use std::rc::Rc; @@ -23,35 +23,35 @@ CloneTypeFoldableAndLiftImpls! { (), bool, usize, - ::ty::layout::VariantIdx, + crate::ty::layout::VariantIdx, u64, String, - ::middle::region::Scope, + crate::middle::region::Scope, ::syntax::ast::FloatTy, ::syntax::ast::NodeId, ::syntax_pos::symbol::Symbol, - ::hir::def::Def, - ::hir::def_id::DefId, - ::hir::InlineAsm, - ::hir::MatchSource, - ::hir::Mutability, - ::hir::Unsafety, + crate::hir::def::Def, + crate::hir::def_id::DefId, + crate::hir::InlineAsm, + crate::hir::MatchSource, + crate::hir::Mutability, + crate::hir::Unsafety, ::rustc_target::spec::abi::Abi, - ::mir::Local, - ::mir::Promoted, - ::traits::Reveal, - ::ty::adjustment::AutoBorrowMutability, - ::ty::AdtKind, + crate::mir::Local, + crate::mir::Promoted, + crate::traits::Reveal, + crate::ty::adjustment::AutoBorrowMutability, + crate::ty::AdtKind, // Including `BoundRegion` is a *bit* dubious, but direct // references to bound region appear in `ty::Error`, and aren't // really meant to be folded. In general, we can only fold a fully // general `Region`. - ::ty::BoundRegion, - ::ty::ClosureKind, - ::ty::IntVarValue, - ::ty::ParamTy, - ::ty::UniverseIndex, - ::ty::Variance, + crate::ty::BoundRegion, + crate::ty::ClosureKind, + crate::ty::IntVarValue, + crate::ty::ParamTy, + crate::ty::UniverseIndex, + crate::ty::Variance, ::syntax_pos::Span, } @@ -421,7 +421,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound { impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { type Lifted = ty::error::TypeError<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - use ty::error::TypeError::*; + use crate::ty::error::TypeError::*; Some(match *self { Mismatch => Mismatch, @@ -651,7 +651,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use ty::InstanceDef::*; + use crate::ty::InstanceDef::*; Self { substs: self.substs.fold_with(folder), def: match self.def { @@ -682,7 +682,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { } fn super_visit_with>(&self, visitor: &mut V) -> bool { - use ty::InstanceDef::*; + use crate::ty::InstanceDef::*; self.substs.visit_with(visitor) || match self.def { Item(did) | VtableShim(did) | Intrinsic(did) | Virtual(did, _) => { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 671a0fc2d5d7a..790cc15ca17b6 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1,17 +1,17 @@ //! This module contains `TyKind` and its major components. -use hir; -use hir::def_id::DefId; -use infer::canonical::Canonical; -use mir::interpret::ConstValue; -use middle::region; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::infer::canonical::Canonical; +use crate::mir::interpret::ConstValue; +use crate::middle::region; use polonius_engine::Atom; use rustc_data_structures::indexed_vec::Idx; -use ty::subst::{Substs, Subst, Kind, UnpackedKind}; -use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; -use ty::{List, TyS, ParamEnvAnd, ParamEnv}; -use util::captures::Captures; -use mir::interpret::{Scalar, Pointer}; +use crate::ty::subst::{Substs, Subst, Kind, UnpackedKind}; +use crate::ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv}; +use crate::util::captures::Captures; +use crate::mir::interpret::{Scalar, Pointer}; use smallvec::SmallVec; use std::iter; @@ -550,7 +550,7 @@ impl<'a, 'gcx, 'tcx> ExistentialPredicate<'tcx> { impl<'a, 'gcx, 'tcx> Binder> { pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { - use ty::ToPredicate; + use crate::ty::ToPredicate; match *self.skip_binder() { ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(), ExistentialPredicate::Projection(p) => diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 64e7af815b4bf..d7c322d0f8402 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -1,9 +1,9 @@ // Type substitutions. -use hir::def_id::DefId; -use infer::canonical::Canonical; -use ty::{self, Lift, List, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::hir::def_id::DefId; +use crate::infer::canonical::Canonical; +use crate::ty::{self, Lift, List, Ty, TyCtxt}; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use serialize::{self, Encodable, Encoder, Decodable, Decoder}; use syntax_pos::{Span, DUMMY_SP}; diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 37ec560d6c19f..5429a2504b97b 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -1,11 +1,11 @@ -use hir; -use hir::def_id::DefId; -use hir::map::DefPathHash; -use ich::{self, StableHashingContext}; -use traits::specialization_graph; -use ty::fast_reject; -use ty::fold::TypeFoldable; -use ty::{Ty, TyCtxt}; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::hir::map::DefPathHash; +use crate::ich::{self, StableHashingContext}; +use crate::traits::specialization_graph; +use crate::ty::fast_reject; +use crate::ty::fold::TypeFoldable; +use crate::ty::{Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 2fe47b2f032f8..61544932b4329 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -1,18 +1,18 @@ //! misc. type-system utilities too small to deserve their own file -use hir::def::Def; -use hir::def_id::DefId; -use hir::map::DefPathData; -use hir::{self, Node}; -use ich::NodeIdHashingMode; -use traits::{self, ObligationCause}; -use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; -use ty::subst::{Subst, Substs, UnpackedKind}; -use ty::query::TyCtxtAt; -use ty::TyKind::*; -use ty::layout::{Integer, IntegerExt}; -use util::common::ErrorReported; -use middle::lang_items; +use crate::hir::def::Def; +use crate::hir::def_id::DefId; +use crate::hir::map::DefPathData; +use crate::hir::{self, Node}; +use crate::ich::NodeIdHashingMode; +use crate::traits::{self, ObligationCause}; +use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; +use crate::ty::subst::{Subst, Substs, UnpackedKind}; +use crate::ty::query::TyCtxtAt; +use crate::ty::TyKind::*; +use crate::ty::layout::{Integer, IntegerExt}; +use crate::util::common::ErrorReported; +use crate::middle::lang_items; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 6887d092fcd62..126f5290af513 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -1,7 +1,7 @@ //! An iterator over the type substructure. //! WARNING: this does not keep track of the region depth. -use ty::{self, Ty}; +use crate::ty::{self, Ty}; use smallvec::{self, SmallVec}; // The TypeWalker's stack is hot enough that it's worth going to some effort to diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index ef68394029680..2aae953c1c40a 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -1,12 +1,12 @@ -use hir::def_id::DefId; -use infer::InferCtxt; -use ty::subst::Substs; -use traits; -use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::hir::def_id::DefId; +use crate::infer::InferCtxt; +use crate::ty::subst::Substs; +use crate::traits; +use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use std::iter::once; use syntax::ast; use syntax_pos::Span; -use middle::lang_items; +use crate::middle::lang_items; /// Returns the set of obligations needed to make `ty` well-formed. /// If `ty` contains unresolved inference variables, this may include diff --git a/src/librustc/util/bug.rs b/src/librustc/util/bug.rs index 7698f5ece98cc..02ddfab6d826e 100644 --- a/src/librustc/util/bug.rs +++ b/src/librustc/util/bug.rs @@ -1,6 +1,6 @@ // These functions are used by macro expansion for bug! and span_bug! -use ty::tls; +use crate::ty::tls; use std::fmt; use syntax_pos::{Span, MultiSpan}; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index cc0ca165053d3..f6743ed75d92e 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -12,10 +12,10 @@ use std::time::{Duration, Instant}; use std::sync::mpsc::{Sender}; use syntax_pos::{SpanData}; -use ty::TyCtxt; -use dep_graph::{DepNode}; +use crate::ty::TyCtxt; +use crate::dep_graph::{DepNode}; use lazy_static; -use session::Session; +use crate::session::Session; // The name of the associated type for `Fn` return types pub const FN_OUTPUT_NAME: &str = "Output"; diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index fe6ab075a1a8a..6969b2f872ade 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -1,7 +1,7 @@ //! An efficient hash map for node IDs -use hir::def_id::DefId; -use hir::{HirId, ItemLocalId}; +use crate::hir::def_id::DefId; +use crate::hir::{HirId, ItemLocalId}; use syntax::ast; pub use rustc_data_structures::fx::FxHashMap; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 51e9192cd290d..2cd82d44af3aa 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,15 +1,15 @@ -use hir::def_id::DefId; -use hir::map::definitions::DefPathData; -use middle::region; -use ty::subst::{self, Subst}; -use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; -use ty::{Bool, Char, Adt}; -use ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; -use ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; -use ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; -use ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; -use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}; -use util::nodemap::FxHashSet; +use crate::hir::def_id::DefId; +use crate::hir::map::definitions::DefPathData; +use crate::middle::region; +use crate::ty::subst::{self, Subst}; +use crate::ty::{BrAnon, BrEnv, BrFresh, BrNamed}; +use crate::ty::{Bool, Char, Adt}; +use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; +use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; +use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; +use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}; +use crate::util::nodemap::FxHashSet; use std::cell::Cell; use std::fmt; @@ -18,7 +18,7 @@ use std::usize; use rustc_target::spec::abi::Abi; use syntax::ast::CRATE_NODE_ID; use syntax::symbol::{Symbol, InternedString}; -use hir; +use crate::hir; /// The "region highlights" are used to control region printing during /// specific error messages. When a "region highlight" is enabled, it diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index d31a06d6cb82d..0e03946f82a5c 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -1,4 +1,4 @@ -use session::config::Options; +use crate::session::config::Options; use std::fs; use std::io::{self, StderrLock, Write}; From 346dc37aee60f995e6c1548ce7f406d5500f8570 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Feb 2019 20:07:45 +0100 Subject: [PATCH 0619/1064] fix str mutating through a ptr derived from &self --- src/libcore/str/mod.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3cb3936038093..b01cb688ee5c6 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1757,7 +1757,7 @@ mod traits { } #[inline] unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { - let ptr = slice.as_ptr().add(self.start); + let ptr = slice.as_mut_ptr().add(self.start); let len = self.end - self.start; super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len)) } @@ -1821,7 +1821,7 @@ mod traits { } #[inline] unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { - let ptr = slice.as_ptr(); + let ptr = slice.as_mut_ptr(); super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end)) } #[inline] @@ -1883,7 +1883,7 @@ mod traits { } #[inline] unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { - let ptr = slice.as_ptr().add(self.start); + let ptr = slice.as_mut_ptr().add(self.start); let len = slice.len() - self.start; super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len)) } @@ -2213,6 +2213,22 @@ impl str { self as *const str as *const u8 } + /// Converts a mutable string slice to a raw pointer. + /// + /// As string slices are a slice of bytes, the raw pointer points to a + /// [`u8`]. This pointer will be pointing to the first byte of the string + /// slice. + /// + /// It is your responsibility to make sure that the string slice only gets + /// modified in a way that it remains valid UTF-8. + /// + /// [`u8`]: primitive.u8.html + #[unstable(feature = "str_as_mut_ptr", issue = "0")] + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut u8 { + self as *mut str as *mut u8 + } + /// Returns a subslice of `str`. /// /// This is the non-panicking alternative to indexing the `str`. Returns From 55917ba0e74c44d13bd0ffc9cd134f8379959f28 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 3 Feb 2019 14:42:29 -0800 Subject: [PATCH 0620/1064] Update cargo --- Cargo.lock | 30 +++++++++++++++--------------- src/tools/cargo | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b52f2094584ce..4cea89ea0415f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,8 +75,8 @@ dependencies = [ "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -237,7 +237,7 @@ dependencies = [ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -530,7 +530,7 @@ name = "crates-io" version = "0.23.0" dependencies = [ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -841,16 +841,16 @@ dependencies = [ [[package]] name = "failure" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1677,8 +1677,8 @@ name = "opener" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2254,7 +2254,7 @@ dependencies = [ "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3014,7 +3014,7 @@ name = "rustfix" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3032,7 +3032,7 @@ dependencies = [ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3818,7 +3818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3997,8 +3997,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" -"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" -"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" diff --git a/src/tools/cargo b/src/tools/cargo index 245818076052d..4e74e2fc09085 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 245818076052dd7178f5bb7585f5aec5b6c1e03e +Subproject commit 4e74e2fc0908524d17735c768067117d3e84ee9c From 8d6e5fc20f1c69f453ea7a786a6e47b2da85ed28 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 4 Feb 2019 16:27:09 +0100 Subject: [PATCH 0621/1064] rustc: partially HirIdify --- src/librustc/infer/error_reporting/mod.rs | 18 ++++++++---------- src/librustc/infer/error_reporting/note.rs | 6 ++---- src/librustc/middle/reachable.rs | 4 ++-- src/librustc/middle/resolve_lifetime.rs | 8 ++++---- src/librustc/traits/error_reporting.rs | 3 ++- src/librustc/traits/util.rs | 6 +++--- src/librustc/ty/item_path.rs | 4 ++-- src/librustc/ty/mod.rs | 12 ++++++------ src/librustc/util/ppaux.rs | 2 +- 9 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 66e4cd49c807f..dda079e295ec5 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -56,7 +56,6 @@ use hir::def_id::DefId; use hir::Node; use middle::region; use std::{cmp, fmt}; -use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; use traits::{ObligationCause, ObligationCauseCode}; use ty::error::TypeError; @@ -182,8 +181,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let cm = self.sess.source_map(); let scope = region.free_region_binding_scope(self); - let node = self.hir().as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID); - let tag = match self.hir().find(node) { + let node = self.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID); + let tag = match self.hir().find_by_hir_id(node) { Some(Node::Block(_)) | Some(Node::Expr(_)) => "body", Some(Node::Item(it)) => Self::item_scope_tag(&it), Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it), @@ -192,7 +191,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }; let (prefix, span) = match *region { ty::ReEarlyBound(ref br) => { - let mut sp = cm.def_span(self.hir().span(node)); + let mut sp = cm.def_span(self.hir().span_by_hir_id(node)); if let Some(param) = self.hir() .get_generics(scope) .and_then(|generics| generics.get_named(&br.name)) @@ -205,7 +204,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { bound_region: ty::BoundRegion::BrNamed(_, ref name), .. }) => { - let mut sp = cm.def_span(self.hir().span(node)); + let mut sp = cm.def_span(self.hir().span_by_hir_id(node)); if let Some(param) = self.hir() .get_generics(scope) .and_then(|generics| generics.get_named(&name)) @@ -217,15 +216,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::ReFree(ref fr) => match fr.bound_region { ty::BrAnon(idx) => ( format!("the anonymous lifetime #{} defined on", idx + 1), - self.hir().span(node), + self.hir().span_by_hir_id(node), ), ty::BrFresh(_) => ( "an anonymous lifetime defined on".to_owned(), - self.hir().span(node), + self.hir().span_by_hir_id(node), ), _ => ( format!("the lifetime {} as defined on", fr.bound_region), - cm.def_span(self.hir().span(node)), + cm.def_span(self.hir().span_by_hir_id(node)), ), }, _ => bug!(), @@ -1451,8 +1450,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { format!(" for lifetime parameter `{}` in coherence check", name) } infer::UpvarRegion(ref upvar_id, _) => { - let var_node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id); - let var_name = self.tcx.hir().name(var_node_id); + let var_name = self.tcx.hir().name_by_hir_id(upvar_id.var_path.hir_id); format!(" for capture of `{}` by closure", var_name) } infer::NLL(..) => bug!("NLL variable found in lexical phase"), diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index e45a4b17cdd9c..397081292b91f 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -31,8 +31,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "...so that reference does not outlive borrowed content"); } infer::ReborrowUpvar(span, ref upvar_id) => { - let var_node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id); - let var_name = self.tcx.hir().name(var_node_id); + let var_name = self.tcx.hir().name_by_hir_id(upvar_id.var_path.hir_id); err.span_note(span, &format!("...so that closure can access `{}`", var_name)); } @@ -164,8 +163,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err } infer::ReborrowUpvar(span, ref upvar_id) => { - let var_node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id); - let var_name = self.tcx.hir().name(var_node_id); + let var_name = self.tcx.hir().name_by_hir_id(upvar_id.var_path.hir_id); let mut err = struct_span_err!(self.tcx.sess, span, E0313, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 10deca836fff3..96f07ef835141 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -177,8 +177,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // Check the impl. If the generics on the self // type of the impl require inlining, this method // does too. - let impl_node_id = self.tcx.hir().as_local_node_id(impl_did).unwrap(); - match self.tcx.hir().expect_item(impl_node_id).node { + let impl_hir_id = self.tcx.hir().as_local_hir_id(impl_did).unwrap(); + match self.tcx.hir().expect_item_by_hir_id(impl_hir_id).node { hir::ItemKind::Impl(..) => { let generics = self.tcx.generics_of(impl_did); generics.requires_monomorphization(self.tcx) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 34db30a1706b9..c9d0ddc3fb4e4 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1248,12 +1248,12 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) { } => { // FIXME (#24278): non-hygienic comparison if let Some(def) = lifetimes.get(&hir::ParamName::Plain(label.modern())) { - let node_id = tcx.hir().as_local_node_id(def.id().unwrap()).unwrap(); + let hir_id = tcx.hir().as_local_hir_id(def.id().unwrap()).unwrap(); signal_shadowing_problem( tcx, label.name, - original_lifetime(tcx.hir().span(node_id)), + original_lifetime(tcx.hir().span_by_hir_id(hir_id)), shadower_label(label.span), ); return; @@ -2593,12 +2593,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ref lifetimes, s, .. } => { if let Some(&def) = lifetimes.get(¶m.name.modern()) { - let node_id = self.tcx.hir().as_local_node_id(def.id().unwrap()).unwrap(); + let hir_id = self.tcx.hir().as_local_hir_id(def.id().unwrap()).unwrap(); signal_shadowing_problem( self.tcx, param.name.ident().name, - original_lifetime(self.tcx.hir().span(node_id)), + original_lifetime(self.tcx.hir().span_by_hir_id(hir_id)), shadower_lifetime(¶m), ); return; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index ea3ea59c7613f..c026ca6ec8f1e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1035,7 +1035,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ).collect::>()) } Node::StructCtor(ref variant_data) => { - (self.tcx.sess.source_map().def_span(self.tcx.hir().span(variant_data.id())), + (self.tcx.sess.source_map().def_span( + self.tcx.hir().span_by_hir_id(variant_data.hir_id())), vec![ArgKind::empty(); variant_data.fields().len()]) } _ => panic!("non-FnLike node found: {:?}", node), diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 5b7ba5386725e..8e8deeb7a6bde 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -525,9 +525,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn impl_is_default(self, node_item_def_id: DefId) -> bool { - match self.hir().as_local_node_id(node_item_def_id) { - Some(node_id) => { - let item = self.hir().expect_item(node_id); + match self.hir().as_local_hir_id(node_item_def_id) { + Some(hir_id) => { + let item = self.hir().expect_item_by_hir_id(hir_id); if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.node { defaultness.is_default() } else { diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index adb7e1fb3e322..c7b81824113b8 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -461,8 +461,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // only occur very early in the compiler pipeline. let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); - let node_id = self.hir().as_local_node_id(impl_def_id).unwrap(); - let item = self.hir().expect_item(node_id); + let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap(); + let item = self.hir().expect_item_by_hir_id(hir_id); let span_str = self.sess.source_map().span_to_string(item.span); buffer.push(&format!("", span_str)); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c9089428b2324..263724998d7d5 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2939,8 +2939,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Get the attributes of a definition. pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> { - if let Some(id) = self.hir().as_local_node_id(did) { - Attributes::Borrowed(self.hir().attrs(id)) + if let Some(id) = self.hir().as_local_hir_id(did) { + Attributes::Borrowed(self.hir().attrs_by_hir_id(id)) } else { Attributes::Owned(self.item_attrs(did)) } @@ -2991,8 +2991,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// with the name of the crate containing the impl. pub fn span_of_impl(self, impl_did: DefId) -> Result { if impl_did.is_local() { - let node_id = self.hir().as_local_node_id(impl_did).unwrap(); - Ok(self.hir().span(node_id)) + let hir_id = self.hir().as_local_hir_id(impl_did).unwrap(); + Ok(self.hir().span_by_hir_id(hir_id)) } else { Err(self.crate_name(impl_did.krate)) } @@ -3110,8 +3110,8 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Lrc> { - let id = tcx.hir().as_local_node_id(def_id).unwrap(); - let item = tcx.hir().expect_item(id); + let id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let item = tcx.hir().expect_item_by_hir_id(id); let vec: Vec<_> = match item.node { hir::ItemKind::Trait(.., ref trait_item_refs) => { trait_item_refs.iter() diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 51e9192cd290d..5830a0bab2743 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -801,7 +801,7 @@ impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, - ty::tls::with(|tcx| tcx.hir().name(tcx.hir().hir_to_node_id(self.var_path.hir_id))), + ty::tls::with(|tcx| tcx.hir().name_by_hir_id(self.var_path.hir_id)), self.closure_expr_id) } } From 44752c260bc338999c74e8b2324ef26f489c8632 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 4 Feb 2019 16:35:52 +0100 Subject: [PATCH 0622/1064] mir: partially HirIdify --- src/librustc_mir/borrow_check/error_reporting.rs | 4 ++-- src/librustc_mir/borrow_check/move_errors.rs | 5 ++--- .../nll/region_infer/error_reporting/region_name.rs | 6 +++--- .../nll/region_infer/error_reporting/var_name.rs | 7 +++---- src/librustc_mir/borrow_check/nll/universal_regions.rs | 5 ++--- src/librustc_mir/build/mod.rs | 6 +++--- src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 8 ++++---- 8 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index b070031756798..248ac84237a2c 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -833,13 +833,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { format!("`{}` would have to be valid for `{}`...", name, region_name), ); - if let Some(fn_node_id) = self.infcx.tcx.hir().as_local_node_id(self.mir_def_id) { + if let Some(fn_hir_id) = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id) { err.span_label( drop_span, format!( "...but `{}` will be dropped here, when the function `{}` returns", name, - self.infcx.tcx.hir().name(fn_node_id), + self.infcx.tcx.hir().name_by_hir_id(fn_hir_id), ), ); diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index 8539b5c26cee8..52003f01f9c3e 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -308,9 +308,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { let upvar_decl = &self.mir.upvar_decls[field.index()]; let upvar_hir_id = upvar_decl.var_hir_id.assert_crate_local(); - let upvar_node_id = - self.infcx.tcx.hir().hir_to_node_id(upvar_hir_id); - let upvar_span = self.infcx.tcx.hir().span(upvar_node_id); + let upvar_span = self.infcx.tcx.hir().span_by_hir_id( + upvar_hir_id); diag.span_label(upvar_span, "captured outer variable"); break; } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index bff8015511242..f164cfb08766b 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -10,7 +10,7 @@ use rustc::ty::subst::{Substs, UnpackedKind}; use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt}; use rustc::util::ppaux::RegionHighlightMode; use rustc_errors::DiagnosticBuilder; -use syntax::ast::{Name, DUMMY_NODE_ID}; +use syntax::ast::Name; use syntax::symbol::keywords; use syntax_pos::Span; use syntax_pos::symbol::InternedString; @@ -293,9 +293,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { name: &InternedString, ) -> Span { let scope = error_region.free_region_binding_scope(tcx); - let node = tcx.hir().as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID); + let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID); - let span = tcx.sess.source_map().def_span(tcx.hir().span(node)); + let span = tcx.sess.source_map().def_span(tcx.hir().span_by_hir_id(node)); if let Some(param) = tcx.hir() .get_generics(scope) .and_then(|generics| generics.get_named(name)) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs index c2f2e99c0a55b..b6dfb2da77994 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs @@ -71,11 +71,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { upvar_index: usize, ) -> (Symbol, Span) { let upvar_hir_id = mir.upvar_decls[upvar_index].var_hir_id.assert_crate_local(); - let upvar_node_id = tcx.hir().hir_to_node_id(upvar_hir_id); - debug!("get_upvar_name_and_span_for_region: upvar_node_id={:?}", upvar_node_id); + debug!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id); - let upvar_name = tcx.hir().name(upvar_node_id); - let upvar_span = tcx.hir().span(upvar_node_id); + let upvar_name = tcx.hir().name_by_hir_id(upvar_hir_id); + let upvar_span = tcx.hir().span_by_hir_id(upvar_hir_id); debug!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}", upvar_name, upvar_span); diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 0a214e60bdd78..ad4444e0df24c 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -771,9 +771,8 @@ fn for_each_late_bound_region_defined_on<'tcx>( owner: fn_def_id.index, local_id: *late_bound, }; - let region_node_id = tcx.hir().hir_to_node_id(hir_id); - let name = tcx.hir().name(region_node_id).as_interned_str(); - let region_def_id = tcx.hir().local_def_id(region_node_id); + let name = tcx.hir().name_by_hir_id(hir_id).as_interned_str(); + let region_def_id = tcx.hir().local_def_id_from_hir_id(hir_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, bound_region: ty::BoundRegion::BrNamed(region_def_id, name), diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f38648fda0e36..b1a745b6980fb 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -64,8 +64,8 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t ) => { (*body_id, ty.span) } - Node::AnonConst(hir::AnonConst { body, id, .. }) => { - (*body, tcx.hir().span(*id)) + Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => { + (*body, tcx.hir().span_by_hir_id(*hir_id)) } _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def_id), @@ -114,7 +114,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t let self_arg; if let Some(ref fn_decl) = tcx.hir().fn_decl(owner_id) { let ty_hir_id = fn_decl.inputs[index].hir_id; - let ty_span = tcx.hir().span(tcx.hir().hir_to_node_id(ty_hir_id)); + let ty_span = tcx.hir().span_by_hir_id(ty_hir_id); opt_ty_info = Some(ty_span); self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() { match fn_decl.implicit_self { diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 518ae978ae17a..466bdd1d25587 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -48,7 +48,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, for (index, stmt) in stmts.iter().enumerate() { let hir_id = stmt.hir_id; let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id); - let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.id)); + let stmt_span = StatementSpan(cx.tcx.hir().span_by_hir_id(hir_id)); match stmt.node { hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index e713ab17c3af5..57cbc7002acba 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -450,8 +450,8 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if recursion_depth > *tcx.sess.recursion_limit.get() { let error = format!("reached the recursion limit while instantiating `{}`", instance); - if let Some(node_id) = tcx.hir().as_local_node_id(def_id) { - tcx.sess.span_fatal(tcx.hir().span(node_id), &error); + if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { + tcx.sess.span_fatal(tcx.hir().span_by_hir_id(hir_id), &error); } else { tcx.sess.fatal(&error); } @@ -482,8 +482,8 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let instance_name = instance.to_string(); let msg = format!("reached the type-length limit while instantiating `{:.64}...`", instance_name); - let mut diag = if let Some(node_id) = tcx.hir().as_local_node_id(instance.def_id()) { - tcx.sess.struct_span_fatal(tcx.hir().span(node_id), &msg) + let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) { + tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg) } else { tcx.sess.struct_fatal(&msg) }; From 6da9129b3676e88029e682faed5dbfaf4572758a Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 4 Feb 2019 16:45:04 +0100 Subject: [PATCH 0623/1064] typeck: partially HirIdify --- src/librustc/hir/map/mod.rs | 8 ++++++-- src/librustc_metadata/encoder.rs | 2 +- src/librustc_typeck/astconv.rs | 13 +++++++------ src/librustc_typeck/check/compare_method.rs | 6 +++--- src/librustc_typeck/check/dropck.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 14 +++++++------- src/librustc_typeck/check/upvar.rs | 3 +-- src/librustc_typeck/check/wfcheck.rs | 10 +++++----- src/librustc_typeck/check/writeback.rs | 10 ++++------ src/librustc_typeck/coherence/builtin.rs | 8 ++++---- src/librustc_typeck/collect.rs | 12 ++++++------ src/librustc_typeck/variance/mod.rs | 6 +++--- 12 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d35306ba353a3..58c0380816bcc 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -931,7 +931,9 @@ impl<'hir> Map<'hir> { } } - pub fn expect_variant_data(&self, id: NodeId) -> &'hir VariantData { + pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData { + let id = self.hir_to_node_id(id); // FIXME(@ljedrz): remove when possible + match self.find(id) { Some(Node::Item(i)) => { match i.node { @@ -946,7 +948,9 @@ impl<'hir> Map<'hir> { } } - pub fn expect_variant(&self, id: NodeId) -> &'hir Variant { + pub fn expect_variant(&self, id: HirId) -> &'hir Variant { + let id = self.hir_to_node_id(id); // FIXME(@ljedrz): remove when possible + match self.find(id) { Some(Node::Variant(variant)) => variant, _ => bug!("expected variant, found {}", self.node_to_string(id)), diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 3b212f3b7472d..6963c54b50358 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -673,7 +673,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let def_id = field.did; debug!("IsolatedEncoder::encode_field({:?})", def_id); - let variant_id = tcx.hir().as_local_node_id(variant.did).unwrap(); + let variant_id = tcx.hir().as_local_hir_id(variant.did).unwrap(); let variant_data = tcx.hir().expect_variant_data(variant_id); Entry { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8da0b6dcbeac3..210a3886e92a0 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -111,7 +111,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { { let tcx = self.tcx(); let lifetime_name = |def_id| { - tcx.hir().name(tcx.hir().as_local_node_id(def_id).unwrap()).as_interned_str() + tcx.hir().name_by_hir_id(tcx.hir().as_local_hir_id(def_id).unwrap()).as_interned_str() }; let r = match tcx.named_region(lifetime.hir_id) { @@ -1682,12 +1682,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); - let node_id = tcx.hir().as_local_node_id(did).unwrap(); - let item_id = tcx.hir().get_parent_node(node_id); - let item_def_id = tcx.hir().local_def_id(item_id); + let hir_id = tcx.hir().as_local_hir_id(did).unwrap(); + let item_id = tcx.hir().get_parent_node_by_hir_id(hir_id); + let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id); let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)]; - tcx.mk_ty_param(index, tcx.hir().name(node_id).as_interned_str()) + let index = generics.param_def_id_to_index[ + &tcx.hir().local_def_id_from_hir_id(hir_id)]; + tcx.mk_ty_param(index, tcx.hir().name_by_hir_id(hir_id).as_interned_str()) } Def::SelfTy(_, Some(def_id)) => { // `Self` in impl (we know the concrete type). diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 0eb8d7d06b1f6..0cc5071dbdd4f 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -736,8 +736,8 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, in impl_m_type_params.zip(trait_m_type_params) { if impl_synthetic != trait_synthetic { - let impl_node_id = tcx.hir().as_local_node_id(impl_def_id).unwrap(); - let impl_span = tcx.hir().span(impl_node_id); + let impl_hir_id = tcx.hir().as_local_hir_id(impl_def_id).unwrap(); + let impl_span = tcx.hir().span_by_hir_id(impl_hir_id); let trait_span = tcx.def_span(trait_def_id); let mut err = struct_span_err!(tcx.sess, impl_span, @@ -840,7 +840,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match param.kind { GenericParamKind::Lifetime { .. } => None, GenericParamKind::Type { .. } => { - if param.id == impl_node_id { + if param.hir_id == impl_hir_id { Some(¶m.bounds) } else { None diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 60b5db0d12cc4..e210909127b2a 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -184,7 +184,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( // absent. So we report an error that the Drop impl injected a // predicate that is not present on the struct definition. - let self_type_node_id = tcx.hir().as_local_node_id(self_type_did).unwrap(); + let self_type_hir_id = tcx.hir().as_local_hir_id(self_type_did).unwrap(); let drop_impl_span = tcx.def_span(drop_impl_did); @@ -216,7 +216,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( // repeated `contains` calls. if !assumptions_in_impl_context.contains(&predicate) { - let item_span = tcx.hir().span(self_type_node_id); + let item_span = tcx.hir().span_by_hir_id(self_type_hir_id); struct_span_err!( tcx.sess, drop_impl_span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3e2a9d720f1c1..bd45369f6014b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1883,14 +1883,14 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check for duplicate discriminant values if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) { let variant_did = def.variants[VariantIdx::new(i)].did; - let variant_i_node_id = tcx.hir().as_local_node_id(variant_did).unwrap(); - let variant_i = tcx.hir().expect_variant(variant_i_node_id); + let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap(); + let variant_i = tcx.hir().expect_variant(variant_i_hir_id); let i_span = match variant_i.node.disr_expr { - Some(ref expr) => tcx.hir().span(expr.id), - None => tcx.hir().span(variant_i_node_id) + Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id), + None => tcx.hir().span_by_hir_id(variant_i_hir_id) }; let span = match v.node.disr_expr { - Some(ref expr) => tcx.hir().span(expr.id), + Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id), None => v.span }; struct_span_err!(tcx.sess, span, E0081, @@ -5703,8 +5703,8 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }); for (&used, param) in types_used.iter().zip(types) { if !used { - let id = tcx.hir().as_local_node_id(param.def_id).unwrap(); - let span = tcx.hir().span(id); + let id = tcx.hir().as_local_hir_id(param.def_id).unwrap(); + let span = tcx.hir().span_by_hir_id(id); struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name) .span_label(span, "unused type parameter") .emit(); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index ffd7c2114e5ab..15ae0166b93cb 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -650,6 +650,5 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { } fn var_name(tcx: TyCtxt, var_hir_id: hir::HirId) -> ast::Name { - let var_node_id = tcx.hir().hir_to_node_id(var_hir_id); - tcx.hir().name(var_node_id) + tcx.hir().name_by_hir_id(var_hir_id) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 97881708b0a07..1206c8eb1eaa5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -62,11 +62,11 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - let item = tcx.hir().expect_item(node_id); + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let item = tcx.hir().expect_item_by_hir_id(hir_id); - debug!("check_item_well_formed(it.id={}, it.name={})", - item.id, + debug!("check_item_well_formed(it.hir_id={:?}, it.name={})", + item.hir_id, tcx.item_path_str(def_id)); match item.node { @@ -88,7 +88,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` hir::ItemKind::Impl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => { - let is_auto = tcx.impl_trait_ref(tcx.hir().local_def_id(item.id)) + let is_auto = tcx.impl_trait_ref(tcx.hir().local_def_id_from_hir_id(item.hir_id)) .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) { tcx.sess.span_err(item.span, "impls of auto traits cannot be default"); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 238b087fe32f8..29f531201e4d8 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -407,8 +407,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { if let ty::UserType::TypeOf(_, user_substs) = c_ty.value { if self.rustc_dump_user_substs { // This is a unit-testing mechanism. - let node_id = self.tcx().hir().hir_to_node_id(hir_id); - let span = self.tcx().hir().span(node_id); + let span = self.tcx().hir().span_by_hir_id(hir_id); // We need to buffer the errors in order to guarantee a consistent // order when emitting them. let err = self.tcx().sess.struct_span_err( @@ -739,15 +738,14 @@ impl Locatable for ast::NodeId { impl Locatable for DefIndex { fn to_span(&self, tcx: &TyCtxt) -> Span { - let node_id = tcx.hir().def_index_to_node_id(*self); - tcx.hir().span(node_id) + let hir_id = tcx.hir().def_index_to_hir_id(*self); + tcx.hir().span_by_hir_id(hir_id) } } impl Locatable for hir::HirId { fn to_span(&self, tcx: &TyCtxt) -> Span { - let node_id = tcx.hir().hir_to_node_id(*self); - tcx.hir().span(node_id) + tcx.hir().span_by_hir_id(*self) } } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index bd2373d1659c9..3ec08f221f576 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -76,7 +76,7 @@ fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) { debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); - let impl_node_id = if let Some(n) = tcx.hir().as_local_node_id(impl_did) { + let impl_hir_id = if let Some(n) = tcx.hir().as_local_hir_id(impl_did) { n } else { debug!("visit_implementation_of_copy(): impl not in this crate"); @@ -87,7 +87,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); - let span = tcx.hir().span(impl_node_id); + let span = tcx.hir().span_by_hir_id(impl_hir_id); let param_env = tcx.param_env(impl_did); assert!(!self_type.has_escaping_bound_vars()); @@ -97,7 +97,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: match param_env.can_type_implement_copy(tcx, self_type) { Ok(()) => {} Err(CopyImplementationError::InfrigingFields(fields)) => { - let item = tcx.hir().expect_item(impl_node_id); + let item = tcx.hir().expect_item_by_hir_id(impl_hir_id); let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.node { tr.path.span } else { @@ -114,7 +114,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: err.emit() } Err(CopyImplementationError::NotAnAdt) => { - let item = tcx.hir().expect_item(impl_node_id); + let item = tcx.hir().expect_item_by_hir_id(impl_hir_id); let span = if let ItemKind::Impl(.., ref ty, _) = item.node { ty.span } else { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 9dc74c5d63a4e..f5e50678040f6 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -737,8 +737,8 @@ fn super_predicates_of<'a, 'tcx>( } fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::TraitDef { - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - let item = tcx.hir().expect_item(node_id); + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let item = tcx.hir().expect_item_by_hir_id(hir_id); let (is_auto, unsafety) = match item.node { hir::ItemKind::Trait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety), @@ -1509,8 +1509,8 @@ fn impl_trait_ref<'a, 'tcx>( ) -> Option> { let icx = ItemCtxt::new(tcx, def_id); - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - match tcx.hir().expect_item(node_id).node { + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + match tcx.hir().expect_item_by_hir_id(hir_id).node { hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => { opt_trait_ref.as_ref().map(|ast_trait_ref| { let selfty = tcx.type_of(def_id); @@ -1522,8 +1522,8 @@ fn impl_trait_ref<'a, 'tcx>( } fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> hir::ImplPolarity { - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - match tcx.hir().expect_item(node_id).node { + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + match tcx.hir().expect_item_by_hir_id(hir_id).node { hir::ItemKind::Impl(_, polarity, ..) => polarity, ref item => bug!("impl_polarity: {:?} not an impl", item), } diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index afb6a68482013..347422780d516 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -46,12 +46,12 @@ fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) -> Lrc> { - let id = tcx.hir().as_local_node_id(item_def_id).expect("expected local def-id"); + let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id"); let unsupported = || { // Variance not relevant. - span_bug!(tcx.hir().span(id), "asked to compute variance for wrong kind of item") + span_bug!(tcx.hir().span_by_hir_id(id), "asked to compute variance for wrong kind of item") }; - match tcx.hir().get(id) { + match tcx.hir().get_by_hir_id(id) { Node::Item(item) => match item.node { hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | From 113b7f7be15c49fcd0854ca53486e92f1badfdd6 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Mon, 4 Feb 2019 12:41:01 -0500 Subject: [PATCH 0624/1064] allow shorthand syntax for deprecation reason --- src/libsyntax/attr/builtin.rs | 125 +++++++++--------- src/libsyntax/attr/mod.rs | 4 + src/libsyntax/feature_gate.rs | 12 +- src/test/rustdoc/deprecated.rs | 5 + src/test/ui/deprecation/deprecation-sanity.rs | 6 + .../ui/deprecation/deprecation-sanity.stderr | 20 ++- src/test/ui/deprecation/invalid-literal.rs | 4 + .../ui/deprecation/invalid-literal.stderr | 8 ++ 8 files changed, 117 insertions(+), 67 deletions(-) create mode 100644 src/test/ui/deprecation/invalid-literal.rs create mode 100644 src/test/ui/deprecation/invalid-literal.stderr diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 08c7c617a7bef..7230a2922c420 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -592,81 +592,86 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, let diagnostic = &sess.span_diagnostic; 'outer: for attr in attrs_iter { - if attr.path != "deprecated" { - continue + if !attr.check_name("deprecated") { + continue; } - mark_used(attr); - if depr.is_some() { span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes"); break } - depr = if let Some(metas) = attr.meta_item_list() { - let get = |meta: &MetaItem, item: &mut Option| { - if item.is_some() { - handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); - return false - } - if let Some(v) = meta.value_str() { - *item = Some(v); - true - } else { - if let Some(lit) = meta.name_value_literal() { - handle_errors( - sess, - lit.span, - AttrError::UnsupportedLiteral( - "literal in `deprecated` \ - value must be a string", - lit.node.is_bytestr() - ), - ); - } else { - span_err!(diagnostic, meta.span, E0551, "incorrect meta item"); + let meta = attr.meta().unwrap(); + depr = match &meta.node { + MetaItemKind::Word => Some(Deprecation { since: None, note: None }), + MetaItemKind::NameValue(..) => { + meta.value_str().map(|note| { + Deprecation { since: None, note: Some(note) } + }) + } + MetaItemKind::List(list) => { + let get = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); + return false } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + if let Some(lit) = meta.name_value_literal() { + handle_errors( + sess, + lit.span, + AttrError::UnsupportedLiteral( + "literal in `deprecated` \ + value must be a string", + lit.node.is_bytestr() + ), + ); + } else { + span_err!(diagnostic, meta.span, E0551, "incorrect meta item"); + } - false - } - }; + false + } + }; - let mut since = None; - let mut note = None; - for meta in metas { - match &meta.node { - NestedMetaItemKind::MetaItem(mi) => { - match &*mi.name().as_str() { - "since" => if !get(mi, &mut since) { continue 'outer }, - "note" => if !get(mi, &mut note) { continue 'outer }, - _ => { - handle_errors( - sess, - meta.span, - AttrError::UnknownMetaItem(mi.name(), &["since", "note"]), - ); - continue 'outer + let mut since = None; + let mut note = None; + for meta in list { + match &meta.node { + NestedMetaItemKind::MetaItem(mi) => { + match &*mi.name().as_str() { + "since" => if !get(mi, &mut since) { continue 'outer }, + "note" => if !get(mi, &mut note) { continue 'outer }, + _ => { + handle_errors( + sess, + meta.span, + AttrError::UnknownMetaItem(mi.name(), &["since", "note"]), + ); + continue 'outer + } } } - } - NestedMetaItemKind::Literal(lit) => { - handle_errors( - sess, - lit.span, - AttrError::UnsupportedLiteral( - "item in `deprecated` must be a key/value pair", - false, - ), - ); - continue 'outer + NestedMetaItemKind::Literal(lit) => { + handle_errors( + sess, + lit.span, + AttrError::UnsupportedLiteral( + "item in `deprecated` must be a key/value pair", + false, + ), + ); + continue 'outer + } } } - } - Some(Deprecation {since: since, note: note}) - } else { - Some(Deprecation{since: None, note: None}) - } + Some(Deprecation { since, note }) + } + }; } depr diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 58be7c3e085c3..7e0342e1cba55 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -161,6 +161,10 @@ fn name_from_path(path: &Path) -> Name { } impl Attribute { + /// Returns `true` if the attribute's path matches the argument. If it matches, then the + /// attribute is marked as used. + /// + /// To check the attribute name without marking it used, use the `path` field directly. pub fn check_name(&self, name: &str) -> bool { let matches = self.path == name; if matches { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9dd17b420aa44..9a63a2c678b88 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1176,9 +1176,15 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu ("stable", Whitelisted, template!(List: r#"feature = "name", since = "version""#), Ungated), ("unstable", Whitelisted, template!(List: r#"feature = "name", reason = "...", issue = "N""#), Ungated), - ("deprecated", Normal, template!(Word, List: r#"/*opt*/ since = "version", - /*opt*/ note = "reason"#, - NameValueStr: "reason"), Ungated), + ("deprecated", + Normal, + template!( + Word, + List: r#"/*opt*/ since = "version", /*opt*/ note = "reason"#, + NameValueStr: "reason" + ), + Ungated + ), ("rustc_paren_sugar", Normal, template!(Word), Gated(Stability::Unstable, "unboxed_closures", diff --git a/src/test/rustdoc/deprecated.rs b/src/test/rustdoc/deprecated.rs index ca3f380ed2825..ecb74719d74cc 100644 --- a/src/test/rustdoc/deprecated.rs +++ b/src/test/rustdoc/deprecated.rs @@ -26,3 +26,8 @@ pub struct V; // 'Deprecated$' #[deprecated] pub struct W; + +// @matches deprecated/struct.X.html '//*[@class="stab deprecated"]' \ +// 'Deprecated: shorthand reason$' +#[deprecated = "shorthand reason"] +pub struct X; diff --git a/src/test/ui/deprecation/deprecation-sanity.rs b/src/test/ui/deprecation/deprecation-sanity.rs index 09bae0bdfb13e..a559908b792bb 100644 --- a/src/test/ui/deprecation/deprecation-sanity.rs +++ b/src/test/ui/deprecation/deprecation-sanity.rs @@ -15,6 +15,12 @@ mod bogus_attribute_types_1 { #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item fn f6() { } + + #[deprecated(note = b"test")] //~ ERROR literal in `deprecated` value must be a string + fn f7() { } + + #[deprecated("test")] //~ ERROR item in `deprecated` must be a key/value pair + fn f8() { } } #[deprecated(since = "a", note = "b")] diff --git a/src/test/ui/deprecation/deprecation-sanity.stderr b/src/test/ui/deprecation/deprecation-sanity.stderr index a8bfcc23cc8cc..a071a4fc10d51 100644 --- a/src/test/ui/deprecation/deprecation-sanity.stderr +++ b/src/test/ui/deprecation/deprecation-sanity.stderr @@ -28,19 +28,31 @@ error[E0551]: incorrect meta item LL | #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item | ^^^^^^^^ +error[E0565]: literal in `deprecated` value must be a string + --> $DIR/deprecation-sanity.rs:19:25 + | +LL | #[deprecated(note = b"test")] //~ ERROR literal in `deprecated` value must be a string + | ^^^^^^^ help: consider removing the prefix: `"test"` + +error[E0565]: item in `deprecated` must be a key/value pair + --> $DIR/deprecation-sanity.rs:22:18 + | +LL | #[deprecated("test")] //~ ERROR item in `deprecated` must be a key/value pair + | ^^^^^^ + error[E0550]: multiple deprecated attributes - --> $DIR/deprecation-sanity.rs:22:1 + --> $DIR/deprecation-sanity.rs:28:1 | LL | fn multiple1() { } //~ ERROR multiple deprecated attributes | ^^^^^^^^^^^^^^^^^^ error[E0538]: multiple 'since' items - --> $DIR/deprecation-sanity.rs:24:27 + --> $DIR/deprecation-sanity.rs:30:27 | LL | #[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items | ^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors -Some errors occurred: E0538, E0541, E0550, E0551. +Some errors occurred: E0538, E0541, E0550, E0551, E0565. For more information about an error, try `rustc --explain E0538`. diff --git a/src/test/ui/deprecation/invalid-literal.rs b/src/test/ui/deprecation/invalid-literal.rs new file mode 100644 index 0000000000000..7e0d8cdfc2f72 --- /dev/null +++ b/src/test/ui/deprecation/invalid-literal.rs @@ -0,0 +1,4 @@ +#[deprecated = b"test"] //~ ERROR attribute must be of the form +fn foo() {} + +fn main() {} diff --git a/src/test/ui/deprecation/invalid-literal.stderr b/src/test/ui/deprecation/invalid-literal.stderr new file mode 100644 index 0000000000000..f13d599c0b137 --- /dev/null +++ b/src/test/ui/deprecation/invalid-literal.stderr @@ -0,0 +1,8 @@ +error: attribute must be of the form `#[deprecated]` or `#[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason)]` or `#[deprecated = "reason"]` + --> $DIR/invalid-literal.rs:1:1 + | +LL | #[deprecated = b"test"] //~ ERROR attribute must be of the form + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 9204497c2999ce4a3df9802d48cb990be7ee1164 Mon Sep 17 00:00:00 2001 From: Patrick McCarter Date: Tue, 5 Feb 2019 15:36:31 -0500 Subject: [PATCH 0625/1064] Allow const assignment for int saturating_add() calls for #58030 --- src/libcore/num/mod.rs | 57 +++++++++++++++---- src/librustc/mir/interpret/mod.rs | 2 +- src/librustc_mir/interpret/intrinsics.rs | 29 +++++++++- src/librustc_mir/transform/qualify_consts.rs | 1 + .../transform/qualify_min_const_fn.rs | 1 + .../run-pass/const-int-saturating-arith.rs | 13 +++++ 6 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 src/test/run-pass/const-int-saturating-arith.rs diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f80f839282781..55de04db028e1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -882,17 +882,37 @@ $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[cfg(stage0)] pub fn saturating_add(self, rhs: Self) -> Self { - #[cfg(stage0)] match self.checked_add(rhs) { Some(x) => x, None if rhs >= 0 => Self::max_value(), None => Self::min_value(), } - #[cfg(not(stage0))] - { - intrinsics::saturating_add(self, rhs) - } + } + + } + + doc_comment! { + concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric +bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101); +assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT), +"::max_value());", +$EndFeature, " +```"), + + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[cfg(not(stage0))] + pub const fn saturating_add(self, rhs: Self) -> Self { + intrinsics::saturating_add(self, rhs) } } @@ -2753,16 +2773,33 @@ assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[cfg(stage0)] pub fn saturating_add(self, rhs: Self) -> Self { - #[cfg(stage0)] match self.checked_add(rhs) { Some(x) => x, None => Self::max_value(), } - #[cfg(not(stage0))] - { - intrinsics::saturating_add(self, rhs) - } + } + } + + doc_comment! { + concat!("Saturating integer addition. Computes `self + rhs`, saturating at +the numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101); +assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, " +```"), + + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[cfg(not(stage0))] + pub const fn saturating_add(self, rhs: Self) -> Self { + intrinsics::saturating_add(self, rhs) } } diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index e6a560b2ad7b6..4013cfb9558e1 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -418,4 +418,4 @@ pub fn truncate(value: u128, size: Size) -> u128 { let shift = 128 - size; // truncate (shift left to drop out leftover values, shift right to fill with zeroes) (value << shift) >> shift -} +} \ No newline at end of file diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index d8778dfeef7a1..64be3969640e5 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -4,7 +4,7 @@ use syntax::symbol::Symbol; use rustc::ty; -use rustc::ty::layout::{LayoutOf, Primitive}; +use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ EvalResult, EvalErrorKind, Scalar, @@ -122,6 +122,33 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> self.binop_with_overflow(bin_op, lhs, rhs, dest)?; } } + "saturating_add" => { + let l = self.read_immediate(args[0])?; + let r = self.read_immediate(args[1])?; + let (val, overflowed) = self.binary_op_imm(BinOp::Add, l, r)?; + if overflowed { + let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?; + let num_bits = l.layout.size.bits(); + let val = if l.layout.abi.is_signed() { + // For signed addition the saturated value depends on the sign of either term + if first_term & (1 << (num_bits-1)) == 0 { // signed term is positive + Scalar::from_uint((1u128 << (num_bits - 1)) - 1, Size::from_bits(num_bits)) // max signed val + } else { // signed term is negative + Scalar::from_uint(1u128 << (num_bits - 1), Size::from_bits(num_bits)) // min signed val + } + } else { + if num_bits == 128 { // General bit shift method causes overflow for u128 terms + Scalar::from_uint(u128::max_value(), Size::from_bits(128)) + } else { + Scalar::from_uint(u128::max_value() & ((1 << num_bits) - 1), + Size::from_bits(num_bits)) + } + }; + self.write_scalar(val, dest)?; + } else { + self.write_scalar(val, dest)?; + } + } "unchecked_shl" | "unchecked_shr" => { let l = self.read_immediate(args[0])?; let r = self.read_immediate(args[1])?; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2d941902debc3..ac75a95dbe0fa 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -820,6 +820,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" + | "saturating_add" // no need to check feature gates, intrinsics are only callable // from the libstd or with forever unstable feature gates => is_const_fn = true, diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 85bf1e70ebf42..bb7fe0dab548a 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -374,6 +374,7 @@ fn is_intrinsic_whitelisted(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool | "overflowing_add" // ~> .wrapping_add | "overflowing_sub" // ~> .wrapping_sub | "overflowing_mul" // ~> .wrapping_mul + | "saturating_add" // ~> .saturating_add | "unchecked_shl" // ~> .wrapping_shl | "unchecked_shr" // ~> .wrapping_shr | "rotate_left" // ~> .rotate_left diff --git a/src/test/run-pass/const-int-saturating-arith.rs b/src/test/run-pass/const-int-saturating-arith.rs new file mode 100644 index 0000000000000..3ff6a1fc08aa2 --- /dev/null +++ b/src/test/run-pass/const-int-saturating-arith.rs @@ -0,0 +1,13 @@ +const INT_U32_NO: u32 = (42 as u32).saturating_add(2); +const INT_U32: u32 = u32::max_value().saturating_add(1); +const INT_U128: u128 = u128::max_value().saturating_add(1); +const INT_I128: i128 = i128::max_value().saturating_add(1); +const INT_I128_NEG: i128 = i128::min_value().saturating_add(-1); + +fn main() { + assert_eq!(INT_U32_NO, 44); + assert_eq!(INT_U32, u32::max_value()); + assert_eq!(INT_U128, u128::max_value()); + assert_eq!(INT_I128, i128::max_value()); + assert_eq!(INT_I128_NEG, i128::min_value()); +} \ No newline at end of file From d371bcefb58d28caa585e77258747bcb0aba89b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Feb 2019 21:22:11 +0100 Subject: [PATCH 0626/1064] fix test case --- src/test/run-pass/panic-uninitialized-zeroed.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/run-pass/panic-uninitialized-zeroed.rs b/src/test/run-pass/panic-uninitialized-zeroed.rs index d47ff6c630d11..31c0d2994d415 100644 --- a/src/test/run-pass/panic-uninitialized-zeroed.rs +++ b/src/test/run-pass/panic-uninitialized-zeroed.rs @@ -36,7 +36,7 @@ fn main() { assert_eq!( panic::catch_unwind(|| { - mem::MaybeUninit::::uninitialized().into_inner() + mem::MaybeUninit::::uninitialized().into_initialized() }).err().and_then(|a| a.downcast_ref::().map(|s| { s == "Attempted to instantiate uninhabited type !" })), @@ -63,7 +63,7 @@ fn main() { assert_eq!( panic::catch_unwind(|| { - mem::MaybeUninit::::uninitialized().into_inner() + mem::MaybeUninit::::uninitialized().into_initialized() }).err().and_then(|a| a.downcast_ref::().map(|s| { s == "Attempted to instantiate uninhabited type Foo" })), @@ -90,7 +90,7 @@ fn main() { assert_eq!( panic::catch_unwind(|| { - mem::MaybeUninit::::uninitialized().into_inner() + mem::MaybeUninit::::uninitialized().into_initialized() }).err().and_then(|a| a.downcast_ref::().map(|s| { s == "Attempted to instantiate uninhabited type Bar" })), From 80c052bed76d7b7406e956747012bc8a929fe909 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Tue, 5 Feb 2019 15:52:54 +0000 Subject: [PATCH 0627/1064] Do not ICE in codegen given a extern_type static The layout of a extern_type static is unsized, but may pass the Well-Formed check in typeck. As a result, we cannot assume that a static is sized when generating the `Place` for an r-value. --- src/librustc_codegen_ssa/mir/place.rs | 19 ++++++++++++++++++- .../static-extern-type/Makefile | 5 +++++ .../static-extern-type/define-foo.c | 11 +++++++++++ .../static-extern-type/use-foo.rs | 14 ++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/test/run-make-fulldeps/static-extern-type/Makefile create mode 100644 src/test/run-make-fulldeps/static-extern-type/define-foo.c create mode 100644 src/test/run-make-fulldeps/static-extern-type/use-foo.rs diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index b10611e5ac797..596f97a038892 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -41,6 +41,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { } } + fn new_thin_place>( + bx: &mut Bx, + llval: V, + layout: TyLayout<'tcx>, + align: Align, + ) -> PlaceRef<'tcx, V> { + assert!(!bx.cx().type_has_metadata(layout.ty)); + PlaceRef { + llval, + llextra: None, + layout, + align + } + } + pub fn alloca>( bx: &mut Bx, layout: TyLayout<'tcx>, @@ -421,8 +436,10 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } mir::Place::Static(box mir::Static { def_id, ty }) => { + // NB: The layout of a static may be unsized as is the case when working + // with a static that is an extern_type. let layout = cx.layout_of(self.monomorphize(&ty)); - PlaceRef::new_sized(bx.get_static(def_id), layout, layout.align.abi) + PlaceRef::new_thin_place(bx, bx.get_static(def_id), layout, layout.align.abi) }, mir::Place::Projection(box mir::Projection { ref base, diff --git a/src/test/run-make-fulldeps/static-extern-type/Makefile b/src/test/run-make-fulldeps/static-extern-type/Makefile new file mode 100644 index 0000000000000..5879fc0ce7781 --- /dev/null +++ b/src/test/run-make-fulldeps/static-extern-type/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +all: $(call NATIVE_STATICLIB,define-foo) + $(RUSTC) -ldefine-foo use-foo.rs + $(call RUN,use-foo) || exit 1 diff --git a/src/test/run-make-fulldeps/static-extern-type/define-foo.c b/src/test/run-make-fulldeps/static-extern-type/define-foo.c new file mode 100644 index 0000000000000..39be5acfa1118 --- /dev/null +++ b/src/test/run-make-fulldeps/static-extern-type/define-foo.c @@ -0,0 +1,11 @@ +#include + +struct Foo { + uint8_t x; +}; + +struct Foo FOO = { 42 }; + +uint8_t bar(const struct Foo* foo) { + return foo->x; +} diff --git a/src/test/run-make-fulldeps/static-extern-type/use-foo.rs b/src/test/run-make-fulldeps/static-extern-type/use-foo.rs new file mode 100644 index 0000000000000..932b5b5944bc7 --- /dev/null +++ b/src/test/run-make-fulldeps/static-extern-type/use-foo.rs @@ -0,0 +1,14 @@ +#![feature(extern_types)] + +extern "C" { + type Foo; + static FOO: Foo; + fn bar(foo: *const Foo) -> u8; +} + +fn main() { + unsafe { + let foo = &FOO; + assert_eq!(bar(foo), 42); + } +} From b331b86d308d09398cf6202f367ea0f02babe523 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Feb 2019 22:26:30 +0100 Subject: [PATCH 0628/1064] extend box-maybe-uninit test --- src/test/codegen/box-maybe-uninit.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/codegen/box-maybe-uninit.rs b/src/test/codegen/box-maybe-uninit.rs index a7fb74c04731d..ad1d259a0da21 100644 --- a/src/test/codegen/box-maybe-uninit.rs +++ b/src/test/codegen/box-maybe-uninit.rs @@ -9,5 +9,8 @@ use std::mem::MaybeUninit; pub fn box_uninitialized() -> Box> { // CHECK-LABEL: @box_uninitialized // CHECK-NOT: store + // CHECK-NOT: alloca + // CHECK-NOT: memcpy + // CHECK-NOT: memset Box::new(MaybeUninit::uninitialized()) } From 9fcb1658ab13a7f722e4747c5a4b691291e88a3b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Feb 2019 15:20:55 +1100 Subject: [PATCH 0629/1064] Overhaul `syntax::fold::Folder`. This commit changes `syntax::fold::Folder` from a functional style (where most methods take a `T` and produce a new `T`) to a more imperative style (where most methods take and modify a `&mut T`), and renames it `syntax::mut_visit::MutVisitor`. The first benefit is speed. The functional style does not require any reallocations, due to the use of `P::map` and `MoveMap::move_{,flat_}map`. However, every field in the AST must be overwritten; even those fields that are unchanged are overwritten with the same value. This causes a lot of unnecessary memory writes. The imperative style reduces instruction counts by 1--3% across a wide range of workloads, particularly incremental workloads. The second benefit is conciseness; the imperative style is usually more concise. E.g. compare the old functional style: ``` fn fold_abc(&mut self, abc: ABC) { ABC { a: fold_a(abc.a), b: fold_b(abc.b), c: abc.c, } } ``` with the imperative style: ``` fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { visit_a(a); visit_b(b); } ``` (The reductions get larger in more complex examples.) Overall, the patch removes over 200 lines of code -- even though the new code has more comments -- and a lot of the remaining lines have fewer characters. Some notes: - The old style used methods called `fold_*`. The new style mostly uses methods called `visit_*`, but there are a few methods that map a `T` to something other than a `T`, which are called `flat_map_*` (`T` maps to multiple `T`s) or `filter_map_*` (`T` maps to 0 or 1 `T`s). - `move_map.rs`/`MoveMap`/`move_map`/`move_flat_map` are renamed `map_in_place.rs`/`MapInPlace`/`map_in_place`/`flat_map_in_place` to reflect their slightly changed signatures. - Although this commit renames the `fold` module as `mut_visit`, it keeps it in the `fold.rs` file, so as not to confuse git. The next commit will rename the file. --- src/librustc_allocator/expand.rs | 27 +- src/librustc_data_structures/thin_vec.rs | 9 + src/librustc_driver/driver.rs | 12 +- src/librustc_driver/lib.rs | 9 +- src/librustc_driver/pretty.rs | 42 +- src/libsyntax/attr/mod.rs | 60 +- src/libsyntax/config.rs | 166 +- src/libsyntax/ext/base.rs | 48 +- src/libsyntax/ext/derive.rs | 7 +- src/libsyntax/ext/expand.rs | 290 +-- src/libsyntax/ext/placeholders.rs | 79 +- src/libsyntax/ext/tt/transcribe.rs | 6 +- src/libsyntax/fold.rs | 2002 ++++++++--------- src/libsyntax/lib.rs | 4 +- src/libsyntax/parse/parser.rs | 3 +- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/test.rs | 64 +- src/libsyntax/tokenstream.rs | 2 +- .../util/{move_map.rs => map_in_place.rs} | 29 +- src/libsyntax_ext/deriving/generic/mod.rs | 12 +- src/libsyntax_ext/proc_macro_decls.rs | 4 +- .../pprust-expr-roundtrip.rs | 52 +- src/test/ui/issues/issue-49934.rs | 4 +- 23 files changed, 1417 insertions(+), 1516 deletions(-) rename src/libsyntax/util/{move_map.rs => map_in_place.rs} (82%) diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 73a35c7cdcd5f..1fb1794d5147d 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -16,7 +16,7 @@ use syntax::{ expand::ExpansionConfig, hygiene::{self, Mark, SyntaxContext}, }, - fold::{self, Folder}, + mut_visit::{self, MutVisitor}, parse::ParseSess, ptr::P, symbol::Symbol @@ -28,10 +28,10 @@ use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; pub fn modify( sess: &ParseSess, resolver: &mut dyn Resolver, - krate: Crate, + krate: &mut Crate, crate_name: String, handler: &rustc_errors::Handler, -) -> ast::Crate { +) { ExpandAllocatorDirectives { handler, sess, @@ -39,7 +39,7 @@ pub fn modify( found: false, crate_name: Some(crate_name), in_submod: -1, // -1 to account for the "root" module - }.fold_crate(krate) + }.visit_crate(krate); } struct ExpandAllocatorDirectives<'a> { @@ -54,14 +54,14 @@ struct ExpandAllocatorDirectives<'a> { in_submod: isize, } -impl<'a> Folder for ExpandAllocatorDirectives<'a> { - fn fold_item(&mut self, item: P) -> SmallVec<[P; 1]> { +impl<'a> MutVisitor for ExpandAllocatorDirectives<'a> { + fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { debug!("in submodule {}", self.in_submod); let name = if attr::contains_name(&item.attrs, "global_allocator") { "global_allocator" } else { - return fold::noop_fold_item(item, self); + return mut_visit::noop_flat_map_item(item, self); }; match item.node { ItemKind::Static(..) => {} @@ -139,25 +139,24 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { let name = f.kind.fn_name("allocator_abi"); let allocator_abi = Ident::with_empty_ctxt(Symbol::gensym(&name)); let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); - let module = f.cx.monotonic_expander().fold_item(module).pop().unwrap(); + let module = f.cx.monotonic_expander().flat_map_item(module).pop().unwrap(); // Return the item and new submodule smallvec![item, module] } // If we enter a submodule, take note. - fn fold_mod(&mut self, m: Mod) -> Mod { + fn visit_mod(&mut self, m: &mut Mod) { debug!("enter submodule"); self.in_submod += 1; - let ret = fold::noop_fold_mod(m, self); + mut_visit::noop_visit_mod(m, self); self.in_submod -= 1; debug!("exit submodule"); - ret } - // `fold_mac` is disabled by default. Enable it here. - fn fold_mac(&mut self, mac: Mac) -> Mac { - fold::noop_fold_mac(mac, self) + // `visit_mac` is disabled by default. Enable it here. + fn visit_mac(&mut self, mac: &mut Mac) { + mut_visit::noop_visit_mac(mac, self) } } diff --git a/src/librustc_data_structures/thin_vec.rs b/src/librustc_data_structures/thin_vec.rs index 359f9b7842da3..ed57c528f51e0 100644 --- a/src/librustc_data_structures/thin_vec.rs +++ b/src/librustc_data_structures/thin_vec.rs @@ -39,6 +39,15 @@ impl ::std::ops::Deref for ThinVec { } } +impl ::std::ops::DerefMut for ThinVec { + fn deref_mut(&mut self) -> &mut [T] { + match *self { + ThinVec(None) => &mut [], + ThinVec(Some(ref mut vec)) => vec, + } + } +} + impl Extend for ThinVec { fn extend>(&mut self, iter: I) { match *self { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d3412ec2dd93d..4549b20899dd5 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -32,7 +32,7 @@ use rustc_typeck as typeck; use syntax::{self, ast, attr, diagnostics, visit}; use syntax::early_buffered_lints::BufferedEarlyLint; use syntax::ext::base::ExtCtxt; -use syntax::fold::Folder; +use syntax::mut_visit::MutVisitor; use syntax::parse::{self, PResult}; use syntax::util::node_count::NodeCounter; use syntax::util::lev_distance::find_best_match_for_name; @@ -1000,12 +1000,12 @@ where }); sess.profiler(|p| p.end_activity(ProfileCategory::Expansion)); - krate = time(sess, "maybe building test harness", || { + time(sess, "maybe building test harness", || { syntax::test::modify_for_testing( &sess.parse_sess, &mut resolver, sess.opts.test, - krate, + &mut krate, sess.diagnostic(), &sess.features_untracked(), ) @@ -1014,7 +1014,7 @@ where // If we're actually rustdoc then there's no need to actually compile // anything, so switch everything to just looping if sess.opts.actually_rustdoc { - krate = ReplaceBodyWithLoop::new(sess).fold_crate(krate); + ReplaceBodyWithLoop::new(sess).visit_crate(&mut krate); } let (has_proc_macro_decls, has_global_allocator) = time(sess, "AST validation", || { @@ -1045,11 +1045,11 @@ where if has_global_allocator { // Expand global allocators, which are treated as an in-tree proc macro - krate = time(sess, "creating allocators", || { + time(sess, "creating allocators", || { allocator::expand::modify( &sess.parse_sess, &mut resolver, - krate, + &mut krate, crate_name.to_string(), sess.diagnostic(), ) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a95ce810ffaeb..d0dc7799c7b72 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -870,9 +870,9 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { control.after_hir_lowering.stop = Compilation::Stop; control.after_parse.callback = box move |state| { - state.krate = Some(pretty::fold_crate(state.session, - state.krate.take().unwrap(), - ppm)); + let mut krate = state.krate.take().unwrap(); + pretty::visit_crate(state.session, &mut krate, ppm); + state.krate = Some(krate); }; control.after_hir_lowering.callback = box move |state| { pretty::print_after_hir_lowering(state.session, @@ -891,7 +891,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { control.after_parse.stop = Compilation::Stop; control.after_parse.callback = box move |state| { - let krate = pretty::fold_crate(state.session, state.krate.take().unwrap(), ppm); + let mut krate = state.krate.take().unwrap(); + pretty::visit_crate(state.session, &mut krate, ppm); pretty::print_after_parsing(state.session, state.input, &krate, diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index d980c5a3d29c3..4caf2ec676f07 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -16,7 +16,7 @@ use rustc_metadata::cstore::CStore; use rustc_mir::util::{write_mir_pretty, write_mir_graphviz}; use syntax::ast::{self, BlockCheckMode}; -use syntax::fold::{self, Folder}; +use syntax::mut_visit::{*, MutVisitor, visit_clobber}; use syntax::print::{pprust}; use syntax::print::pprust::PrintState; use syntax::ptr::P; @@ -28,6 +28,7 @@ use smallvec::SmallVec; use std::cell::Cell; use std::fs::File; use std::io::{self, Write}; +use std::ops::DerefMut; use std::option; use std::path::Path; use std::str::FromStr; @@ -703,42 +704,42 @@ impl<'a> ReplaceBodyWithLoop<'a> { } } -impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { - fn fold_item_kind(&mut self, i: ast::ItemKind) -> ast::ItemKind { +impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> { + fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { let is_const = match i { ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, ast::ItemKind::Fn(ref decl, ref header, _, _) => header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl), _ => false, }; - self.run(is_const, |s| fold::noop_fold_item_kind(i, s)) + self.run(is_const, |s| noop_visit_item_kind(i, s)) } - fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { + fn flat_map_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { let is_const = match i.node { ast::TraitItemKind::Const(..) => true, ast::TraitItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) => header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl), _ => false, }; - self.run(is_const, |s| fold::noop_fold_trait_item(i, s)) + self.run(is_const, |s| noop_flat_map_trait_item(i, s)) } - fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { + fn flat_map_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { let is_const = match i.node { ast::ImplItemKind::Const(..) => true, ast::ImplItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) => header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl), _ => false, }; - self.run(is_const, |s| fold::noop_fold_impl_item(i, s)) + self.run(is_const, |s| noop_flat_map_impl_item(i, s)) } - fn fold_anon_const(&mut self, c: ast::AnonConst) -> ast::AnonConst { - self.run(true, |s| fold::noop_fold_anon_const(c, s)) + fn visit_anon_const(&mut self, c: &mut ast::AnonConst) { + self.run(true, |s| noop_visit_anon_const(c, s)) } - fn fold_block(&mut self, b: P) -> P { + fn visit_block(&mut self, b: &mut P) { fn stmt_to_block(rules: ast::BlockCheckMode, s: Option, sess: &Session) -> ast::Block { @@ -780,14 +781,14 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { }; if self.within_static_or_const { - fold::noop_fold_block(b, self) + noop_visit_block(b, self) } else { - b.map(|b| { + visit_clobber(b.deref_mut(), |b| { let mut stmts = vec![]; for s in b.stmts { let old_blocks = self.nested_blocks.replace(vec![]); - stmts.extend(self.fold_stmt(s).into_iter().filter(|s| s.is_item())); + stmts.extend(self.flat_map_stmt(s).into_iter().filter(|s| s.is_item())); // we put a Some in there earlier with that replace(), so this is valid let new_blocks = self.nested_blocks.take().unwrap(); @@ -818,9 +819,9 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { } // in general the pretty printer processes unexpanded code, so - // we override the default `fold_mac` method which panics. - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) + // we override the default `visit_mac` method which panics. + fn visit_mac(&mut self, mac: &mut ast::Mac) { + noop_visit_mac(mac, self) } } @@ -889,12 +890,9 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, } } -pub fn fold_crate(sess: &Session, krate: ast::Crate, ppm: PpMode) -> ast::Crate { +pub fn visit_crate(sess: &Session, krate: &mut ast::Crate, ppm: PpMode) { if let PpmSource(PpmEveryBodyLoops) = ppm { - let mut fold = ReplaceBodyWithLoop::new(sess); - fold.fold_crate(krate) - } else { - krate + ReplaceBodyWithLoop::new(sess).visit_crate(krate); } } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 58be7c3e085c3..c5a397e048078 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -15,6 +15,7 @@ use ast; use ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam}; +use mut_visit::visit_clobber; use source_map::{BytePos, Spanned, respan, dummy_spanned}; use syntax_pos::{FileName, Span}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; @@ -28,6 +29,7 @@ use tokenstream::{TokenStream, TokenTree, DelimSpan}; use GLOBALS; use std::iter; +use std::ops::DerefMut; pub fn mark_used(attr: &Attribute) { debug!("Marking {:?} as used.", attr); @@ -695,13 +697,13 @@ impl LitKind { pub trait HasAttrs: Sized { fn attrs(&self) -> &[ast::Attribute]; - fn map_attrs) -> Vec>(self, f: F) -> Self; + fn visit_attrs)>(&mut self, f: F); } impl HasAttrs for Spanned { fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() } - fn map_attrs) -> Vec>(self, f: F) -> Self { - respan(self.span, self.node.map_attrs(f)) + fn visit_attrs)>(&mut self, f: F) { + self.node.visit_attrs(f); } } @@ -709,7 +711,7 @@ impl HasAttrs for Vec { fn attrs(&self) -> &[Attribute] { self } - fn map_attrs) -> Vec>(self, f: F) -> Self { + fn visit_attrs)>(&mut self, f: F) { f(self) } } @@ -718,8 +720,12 @@ impl HasAttrs for ThinVec { fn attrs(&self) -> &[Attribute] { self } - fn map_attrs) -> Vec>(self, f: F) -> Self { - f(self.into()).into() + fn visit_attrs)>(&mut self, f: F) { + visit_clobber(self, |this| { + let mut vec = this.into(); + f(&mut vec); + vec.into() + }); } } @@ -727,8 +733,8 @@ impl HasAttrs for P { fn attrs(&self) -> &[Attribute] { (**self).attrs() } - fn map_attrs) -> Vec>(self, f: F) -> Self { - self.map(|t| t.map_attrs(f)) + fn visit_attrs)>(&mut self, f: F) { + (**self).visit_attrs(f); } } @@ -745,23 +751,27 @@ impl HasAttrs for StmtKind { } } - fn map_attrs) -> Vec>(self, f: F) -> Self { + fn visit_attrs)>(&mut self, f: F) { match self { - StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)), - StmtKind::Item(..) => self, - StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)), - StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)), - StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| { - (mac, style, attrs.map_attrs(f)) - })), + StmtKind::Local(local) => local.visit_attrs(f), + StmtKind::Item(..) => {} + StmtKind::Expr(expr) => expr.visit_attrs(f), + StmtKind::Semi(expr) => expr.visit_attrs(f), + StmtKind::Mac(mac) => { + let (_mac, _style, attrs) = mac.deref_mut(); + attrs.visit_attrs(f); + } } } } impl HasAttrs for Stmt { - fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() } - fn map_attrs) -> Vec>(self, f: F) -> Self { - Stmt { id: self.id, node: self.node.map_attrs(f), span: self.span } + fn attrs(&self) -> &[ast::Attribute] { + self.node.attrs() + } + + fn visit_attrs)>(&mut self, f: F) { + self.node.visit_attrs(f); } } @@ -770,9 +780,8 @@ impl HasAttrs for GenericParam { &self.attrs } - fn map_attrs) -> Vec>(mut self, f: F) -> Self { - self.attrs = self.attrs.map_attrs(f); - self + fn visit_attrs)>(&mut self, f: F) { + self.attrs.visit_attrs(f); } } @@ -783,11 +792,8 @@ macro_rules! derive_has_attrs { &self.attrs } - fn map_attrs(mut self, f: F) -> Self - where F: FnOnce(Vec) -> Vec, - { - self.attrs = self.attrs.map_attrs(f); - self + fn visit_attrs)>(&mut self, f: F) { + self.attrs.visit_attrs(f); } } )* } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index b35730bf2381b..fce2601e3aa84 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -6,16 +6,15 @@ use feature_gate::{ get_features, GateIssue, }; -use {fold, attr}; +use attr; use ast; -use source_map::Spanned; use edition::Edition; -use parse::{token, ParseSess}; -use smallvec::SmallVec; use errors::Applicability; -use util::move_map::MoveMap; - +use mut_visit::*; +use parse::{token, ParseSess}; use ptr::P; +use smallvec::SmallVec; +use util::map_in_place::MapInPlace; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { @@ -65,8 +64,8 @@ macro_rules! configure { } impl<'a> StripUnconfigured<'a> { - pub fn configure(&mut self, node: T) -> Option { - let node = self.process_cfg_attrs(node); + pub fn configure(&mut self, mut node: T) -> Option { + self.process_cfg_attrs(&mut node); if self.in_cfg(node.attrs()) { Some(node) } else { None } } @@ -76,10 +75,10 @@ impl<'a> StripUnconfigured<'a> { /// Gives compiler warnigns if any `cfg_attr` does not contain any /// attributes and is in the original source code. Gives compiler errors if /// the syntax of any `cfg_attr` is incorrect. - pub fn process_cfg_attrs(&mut self, node: T) -> T { - node.map_attrs(|attrs| { - attrs.into_iter().flat_map(|attr| self.process_cfg_attr(attr)).collect() - }) + pub fn process_cfg_attrs(&mut self, node: &mut T) { + node.visit_attrs(|attrs| { + attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); + }); } /// Parse and expand a single `cfg_attr` attribute into a list of attributes @@ -218,70 +217,47 @@ impl<'a> StripUnconfigured<'a> { } } - pub fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod { - ast::ForeignMod { - abi: foreign_mod.abi, - items: foreign_mod.items.move_flat_map(|item| self.configure(item)), - } + pub fn configure_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) { + let ast::ForeignMod { abi: _, items } = foreign_mod; + items.flat_map_in_place(|item| self.configure(item)); } - fn configure_variant_data(&mut self, vdata: ast::VariantData) -> ast::VariantData { + fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) { match vdata { - ast::VariantData::Struct(fields, id) => { - let fields = fields.move_flat_map(|field| self.configure(field)); - ast::VariantData::Struct(fields, id) - } - ast::VariantData::Tuple(fields, id) => { - let fields = fields.move_flat_map(|field| self.configure(field)); - ast::VariantData::Tuple(fields, id) - } - ast::VariantData::Unit(id) => ast::VariantData::Unit(id) + ast::VariantData::Struct(fields, _id) | + ast::VariantData::Tuple(fields, _id) => + fields.flat_map_in_place(|field| self.configure(field)), + ast::VariantData::Unit(_id) => {} } } - pub fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind { + pub fn configure_item_kind(&mut self, item: &mut ast::ItemKind) { match item { - ast::ItemKind::Struct(def, generics) => { - ast::ItemKind::Struct(self.configure_variant_data(def), generics) - } - ast::ItemKind::Union(def, generics) => { - ast::ItemKind::Union(self.configure_variant_data(def), generics) - } - ast::ItemKind::Enum(def, generics) => { - let variants = def.variants.move_flat_map(|v| { - self.configure(v).map(|v| { - Spanned { - node: ast::Variant_ { - ident: v.node.ident, - attrs: v.node.attrs, - data: self.configure_variant_data(v.node.data), - disr_expr: v.node.disr_expr, - }, - span: v.span - } - }) - }); - ast::ItemKind::Enum(ast::EnumDef { variants }, generics) + ast::ItemKind::Struct(def, _generics) | + ast::ItemKind::Union(def, _generics) => self.configure_variant_data(def), + ast::ItemKind::Enum(ast::EnumDef { variants }, _generics) => { + variants.flat_map_in_place(|variant| self.configure(variant)); + for variant in variants { + self.configure_variant_data(&mut variant.node.data); + } } - item => item, + _ => {} } } - pub fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind { + pub fn configure_expr_kind(&mut self, expr_kind: &mut ast::ExprKind) { match expr_kind { - ast::ExprKind::Match(m, arms) => { - let arms = arms.move_flat_map(|a| self.configure(a)); - ast::ExprKind::Match(m, arms) + ast::ExprKind::Match(_m, arms) => { + arms.flat_map_in_place(|arm| self.configure(arm)); } - ast::ExprKind::Struct(path, fields, base) => { - let fields = fields.move_flat_map(|field| self.configure(field)); - ast::ExprKind::Struct(path, fields, base) + ast::ExprKind::Struct(_path, fields, _base) => { + fields.flat_map_in_place(|field| self.configure(field)); } - _ => expr_kind, + _ => {} } } - pub fn configure_expr(&mut self, expr: P) -> P { + pub fn configure_expr(&mut self, expr: &mut P) { self.visit_expr_attrs(expr.attrs()); // If an expr is valid to cfg away it will have been removed by the @@ -289,8 +265,8 @@ impl<'a> StripUnconfigured<'a> { // Anything else is always required, and thus has to error out // in case of a cfg attr. // - // N.B., this is intentionally not part of the fold_expr() function - // in order for fold_opt_expr() to be able to avoid this check + // N.B., this is intentionally not part of the visit_expr() function + // in order for filter_map_expr() to be able to avoid this check if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) { let msg = "removing an expression is not supported in this position"; self.sess.span_diagnostic.span_err(attr.span, msg); @@ -299,14 +275,10 @@ impl<'a> StripUnconfigured<'a> { self.process_cfg_attrs(expr) } - pub fn configure_pat(&mut self, pattern: P) -> P { - pattern.map(|mut pattern| { - if let ast::PatKind::Struct(path, fields, etc) = pattern.node { - let fields = fields.move_flat_map(|field| self.configure(field)); - pattern.node = ast::PatKind::Struct(path, fields, etc); - } - pattern - }) + pub fn configure_pat(&mut self, pat: &mut P) { + if let ast::PatKind::Struct(_path, fields, _etc) = &mut pat.node { + fields.flat_map_in_place(|field| self.configure(field)); + } } // deny #[cfg] on generic parameters until we decide what to do with it. @@ -326,54 +298,54 @@ impl<'a> StripUnconfigured<'a> { } } -impl<'a> fold::Folder for StripUnconfigured<'a> { - fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod { - let foreign_mod = self.configure_foreign_mod(foreign_mod); - fold::noop_fold_foreign_mod(foreign_mod, self) +impl<'a> MutVisitor for StripUnconfigured<'a> { + fn visit_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) { + self.configure_foreign_mod(foreign_mod); + noop_visit_foreign_mod(foreign_mod, self); } - fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind { - let item = self.configure_item_kind(item); - fold::noop_fold_item_kind(item, self) + fn visit_item_kind(&mut self, item: &mut ast::ItemKind) { + self.configure_item_kind(item); + noop_visit_item_kind(item, self); } - fn fold_expr(&mut self, expr: P) -> P { - let mut expr = self.configure_expr(expr).into_inner(); - expr.node = self.configure_expr_kind(expr.node); - P(fold::noop_fold_expr(expr, self)) + fn visit_expr(&mut self, expr: &mut P) { + self.configure_expr(expr); + self.configure_expr_kind(&mut expr.node); + noop_visit_expr(expr, self); } - fn fold_opt_expr(&mut self, expr: P) -> Option> { - let mut expr = configure!(self, expr).into_inner(); - expr.node = self.configure_expr_kind(expr.node); - Some(P(fold::noop_fold_expr(expr, self))) + fn filter_map_expr(&mut self, expr: P) -> Option> { + let mut expr = configure!(self, expr); + self.configure_expr_kind(&mut expr.node); + noop_visit_expr(&mut expr, self); + Some(expr) } - fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { - fold::noop_fold_stmt(configure!(self, stmt), self) + fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { + noop_flat_map_stmt(configure!(self, stmt), self) } - fn fold_item(&mut self, item: P) -> SmallVec<[P; 1]> { - fold::noop_fold_item(configure!(self, item), self) + fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { + noop_flat_map_item(configure!(self, item), self) } - fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> - { - fold::noop_fold_impl_item(configure!(self, item), self) + fn flat_map_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { + noop_flat_map_impl_item(configure!(self, item), self) } - fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { - fold::noop_fold_trait_item(configure!(self, item), self) + fn flat_map_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { + noop_flat_map_trait_item(configure!(self, item), self) } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fn visit_mac(&mut self, _mac: &mut ast::Mac) { // Don't configure interpolated AST (cf. issue #34171). // Interpolated AST will get configured once the surrounding tokens are parsed. - mac } - fn fold_pat(&mut self, pattern: P) -> P { - fold::noop_fold_pat(self.configure_pat(pattern), self) + fn visit_pat(&mut self, pat: &mut P) { + self.configure_pat(pat); + noop_visit_pat(pat, self) } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 09e7e57f78cfa..b53068f5bc2a4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -8,7 +8,7 @@ use edition::Edition; use errors::{DiagnosticBuilder, DiagnosticId}; use ext::expand::{self, AstFragment, Invocation}; use ext::hygiene::{self, Mark, SyntaxContext, Transparency}; -use fold::{self, Folder}; +use mut_visit::{self, MutVisitor}; use parse::{self, parser, DirectoryOwnership}; use parse::token; use ptr::P; @@ -47,15 +47,14 @@ impl HasAttrs for Annotatable { } } - fn map_attrs) -> Vec>(self, f: F) -> Self { + fn visit_attrs)>(&mut self, f: F) { match self { - Annotatable::Item(item) => Annotatable::Item(item.map_attrs(f)), - Annotatable::TraitItem(trait_item) => Annotatable::TraitItem(trait_item.map_attrs(f)), - Annotatable::ImplItem(impl_item) => Annotatable::ImplItem(impl_item.map_attrs(f)), - Annotatable::ForeignItem(foreign_item) => - Annotatable::ForeignItem(foreign_item.map_attrs(f)), - Annotatable::Stmt(stmt) => Annotatable::Stmt(stmt.map_attrs(f)), - Annotatable::Expr(expr) => Annotatable::Expr(expr.map_attrs(f)), + Annotatable::Item(item) => item.visit_attrs(f), + Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f), + Annotatable::ImplItem(impl_item) => impl_item.visit_attrs(f), + Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f), + Annotatable::Stmt(stmt) => stmt.visit_attrs(f), + Annotatable::Expr(expr) => expr.visit_attrs(f), } } } @@ -263,24 +262,24 @@ impl TTMacroExpander for F ) -> Box { struct AvoidInterpolatedIdents; - impl Folder for AvoidInterpolatedIdents { - fn fold_tt(&mut self, tt: tokenstream::TokenTree) -> tokenstream::TokenTree { - if let tokenstream::TokenTree::Token(_, token::Interpolated(ref nt)) = tt { + impl MutVisitor for AvoidInterpolatedIdents { + fn visit_tt(&mut self, tt: &mut tokenstream::TokenTree) { + if let tokenstream::TokenTree::Token(_, token::Interpolated(nt)) = tt { if let token::NtIdent(ident, is_raw) = nt.0 { - return tokenstream::TokenTree::Token(ident.span, - token::Ident(ident, is_raw)); + *tt = tokenstream::TokenTree::Token(ident.span, + token::Ident(ident, is_raw)); } } - fold::noop_fold_tt(tt, self) + mut_visit::noop_visit_tt(tt, self) } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) + fn visit_mac(&mut self, mac: &mut ast::Mac) { + mut_visit::noop_visit_mac(mac, self) } } let input: Vec<_> = - input.trees().map(|tt| AvoidInterpolatedIdents.fold_tt(tt)).collect(); + input.trees().map(|mut tt| { AvoidInterpolatedIdents.visit_tt(&mut tt); tt }).collect(); (*self)(ecx, span, &input) } } @@ -981,17 +980,14 @@ impl<'a> ExtCtxt<'a> { /// compilation on error, merely emits a non-fatal error and returns None. pub fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt, - expr: P, + mut expr: P, err_msg: &str, ) -> Result, Option>> { // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation. - let expr = expr.map(|mut expr| { - expr.span = expr.span.apply_mark(cx.current_expansion.mark); - expr - }); + expr.span = expr.span.apply_mark(cx.current_expansion.mark); // we want to be able to handle e.g., `concat!("foo", "bar")` - let expr = cx.expander().fold_expr(expr); + cx.expander().visit_expr(&mut expr); Err(match expr.node { ast::ExprKind::Lit(ref l) => match l.node { ast::LitKind::Str(s, style) => return Ok(respan(expr.span, (s, style))), @@ -1055,7 +1051,9 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt, let mut p = cx.new_parser_from_tts(tts); let mut es = Vec::new(); while p.token != token::Eof { - es.push(cx.expander().fold_expr(panictry!(p.parse_expr()))); + let mut expr = panictry!(p.parse_expr()); + cx.expander().visit_expr(&mut expr); + es.push(expr); if p.eat(&token::Comma) { continue; } diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 7ef09ce5fbd40..fa8cf6c496a39 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -40,7 +40,7 @@ pub fn collect_derives(cx: &mut ExtCtxt, attrs: &mut Vec) -> Vec result } -pub fn add_derived_markers(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path], item: T) -> T +pub fn add_derived_markers(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path], item: &mut T) where T: HasAttrs, { let (mut names, mut pretty_name) = (FxHashSet::default(), "derive(".to_owned()); @@ -64,7 +64,7 @@ pub fn add_derived_markers(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path] }); let span = span.with_ctxt(cx.backtrace()); - item.map_attrs(|mut attrs| { + item.visit_attrs(|attrs| { if names.contains(&Symbol::intern("Eq")) && names.contains(&Symbol::intern("PartialEq")) { let meta = cx.meta_word(span, Symbol::intern("structural_match")); attrs.push(cx.attribute(span, meta)); @@ -73,6 +73,5 @@ pub fn add_derived_markers(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path] let meta = cx.meta_word(span, Symbol::intern("rustc_copy_clone_marker")); attrs.push(cx.attribute(span, meta)); } - attrs - }) + }); } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2effd910e8545..a0ccce986592a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -9,7 +9,7 @@ use ext::derive::{add_derived_markers, collect_derives}; use ext::hygiene::{self, Mark, SyntaxContext}; use ext::placeholders::{placeholder, PlaceholderExpander}; use feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; -use fold::*; +use mut_visit::*; use parse::{DirectoryOwnership, PResult, ParseSess}; use parse::token::{self, Token}; use parse::parser::Parser; @@ -21,11 +21,13 @@ use syntax_pos::{Span, DUMMY_SP, FileName}; use syntax_pos::hygiene::ExpnFormat; use tokenstream::{TokenStream, TokenTree}; use visit::{self, Visitor}; +use util::map_in_place::MapInPlace; use rustc_data_structures::fx::FxHashMap; use std::fs; use std::io::ErrorKind; use std::{iter, mem}; +use std::ops::DerefMut; use std::rc::Rc; use std::path::PathBuf; @@ -35,8 +37,8 @@ macro_rules! ast_fragments { $kind_name:expr; // FIXME: HACK: this should be `$(one ...)?` and `$(many ...)?` but `?` macro // repetition was removed from 2015 edition in #51587 because of ambiguities. - $(one fn $fold_ast:ident; fn $visit_ast:ident;)* - $(many fn $fold_ast_elt:ident; fn $visit_ast_elt:ident;)* + $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)* + $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)* fn $make_ast:ident; })* ) => { @@ -86,16 +88,20 @@ macro_rules! ast_fragments { } })* - pub fn fold_with(self, folder: &mut F) -> Self { + pub fn mut_visit_with(&mut self, vis: &mut F) { match self { - AstFragment::OptExpr(expr) => - AstFragment::OptExpr(expr.and_then(|expr| folder.fold_opt_expr(expr))), - $($(AstFragment::$Kind(ast) => - AstFragment::$Kind(folder.$fold_ast(ast)),)*)* + AstFragment::OptExpr(opt_expr) => { + visit_clobber(opt_expr, |opt_expr| { + if let Some(expr) = opt_expr { + vis.filter_map_expr(expr) + } else { + None + } + }); + } + $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)*)* $($(AstFragment::$Kind(ast) => - AstFragment::$Kind(ast.into_iter() - .flat_map(|ast| folder.$fold_ast_elt(ast)) - .collect()),)*)* + ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)*)* } } @@ -111,14 +117,14 @@ macro_rules! ast_fragments { } } - impl<'a, 'b> Folder for MacroExpander<'a, 'b> { - fn fold_opt_expr(&mut self, expr: P) -> Option> { + impl<'a, 'b> MutVisitor for MacroExpander<'a, 'b> { + fn filter_map_expr(&mut self, expr: P) -> Option> { self.expand_fragment(AstFragment::OptExpr(Some(expr))).make_opt_expr() } - $($(fn $fold_ast(&mut self, ast: $AstTy) -> $AstTy { - self.expand_fragment(AstFragment::$Kind(ast)).$make_ast() + $($(fn $mut_visit_ast(&mut self, ast: &mut $AstTy) { + visit_clobber(ast, |ast| self.expand_fragment(AstFragment::$Kind(ast)).$make_ast()); })*)* - $($(fn $fold_ast_elt(&mut self, ast_elt: <$AstTy as IntoIterator>::Item) -> $AstTy { + $($(fn $flat_map_ast_elt(&mut self, ast_elt: <$AstTy as IntoIterator>::Item) -> $AstTy { self.expand_fragment(AstFragment::$Kind(smallvec![ast_elt])).$make_ast() })*)* } @@ -133,23 +139,23 @@ macro_rules! ast_fragments { } ast_fragments! { - Expr(P) { "expression"; one fn fold_expr; fn visit_expr; fn make_expr; } - Pat(P) { "pattern"; one fn fold_pat; fn visit_pat; fn make_pat; } - Ty(P) { "type"; one fn fold_ty; fn visit_ty; fn make_ty; } + Expr(P) { "expression"; one fn visit_expr; fn visit_expr; fn make_expr; } + Pat(P) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; } + Ty(P) { "type"; one fn visit_ty; fn visit_ty; fn make_ty; } Stmts(SmallVec<[ast::Stmt; 1]>) { - "statement"; many fn fold_stmt; fn visit_stmt; fn make_stmts; + "statement"; many fn flat_map_stmt; fn visit_stmt; fn make_stmts; } Items(SmallVec<[P; 1]>) { - "item"; many fn fold_item; fn visit_item; fn make_items; + "item"; many fn flat_map_item; fn visit_item; fn make_items; } TraitItems(SmallVec<[ast::TraitItem; 1]>) { - "trait item"; many fn fold_trait_item; fn visit_trait_item; fn make_trait_items; + "trait item"; many fn flat_map_trait_item; fn visit_trait_item; fn make_trait_items; } ImplItems(SmallVec<[ast::ImplItem; 1]>) { - "impl item"; many fn fold_impl_item; fn visit_impl_item; fn make_impl_items; + "impl item"; many fn flat_map_impl_item; fn visit_impl_item; fn make_impl_items; } ForeignItems(SmallVec<[ast::ForeignItem; 1]>) { - "foreign item"; many fn fold_foreign_item; fn visit_foreign_item; fn make_foreign_items; + "foreign item"; many fn flat_map_foreign_item; fn visit_foreign_item; fn make_foreign_items; } } @@ -297,7 +303,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.current_expansion.depth = 0; // Collect all macro invocations and replace them with placeholders. - let (fragment_with_placeholders, mut invocations) + let (mut fragment_with_placeholders, mut invocations) = self.collect_invocations(input_fragment, &[]); // Optimization: if we resolve all imports now, @@ -369,10 +375,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { err.emit(); } - let item = self.fully_configure(item) - .map_attrs(|mut attrs| { attrs.retain(|a| a.path != "derive"); attrs }); - let item_with_markers = - add_derived_markers(&mut self.cx, item.span(), &traits, item.clone()); + let mut item = self.fully_configure(item); + item.visit_attrs(|attrs| attrs.retain(|a| a.path != "derive")); + let mut item_with_markers = item.clone(); + add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers); let derives = derives.entry(invoc.expansion_data.mark).or_default(); derives.reserve(traits.len()); @@ -427,7 +433,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { expanded_fragment, derives); } } - fragment_with_placeholders.fold_with(&mut placeholder_expander) + fragment_with_placeholders.mut_visit_with(&mut placeholder_expander); + fragment_with_placeholders } fn resolve_imports(&mut self) { @@ -440,12 +447,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s. /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and /// prepares data for resolving paths of macro invocations. - fn collect_invocations(&mut self, fragment: AstFragment, derives: &[Mark]) + fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[Mark]) -> (AstFragment, Vec) { // Resolve `$crate`s in the fragment for pretty-printing. self.cx.resolver.resolve_dollar_crates(&fragment); - let (fragment_with_placeholders, invocations) = { + let invocations = { let mut collector = InvocationCollector { cfg: StripUnconfigured { sess: self.cx.parse_sess, @@ -455,16 +462,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> { invocations: Vec::new(), monotonic: self.monotonic, }; - (fragment.fold_with(&mut collector), collector.invocations) + fragment.mut_visit_with(&mut collector); + collector.invocations }; if self.monotonic { self.cx.resolver.visit_ast_fragment_with_placeholders( - self.cx.current_expansion.mark, &fragment_with_placeholders, derives - ); + self.cx.current_expansion.mark, &fragment, derives); } - (fragment_with_placeholders, invocations) + (fragment, invocations) } fn fully_configure(&mut self, item: Annotatable) -> Annotatable { @@ -476,24 +483,25 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // we know that fold result vector will contain exactly one element match item { Annotatable::Item(item) => { - Annotatable::Item(cfg.fold_item(item).pop().unwrap()) + Annotatable::Item(cfg.flat_map_item(item).pop().unwrap()) } Annotatable::TraitItem(item) => { - Annotatable::TraitItem(item.map(|item| cfg.fold_trait_item(item).pop().unwrap())) + Annotatable::TraitItem( + item.map(|item| cfg.flat_map_trait_item(item).pop().unwrap())) } Annotatable::ImplItem(item) => { - Annotatable::ImplItem(item.map(|item| cfg.fold_impl_item(item).pop().unwrap())) + Annotatable::ImplItem(item.map(|item| cfg.flat_map_impl_item(item).pop().unwrap())) } Annotatable::ForeignItem(item) => { Annotatable::ForeignItem( - item.map(|item| cfg.fold_foreign_item(item).pop().unwrap()) + item.map(|item| cfg.flat_map_foreign_item(item).pop().unwrap()) ) } Annotatable::Stmt(stmt) => { - Annotatable::Stmt(stmt.map(|stmt| cfg.fold_stmt(stmt).pop().unwrap())) + Annotatable::Stmt(stmt.map(|stmt| cfg.flat_map_stmt(stmt).pop().unwrap())) } - Annotatable::Expr(expr) => { - Annotatable::Expr(cfg.fold_expr(expr)) + Annotatable::Expr(mut expr) => { + Annotatable::Expr({ cfg.visit_expr(&mut expr); expr }) } } } @@ -535,7 +543,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { invoc: Invocation, ext: &SyntaxExtension) -> Option { - let (attr, item) = match invoc.kind { + let (attr, mut item) = match invoc.kind { InvocationKind::Attr { attr, item, .. } => (attr?, item), _ => unreachable!(), }; @@ -558,7 +566,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { NonMacroAttr { .. } => { attr::mark_known(&attr); - let item = item.map_attrs(|mut attrs| { attrs.push(attr); attrs }); + item.visit_attrs(|attrs| attrs.push(attr)); Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) } MultiModifier(ref mac) => { @@ -1113,34 +1121,32 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } /// If `item` is an attr invocation, remove and return the macro attribute and derive traits. - fn classify_item(&mut self, mut item: T) - -> (Option, Vec, T, /* after_derive */ bool) + fn classify_item(&mut self, item: &mut T) + -> (Option, Vec, /* after_derive */ bool) where T: HasAttrs, { let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false); - item = item.map_attrs(|mut attrs| { + item.visit_attrs(|mut attrs| { attr = self.find_attr_invoc(&mut attrs, &mut after_derive); traits = collect_derives(&mut self.cx, &mut attrs); - attrs }); - (attr, traits, item, after_derive) + (attr, traits, after_derive) } - /// Alternative of `classify_item()` that ignores `#[derive]` so invocations fallthrough + /// Alternative to `classify_item()` that ignores `#[derive]` so invocations fallthrough /// to the unused-attributes lint (making it an error on statements and expressions /// is a breaking change) - fn classify_nonitem(&mut self, mut item: T) - -> (Option, T, /* after_derive */ bool) { + fn classify_nonitem(&mut self, nonitem: &mut T) + -> (Option, /* after_derive */ bool) { let (mut attr, mut after_derive) = (None, false); - item = item.map_attrs(|mut attrs| { + nonitem.visit_attrs(|mut attrs| { attr = self.find_attr_invoc(&mut attrs, &mut after_derive); - attrs }); - (attr, item, after_derive) + (attr, after_derive) } fn configure(&mut self, node: T) -> Option { @@ -1173,14 +1179,14 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } } -impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { - fn fold_expr(&mut self, expr: P) -> P { - let expr = self.cfg.configure_expr(expr); - expr.map(|mut expr| { - expr.node = self.cfg.configure_expr_kind(expr.node); +impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { + fn visit_expr(&mut self, expr: &mut P) { + self.cfg.configure_expr(expr); + visit_clobber(expr.deref_mut(), |mut expr| { + self.cfg.configure_expr_kind(&mut expr.node); // ignore derives so they remain unused - let (attr, expr, after_derive) = self.classify_nonitem(expr); + let (attr, after_derive) = self.classify_nonitem(&mut expr); if attr.is_some() { // Collect the invoc regardless of whether or not attributes are permitted here @@ -1189,7 +1195,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { // AstFragmentKind::Expr requires the macro to emit an expression. return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)), - AstFragmentKind::Expr, after_derive) + AstFragmentKind::Expr, after_derive) .make_expr() .into_inner() } @@ -1200,18 +1206,19 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { .make_expr() .into_inner() } else { - noop_fold_expr(expr, self) + noop_visit_expr(&mut expr, self); + expr } - }) + }); } - fn fold_opt_expr(&mut self, expr: P) -> Option> { + fn filter_map_expr(&mut self, expr: P) -> Option> { let expr = configure!(self, expr); expr.filter_map(|mut expr| { - expr.node = self.cfg.configure_expr_kind(expr.node); + self.cfg.configure_expr_kind(&mut expr.node); // Ignore derives so they remain unused. - let (attr, expr, after_derive) = self.classify_nonitem(expr); + let (attr, after_derive) = self.classify_nonitem(&mut expr); if attr.is_some() { attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a)); @@ -1228,44 +1235,45 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { .make_opt_expr() .map(|expr| expr.into_inner()) } else { - Some(noop_fold_expr(expr, self)) + Some({ noop_visit_expr(&mut expr, self); expr }) } }) } - fn fold_pat(&mut self, pat: P) -> P { - let pat = self.cfg.configure_pat(pat); + fn visit_pat(&mut self, pat: &mut P) { + self.cfg.configure_pat(pat); match pat.node { PatKind::Mac(_) => {} - _ => return noop_fold_pat(pat, self), + _ => return noop_visit_pat(pat, self), } - pat.and_then(|pat| match pat.node { - PatKind::Mac(mac) => self.collect_bang(mac, pat.span, AstFragmentKind::Pat).make_pat(), - _ => unreachable!(), - }) + visit_clobber(pat, |mut pat| { + match mem::replace(&mut pat.node, PatKind::Wild) { + PatKind::Mac(mac) => + self.collect_bang(mac, pat.span, AstFragmentKind::Pat).make_pat(), + _ => unreachable!(), + } + }); } - fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { + fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { let mut stmt = configure!(self, stmt); // we'll expand attributes on expressions separately if !stmt.is_expr() { - let (attr, derives, stmt_, after_derive) = if stmt.is_item() { - self.classify_item(stmt) + let (attr, derives, after_derive) = if stmt.is_item() { + self.classify_item(&mut stmt) } else { // ignore derives on non-item statements so it falls through // to the unused-attributes lint - let (attr, stmt, after_derive) = self.classify_nonitem(stmt); - (attr, vec![], stmt, after_derive) + let (attr, after_derive) = self.classify_nonitem(&mut stmt); + (attr, vec![], after_derive) }; if attr.is_some() || !derives.is_empty() { - return self.collect_attr(attr, derives, Annotatable::Stmt(P(stmt_)), + return self.collect_attr(attr, derives, Annotatable::Stmt(P(stmt)), AstFragmentKind::Stmts, after_derive).make_stmts(); } - - stmt = stmt_; } if let StmtKind::Mac(mac) = stmt.node { @@ -1287,24 +1295,23 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { // The placeholder expander gives ids to statements, so we avoid folding the id here. let ast::Stmt { id, node, span } = stmt; - noop_fold_stmt_kind(node, self).into_iter().map(|node| { + noop_flat_map_stmt_kind(node, self).into_iter().map(|node| { ast::Stmt { id, node, span } }).collect() } - fn fold_block(&mut self, block: P) -> P { + fn visit_block(&mut self, block: &mut P) { let old_directory_ownership = self.cx.current_expansion.directory_ownership; self.cx.current_expansion.directory_ownership = DirectoryOwnership::UnownedViaBlock; - let result = noop_fold_block(block, self); + noop_visit_block(block, self); self.cx.current_expansion.directory_ownership = old_directory_ownership; - result } - fn fold_item(&mut self, item: P) -> SmallVec<[P; 1]> { - let item = configure!(self, item); + fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { + let mut item = configure!(self, item); - let (attr, traits, item, after_derive) = self.classify_item(item); + let (attr, traits, after_derive) = self.classify_item(&mut item); if attr.is_some() || !traits.is_empty() { return self.collect_attr(attr, traits, Annotatable::Item(item), AstFragmentKind::Items, after_derive).make_items(); @@ -1326,7 +1333,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } ast::ItemKind::Mod(ast::Mod { inner, .. }) => { if item.ident == keywords::Invalid.ident() { - return noop_fold_item(item, self); + return noop_flat_map_item(item, self); } let orig_directory_ownership = self.cx.current_expansion.directory_ownership; @@ -1366,20 +1373,20 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let orig_module = mem::replace(&mut self.cx.current_expansion.module, Rc::new(module)); - let result = noop_fold_item(item, self); + let result = noop_flat_map_item(item, self); self.cx.current_expansion.module = orig_module; self.cx.current_expansion.directory_ownership = orig_directory_ownership; result } - _ => noop_fold_item(item, self), + _ => noop_flat_map_item(item, self), } } - fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { - let item = configure!(self, item); + fn flat_map_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { + let mut item = configure!(self, item); - let (attr, traits, item, after_derive) = self.classify_item(item); + let (attr, traits, after_derive) = self.classify_item(&mut item); if attr.is_some() || !traits.is_empty() { return self.collect_attr(attr, traits, Annotatable::TraitItem(P(item)), AstFragmentKind::TraitItems, after_derive).make_trait_items() @@ -1391,14 +1398,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { self.check_attributes(&attrs); self.collect_bang(mac, span, AstFragmentKind::TraitItems).make_trait_items() } - _ => noop_fold_trait_item(item, self), + _ => noop_flat_map_trait_item(item, self), } } - fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { - let item = configure!(self, item); + fn flat_map_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { + let mut item = configure!(self, item); - let (attr, traits, item, after_derive) = self.classify_item(item); + let (attr, traits, after_derive) = self.classify_item(&mut item); if attr.is_some() || !traits.is_empty() { return self.collect_attr(attr, traits, Annotatable::ImplItem(P(item)), AstFragmentKind::ImplItems, after_derive).make_impl_items(); @@ -1410,30 +1417,34 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { self.check_attributes(&attrs); self.collect_bang(mac, span, AstFragmentKind::ImplItems).make_impl_items() } - _ => noop_fold_impl_item(item, self), + _ => noop_flat_map_impl_item(item, self), } } - fn fold_ty(&mut self, ty: P) -> P { - let ty = match ty.node { - ast::TyKind::Mac(_) => ty.into_inner(), - _ => return noop_fold_ty(ty, self), + fn visit_ty(&mut self, ty: &mut P) { + match ty.node { + ast::TyKind::Mac(_) => {} + _ => return noop_visit_ty(ty, self), }; - match ty.node { - ast::TyKind::Mac(mac) => self.collect_bang(mac, ty.span, AstFragmentKind::Ty).make_ty(), - _ => unreachable!(), - } + visit_clobber(ty, |mut ty| { + match mem::replace(&mut ty.node, ast::TyKind::Err) { + ast::TyKind::Mac(mac) => + self.collect_bang(mac, ty.span, AstFragmentKind::Ty).make_ty(), + _ => unreachable!(), + } + }); } - fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod { - noop_fold_foreign_mod(self.cfg.configure_foreign_mod(foreign_mod), self) + fn visit_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) { + self.cfg.configure_foreign_mod(foreign_mod); + noop_visit_foreign_mod(foreign_mod, self); } - fn fold_foreign_item(&mut self, foreign_item: ast::ForeignItem) + fn flat_map_foreign_item(&mut self, mut foreign_item: ast::ForeignItem) -> SmallVec<[ast::ForeignItem; 1]> { - let (attr, traits, foreign_item, after_derive) = self.classify_item(foreign_item); + let (attr, traits, after_derive) = self.classify_item(&mut foreign_item); if attr.is_some() || !traits.is_empty() { return self.collect_attr(attr, traits, Annotatable::ForeignItem(P(foreign_item)), @@ -1447,38 +1458,41 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { .make_foreign_items(); } - noop_fold_foreign_item(foreign_item, self) + noop_flat_map_foreign_item(foreign_item, self) } - fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind { + fn visit_item_kind(&mut self, item: &mut ast::ItemKind) { match item { - ast::ItemKind::MacroDef(..) => item, - _ => noop_fold_item_kind(self.cfg.configure_item_kind(item), self), + ast::ItemKind::MacroDef(..) => {} + _ => { + self.cfg.configure_item_kind(item); + noop_visit_item_kind(item, self); + } } } - fn fold_generic_param(&mut self, param: ast::GenericParam) -> ast::GenericParam { + fn visit_generic_param(&mut self, param: &mut ast::GenericParam) { self.cfg.disallow_cfg_on_generic_param(¶m); - noop_fold_generic_param(param, self) + noop_visit_generic_param(param, self) } - fn fold_attribute(&mut self, at: ast::Attribute) -> ast::Attribute { + fn visit_attribute(&mut self, at: &mut ast::Attribute) { // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename", // contents="file contents")]` attributes if !at.check_name("doc") { - return noop_fold_attribute(at, self); + return noop_visit_attribute(at, self); } if let Some(list) = at.meta_item_list() { if !list.iter().any(|it| it.check_name("include")) { - return noop_fold_attribute(at, self); + return noop_visit_attribute(at, self); } let mut items = vec![]; - for it in list { + for mut it in list { if !it.check_name("include") { - items.push(noop_fold_meta_list_item(it, self)); + items.push({ noop_visit_meta_list_item(&mut it, self); it }); continue; } @@ -1487,7 +1501,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { self.check_attribute(&at); if self.cx.parse_sess.span_diagnostic.err_count() > err_count { // avoid loading the file if they haven't enabled the feature - return noop_fold_attribute(at, self); + return noop_visit_attribute(at, self); } let filename = self.cx.root_path.join(file.to_string()); @@ -1582,20 +1596,18 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let meta = attr::mk_list_item(DUMMY_SP, Ident::from_str("doc"), items); match at.style { - ast::AttrStyle::Inner => attr::mk_spanned_attr_inner(at.span, at.id, meta), - ast::AttrStyle::Outer => attr::mk_spanned_attr_outer(at.span, at.id, meta), + ast::AttrStyle::Inner => *at = attr::mk_spanned_attr_inner(at.span, at.id, meta), + ast::AttrStyle::Outer => *at = attr::mk_spanned_attr_outer(at.span, at.id, meta), } } else { - noop_fold_attribute(at, self) + noop_visit_attribute(at, self) } } - fn new_id(&mut self, id: ast::NodeId) -> ast::NodeId { + fn visit_id(&mut self, id: &mut ast::NodeId) { if self.monotonic { - assert_eq!(id, ast::DUMMY_NODE_ID); - self.cx.resolver.next_node_id() - } else { - id + debug_assert_eq!(*id, ast::DUMMY_NODE_ID); + *id = self.cx.resolver.next_node_id() } } } @@ -1660,12 +1672,12 @@ impl<'feat> ExpansionConfig<'feat> { #[derive(Debug)] pub struct Marker(pub Mark); -impl Folder for Marker { - fn new_span(&mut self, span: Span) -> Span { - span.apply_mark(self.0) +impl MutVisitor for Marker { + fn visit_span(&mut self, span: &mut Span) { + *span = span.apply_mark(self.0) } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - noop_fold_mac(mac, self) + fn visit_mac(&mut self, mac: &mut ast::Mac) { + noop_visit_mac(mac, self) } } diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 0928bc804041d..23b34c2660bda 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -4,12 +4,11 @@ use ext::base::ExtCtxt; use ext::expand::{AstFragment, AstFragmentKind}; use ext::hygiene::Mark; use tokenstream::TokenStream; -use fold::*; +use mut_visit::*; use ptr::P; use smallvec::SmallVec; use symbol::keywords; use ThinVec; -use util::move_map::MoveMap; use rustc_data_structures::fx::FxHashMap; @@ -85,8 +84,8 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> { } } - pub fn add(&mut self, id: ast::NodeId, fragment: AstFragment, derives: Vec) { - let mut fragment = fragment.fold_with(self); + pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, derives: Vec) { + fragment.mut_visit_with(self); if let AstFragment::Items(mut items) = fragment { for derive in derives { match self.remove(NodeId::placeholder_from_mark(derive)) { @@ -104,56 +103,56 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> { } } -impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { - fn fold_item(&mut self, item: P) -> SmallVec<[P; 1]> { +impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { + fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { match item.node { ast::ItemKind::Mac(_) => return self.remove(item.id).make_items(), ast::ItemKind::MacroDef(_) => return smallvec![item], _ => {} } - noop_fold_item(item, self) + noop_flat_map_item(item, self) } - fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { + fn flat_map_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { match item.node { ast::TraitItemKind::Macro(_) => self.remove(item.id).make_trait_items(), - _ => noop_fold_trait_item(item, self), + _ => noop_flat_map_trait_item(item, self), } } - fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { + fn flat_map_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { match item.node { ast::ImplItemKind::Macro(_) => self.remove(item.id).make_impl_items(), - _ => noop_fold_impl_item(item, self), + _ => noop_flat_map_impl_item(item, self), } } - fn fold_foreign_item(&mut self, item: ast::ForeignItem) -> SmallVec<[ast::ForeignItem; 1]> { + fn flat_map_foreign_item(&mut self, item: ast::ForeignItem) -> SmallVec<[ast::ForeignItem; 1]> { match item.node { ast::ForeignItemKind::Macro(_) => self.remove(item.id).make_foreign_items(), - _ => noop_fold_foreign_item(item, self), + _ => noop_flat_map_foreign_item(item, self), } } - fn fold_expr(&mut self, expr: P) -> P { + fn visit_expr(&mut self, expr: &mut P) { match expr.node { - ast::ExprKind::Mac(_) => self.remove(expr.id).make_expr(), - _ => expr.map(|expr| noop_fold_expr(expr, self)), + ast::ExprKind::Mac(_) => *expr = self.remove(expr.id).make_expr(), + _ => noop_visit_expr(expr, self), } } - fn fold_opt_expr(&mut self, expr: P) -> Option> { + fn filter_map_expr(&mut self, expr: P) -> Option> { match expr.node { ast::ExprKind::Mac(_) => self.remove(expr.id).make_opt_expr(), - _ => noop_fold_opt_expr(expr, self), + _ => noop_filter_map_expr(expr, self), } } - fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { + fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { let (style, mut stmts) = match stmt.node { ast::StmtKind::Mac(mac) => (mac.1, self.remove(stmt.id).make_stmts()), - _ => return noop_fold_stmt(stmt, self), + _ => return noop_flat_map_stmt(stmt, self), }; if style == ast::MacStmtStyle::Semicolon { @@ -165,44 +164,40 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { stmts } - fn fold_pat(&mut self, pat: P) -> P { + fn visit_pat(&mut self, pat: &mut P) { match pat.node { - ast::PatKind::Mac(_) => self.remove(pat.id).make_pat(), - _ => noop_fold_pat(pat, self), + ast::PatKind::Mac(_) => *pat = self.remove(pat.id).make_pat(), + _ => noop_visit_pat(pat, self), } } - fn fold_ty(&mut self, ty: P) -> P { + fn visit_ty(&mut self, ty: &mut P) { match ty.node { - ast::TyKind::Mac(_) => self.remove(ty.id).make_ty(), - _ => noop_fold_ty(ty, self), + ast::TyKind::Mac(_) => *ty = self.remove(ty.id).make_ty(), + _ => noop_visit_ty(ty, self), } } - fn fold_block(&mut self, block: P) -> P { - noop_fold_block(block, self).map(|mut block| { - block.stmts = block.stmts.move_map(|mut stmt| { - if self.monotonic { - assert_eq!(stmt.id, ast::DUMMY_NODE_ID); - stmt.id = self.cx.resolver.next_node_id(); - } - stmt - }); + fn visit_block(&mut self, block: &mut P) { + noop_visit_block(block, self); - block - }) + for stmt in block.stmts.iter_mut() { + if self.monotonic { + assert_eq!(stmt.id, ast::DUMMY_NODE_ID); + stmt.id = self.cx.resolver.next_node_id(); + } + } } - fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod { - let mut module = noop_fold_mod(module, self); + fn visit_mod(&mut self, module: &mut ast::Mod) { + noop_visit_mod(module, self); module.items.retain(|item| match item.node { ast::ItemKind::Mac(_) if !self.cx.ecfg.keep_macs => false, // remove macro definitions _ => true, }); - module } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - mac + fn visit_mac(&mut self, _mac: &mut ast::Mac) { + // Do nothing. } } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0ef2d3b749d81..08f34b22328b6 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -3,7 +3,7 @@ use ext::base::ExtCtxt; use ext::expand::Marker; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; use ext::tt::quoted; -use fold::noop_fold_tt; +use mut_visit::noop_visit_tt; use parse::token::{self, Token, NtTT}; use smallvec::SmallVec; use syntax_pos::DUMMY_SP; @@ -170,7 +170,9 @@ pub fn transcribe(cx: &ExtCtxt, } quoted::TokenTree::Token(sp, tok) => { let mut marker = Marker(cx.current_expansion.mark); - result.push(noop_fold_tt(TokenTree::Token(sp, tok), &mut marker).into()) + let mut tt = TokenTree::Token(sp, tok); + noop_visit_tt(&mut tt, &mut marker); + result.push(tt.into()); } quoted::TokenTree::MetaVarDecl(..) => panic!("unexpected `TokenTree::MetaVarDecl"), } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5fb0132ad4566..93fedb73d271a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1,11 +1,10 @@ -//! A Folder represents an AST->AST fold; it accepts an AST piece, -//! and returns a piece of the same type. So, for instance, macro -//! expansion is a Folder that walks over an AST and produces another -//! AST. +//! A MutVisitor represents an AST modification; it accepts an AST piece and +//! and mutates it in place. So, for instance, macro expansion is a MutVisitor +//! that walks over an AST and modifies it. //! -//! Note: using a Folder (other than the MacroExpander Folder) on +//! Note: using a MutVisitor (other than the MacroExpander MutVisitor) on //! an AST before macro expansion is probably a bad idea. For instance, -//! a folder renaming item names in a module will miss all of those +//! a MutVisitor renaming item names in a module will miss all of those //! that are created by the expansion of a macro. use ast::*; @@ -14,10 +13,11 @@ use source_map::{Spanned, respan}; use parse::token::{self, Token}; use ptr::P; use smallvec::{Array, SmallVec}; +use std::ops::DerefMut; use symbol::keywords; use ThinVec; use tokenstream::*; -use util::move_map::MoveMap; +use util::map_in_place::MapInPlace; use rustc_data_structures::sync::Lrc; @@ -32,1308 +32,1225 @@ impl ExpectOne for SmallVec { } } -pub trait Folder : Sized { - // Any additions to this trait should happen in form - // of a call to a public `noop_*` function that only calls - // out to the folder again, not other `noop_*` functions. +pub trait MutVisitor: Sized { + // Methods in this trait have one of three forms: // - // This is a necessary API workaround to the problem of not - // being able to call out to the super default method - // in an overridden default method. + // fn visit_t(&mut self, t: &mut T); // common + // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare + // fn filter_map_t(&mut self, t: T) -> Option; // rarest + // + // Any additions to this trait should happen in form of a call to a public + // `noop_*` function that only calls out to the visitor again, not other + // `noop_*` functions. This is a necessary API workaround to the problem of + // not being able to call out to the super default method in an overridden + // default method. + // + // When writing these methods, it is better to use destructuring like this: + // + // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { + // visit_a(a); + // visit_b(b); + // } + // + // than to use field access like this: + // + // fn visit_abc(&mut self, abc: &mut ABC) { + // visit_a(&mut abc.a); + // visit_b(&mut abc.b); + // // ignore abc.c + // } + // + // As well as being more concise, the former is explicit about which fields + // are skipped. Furthermore, if a new field is added, the destructuring + // version will cause a compile error, which is good. In comparison, the + // field access version will continue working and it would be easy to + // forget to add handling for it. - fn fold_crate(&mut self, c: Crate) -> Crate { - noop_fold_crate(c, self) + fn visit_crate(&mut self, c: &mut Crate) { + noop_visit_crate(c, self) } - fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem { - noop_fold_meta_list_item(list_item, self) + fn visit_meta_list_item(&mut self, list_item: &mut NestedMetaItem) { + noop_visit_meta_list_item(list_item, self); } - fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem { - noop_fold_meta_item(meta_item, self) + fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { + noop_visit_meta_item(meta_item, self); } - fn fold_use_tree(&mut self, use_tree: UseTree) -> UseTree { - noop_fold_use_tree(use_tree, self) + fn visit_use_tree(&mut self, use_tree: &mut UseTree) { + noop_visit_use_tree(use_tree, self); } - fn fold_foreign_item(&mut self, ni: ForeignItem) -> SmallVec<[ForeignItem; 1]> { - noop_fold_foreign_item(ni, self) + fn flat_map_foreign_item(&mut self, ni: ForeignItem) -> SmallVec<[ForeignItem; 1]> { + noop_flat_map_foreign_item(ni, self) } - fn fold_item(&mut self, i: P) -> SmallVec<[P; 1]> { - noop_fold_item(i, self) + fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { + noop_flat_map_item(i, self) } - fn fold_fn_header(&mut self, header: FnHeader) -> FnHeader { - noop_fold_fn_header(header, self) + fn visit_fn_header(&mut self, header: &mut FnHeader) { + noop_visit_fn_header(header, self); } - fn fold_struct_field(&mut self, sf: StructField) -> StructField { - noop_fold_struct_field(sf, self) + fn visit_struct_field(&mut self, sf: &mut StructField) { + noop_visit_struct_field(sf, self); } - fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind { - noop_fold_item_kind(i, self) + fn visit_item_kind(&mut self, i: &mut ItemKind) { + noop_visit_item_kind(i, self); } - fn fold_trait_item(&mut self, i: TraitItem) -> SmallVec<[TraitItem; 1]> { - noop_fold_trait_item(i, self) + fn flat_map_trait_item(&mut self, i: TraitItem) -> SmallVec<[TraitItem; 1]> { + noop_flat_map_trait_item(i, self) } - fn fold_impl_item(&mut self, i: ImplItem) -> SmallVec<[ImplItem; 1]> { - noop_fold_impl_item(i, self) + fn flat_map_impl_item(&mut self, i: ImplItem) -> SmallVec<[ImplItem; 1]> { + noop_flat_map_impl_item(i, self) } - fn fold_fn_decl(&mut self, d: P) -> P { - noop_fold_fn_decl(d, self) + fn visit_fn_decl(&mut self, d: &mut P) { + noop_visit_fn_decl(d, self); } - fn fold_asyncness(&mut self, a: IsAsync) -> IsAsync { - noop_fold_asyncness(a, self) + fn visit_asyncness(&mut self, a: &mut IsAsync) { + noop_visit_asyncness(a, self); } - fn fold_block(&mut self, b: P) -> P { - noop_fold_block(b, self) + fn visit_block(&mut self, b: &mut P) { + noop_visit_block(b, self); } - fn fold_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { - noop_fold_stmt(s, self) + fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { + noop_flat_map_stmt(s, self) } - fn fold_arm(&mut self, a: Arm) -> Arm { - noop_fold_arm(a, self) + fn visit_arm(&mut self, a: &mut Arm) { + noop_visit_arm(a, self); } - fn fold_guard(&mut self, g: Guard) -> Guard { - noop_fold_guard(g, self) + fn visit_guard(&mut self, g: &mut Guard) { + noop_visit_guard(g, self); } - fn fold_pat(&mut self, p: P) -> P { - noop_fold_pat(p, self) + fn visit_pat(&mut self, p: &mut P) { + noop_visit_pat(p, self); } - fn fold_anon_const(&mut self, c: AnonConst) -> AnonConst { - noop_fold_anon_const(c, self) + fn visit_anon_const(&mut self, c: &mut AnonConst) { + noop_visit_anon_const(c, self); } - fn fold_expr(&mut self, e: P) -> P { - e.map(|e| noop_fold_expr(e, self)) + fn visit_expr(&mut self, e: &mut P) { + noop_visit_expr(e, self); } - fn fold_opt_expr(&mut self, e: P) -> Option> { - noop_fold_opt_expr(e, self) + fn filter_map_expr(&mut self, e: P) -> Option> { + noop_filter_map_expr(e, self) } - fn fold_generic_arg(&mut self, arg: GenericArg) -> GenericArg { - match arg { - GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.fold_lifetime(lt)), - GenericArg::Type(ty) => GenericArg::Type(self.fold_ty(ty)), - } + fn visit_generic_arg(&mut self, arg: &mut GenericArg) { + noop_visit_generic_arg(arg, self); } - fn fold_ty(&mut self, t: P) -> P { - noop_fold_ty(t, self) + fn visit_ty(&mut self, t: &mut P) { + noop_visit_ty(t, self); } - fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime { - noop_fold_lifetime(l, self) + fn visit_lifetime(&mut self, l: &mut Lifetime) { + noop_visit_lifetime(l, self); } - fn fold_ty_binding(&mut self, t: TypeBinding) -> TypeBinding { - noop_fold_ty_binding(t, self) + fn visit_ty_binding(&mut self, t: &mut TypeBinding) { + noop_visit_ty_binding(t, self); } - fn fold_mod(&mut self, m: Mod) -> Mod { - noop_fold_mod(m, self) + fn visit_mod(&mut self, m: &mut Mod) { + noop_visit_mod(m, self); } - fn fold_foreign_mod(&mut self, nm: ForeignMod) -> ForeignMod { - noop_fold_foreign_mod(nm, self) + fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { + noop_visit_foreign_mod(nm, self); } - fn fold_variant(&mut self, v: Variant) -> Variant { - noop_fold_variant(v, self) + fn visit_variant(&mut self, v: &mut Variant) { + noop_visit_variant(v, self); } - fn fold_ident(&mut self, i: Ident) -> Ident { - noop_fold_ident(i, self) + fn visit_ident(&mut self, i: &mut Ident) { + noop_visit_ident(i, self); } - fn fold_path(&mut self, p: Path) -> Path { - noop_fold_path(p, self) + fn visit_path(&mut self, p: &mut Path) { + noop_visit_path(p, self); } - fn fold_qself(&mut self, qs: Option) -> Option { - noop_fold_qself(qs, self) + fn visit_qself(&mut self, qs: &mut Option) { + noop_visit_qself(qs, self); } - fn fold_generic_args(&mut self, p: GenericArgs) -> GenericArgs { - noop_fold_generic_args(p, self) + fn visit_generic_args(&mut self, p: &mut GenericArgs) { + noop_visit_generic_args(p, self); } - fn fold_angle_bracketed_parameter_data(&mut self, p: AngleBracketedArgs) - -> AngleBracketedArgs - { - noop_fold_angle_bracketed_parameter_data(p, self) + fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { + noop_visit_angle_bracketed_parameter_data(p, self); } - fn fold_parenthesized_parameter_data(&mut self, p: ParenthesizedArgs) - -> ParenthesizedArgs - { - noop_fold_parenthesized_parameter_data(p, self) + fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { + noop_visit_parenthesized_parameter_data(p, self); } - fn fold_local(&mut self, l: P) -> P { - noop_fold_local(l, self) + fn visit_local(&mut self, l: &mut P) { + noop_visit_local(l, self); } - fn fold_mac(&mut self, _mac: Mac) -> Mac { - panic!("fold_mac disabled by default"); - // N.B., see note about macros above. - // if you really want a folder that - // works on macros, use this - // definition in your trait impl: - // fold::noop_fold_mac(_mac, self) + fn visit_mac(&mut self, _mac: &mut Mac) { + panic!("visit_mac disabled by default"); + // N.B., see note about macros above. If you really want a visitor that + // works on macros, use this definition in your trait impl: + // mut_visit::noop_visit_mac(_mac, self); } - fn fold_macro_def(&mut self, def: MacroDef) -> MacroDef { - noop_fold_macro_def(def, self) + fn visit_macro_def(&mut self, def: &mut MacroDef) { + noop_visit_macro_def(def, self); } - fn fold_label(&mut self, label: Label) -> Label { - noop_fold_label(label, self) + fn visit_label(&mut self, label: &mut Label) { + noop_visit_label(label, self); } - fn fold_attribute(&mut self, at: Attribute) -> Attribute { - noop_fold_attribute(at, self) + fn visit_attribute(&mut self, at: &mut Attribute) { + noop_visit_attribute(at, self); } - fn fold_arg(&mut self, a: Arg) -> Arg { - noop_fold_arg(a, self) + fn visit_arg(&mut self, a: &mut Arg) { + noop_visit_arg(a, self); } - fn fold_generics(&mut self, generics: Generics) -> Generics { - noop_fold_generics(generics, self) + fn visit_generics(&mut self, generics: &mut Generics) { + noop_visit_generics(generics, self); } - fn fold_trait_ref(&mut self, p: TraitRef) -> TraitRef { - noop_fold_trait_ref(p, self) + fn visit_trait_ref(&mut self, tr: &mut TraitRef) { + noop_visit_trait_ref(tr, self); } - fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef { - noop_fold_poly_trait_ref(p, self) + fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { + noop_visit_poly_trait_ref(p, self); } - fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData { - noop_fold_variant_data(vdata, self) + fn visit_variant_data(&mut self, vdata: &mut VariantData) { + noop_visit_variant_data(vdata, self); } - fn fold_generic_param(&mut self, param: GenericParam) -> GenericParam { - noop_fold_generic_param(param, self) + fn visit_generic_param(&mut self, param: &mut GenericParam) { + noop_visit_generic_param(param, self); } - fn fold_generic_params(&mut self, params: Vec) -> Vec { - noop_fold_generic_params(params, self) + fn visit_generic_params(&mut self, params: &mut Vec) { + noop_visit_generic_params(params, self); } - fn fold_tt(&mut self, tt: TokenTree) -> TokenTree { - noop_fold_tt(tt, self) + fn visit_tt(&mut self, tt: &mut TokenTree) { + noop_visit_tt(tt, self); } - fn fold_tts(&mut self, tts: TokenStream) -> TokenStream { - noop_fold_tts(tts, self) + fn visit_tts(&mut self, tts: &mut TokenStream) { + noop_visit_tts(tts, self); } - fn fold_token(&mut self, t: token::Token) -> token::Token { - noop_fold_token(t, self) + fn visit_token(&mut self, t: &mut Token) { + noop_visit_token(t, self); } - fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal { - noop_fold_interpolated(nt, self) + fn visit_interpolated(&mut self, nt: &mut token::Nonterminal) { + noop_visit_interpolated(nt, self); } - fn fold_param_bound(&mut self, tpb: GenericBound) -> GenericBound { - noop_fold_param_bound(tpb, self) + fn visit_param_bound(&mut self, tpb: &mut GenericBound) { + noop_visit_param_bound(tpb, self); } - fn fold_mt(&mut self, mt: MutTy) -> MutTy { - noop_fold_mt(mt, self) + fn visit_mt(&mut self, mt: &mut MutTy) { + noop_visit_mt(mt, self); } - fn fold_field(&mut self, field: Field) -> Field { - noop_fold_field(field, self) + fn visit_field(&mut self, field: &mut Field) { + noop_visit_field(field, self); } - fn fold_where_clause(&mut self, where_clause: WhereClause) - -> WhereClause { - noop_fold_where_clause(where_clause, self) + fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { + noop_visit_where_clause(where_clause, self); } - fn fold_where_predicate(&mut self, where_predicate: WherePredicate) - -> WherePredicate { - noop_fold_where_predicate(where_predicate, self) + fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { + noop_visit_where_predicate(where_predicate, self); } - fn fold_vis(&mut self, vis: Visibility) -> Visibility { - noop_fold_vis(vis, self) + fn visit_vis(&mut self, vis: &mut Visibility) { + noop_visit_vis(vis, self); } - fn new_id(&mut self, i: NodeId) -> NodeId { - i + fn visit_id(&mut self, _id: &mut NodeId) { + // Do nothing. } - fn new_span(&mut self, sp: Span) -> Span { - sp + fn visit_span(&mut self, _sp: &mut Span) { + // Do nothing. } } -// No `noop_` prefix because there isn't a corresponding method in `Folder`. -fn fold_attrs(attrs: Vec, fld: &mut T) -> Vec { - attrs.move_map(|x| fld.fold_attribute(x)) +/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful +/// when using a `flat_map_*` or `filter_map_*` method within a `visit_` +/// method. +// +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_clobber(t: &mut T, f: F) where F: FnOnce(T) -> T { + unsafe { std::ptr::write(t, f(std::ptr::read(t))); } } -// No `noop_` prefix because there isn't a corresponding method in `Folder`. -fn fold_thin_attrs(attrs: ThinVec, fld: &mut T) -> ThinVec { - fold_attrs(attrs.into(), fld).into() +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +#[inline] +pub fn visit_vec(elems: &mut Vec, mut visit_elem: F) where F: FnMut(&mut T) { + for elem in elems { + visit_elem(elem); + } } -// No `noop_` prefix because there isn't a corresponding method in `Folder`. -fn fold_exprs(es: Vec>, fld: &mut T) -> Vec> { - es.move_flat_map(|e| fld.fold_opt_expr(e)) +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +#[inline] +pub fn visit_opt(opt: &mut Option, mut visit_elem: F) where F: FnMut(&mut T) { + if let Some(elem) = opt { + visit_elem(elem); + } } -// No `noop_` prefix because there isn't a corresponding method in `Folder`. -fn fold_bounds(bounds: GenericBounds, folder: &mut T) -> GenericBounds { - bounds.move_map(|bound| folder.fold_param_bound(bound)) +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_attrs(attrs: &mut Vec, vis: &mut T) { + visit_vec(attrs, |attr| vis.visit_attribute(attr)); } -// No `noop_` prefix because there isn't a corresponding method in `Folder`. -fn fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { - MethodSig { - header: folder.fold_fn_header(sig.header), - decl: folder.fold_fn_decl(sig.decl) +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_thin_attrs(attrs: &mut ThinVec, vis: &mut T) { + for attr in attrs.iter_mut() { + vis.visit_attribute(attr); } } -pub fn noop_fold_use_tree(use_tree: UseTree, fld: &mut T) -> UseTree { - UseTree { - span: fld.new_span(use_tree.span), - prefix: fld.fold_path(use_tree.prefix), - kind: match use_tree.kind { - UseTreeKind::Simple(rename, id1, id2) => - UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident)), - fld.new_id(id1), fld.new_id(id2)), - UseTreeKind::Glob => UseTreeKind::Glob, - UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| { - (fld.fold_use_tree(tree), fld.new_id(id)) - })), - }, - } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_exprs(exprs: &mut Vec>, vis: &mut T) { + exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) } -pub fn noop_fold_arm(Arm {attrs, pats, guard, body}: Arm, - fld: &mut T) -> Arm { - Arm { - attrs: fold_attrs(attrs, fld), - pats: pats.move_map(|x| fld.fold_pat(x)), - guard: guard.map(|x| fld.fold_guard(x)), - body: fld.fold_expr(body), - } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_bounds(bounds: &mut GenericBounds, vis: &mut T) { + visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } -pub fn noop_fold_guard(g: Guard, fld: &mut T) -> Guard { - match g { - Guard::If(e) => Guard::If(fld.fold_expr(e)), - } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_method_sig(MethodSig { header, decl }: &mut MethodSig, vis: &mut T) { + vis.visit_fn_header(header); + vis.visit_fn_decl(decl); } -pub fn noop_fold_ty_binding(b: TypeBinding, fld: &mut T) -> TypeBinding { - TypeBinding { - id: fld.new_id(b.id), - ident: fld.fold_ident(b.ident), - ty: fld.fold_ty(b.ty), - span: fld.new_span(b.span), +pub fn noop_visit_use_tree(use_tree: &mut UseTree, vis: &mut T) { + let UseTree { prefix, kind, span } = use_tree; + vis.visit_path(prefix); + match kind { + UseTreeKind::Simple(rename, id1, id2) => { + visit_opt(rename, |rename| vis.visit_ident(rename)); + vis.visit_id(id1); + vis.visit_id(id2); + } + UseTreeKind::Nested(items) => { + for (tree, id) in items { + vis.visit_use_tree(tree); + vis.visit_id(id); + } + } + UseTreeKind::Glob => {} } + vis.visit_span(span); } -pub fn noop_fold_ty(t: P, fld: &mut T) -> P { - t.map(|Ty {id, node, span}| Ty { - id: fld.new_id(id), - node: match node { - TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => node, - TyKind::Slice(ty) => TyKind::Slice(fld.fold_ty(ty)), - TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)), - TyKind::Rptr(region, mt) => { - TyKind::Rptr(region.map(|lt| noop_fold_lifetime(lt, fld)), fld.fold_mt(mt)) - } - TyKind::BareFn(f) => { - TyKind::BareFn(f.map(|BareFnTy {generic_params, unsafety, abi, decl}| BareFnTy { - generic_params: fld.fold_generic_params(generic_params), - unsafety, - abi, - decl: fld.fold_fn_decl(decl) - })) - } - TyKind::Never => node, - TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))), - TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)), - TyKind::Path(qself, path) => { - TyKind::Path(fld.fold_qself(qself), fld.fold_path(path)) - } - TyKind::Array(ty, length) => { - TyKind::Array(fld.fold_ty(ty), fld.fold_anon_const(length)) - } - TyKind::Typeof(expr) => { - TyKind::Typeof(fld.fold_anon_const(expr)) - } - TyKind::TraitObject(bounds, syntax) => { - TyKind::TraitObject(bounds.move_map(|b| fld.fold_param_bound(b)), syntax) - } - TyKind::ImplTrait(id, bounds) => { - TyKind::ImplTrait(fld.new_id(id), bounds.move_map(|b| fld.fold_param_bound(b))) - } - TyKind::Mac(mac) => { - TyKind::Mac(fld.fold_mac(mac)) - } - }, - span: fld.new_span(span) - }) +pub fn noop_visit_arm(Arm { attrs, pats, guard, body }: &mut Arm, vis: &mut T) { + visit_attrs(attrs, vis); + visit_vec(pats, |pat| vis.visit_pat(pat)); + visit_opt(guard, |guard| vis.visit_guard(guard)); + vis.visit_expr(body); } -pub fn noop_fold_foreign_mod(ForeignMod {abi, items}: ForeignMod, - fld: &mut T) -> ForeignMod { - ForeignMod { - abi, - items: items.move_flat_map(|x| fld.fold_foreign_item(x)), +pub fn noop_visit_guard(g: &mut Guard, vis: &mut T) { + match g { + Guard::If(e) => vis.visit_expr(e), } } -pub fn noop_fold_variant(v: Variant, fld: &mut T) -> Variant { - Spanned { - node: Variant_ { - ident: fld.fold_ident(v.node.ident), - attrs: fold_attrs(v.node.attrs, fld), - data: fld.fold_variant_data(v.node.data), - disr_expr: v.node.disr_expr.map(|e| fld.fold_anon_const(e)), - }, - span: fld.new_span(v.span), +pub fn noop_visit_ty_binding(TypeBinding { id, ident, ty, span }: &mut TypeBinding, + vis: &mut T) { + vis.visit_id(id); + vis.visit_ident(ident); + vis.visit_ty(ty); + vis.visit_span(span); +} + +pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { + let Ty { id, node, span } = ty.deref_mut(); + vis.visit_id(id); + match node { + TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never => {} + TyKind::Slice(ty) => vis.visit_ty(ty), + TyKind::Ptr(mt) => vis.visit_mt(mt), + TyKind::Rptr(lt, mt) => { + visit_opt(lt, |lt| noop_visit_lifetime(lt, vis)); + vis.visit_mt(mt); + } + TyKind::BareFn(bft) => { + let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut(); + vis.visit_generic_params(generic_params); + vis.visit_fn_decl(decl); + } + TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)), + TyKind::Paren(ty) => vis.visit_ty(ty), + TyKind::Path(qself, path) => { + vis.visit_qself(qself); + vis.visit_path(path); + } + TyKind::Array(ty, length) => { + vis.visit_ty(ty); + vis.visit_anon_const(length); + } + TyKind::Typeof(expr) => vis.visit_anon_const(expr), + TyKind::TraitObject(bounds, _syntax) => + visit_vec(bounds, |bound| vis.visit_param_bound(bound)), + TyKind::ImplTrait(id, bounds) => { + vis.visit_id(id); + visit_vec(bounds, |bound| vis.visit_param_bound(bound)); + } + TyKind::Mac(mac) => vis.visit_mac(mac), } + vis.visit_span(span); +} + +pub fn noop_visit_foreign_mod(foreign_mod: &mut ForeignMod, vis: &mut T) { + let ForeignMod { abi: _, items} = foreign_mod; + items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); +} + +pub fn noop_visit_variant(variant: &mut Variant, vis: &mut T) { + let Spanned { node: Variant_ { ident, attrs, data, disr_expr }, span } = variant; + vis.visit_ident(ident); + visit_attrs(attrs, vis); + vis.visit_variant_data(data); + visit_opt(disr_expr, |disr_expr| vis.visit_anon_const(disr_expr)); + vis.visit_span(span); } -pub fn noop_fold_ident(ident: Ident, fld: &mut T) -> Ident { - Ident::new(ident.name, fld.new_span(ident.span)) +pub fn noop_visit_ident(Ident { name: _, span }: &mut Ident, vis: &mut T) { + vis.visit_span(span); } -pub fn noop_fold_path(Path { segments, span }: Path, fld: &mut T) -> Path { - Path { - segments: segments.move_map(|PathSegment { ident, id, args }| PathSegment { - ident: fld.fold_ident(ident), - id: fld.new_id(id), - args: args.map(|args| args.map(|args| fld.fold_generic_args(args))), - }), - span: fld.new_span(span) +pub fn noop_visit_path(Path { segments, span }: &mut Path, vis: &mut T) { + vis.visit_span(span); + for PathSegment { ident, id, args } in segments { + vis.visit_ident(ident); + vis.visit_id(id); + visit_opt(args, |args| vis.visit_generic_args(args)); } } -pub fn noop_fold_qself(qself: Option, fld: &mut T) -> Option { - qself.map(|QSelf { ty, path_span, position }| { - QSelf { - ty: fld.fold_ty(ty), - path_span: fld.new_span(path_span), - position, - } +pub fn noop_visit_qself(qself: &mut Option, vis: &mut T) { + visit_opt(qself, |QSelf { ty, path_span, position: _ }| { + vis.visit_ty(ty); + vis.visit_span(path_span); }) } -pub fn noop_fold_generic_args(generic_args: GenericArgs, fld: &mut T) -> GenericArgs -{ +pub fn noop_visit_generic_args(generic_args: &mut GenericArgs, vis: &mut T) { match generic_args { - GenericArgs::AngleBracketed(data) => { - GenericArgs::AngleBracketed(fld.fold_angle_bracketed_parameter_data(data)) - } - GenericArgs::Parenthesized(data) => { - GenericArgs::Parenthesized(fld.fold_parenthesized_parameter_data(data)) - } + GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), + GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), } } -pub fn noop_fold_angle_bracketed_parameter_data(data: AngleBracketedArgs, - fld: &mut T) - -> AngleBracketedArgs -{ - let AngleBracketedArgs { args, bindings, span } = data; - AngleBracketedArgs { - args: args.move_map(|arg| fld.fold_generic_arg(arg)), - bindings: bindings.move_map(|b| fld.fold_ty_binding(b)), - span: fld.new_span(span) +pub fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) { + match arg { + GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), + GenericArg::Type(ty) => vis.visit_ty(ty), } } -pub fn noop_fold_parenthesized_parameter_data(data: ParenthesizedArgs, - fld: &mut T) - -> ParenthesizedArgs -{ - let ParenthesizedArgs { inputs, output, span } = data; - ParenthesizedArgs { - inputs: inputs.move_map(|ty| fld.fold_ty(ty)), - output: output.map(|ty| fld.fold_ty(ty)), - span: fld.new_span(span) - } -} - -pub fn noop_fold_local(l: P, fld: &mut T) -> P { - l.map(|Local {id, pat, ty, init, span, attrs}| Local { - id: fld.new_id(id), - pat: fld.fold_pat(pat), - ty: ty.map(|t| fld.fold_ty(t)), - init: init.map(|e| fld.fold_expr(e)), - span: fld.new_span(span), - attrs: fold_attrs(attrs.into(), fld).into(), - }) +pub fn noop_visit_angle_bracketed_parameter_data(data: &mut AngleBracketedArgs, + vis: &mut T) { + let AngleBracketedArgs { args, bindings, span } = data; + visit_vec(args, |arg| vis.visit_generic_arg(arg)); + visit_vec(bindings, |binding| vis.visit_ty_binding(binding)); + vis.visit_span(span); } -pub fn noop_fold_attribute(attr: Attribute, fld: &mut T) -> Attribute { - Attribute { - id: attr.id, - style: attr.style, - path: fld.fold_path(attr.path), - tokens: fld.fold_tts(attr.tokens), - is_sugared_doc: attr.is_sugared_doc, - span: fld.new_span(attr.span), - } +pub fn noop_visit_parenthesized_parameter_data(args: &mut ParenthesizedArgs, + vis: &mut T) { + let ParenthesizedArgs { inputs, output, span } = args; + visit_vec(inputs, |input| vis.visit_ty(input)); + visit_opt(output, |output| vis.visit_ty(output)); + vis.visit_span(span); } -pub fn noop_fold_mac(Spanned {node, span}: Mac, fld: &mut T) -> Mac { - Spanned { - node: Mac_ { - tts: fld.fold_tts(node.stream()).into(), - path: fld.fold_path(node.path), - delim: node.delim, - }, - span: fld.new_span(span) - } +pub fn noop_visit_local(local: &mut P, vis: &mut T) { + let Local { id, pat, ty, init, span, attrs } = local.deref_mut(); + vis.visit_id(id); + vis.visit_pat(pat); + visit_opt(ty, |ty| vis.visit_ty(ty)); + visit_opt(init, |init| vis.visit_expr(init)); + vis.visit_span(span); + visit_thin_attrs(attrs, vis); } -pub fn noop_fold_macro_def(def: MacroDef, fld: &mut T) -> MacroDef { - MacroDef { - tokens: fld.fold_tts(def.tokens.into()).into(), - legacy: def.legacy, - } +pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { + let Attribute { id: _, style: _, path, tokens, is_sugared_doc: _, span } = attr; + vis.visit_path(path); + vis.visit_tts(tokens); + vis.visit_span(span); } -pub fn noop_fold_meta_list_item(li: NestedMetaItem, fld: &mut T) - -> NestedMetaItem { - Spanned { - node: match li.node { - NestedMetaItemKind::MetaItem(mi) => { - NestedMetaItemKind::MetaItem(fld.fold_meta_item(mi)) - }, - NestedMetaItemKind::Literal(lit) => NestedMetaItemKind::Literal(lit) - }, - span: fld.new_span(li.span) - } +pub fn noop_visit_mac(Spanned { node, span }: &mut Mac, vis: &mut T) { + let Mac_ { path, delim: _, tts } = node; + vis.visit_path(path); + vis.visit_tts(tts); + vis.visit_span(span); } -pub fn noop_fold_meta_item(mi: MetaItem, fld: &mut T) -> MetaItem { - MetaItem { - ident: mi.ident, - node: match mi.node { - MetaItemKind::Word => MetaItemKind::Word, - MetaItemKind::List(mis) => { - MetaItemKind::List(mis.move_map(|e| fld.fold_meta_list_item(e))) - }, - MetaItemKind::NameValue(s) => MetaItemKind::NameValue(s), - }, - span: fld.new_span(mi.span) +pub fn noop_visit_macro_def(macro_def: &mut MacroDef, vis: &mut T) { + let MacroDef { tokens, legacy: _ } = macro_def; + vis.visit_tts(tokens); +} + +pub fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T) { + let Spanned { node, span } = li; + match node { + NestedMetaItemKind::MetaItem(mi) => vis.visit_meta_item(mi), + NestedMetaItemKind::Literal(_lit) => {} } + vis.visit_span(span); } -pub fn noop_fold_arg(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg { - Arg { - id: fld.new_id(id), - pat: fld.fold_pat(pat), - ty: fld.fold_ty(ty) +pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { + let MetaItem { ident: _, node, span } = mi; + match node { + MetaItemKind::Word => {} + MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)), + MetaItemKind::NameValue(_s) => {} } + vis.visit_span(span); +} + +pub fn noop_visit_arg(Arg { id, pat, ty }: &mut Arg, vis: &mut T) { + vis.visit_id(id); + vis.visit_pat(pat); + vis.visit_ty(ty); } -pub fn noop_fold_tt(tt: TokenTree, fld: &mut T) -> TokenTree { +pub fn noop_visit_tt(tt: &mut TokenTree, vis: &mut T) { match tt { - TokenTree::Token(span, tok) => - TokenTree::Token(fld.new_span(span), fld.fold_token(tok)), - TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited( - DelimSpan::from_pair(fld.new_span(span.open), fld.new_span(span.close)), - delim, - fld.fold_tts(tts).into(), - ), + TokenTree::Token(span, tok) => { + vis.visit_span(span); + vis.visit_token(tok); + } + TokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { + vis.visit_span(open); + vis.visit_span(close); + vis.visit_tts(tts); + } } } -pub fn noop_fold_tts(tts: TokenStream, fld: &mut T) -> TokenStream { - tts.map(|tt| fld.fold_tt(tt)) +pub fn noop_visit_tts(TokenStream(tts): &mut TokenStream, vis: &mut T) { + visit_opt(tts, |tts| { + let tts = Lrc::make_mut(tts); + visit_vec(tts, |(tree, _is_joint)| vis.visit_tt(tree)); + }) } -// apply ident folder if it's an ident, apply other folds to interpolated nodes -pub fn noop_fold_token(t: token::Token, fld: &mut T) -> token::Token { +// apply ident visitor if it's an ident, apply other visits to interpolated nodes +pub fn noop_visit_token(t: &mut Token, vis: &mut T) { match t { - token::Ident(id, is_raw) => token::Ident(fld.fold_ident(id), is_raw), - token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)), + token::Ident(id, _is_raw) => vis.visit_ident(id), + token::Lifetime(id) => vis.visit_ident(id), token::Interpolated(nt) => { - let nt = match Lrc::try_unwrap(nt) { - Ok(nt) => nt, - Err(nt) => (*nt).clone(), - }; - Token::interpolated(fld.fold_interpolated(nt.0)) + let nt = Lrc::make_mut(nt); + vis.visit_interpolated(&mut nt.0); + nt.1 = token::LazyTokenStream::new(); } - _ => t + _ => {} } } -/// apply folder to elements of interpolated nodes +/// Apply visitor to elements of interpolated nodes. // -// N.B., this can occur only when applying a fold to partially expanded code, where -// parsed pieces have gotten implanted ito *other* macro invocations. This is relevant -// for macro hygiene, but possibly not elsewhere. +// N.B., this can occur only when applying a visitor to partially expanded +// code, where parsed pieces have gotten implanted ito *other* macro +// invocations. This is relevant for macro hygiene, but possibly not elsewhere. // -// One problem here occurs because the types for fold_item, fold_stmt, etc. allow the -// folder to return *multiple* items; this is a problem for the nodes here, because -// they insist on having exactly one piece. One solution would be to mangle the fold -// trait to include one-to-many and one-to-one versions of these entry points, but that -// would probably confuse a lot of people and help very few. Instead, I'm just going -// to put in dynamic checks. I think the performance impact of this will be pretty much -// nonexistent. The danger is that someone will apply a fold to a partially expanded -// node, and will be confused by the fact that their "fold_item" or "fold_stmt" isn't -// getting called on NtItem or NtStmt nodes. Hopefully they'll wind up reading this -// comment, and doing something appropriate. +// One problem here occurs because the types for flat_map_item, flat_map_stmt, +// etc. allow the visitor to return *multiple* items; this is a problem for the +// nodes here, because they insist on having exactly one piece. One solution +// would be to mangle the MutVisitor trait to include one-to-many and +// one-to-one versions of these entry points, but that would probably confuse a +// lot of people and help very few. Instead, I'm just going to put in dynamic +// checks. I think the performance impact of this will be pretty much +// nonexistent. The danger is that someone will apply a MutVisitor to a +// partially expanded node, and will be confused by the fact that their +// "flat_map_item" or "flat_map_stmt" isn't getting called on NtItem or NtStmt +// nodes. Hopefully they'll wind up reading this comment, and doing something +// appropriate. // -// BTW, design choice: I considered just changing the type of, e.g., NtItem to contain -// multiple items, but decided against it when I looked at parse_item_or_view_item and -// tried to figure out what I would do with multiple items there.... -pub fn noop_fold_interpolated(nt: token::Nonterminal, fld: &mut T) - -> token::Nonterminal { +// BTW, design choice: I considered just changing the type of, e.g., NtItem to +// contain multiple items, but decided against it when I looked at +// parse_item_or_view_item and tried to figure out what I would do with +// multiple items there.... +pub fn noop_visit_interpolated(nt: &mut token::Nonterminal, vis: &mut T) { match nt { token::NtItem(item) => - token::NtItem(fld.fold_item(item) - // this is probably okay, because the only folds likely - // to peek inside interpolated nodes will be renamings/markings, - // which map single items to single items - .expect_one("expected fold to produce exactly one item")), - token::NtBlock(block) => token::NtBlock(fld.fold_block(block)), + visit_clobber(item, |item| { + // This is probably okay, because the only visitors likely to + // peek inside interpolated nodes will be renamings/markings, + // which map single items to single items. + vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") + }), + token::NtBlock(block) => vis.visit_block(block), token::NtStmt(stmt) => - token::NtStmt(fld.fold_stmt(stmt) - // this is probably okay, because the only folds likely - // to peek inside interpolated nodes will be renamings/markings, - // which map single items to single items - .expect_one("expected fold to produce exactly one statement")), - token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), - token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), - token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), - token::NtIdent(ident, is_raw) => token::NtIdent(fld.fold_ident(ident), is_raw), - token::NtLifetime(ident) => token::NtLifetime(fld.fold_ident(ident)), - token::NtLiteral(expr) => token::NtLiteral(fld.fold_expr(expr)), - token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)), - token::NtPath(path) => token::NtPath(fld.fold_path(path)), - token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)), - token::NtArm(arm) => token::NtArm(fld.fold_arm(arm)), + visit_clobber(stmt, |stmt| { + // See reasoning above. + vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") + }), + token::NtPat(pat) => vis.visit_pat(pat), + token::NtExpr(expr) => vis.visit_expr(expr), + token::NtTy(ty) => vis.visit_ty(ty), + token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), + token::NtLifetime(ident) => vis.visit_ident(ident), + token::NtLiteral(expr) => vis.visit_expr(expr), + token::NtMeta(meta) => vis.visit_meta_item(meta), + token::NtPath(path) => vis.visit_path(path), + token::NtTT(tt) => vis.visit_tt(tt), + token::NtArm(arm) => vis.visit_arm(arm), token::NtImplItem(item) => - token::NtImplItem(fld.fold_impl_item(item) - .expect_one("expected fold to produce exactly one item")), + visit_clobber(item, |item| { + // See reasoning above. + vis.flat_map_impl_item(item) + .expect_one("expected visitor to produce exactly one item") + }), token::NtTraitItem(item) => - token::NtTraitItem(fld.fold_trait_item(item) - .expect_one("expected fold to produce exactly one item")), - token::NtGenerics(generics) => token::NtGenerics(fld.fold_generics(generics)), - token::NtWhereClause(where_clause) => - token::NtWhereClause(fld.fold_where_clause(where_clause)), - token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)), - token::NtVis(vis) => token::NtVis(fld.fold_vis(vis)), - token::NtForeignItem(ni) => - token::NtForeignItem(fld.fold_foreign_item(ni) - // see reasoning above - .expect_one("expected fold to produce exactly one item")), - } -} - -pub fn noop_fold_asyncness(asyncness: IsAsync, fld: &mut T) -> IsAsync { + visit_clobber(item, |item| { + // See reasoning above. + vis.flat_map_trait_item(item) + .expect_one("expected visitor to produce exactly one item") + }), + token::NtGenerics(generics) => vis.visit_generics(generics), + token::NtWhereClause(where_clause) => vis.visit_where_clause(where_clause), + token::NtArg(arg) => vis.visit_arg(arg), + token::NtVis(visib) => vis.visit_vis(visib), + token::NtForeignItem(item) => + visit_clobber(item, |item| { + // See reasoning above. + vis.flat_map_foreign_item(item) + .expect_one("expected visitor to produce exactly one item") + }), + } +} + +pub fn noop_visit_asyncness(asyncness: &mut IsAsync, vis: &mut T) { match asyncness { - IsAsync::Async { closure_id, return_impl_trait_id } => IsAsync::Async { - closure_id: fld.new_id(closure_id), - return_impl_trait_id: fld.new_id(return_impl_trait_id), - }, - IsAsync::NotAsync => IsAsync::NotAsync, + IsAsync::Async { closure_id, return_impl_trait_id } => { + vis.visit_id(closure_id); + vis.visit_id(return_impl_trait_id); + } + IsAsync::NotAsync => {} } } -pub fn noop_fold_fn_decl(decl: P, fld: &mut T) -> P { - decl.map(|FnDecl {inputs, output, variadic}| FnDecl { - inputs: inputs.move_map(|x| fld.fold_arg(x)), - output: match output { - FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(fld.fold_ty(ty)), - FunctionRetTy::Default(span) => FunctionRetTy::Default(fld.new_span(span)), - }, - variadic, - }) +pub fn noop_visit_fn_decl(decl: &mut P, vis: &mut T) { + let FnDecl { inputs, output, variadic: _ } = decl.deref_mut(); + visit_vec(inputs, |input| vis.visit_arg(input)); + match output { + FunctionRetTy::Default(span) => vis.visit_span(span), + FunctionRetTy::Ty(ty) => vis.visit_ty(ty), + } } -pub fn noop_fold_param_bound(pb: GenericBound, fld: &mut T) -> GenericBound where T: Folder { +pub fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) { match pb { - GenericBound::Trait(ty, modifier) => { - GenericBound::Trait(fld.fold_poly_trait_ref(ty), modifier) - } - GenericBound::Outlives(lifetime) => { - GenericBound::Outlives(noop_fold_lifetime(lifetime, fld)) - } + GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), + GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis), } } -pub fn noop_fold_generic_param(param: GenericParam, fld: &mut T) -> GenericParam { - GenericParam { - ident: fld.fold_ident(param.ident), - id: fld.new_id(param.id), - attrs: fold_thin_attrs(param.attrs, fld), - bounds: param.bounds.move_map(|l| noop_fold_param_bound(l, fld)), - kind: match param.kind { - GenericParamKind::Lifetime => GenericParamKind::Lifetime, - GenericParamKind::Type { default } => GenericParamKind::Type { - default: default.map(|ty| fld.fold_ty(ty)) - } +pub fn noop_visit_generic_param(param: &mut GenericParam, vis: &mut T) { + let GenericParam { id, ident, attrs, bounds, kind } = param; + vis.visit_id(id); + vis.visit_ident(ident); + visit_thin_attrs(attrs, vis); + visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); + match kind { + GenericParamKind::Lifetime => {} + GenericParamKind::Type { default } => { + visit_opt(default, |default| vis.visit_ty(default)); } } } -pub fn noop_fold_generic_params( - params: Vec, - fld: &mut T -) -> Vec { - params.move_map(|p| fld.fold_generic_param(p)) +pub fn noop_visit_generic_params(params: &mut Vec, vis: &mut T){ + visit_vec(params, |param| vis.visit_generic_param(param)); } -pub fn noop_fold_label(label: Label, fld: &mut T) -> Label { - Label { - ident: fld.fold_ident(label.ident), - } +pub fn noop_visit_label(Label { ident }: &mut Label, vis: &mut T) { + vis.visit_ident(ident); } -fn noop_fold_lifetime(l: Lifetime, fld: &mut T) -> Lifetime { - Lifetime { - id: fld.new_id(l.id), - ident: fld.fold_ident(l.ident), - } +fn noop_visit_lifetime(Lifetime { id, ident }: &mut Lifetime, vis: &mut T) { + vis.visit_id(id); + vis.visit_ident(ident); } -pub fn noop_fold_generics(Generics { params, where_clause, span }: Generics, - fld: &mut T) -> Generics { - Generics { - params: fld.fold_generic_params(params), - where_clause: fld.fold_where_clause(where_clause), - span: fld.new_span(span), - } +pub fn noop_visit_generics(generics: &mut Generics, vis: &mut T) { + let Generics { params, where_clause, span } = generics; + vis.visit_generic_params(params); + vis.visit_where_clause(where_clause); + vis.visit_span(span); } -pub fn noop_fold_where_clause( - WhereClause {id, predicates, span}: WhereClause, - fld: &mut T) - -> WhereClause { - WhereClause { - id: fld.new_id(id), - predicates: predicates.move_map(|predicate| { - fld.fold_where_predicate(predicate) - }), - span: fld.new_span(span), - } +pub fn noop_visit_where_clause(wc: &mut WhereClause, vis: &mut T) { + let WhereClause { id, predicates, span } = wc; + vis.visit_id(id); + visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); + vis.visit_span(span); } -pub fn noop_fold_where_predicate( - pred: WherePredicate, - fld: &mut T) - -> WherePredicate { +pub fn noop_visit_where_predicate(pred: &mut WherePredicate, vis: &mut T) { match pred { - WherePredicate::BoundPredicate(WhereBoundPredicate { bound_generic_params, - bounded_ty, - bounds, - span }) => { - WherePredicate::BoundPredicate(WhereBoundPredicate { - bound_generic_params: fld.fold_generic_params(bound_generic_params), - bounded_ty: fld.fold_ty(bounded_ty), - bounds: bounds.move_map(|x| fld.fold_param_bound(x)), - span: fld.new_span(span) - }) - } - WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => { - WherePredicate::RegionPredicate(WhereRegionPredicate { - span: fld.new_span(span), - lifetime: noop_fold_lifetime(lifetime, fld), - bounds: bounds.move_map(|bound| noop_fold_param_bound(bound, fld)) - }) - } - WherePredicate::EqPredicate(WhereEqPredicate { id, lhs_ty, rhs_ty, span }) => { - WherePredicate::EqPredicate(WhereEqPredicate{ - id: fld.new_id(id), - lhs_ty: fld.fold_ty(lhs_ty), - rhs_ty: fld.fold_ty(rhs_ty), - span: fld.new_span(span) - }) - } - } -} - -pub fn noop_fold_variant_data(vdata: VariantData, fld: &mut T) -> VariantData { - match vdata { - VariantData::Struct(fields, id) => { - VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)), fld.new_id(id)) + WherePredicate::BoundPredicate(bp) => { + let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; + vis.visit_span(span); + vis.visit_generic_params(bound_generic_params); + vis.visit_ty(bounded_ty); + visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } - VariantData::Tuple(fields, id) => { - VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)), fld.new_id(id)) + WherePredicate::RegionPredicate(rp) => { + let WhereRegionPredicate { span, lifetime, bounds } = rp; + vis.visit_span(span); + noop_visit_lifetime(lifetime, vis); + visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); + } + WherePredicate::EqPredicate(ep) => { + let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep; + vis.visit_id(id); + vis.visit_span(span); + vis.visit_ty(lhs_ty); + vis.visit_ty(rhs_ty); } - VariantData::Unit(id) => VariantData::Unit(fld.new_id(id)) } } -pub fn noop_fold_trait_ref(p: TraitRef, fld: &mut T) -> TraitRef { - let id = fld.new_id(p.ref_id); - let TraitRef { - path, - ref_id: _, - } = p; - TraitRef { - path: fld.fold_path(path), - ref_id: id, +pub fn noop_visit_variant_data(vdata: &mut VariantData, vis: &mut T) { + match vdata { + VariantData::Struct(fields, id) | + VariantData::Tuple(fields, id) => { + visit_vec(fields, |field| vis.visit_struct_field(field)); + vis.visit_id(id); + } + VariantData::Unit(id) => vis.visit_id(id), } } -pub fn noop_fold_poly_trait_ref(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef { - PolyTraitRef { - bound_generic_params: fld.fold_generic_params(p.bound_generic_params), - trait_ref: fld.fold_trait_ref(p.trait_ref), - span: fld.new_span(p.span), - } +pub fn noop_visit_trait_ref(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { + vis.visit_path(path); + vis.visit_id(ref_id); } -pub fn noop_fold_struct_field(f: StructField, fld: &mut T) -> StructField { - StructField { - span: fld.new_span(f.span), - id: fld.new_id(f.id), - ident: f.ident.map(|ident| fld.fold_ident(ident)), - vis: fld.fold_vis(f.vis), - ty: fld.fold_ty(f.ty), - attrs: fold_attrs(f.attrs, fld), - } +pub fn noop_visit_poly_trait_ref(p: &mut PolyTraitRef, vis: &mut T) { + let PolyTraitRef { bound_generic_params, trait_ref, span } = p; + vis.visit_generic_params(bound_generic_params); + vis.visit_trait_ref(trait_ref); + vis.visit_span(span); } -pub fn noop_fold_field(f: Field, folder: &mut T) -> Field { - Field { - ident: folder.fold_ident(f.ident), - expr: folder.fold_expr(f.expr), - span: folder.new_span(f.span), - is_shorthand: f.is_shorthand, - attrs: fold_thin_attrs(f.attrs, folder), - } +pub fn noop_visit_struct_field(f: &mut StructField, visitor: &mut T) { + let StructField { span, ident, vis, id, ty, attrs } = f; + visitor.visit_span(span); + visit_opt(ident, |ident| visitor.visit_ident(ident)); + visitor.visit_vis(vis); + visitor.visit_id(id); + visitor.visit_ty(ty); + visit_attrs(attrs, visitor); } -pub fn noop_fold_mt(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutTy { - MutTy { - ty: folder.fold_ty(ty), - mutbl, - } +pub fn noop_visit_field(f: &mut Field, vis: &mut T) { + let Field { ident, expr, span, is_shorthand: _, attrs } = f; + vis.visit_ident(ident); + vis.visit_expr(expr); + vis.visit_span(span); + visit_thin_attrs(attrs, vis); } -pub fn noop_fold_block(b: P, folder: &mut T) -> P { - b.map(|Block {id, stmts, rules, span}| Block { - id: folder.new_id(id), - stmts: stmts.move_flat_map(|s| folder.fold_stmt(s).into_iter()), - rules, - span: folder.new_span(span), - }) +pub fn noop_visit_mt(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) { + vis.visit_ty(ty); } -pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { - match i { - ItemKind::ExternCrate(orig_name) => ItemKind::ExternCrate(orig_name), - ItemKind::Use(use_tree) => { - ItemKind::Use(use_tree.map(|tree| folder.fold_use_tree(tree))) - } - ItemKind::Static(t, m, e) => { - ItemKind::Static(folder.fold_ty(t), m, folder.fold_expr(e)) +pub fn noop_visit_block(block: &mut P, vis: &mut T) { + let Block { id, stmts, rules: _, span } = block.deref_mut(); + vis.visit_id(id); + stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); + vis.visit_span(span); +} + +pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { + match kind { + ItemKind::ExternCrate(_orig_name) => {} + ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), + ItemKind::Static(ty, _mut, expr) => { + vis.visit_ty(ty); + vis.visit_expr(expr); } - ItemKind::Const(t, e) => { - ItemKind::Const(folder.fold_ty(t), folder.fold_expr(e)) + ItemKind::Const(ty, expr) => { + vis.visit_ty(ty); + vis.visit_expr(expr); } ItemKind::Fn(decl, header, generics, body) => { - let generics = folder.fold_generics(generics); - let header = folder.fold_fn_header(header); - let decl = folder.fold_fn_decl(decl); - let body = folder.fold_block(body); - ItemKind::Fn(decl, header, generics, body) - } - ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)), - ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)), - ItemKind::GlobalAsm(ga) => ItemKind::GlobalAsm(ga), - ItemKind::Ty(t, generics) => { - ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics)) - } - ItemKind::Existential(bounds, generics) => ItemKind::Existential( - fold_bounds(bounds, folder), - folder.fold_generics(generics), - ), - ItemKind::Enum(enum_definition, generics) => { - let generics = folder.fold_generics(generics); - let variants = enum_definition.variants.move_map(|x| folder.fold_variant(x)); - ItemKind::Enum(EnumDef { variants }, generics) - } - ItemKind::Struct(struct_def, generics) => { - let generics = folder.fold_generics(generics); - ItemKind::Struct(folder.fold_variant_data(struct_def), generics) - } - ItemKind::Union(struct_def, generics) => { - let generics = folder.fold_generics(generics); - ItemKind::Union(folder.fold_variant_data(struct_def), generics) - } - ItemKind::Impl(unsafety, - polarity, - defaultness, - generics, - ifce, - ty, - impl_items) => ItemKind::Impl( - unsafety, - polarity, - defaultness, - folder.fold_generics(generics), - ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref)), - folder.fold_ty(ty), - impl_items.move_flat_map(|item| folder.fold_impl_item(item)), - ), - ItemKind::Trait(is_auto, unsafety, generics, bounds, items) => ItemKind::Trait( - is_auto, - unsafety, - folder.fold_generics(generics), - fold_bounds(bounds, folder), - items.move_flat_map(|item| folder.fold_trait_item(item)), - ), - ItemKind::TraitAlias(generics, bounds) => ItemKind::TraitAlias( - folder.fold_generics(generics), - fold_bounds(bounds, folder)), - ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)), - ItemKind::MacroDef(def) => ItemKind::MacroDef(folder.fold_macro_def(def)), - } -} - -pub fn noop_fold_trait_item(i: TraitItem, folder: &mut T) -> SmallVec<[TraitItem; 1]> { - smallvec![TraitItem { - id: folder.new_id(i.id), - ident: folder.fold_ident(i.ident), - attrs: fold_attrs(i.attrs, folder), - generics: folder.fold_generics(i.generics), - node: match i.node { - TraitItemKind::Const(ty, default) => { - TraitItemKind::Const(folder.fold_ty(ty), - default.map(|x| folder.fold_expr(x))) - } - TraitItemKind::Method(sig, body) => { - TraitItemKind::Method(fold_method_sig(sig, folder), - body.map(|x| folder.fold_block(x))) - } - TraitItemKind::Type(bounds, default) => { - TraitItemKind::Type(fold_bounds(bounds, folder), - default.map(|x| folder.fold_ty(x))) - } - TraitItemKind::Macro(mac) => { - TraitItemKind::Macro(folder.fold_mac(mac)) - } - }, - span: folder.new_span(i.span), - tokens: i.tokens, - }] -} - -pub fn noop_fold_impl_item(i: ImplItem, folder: &mut T)-> SmallVec<[ImplItem; 1]> { - smallvec![ImplItem { - id: folder.new_id(i.id), - vis: folder.fold_vis(i.vis), - ident: folder.fold_ident(i.ident), - attrs: fold_attrs(i.attrs, folder), - generics: folder.fold_generics(i.generics), - defaultness: i.defaultness, - node: match i.node { - ImplItemKind::Const(ty, expr) => { - ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr)) - } - ImplItemKind::Method(sig, body) => { - ImplItemKind::Method(fold_method_sig(sig, folder), - folder.fold_block(body)) - } - ImplItemKind::Type(ty) => ImplItemKind::Type(folder.fold_ty(ty)), - ImplItemKind::Existential(bounds) => { - ImplItemKind::Existential(fold_bounds(bounds, folder)) - }, - ImplItemKind::Macro(mac) => ImplItemKind::Macro(folder.fold_mac(mac)) - }, - span: folder.new_span(i.span), - tokens: i.tokens, - }] -} - -pub fn noop_fold_fn_header(mut header: FnHeader, folder: &mut T) -> FnHeader { - header.asyncness = folder.fold_asyncness(header.asyncness); - header + vis.visit_fn_decl(decl); + vis.visit_fn_header(header); + vis.visit_generics(generics); + vis.visit_block(body); + } + ItemKind::Mod(m) => vis.visit_mod(m), + ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), + ItemKind::GlobalAsm(_ga) => {} + ItemKind::Ty(ty, generics) => { + vis.visit_ty(ty); + vis.visit_generics(generics); + } + ItemKind::Existential(bounds, generics) => { + visit_bounds(bounds, vis); + vis.visit_generics(generics); + } + ItemKind::Enum(EnumDef { variants }, generics) => { + visit_vec(variants, |variant| vis.visit_variant(variant)); + vis.visit_generics(generics); + } + ItemKind::Struct(variant_data, generics) | + ItemKind::Union(variant_data, generics) => { + vis.visit_variant_data(variant_data); + vis.visit_generics(generics); + } + ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => { + vis.visit_generics(generics); + visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref)); + vis.visit_ty(ty); + items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); + } + ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => { + vis.visit_generics(generics); + visit_bounds(bounds, vis); + items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); + } + ItemKind::TraitAlias(generics, bounds) => { + vis.visit_generics(generics); + visit_bounds(bounds, vis); + } + ItemKind::Mac(m) => vis.visit_mac(m), + ItemKind::MacroDef(def) => vis.visit_macro_def(def), + } } -pub fn noop_fold_mod(Mod {inner, items, inline}: Mod, folder: &mut T) -> Mod { - Mod { - inner: folder.new_span(inner), - items: items.move_flat_map(|x| folder.fold_item(x)), - inline: inline, +pub fn noop_flat_map_trait_item(mut item: TraitItem, vis: &mut T) + -> SmallVec<[TraitItem; 1]> +{ + let TraitItem { id, ident, attrs, generics, node, span, tokens: _ } = &mut item; + vis.visit_id(id); + vis.visit_ident(ident); + visit_attrs(attrs, vis); + vis.visit_generics(generics); + match node { + TraitItemKind::Const(ty, default) => { + vis.visit_ty(ty); + visit_opt(default, |default| vis.visit_expr(default)); + } + TraitItemKind::Method(sig, body) => { + visit_method_sig(sig, vis); + visit_opt(body, |body| vis.visit_block(body)); + } + TraitItemKind::Type(bounds, default) => { + visit_bounds(bounds, vis); + visit_opt(default, |default| vis.visit_ty(default)); + } + TraitItemKind::Macro(mac) => { + vis.visit_mac(mac); + } } -} + vis.visit_span(span); -pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, - folder: &mut T) -> Crate { - let item = P(Item { - ident: keywords::Invalid.ident(), - attrs, - id: DUMMY_NODE_ID, - vis: respan(span.shrink_to_lo(), VisibilityKind::Public), - span, - node: ItemKind::Mod(module), - tokens: None, - }); - let items = folder.fold_item(item); + smallvec![item] +} - let len = items.len(); - if len == 0 { - let module = Mod { inner: span, items: vec![], inline: true }; - Crate { module, attrs: vec![], span } - } else if len == 1 { - let Item { attrs, span, node, .. } = items.into_iter().next().unwrap().into_inner(); - match node { - ItemKind::Mod(module) => Crate { module, attrs, span }, - _ => panic!("fold converted a module to not a module"), +pub fn noop_flat_map_impl_item(mut item: ImplItem, visitor: &mut T) + -> SmallVec<[ImplItem; 1]> +{ + let ImplItem { id, ident, vis, defaultness: _, attrs, generics, node, span, tokens: _ } = + &mut item; + visitor.visit_id(id); + visitor.visit_ident(ident); + visitor.visit_vis(vis); + visit_attrs(attrs, visitor); + visitor.visit_generics(generics); + match node { + ImplItemKind::Const(ty, expr) => { + visitor.visit_ty(ty); + visitor.visit_expr(expr); } - } else { - panic!("a crate cannot expand to more than one item"); - } + ImplItemKind::Method(sig, body) => { + visit_method_sig(sig, visitor); + visitor.visit_block(body); + } + ImplItemKind::Type(ty) => visitor.visit_ty(ty), + ImplItemKind::Existential(bounds) => visit_bounds(bounds, visitor), + ImplItemKind::Macro(mac) => visitor.visit_mac(mac), + } + visitor.visit_span(span); + + smallvec![item] +} + +pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { + let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header; + vis.visit_asyncness(asyncness); +} + +pub fn noop_visit_mod(Mod { inner, items, inline: _ }: &mut Mod, vis: &mut T) { + vis.visit_span(inner); + items.flat_map_in_place(|item| vis.flat_map_item(item)); +} + +pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { + visit_clobber(krate, |Crate { module, attrs, span }| { + let item = P(Item { + ident: keywords::Invalid.ident(), + attrs, + id: DUMMY_NODE_ID, + vis: respan(span.shrink_to_lo(), VisibilityKind::Public), + span, + node: ItemKind::Mod(module), + tokens: None, + }); + let items = vis.flat_map_item(item); + + let len = items.len(); + if len == 0 { + let module = Mod { inner: span, items: vec![], inline: true }; + Crate { module, attrs: vec![], span } + } else if len == 1 { + let Item { attrs, span, node, .. } = items.into_iter().next().unwrap().into_inner(); + match node { + ItemKind::Mod(module) => Crate { module, attrs, span }, + _ => panic!("visitor converted a module to not a module"), + } + } else { + panic!("a crate cannot expand to more than one item"); + } + }); } -// fold one item into possibly many items -pub fn noop_fold_item(i: P, folder: &mut T) -> SmallVec<[P; 1]> { - smallvec![i.map(|i| { - let Item {id, ident, attrs, node, vis, span, tokens} = i; - Item { - id: folder.new_id(id), - vis: folder.fold_vis(vis), - ident: folder.fold_ident(ident), - attrs: fold_attrs(attrs, folder), - node: folder.fold_item_kind(node), - span: folder.new_span(span), +// Mutate one item into possibly many items. +pub fn noop_flat_map_item(mut item: P, visitor: &mut T) + -> SmallVec<[P; 1]> { + let Item { ident, attrs, id, node, vis, span, tokens: _ } = item.deref_mut(); + visitor.visit_ident(ident); + visit_attrs(attrs, visitor); + visitor.visit_id(id); + visitor.visit_item_kind(node); + visitor.visit_vis(vis); + visitor.visit_span(span); - // FIXME: if this is replaced with a call to `folder.fold_tts` it causes - // an ICE during resolve... odd! - tokens, - } - })] + // FIXME: if `tokens` is modified with a call to `vis.visit_tts` it causes + // an ICE during resolve... odd! + + smallvec![item] } -pub fn noop_fold_foreign_item(ni: ForeignItem, folder: &mut T) +pub fn noop_flat_map_foreign_item(mut item: ForeignItem, visitor: &mut T) -> SmallVec<[ForeignItem; 1]> { - smallvec![ForeignItem { - id: folder.new_id(ni.id), - vis: folder.fold_vis(ni.vis), - ident: folder.fold_ident(ni.ident), - attrs: fold_attrs(ni.attrs, folder), - node: match ni.node { - ForeignItemKind::Fn(fdec, generics) => { - ForeignItemKind::Fn(folder.fold_fn_decl(fdec), folder.fold_generics(generics)) - } - ForeignItemKind::Static(t, m) => { - ForeignItemKind::Static(folder.fold_ty(t), m) - } - ForeignItemKind::Ty => ForeignItemKind::Ty, - ForeignItemKind::Macro(mac) => ForeignItemKind::Macro(folder.fold_mac(mac)), - }, - span: folder.new_span(ni.span) - }] -} - -pub fn noop_fold_pat(p: P, folder: &mut T) -> P { - p.map(|Pat {id, node, span}| Pat { - id: folder.new_id(id), - node: match node { - PatKind::Wild => PatKind::Wild, - PatKind::Ident(binding_mode, ident, sub) => { - PatKind::Ident(binding_mode, - folder.fold_ident(ident), - sub.map(|x| folder.fold_pat(x))) - } - PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), - PatKind::TupleStruct(pth, pats, ddpos) => { - PatKind::TupleStruct(folder.fold_path(pth), - pats.move_map(|x| folder.fold_pat(x)), ddpos) - } - PatKind::Path(qself, pth) => { - PatKind::Path(folder.fold_qself(qself), folder.fold_path(pth)) - } - PatKind::Struct(pth, fields, etc) => { - let pth = folder.fold_path(pth); - let fs = fields.move_map(|f| { - Spanned { span: folder.new_span(f.span), - node: FieldPat { - ident: folder.fold_ident(f.node.ident), - pat: folder.fold_pat(f.node.pat), - is_shorthand: f.node.is_shorthand, - attrs: fold_attrs(f.node.attrs.into(), folder).into() - }} - }); - PatKind::Struct(pth, fs, etc) - } - PatKind::Tuple(elts, ddpos) => { - PatKind::Tuple(elts.move_map(|x| folder.fold_pat(x)), ddpos) - } - PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)), - PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl), - PatKind::Range(e1, e2, Spanned { span, node }) => { - PatKind::Range(folder.fold_expr(e1), - folder.fold_expr(e2), - Spanned { node, span: folder.new_span(span) }) - }, - PatKind::Slice(before, slice, after) => { - PatKind::Slice(before.move_map(|x| folder.fold_pat(x)), - slice.map(|x| folder.fold_pat(x)), - after.move_map(|x| folder.fold_pat(x))) - } - PatKind::Paren(inner) => PatKind::Paren(folder.fold_pat(inner)), - PatKind::Mac(mac) => PatKind::Mac(folder.fold_mac(mac)) - }, - span: folder.new_span(span) - }) + let ForeignItem { ident, attrs, node, id, span, vis } = &mut item; + visitor.visit_ident(ident); + visit_attrs(attrs, visitor); + match node { + ForeignItemKind::Fn(fdec, generics) => { + visitor.visit_fn_decl(fdec); + visitor.visit_generics(generics); + } + ForeignItemKind::Static(t, _m) => visitor.visit_ty(t), + ForeignItemKind::Ty => {} + ForeignItemKind::Macro(mac) => visitor.visit_mac(mac), + } + visitor.visit_id(id); + visitor.visit_span(span); + visitor.visit_vis(vis); + + smallvec![item] } -pub fn noop_fold_anon_const(constant: AnonConst, folder: &mut T) -> AnonConst { - let AnonConst {id, value} = constant; - AnonConst { - id: folder.new_id(id), - value: folder.fold_expr(value), +pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { + let Pat { id, node, span } = pat.deref_mut(); + vis.visit_id(id); + match node { + PatKind::Wild => {} + PatKind::Ident(_binding_mode, ident, sub) => { + vis.visit_ident(ident); + visit_opt(sub, |sub| vis.visit_pat(sub)); + } + PatKind::Lit(e) => vis.visit_expr(e), + PatKind::TupleStruct(path, pats, _ddpos) => { + vis.visit_path(path); + visit_vec(pats, |pat| vis.visit_pat(pat)); + } + PatKind::Path(qself, path) => { + vis.visit_qself(qself); + vis.visit_path(path); + } + PatKind::Struct(path, fields, _etc) => { + vis.visit_path(path); + for Spanned { node: FieldPat { ident, pat, is_shorthand: _, attrs }, span } in fields { + vis.visit_ident(ident); + vis.visit_pat(pat); + visit_thin_attrs(attrs, vis); + vis.visit_span(span); + }; + } + PatKind::Tuple(elts, _ddpos) => visit_vec(elts, |elt| vis.visit_pat(elt)), + PatKind::Box(inner) => vis.visit_pat(inner), + PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), + PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { + vis.visit_expr(e1); + vis.visit_expr(e2); + vis.visit_span(span); + }, + PatKind::Slice(before, slice, after) => { + visit_vec(before, |pat| vis.visit_pat(pat)); + visit_opt(slice, |slice| vis.visit_pat(slice)); + visit_vec(after, |pat| vis.visit_pat(pat)); + } + PatKind::Paren(inner) => vis.visit_pat(inner), + PatKind::Mac(mac) => vis.visit_mac(mac), } + vis.visit_span(span); } -pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr { - Expr { - node: match node { - ExprKind::Box(e) => { - ExprKind::Box(folder.fold_expr(e)) - } - ExprKind::ObsoleteInPlace(a, b) => { - ExprKind::ObsoleteInPlace(folder.fold_expr(a), folder.fold_expr(b)) - } - ExprKind::Array(exprs) => { - ExprKind::Array(fold_exprs(exprs, folder)) - } - ExprKind::Repeat(expr, count) => { - ExprKind::Repeat(folder.fold_expr(expr), folder.fold_anon_const(count)) - } - ExprKind::Tup(exprs) => ExprKind::Tup(fold_exprs(exprs, folder)), - ExprKind::Call(f, args) => { - ExprKind::Call(folder.fold_expr(f), - fold_exprs(args, folder)) - } - ExprKind::MethodCall(seg, args) => { - ExprKind::MethodCall( - PathSegment { - ident: folder.fold_ident(seg.ident), - id: folder.new_id(seg.id), - args: seg.args.map(|args| { - args.map(|args| folder.fold_generic_args(args)) - }), - }, - fold_exprs(args, folder)) - } - ExprKind::Binary(binop, lhs, rhs) => { - ExprKind::Binary(binop, - folder.fold_expr(lhs), - folder.fold_expr(rhs)) - } - ExprKind::Unary(binop, ohs) => { - ExprKind::Unary(binop, folder.fold_expr(ohs)) - } - ExprKind::Lit(l) => ExprKind::Lit(l), - ExprKind::Cast(expr, ty) => { - ExprKind::Cast(folder.fold_expr(expr), folder.fold_ty(ty)) - } - ExprKind::Type(expr, ty) => { - ExprKind::Type(folder.fold_expr(expr), folder.fold_ty(ty)) - } - ExprKind::AddrOf(m, ohs) => ExprKind::AddrOf(m, folder.fold_expr(ohs)), - ExprKind::If(cond, tr, fl) => { - ExprKind::If(folder.fold_expr(cond), - folder.fold_block(tr), - fl.map(|x| folder.fold_expr(x))) - } - ExprKind::IfLet(pats, expr, tr, fl) => { - ExprKind::IfLet(pats.move_map(|pat| folder.fold_pat(pat)), - folder.fold_expr(expr), - folder.fold_block(tr), - fl.map(|x| folder.fold_expr(x))) - } - ExprKind::While(cond, body, opt_label) => { - ExprKind::While(folder.fold_expr(cond), - folder.fold_block(body), - opt_label.map(|label| folder.fold_label(label))) - } - ExprKind::WhileLet(pats, expr, body, opt_label) => { - ExprKind::WhileLet(pats.move_map(|pat| folder.fold_pat(pat)), - folder.fold_expr(expr), - folder.fold_block(body), - opt_label.map(|label| folder.fold_label(label))) - } - ExprKind::ForLoop(pat, iter, body, opt_label) => { - ExprKind::ForLoop(folder.fold_pat(pat), - folder.fold_expr(iter), - folder.fold_block(body), - opt_label.map(|label| folder.fold_label(label))) - } - ExprKind::Loop(body, opt_label) => { - ExprKind::Loop(folder.fold_block(body), - opt_label.map(|label| folder.fold_label(label))) - } - ExprKind::Match(expr, arms) => { - ExprKind::Match(folder.fold_expr(expr), - arms.move_map(|x| folder.fold_arm(x))) - } - ExprKind::Closure(capture_clause, asyncness, movability, decl, body, span) => { - ExprKind::Closure(capture_clause, - folder.fold_asyncness(asyncness), - movability, - folder.fold_fn_decl(decl), - folder.fold_expr(body), - folder.new_span(span)) - } - ExprKind::Block(blk, opt_label) => { - ExprKind::Block(folder.fold_block(blk), - opt_label.map(|label| folder.fold_label(label))) - } - ExprKind::Async(capture_clause, node_id, body) => { - ExprKind::Async( - capture_clause, - folder.new_id(node_id), - folder.fold_block(body), - ) - } - ExprKind::Assign(el, er) => { - ExprKind::Assign(folder.fold_expr(el), folder.fold_expr(er)) - } - ExprKind::AssignOp(op, el, er) => { - ExprKind::AssignOp(op, - folder.fold_expr(el), - folder.fold_expr(er)) - } - ExprKind::Field(el, ident) => { - ExprKind::Field(folder.fold_expr(el), folder.fold_ident(ident)) - } - ExprKind::Index(el, er) => { - ExprKind::Index(folder.fold_expr(el), folder.fold_expr(er)) - } - ExprKind::Range(e1, e2, lim) => { - ExprKind::Range(e1.map(|x| folder.fold_expr(x)), - e2.map(|x| folder.fold_expr(x)), - lim) - } - ExprKind::Path(qself, path) => { - ExprKind::Path(folder.fold_qself(qself), folder.fold_path(path)) - } - ExprKind::Break(opt_label, opt_expr) => { - ExprKind::Break(opt_label.map(|label| folder.fold_label(label)), - opt_expr.map(|e| folder.fold_expr(e))) - } - ExprKind::Continue(opt_label) => { - ExprKind::Continue(opt_label.map(|label| folder.fold_label(label))) - } - ExprKind::Ret(e) => ExprKind::Ret(e.map(|x| folder.fold_expr(x))), - ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(asm.map(|asm| { - InlineAsm { - inputs: asm.inputs.move_map(|(c, input)| { - (c, folder.fold_expr(input)) - }), - outputs: asm.outputs.move_map(|out| { - InlineAsmOutput { - constraint: out.constraint, - expr: folder.fold_expr(out.expr), - is_rw: out.is_rw, - is_indirect: out.is_indirect, - } - }), - ..asm - } - })), - ExprKind::Mac(mac) => ExprKind::Mac(folder.fold_mac(mac)), - ExprKind::Struct(path, fields, maybe_expr) => { - ExprKind::Struct(folder.fold_path(path), - fields.move_map(|x| folder.fold_field(x)), - maybe_expr.map(|x| folder.fold_expr(x))) - }, - ExprKind::Paren(ex) => { - let sub_expr = folder.fold_expr(ex); - return Expr { - // Nodes that are equal modulo `Paren` sugar no-ops should have the same ids. - id: sub_expr.id, - node: ExprKind::Paren(sub_expr), - span: folder.new_span(span), - attrs: fold_attrs(attrs.into(), folder).into(), - }; +pub fn noop_visit_anon_const(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { + vis.visit_id(id); + vis.visit_expr(value); +} + +pub fn noop_visit_expr(Expr { node, id, span, attrs }: &mut Expr, vis: &mut T) { + match node { + ExprKind::Box(expr) => vis.visit_expr(expr), + ExprKind::ObsoleteInPlace(a, b) => { + vis.visit_expr(a); + vis.visit_expr(b); + } + ExprKind::Array(exprs) => visit_exprs(exprs, vis), + ExprKind::Repeat(expr, count) => { + vis.visit_expr(expr); + vis.visit_anon_const(count); + } + ExprKind::Tup(exprs) => visit_exprs(exprs, vis), + ExprKind::Call(f, args) => { + vis.visit_expr(f); + visit_exprs(args, vis); + } + ExprKind::MethodCall(PathSegment { ident, id, args }, exprs) => { + vis.visit_ident(ident); + vis.visit_id(id); + visit_opt(args, |args| vis.visit_generic_args(args)); + visit_exprs(exprs, vis); + } + ExprKind::Binary(_binop, lhs, rhs) => { + vis.visit_expr(lhs); + vis.visit_expr(rhs); + } + ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), + ExprKind::Lit(_lit) => {} + ExprKind::Cast(expr, ty) => { + vis.visit_expr(expr); + vis.visit_ty(ty); + } + ExprKind::Type(expr, ty) => { + vis.visit_expr(expr); + vis.visit_ty(ty); + } + ExprKind::AddrOf(_m, ohs) => vis.visit_expr(ohs), + ExprKind::If(cond, tr, fl) => { + vis.visit_expr(cond); + vis.visit_block(tr); + visit_opt(fl, |fl| vis.visit_expr(fl)); + } + ExprKind::IfLet(pats, expr, tr, fl) => { + visit_vec(pats, |pat| vis.visit_pat(pat)); + vis.visit_expr(expr); + vis.visit_block(tr); + visit_opt(fl, |fl| vis.visit_expr(fl)); + } + ExprKind::While(cond, body, label) => { + vis.visit_expr(cond); + vis.visit_block(body); + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::WhileLet(pats, expr, body, label) => { + visit_vec(pats, |pat| vis.visit_pat(pat)); + vis.visit_expr(expr); + vis.visit_block(body); + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::ForLoop(pat, iter, body, label) => { + vis.visit_pat(pat); + vis.visit_expr(iter); + vis.visit_block(body); + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::Loop(body, label) => { + vis.visit_block(body); + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::Match(expr, arms) => { + vis.visit_expr(expr); + visit_vec(arms, |arm| vis.visit_arm(arm)); + } + ExprKind::Closure(_capture_by, asyncness, _movability, decl, body, span) => { + vis.visit_asyncness(asyncness); + vis.visit_fn_decl(decl); + vis.visit_expr(body); + vis.visit_span(span); + } + ExprKind::Block(blk, label) => { + vis.visit_block(blk); + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::Async(_capture_by, node_id, body) => { + vis.visit_id(node_id); + vis.visit_block(body); + } + ExprKind::Assign(el, er) => { + vis.visit_expr(el); + vis.visit_expr(er); + } + ExprKind::AssignOp(_op, el, er) => { + vis.visit_expr(el); + vis.visit_expr(er); + } + ExprKind::Field(el, ident) => { + vis.visit_expr(el); + vis.visit_ident(ident); + } + ExprKind::Index(el, er) => { + vis.visit_expr(el); + vis.visit_expr(er); + } + ExprKind::Range(e1, e2, _lim) => { + visit_opt(e1, |e1| vis.visit_expr(e1)); + visit_opt(e2, |e2| vis.visit_expr(e2)); + } + ExprKind::Path(qself, path) => { + vis.visit_qself(qself); + vis.visit_path(path); + } + ExprKind::Break(label, expr) => { + visit_opt(label, |label| vis.visit_label(label)); + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Continue(label) => { + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::Ret(expr) => { + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::InlineAsm(asm) => { + let InlineAsm { asm: _, asm_str_style: _, outputs, inputs, clobbers: _, volatile: _, + alignstack: _, dialect: _, ctxt: _ } = asm.deref_mut(); + for out in outputs { + let InlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out; + vis.visit_expr(expr); } - ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))), - ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)), - ExprKind::TryBlock(body) => ExprKind::TryBlock(folder.fold_block(body)), - ExprKind::Err => ExprKind::Err, + visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr)); + } + ExprKind::Mac(mac) => vis.visit_mac(mac), + ExprKind::Struct(path, fields, expr) => { + vis.visit_path(path); + visit_vec(fields, |field| vis.visit_field(field)); + visit_opt(expr, |expr| vis.visit_expr(expr)); }, - id: folder.new_id(id), - span: folder.new_span(span), - attrs: fold_attrs(attrs.into(), folder).into(), + ExprKind::Paren(expr) => { + vis.visit_expr(expr); + + // Nodes that are equal modulo `Paren` sugar no-ops should have the same ids. + *id = expr.id; + vis.visit_span(span); + visit_thin_attrs(attrs, vis); + return; + } + ExprKind::Yield(expr) => { + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Try(expr) => vis.visit_expr(expr), + ExprKind::TryBlock(body) => vis.visit_block(body), + ExprKind::Err => {} } + vis.visit_id(id); + vis.visit_span(span); + visit_thin_attrs(attrs, vis); } -pub fn noop_fold_opt_expr(e: P, folder: &mut T) -> Option> { - Some(folder.fold_expr(e)) +pub fn noop_filter_map_expr(mut e: P, vis: &mut T) -> Option> { + Some({ vis.visit_expr(&mut e); e }) } -pub fn noop_fold_stmt(Stmt {node, span, id}: Stmt, folder: &mut T) -> SmallVec<[Stmt; 1]> +pub fn noop_flat_map_stmt(Stmt { node, mut span, mut id }: Stmt, vis: &mut T) + -> SmallVec<[Stmt; 1]> { - let id = folder.new_id(id); - let span = folder.new_span(span); - noop_fold_stmt_kind(node, folder).into_iter().map(|node| { - Stmt { id: id, node: node, span: span } + vis.visit_id(&mut id); + vis.visit_span(&mut span); + noop_flat_map_stmt_kind(node, vis).into_iter().map(|node| { + Stmt { id, node, span } }).collect() } -pub fn noop_fold_stmt_kind(node: StmtKind, folder: &mut T) -> SmallVec<[StmtKind; 1]> { +pub fn noop_flat_map_stmt_kind(node: StmtKind, vis: &mut T) + -> SmallVec<[StmtKind; 1]> { match node { - StmtKind::Local(local) => smallvec![StmtKind::Local(folder.fold_local(local))], - StmtKind::Item(item) => folder.fold_item(item).into_iter().map(StmtKind::Item).collect(), + StmtKind::Local(mut local) => + smallvec![StmtKind::Local({ vis.visit_local(&mut local); local })], + StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), StmtKind::Expr(expr) => { - folder.fold_opt_expr(expr).into_iter().map(StmtKind::Expr).collect() + vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect() } StmtKind::Semi(expr) => { - folder.fold_opt_expr(expr).into_iter().map(StmtKind::Semi).collect() + vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect() + } + StmtKind::Mac(mut mac) => { + let (mac_, _semi, attrs) = mac.deref_mut(); + vis.visit_mac(mac_); + visit_thin_attrs(attrs, vis); + smallvec![StmtKind::Mac(mac)] } - StmtKind::Mac(mac) => smallvec![StmtKind::Mac(mac.map(|(mac, semi, attrs)| { - (folder.fold_mac(mac), semi, fold_attrs(attrs.into(), folder).into()) - }))], } } -pub fn noop_fold_vis(Spanned { node, span }: Visibility, folder: &mut T) -> Visibility { - Visibility { - node: match node { - VisibilityKind::Public => VisibilityKind::Public, - VisibilityKind::Crate(sugar) => VisibilityKind::Crate(sugar), - VisibilityKind::Restricted { path, id } => { - VisibilityKind::Restricted { - path: path.map(|path| folder.fold_path(path)), - id: folder.new_id(id), - } - } - VisibilityKind::Inherited => VisibilityKind::Inherited, - }, - span: folder.new_span(span), +pub fn noop_visit_vis(Spanned { node, span }: &mut Visibility, vis: &mut T) { + match node { + VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} + VisibilityKind::Restricted { path, id } => { + vis.visit_path(path); + vis.visit_id(id); + } } + vis.visit_span(span); } #[cfg(test)] @@ -1342,7 +1259,7 @@ mod tests { use ast::{self, Ident}; use util::parser_testing::{string_to_crate, matches_codepattern}; use print::pprust; - use fold; + use mut_visit; use with_globals; use super::*; @@ -1353,14 +1270,14 @@ mod tests { } // change every identifier to "zz" - struct ToZzIdentFolder; + struct ToZzIdentMutVisitor; - impl Folder for ToZzIdentFolder { - fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident { - Ident::from_str("zz") + impl MutVisitor for ToZzIdentMutVisitor { + fn visit_ident(&mut self, ident: &mut ast::Ident) { + *ident = Ident::from_str("zz"); } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) + fn visit_mac(&mut self, mac: &mut ast::Mac) { + mut_visit::noop_visit_mac(mac, self) } } @@ -1382,14 +1299,14 @@ mod tests { // make sure idents get transformed everywhere #[test] fn ident_transformation () { with_globals(|| { - let mut zz_fold = ToZzIdentFolder; - let ast = string_to_crate( + let mut zz_visitor = ToZzIdentMutVisitor; + let mut krate = string_to_crate( "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); - let folded_crate = zz_fold.fold_crate(ast); + zz_visitor.visit_crate(&mut krate); assert_pred!( matches_codepattern, "matches_codepattern", - pprust::to_string(|s| fake_print_crate(s, &folded_crate)), + pprust::to_string(|s| fake_print_crate(s, &krate)), "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()); }) } @@ -1397,16 +1314,17 @@ mod tests { // even inside macro defs.... #[test] fn ident_transformation_in_defs () { with_globals(|| { - let mut zz_fold = ToZzIdentFolder; - let ast = string_to_crate( + let mut zz_visitor = ToZzIdentMutVisitor; + let mut krate = string_to_crate( "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ (g $(d $d $e)+))} ".to_string()); - let folded_crate = zz_fold.fold_crate(ast); + zz_visitor.visit_crate(&mut krate); assert_pred!( matches_codepattern, "matches_codepattern", - pprust::to_string(|s| fake_print_crate(s, &folded_crate)), + pprust::to_string(|s| fake_print_crate(s, &krate)), "macro_rules! zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)));".to_string()); }) } } + diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b2a3ae7f9d975..dacb0d811cedb 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -133,7 +133,7 @@ pub mod util { pub mod parser; #[cfg(test)] pub mod parser_testing; - pub mod move_map; + pub mod map_in_place; } pub mod json; @@ -151,7 +151,7 @@ pub mod source_map; pub mod config; pub mod entry; pub mod feature_gate; -pub mod fold; +#[path="fold.rs"] pub mod mut_visit; // temporary pub mod parse; pub mod ptr; pub mod show_span; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 514b2952c5036..a9f3acecc818b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7046,7 +7046,8 @@ impl<'a> Parser<'a> { sess: self.sess, features: None, // don't perform gated feature checking }; - let outer_attrs = strip_unconfigured.process_cfg_attrs(outer_attrs.to_owned()); + let mut outer_attrs = outer_attrs.to_owned(); + strip_unconfigured.process_cfg_attrs(&mut outer_attrs); (!self.cfg_mods || strip_unconfigured.in_cfg(&outer_attrs), outer_attrs) }; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index f06e975a6d95a..5181bb8f34e66 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -735,7 +735,7 @@ impl fmt::Debug for LazyTokenStream { } impl LazyTokenStream { - fn new() -> Self { + pub fn new() -> Self { LazyTokenStream(Lock::new(None)) } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index b352486e39a64..12f82a01dcfcd 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -20,10 +20,9 @@ use ext::base::{ExtCtxt, Resolver}; use ext::build::AstBuilder; use ext::expand::ExpansionConfig; use ext::hygiene::{self, Mark, SyntaxContext}; -use fold::Folder; +use mut_visit::{*, ExpectOne}; use feature_gate::Features; -use util::move_map::MoveMap; -use fold::{self, ExpectOne}; +use util::map_in_place::MapInPlace; use parse::{token, ParseSess}; use print::pprust; use ast::{self, Ident}; @@ -57,9 +56,9 @@ struct TestCtxt<'a> { pub fn modify_for_testing(sess: &ParseSess, resolver: &mut dyn Resolver, should_test: bool, - krate: ast::Crate, + krate: &mut ast::Crate, span_diagnostic: &errors::Handler, - features: &Features) -> ast::Crate { + features: &Features) { // Check for #[reexport_test_harness_main = "some_name"] which // creates a `use __test::main as some_name;`. This needs to be // unconditional, so that the attribute is still marked as used in @@ -75,8 +74,6 @@ pub fn modify_for_testing(sess: &ParseSess, if should_test { generate_test_harness(sess, resolver, reexport_test_harness_main, krate, span_diagnostic, features, test_runner) - } else { - krate } } @@ -88,21 +85,20 @@ struct TestHarnessGenerator<'a> { tested_submods: Vec<(Ident, Ident)>, } -impl<'a> fold::Folder for TestHarnessGenerator<'a> { - fn fold_crate(&mut self, c: ast::Crate) -> ast::Crate { - let mut folded = fold::noop_fold_crate(c, self); +impl<'a> MutVisitor for TestHarnessGenerator<'a> { + fn visit_crate(&mut self, c: &mut ast::Crate) { + noop_visit_crate(c, self); // Create a main function to run our tests let test_main = { let unresolved = mk_main(&mut self.cx); - self.cx.ext_cx.monotonic_expander().fold_item(unresolved).pop().unwrap() + self.cx.ext_cx.monotonic_expander().flat_map_item(unresolved).pop().unwrap() }; - folded.module.items.push(test_main); - folded + c.module.items.push(test_main); } - fn fold_item(&mut self, i: P) -> SmallVec<[P; 1]> { + fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { let ident = i.ident; if ident.name != keywords::Invalid.name() { self.cx.path.push(ident); @@ -123,16 +119,16 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { // We don't want to recurse into anything other than mods, since // mods or tests inside of functions will break things - if let ast::ItemKind::Mod(module) = item.node { + if let ast::ItemKind::Mod(mut module) = item.node { let tests = mem::replace(&mut self.tests, Vec::new()); let tested_submods = mem::replace(&mut self.tested_submods, Vec::new()); - let mut mod_folded = fold::noop_fold_mod(module, self); + noop_visit_mod(&mut module, self); let tests = mem::replace(&mut self.tests, tests); let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); if !tests.is_empty() || !tested_submods.is_empty() { let (it, sym) = mk_reexport_mod(&mut self.cx, item.id, tests, tested_submods); - mod_folded.items.push(it); + module.items.push(it); if !self.cx.path.is_empty() { self.tested_submods.push((self.cx.path[self.cx.path.len()-1], sym)); @@ -141,7 +137,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { self.cx.toplevel_reexport = Some(sym); } } - item.node = ast::ItemKind::Mod(mod_folded); + item.node = ast::ItemKind::Mod(module); } if ident.name != keywords::Invalid.name() { self.cx.path.pop(); @@ -149,7 +145,9 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { smallvec![P(item)] } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { mac } + fn visit_mac(&mut self, _mac: &mut ast::Mac) { + // Do nothing. + } } /// A folder used to remove any entry points (like fn main) because the harness @@ -159,20 +157,20 @@ struct EntryPointCleaner { depth: usize, } -impl fold::Folder for EntryPointCleaner { - fn fold_item(&mut self, i: P) -> SmallVec<[P; 1]> { +impl MutVisitor for EntryPointCleaner { + fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { self.depth += 1; - let folded = fold::noop_fold_item(i, self).expect_one("noop did something"); + let item = noop_flat_map_item(i, self).expect_one("noop did something"); self.depth -= 1; // Remove any #[main] or #[start] from the AST so it doesn't // clash with the one we're going to add, but mark it as // #[allow(dead_code)] to avoid printing warnings. - let folded = match entry::entry_point_type(&folded, self.depth) { + let item = match entry::entry_point_type(&item, self.depth) { EntryPointType::MainNamed | EntryPointType::MainAttr | EntryPointType::Start => - folded.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| { + item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| { let allow_ident = Ident::from_str("allow"); let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code")); let allow_dead_code_item = attr::mk_list_item(DUMMY_SP, allow_ident, @@ -197,13 +195,15 @@ impl fold::Folder for EntryPointCleaner { } }), EntryPointType::None | - EntryPointType::OtherMain => folded, + EntryPointType::OtherMain => item, }; - smallvec![folded] + smallvec![item] } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { mac } + fn visit_mac(&mut self, _mac: &mut ast::Mac) { + // Do nothing. + } } /// Creates an item (specifically a module) that "pub use"s the tests passed in. @@ -235,7 +235,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt, let sym = Ident::with_empty_ctxt(Symbol::gensym("__test_reexports")); let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent }; cx.ext_cx.current_expansion.mark = cx.ext_cx.resolver.get_module_scope(parent); - let it = cx.ext_cx.monotonic_expander().fold_item(P(ast::Item { + let it = cx.ext_cx.monotonic_expander().flat_map_item(P(ast::Item { ident: sym, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, @@ -252,13 +252,13 @@ fn mk_reexport_mod(cx: &mut TestCtxt, fn generate_test_harness(sess: &ParseSess, resolver: &mut dyn Resolver, reexport_test_harness_main: Option, - krate: ast::Crate, + krate: &mut ast::Crate, sd: &errors::Handler, features: &Features, - test_runner: Option) -> ast::Crate { + test_runner: Option) { // Remove the entry points let mut cleaner = EntryPointCleaner { depth: 0 }; - let krate = cleaner.fold_crate(krate); + cleaner.visit_crate(krate); let mark = Mark::fresh(Mark::root()); @@ -293,7 +293,7 @@ fn generate_test_harness(sess: &ParseSess, cx, tests: Vec::new(), tested_submods: Vec::new(), - }.fold_crate(krate) + }.visit_crate(krate); } /// Craft a span that will be ignored by the stability lint's diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index f5d2d6f18ee87..ff5978a7ee581 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -147,7 +147,7 @@ impl TokenTree { /// empty stream is represented with `None`; it may be represented as a `Some` /// around an empty `Vec`. #[derive(Clone, Debug)] -pub struct TokenStream(Option>>); +pub struct TokenStream(pub Option>>); pub type TreeAndJoint = (TokenTree, IsJoint); diff --git a/src/libsyntax/util/move_map.rs b/src/libsyntax/util/map_in_place.rs similarity index 82% rename from src/libsyntax/util/move_map.rs rename to src/libsyntax/util/map_in_place.rs index a0f9d39ce89b3..5724b540a0dcf 100644 --- a/src/libsyntax/util/move_map.rs +++ b/src/libsyntax/util/map_in_place.rs @@ -1,18 +1,18 @@ use std::ptr; use smallvec::{Array, SmallVec}; -pub trait MoveMap: Sized { - fn move_map(self, mut f: F) -> Self where F: FnMut(T) -> T { - self.move_flat_map(|e| Some(f(e))) +pub trait MapInPlace: Sized { + fn map_in_place(&mut self, mut f: F) where F: FnMut(T) -> T { + self.flat_map_in_place(|e| Some(f(e))) } - fn move_flat_map(self, f: F) -> Self + fn flat_map_in_place(&mut self, f: F) where F: FnMut(T) -> I, I: IntoIterator; } -impl MoveMap for Vec { - fn move_flat_map(mut self, mut f: F) -> Self +impl MapInPlace for Vec { + fn flat_map_in_place(&mut self, mut f: F) where F: FnMut(T) -> I, I: IntoIterator { @@ -53,22 +53,11 @@ impl MoveMap for Vec { // write_i tracks the number of actually written new items. self.set_len(write_i); } - - self - } -} - -impl MoveMap for ::ptr::P<[T]> { - fn move_flat_map(self, f: F) -> Self - where F: FnMut(T) -> I, - I: IntoIterator - { - ::ptr::P::from_vec(self.into_vec().move_flat_map(f)) } } -impl> MoveMap for SmallVec { - fn move_flat_map(mut self, mut f: F) -> Self +impl> MapInPlace for SmallVec { + fn flat_map_in_place(&mut self, mut f: F) where F: FnMut(T) -> I, I: IntoIterator { @@ -109,7 +98,5 @@ impl> MoveMap for SmallVec { // write_i tracks the number of actually written new items. self.set_len(write_i); } - - self } } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 22643db501693..ec2c3113fab95 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -189,7 +189,7 @@ use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::source_map::{self, respan}; -use syntax::util::move_map::MoveMap; +use syntax::util::map_in_place::MapInPlace; use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; use syntax::parse::ParseSess; @@ -1184,7 +1184,7 @@ impl<'a> MethodDef<'a> { enum_def: &'b EnumDef, type_attrs: &[ast::Attribute], type_ident: Ident, - self_args: Vec>, + mut self_args: Vec>, nonself_args: &[P]) -> P { let sp = trait_.span; @@ -1417,8 +1417,8 @@ impl<'a> MethodDef<'a> { // them when they are fed as r-values into a tuple // expression; here add a layer of borrowing, turning // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`. - let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg)); - let match_arg = cx.expr(sp, ast::ExprKind::Tup(borrowed_self_args)); + self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg)); + let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args)); // Lastly we create an expression which branches on all discriminants being equal // if discriminant_test { @@ -1494,8 +1494,8 @@ impl<'a> MethodDef<'a> { // them when they are fed as r-values into a tuple // expression; here add a layer of borrowing, turning // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`. - let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg)); - let match_arg = cx.expr(sp, ast::ExprKind::Tup(borrowed_self_args)); + self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg)); + let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args)); cx.expr_match(sp, match_arg, match_arms) } } diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 46c502965eea8..663fb12242c44 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -9,7 +9,7 @@ use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; use syntax::ext::hygiene::Mark; -use syntax::fold::Folder; +use syntax::mut_visit::MutVisitor; use syntax::parse::ParseSess; use syntax::ptr::P; use syntax::symbol::Symbol; @@ -412,5 +412,5 @@ fn mk_decls( i }); - cx.monotonic_expander().fold_item(module).pop().unwrap() + cx.monotonic_expander().flat_map_item(module).pop().unwrap() } diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs index ce3b03efd2604..ee4ecde44f28e 100644 --- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs @@ -27,7 +27,7 @@ use rustc_data_structures::thin_vec::ThinVec; use syntax::ast::*; use syntax::source_map::{Spanned, DUMMY_SP, FileName}; use syntax::source_map::FilePathMapping; -use syntax::fold::{self, Folder}; +use syntax::mut_visit::{self, MutVisitor, visit_clobber}; use syntax::parse::{self, ParseSess}; use syntax::print::pprust; use syntax::ptr::P; @@ -157,32 +157,34 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P)) { // Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. -/// Folder that removes all `ExprKind::Paren` nodes. +/// MutVisitor that removes all `ExprKind::Paren` nodes. struct RemoveParens; -impl Folder for RemoveParens { - fn fold_expr(&mut self, e: P) -> P { - let e = match e.node { - ExprKind::Paren(ref inner) => inner.clone(), - _ => e.clone(), +impl MutVisitor for RemoveParens { + fn visit_expr(&mut self, e: &mut P) { + match e.node.clone() { + ExprKind::Paren(inner) => *e = inner, + _ => {} }; - e.map(|e| fold::noop_fold_expr(e, self)) + mut_visit::noop_visit_expr(e, self); } } -/// Folder that inserts `ExprKind::Paren` nodes around every `Expr`. +/// MutVisitor that inserts `ExprKind::Paren` nodes around every `Expr`. struct AddParens; -impl Folder for AddParens { - fn fold_expr(&mut self, e: P) -> P { - let e = e.map(|e| fold::noop_fold_expr(e, self)); - P(Expr { - id: DUMMY_NODE_ID, - node: ExprKind::Paren(e), - span: DUMMY_SP, - attrs: ThinVec::new(), - }) +impl MutVisitor for AddParens { + fn visit_expr(&mut self, e: &mut P) { + mut_visit::noop_visit_expr(e, self); + visit_clobber(e, |e| { + P(Expr { + id: DUMMY_NODE_ID, + node: ExprKind::Paren(e), + span: DUMMY_SP, + attrs: ThinVec::new(), + }) + }); } } @@ -193,13 +195,13 @@ fn main() { fn run() { let ps = ParseSess::new(FilePathMapping::empty()); - iter_exprs(2, &mut |e| { + iter_exprs(2, &mut |mut e| { // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, // modulo placement of `Paren` nodes. let printed = pprust::expr_to_string(&e); println!("printed: {}", printed); - let parsed = parse_expr(&ps, &printed); + let mut parsed = parse_expr(&ps, &printed); // We want to know if `parsed` is structurally identical to `e`, ignoring trivial // differences like placement of `Paren`s or the exact ranges of node spans. @@ -207,10 +209,12 @@ fn run() { // everywhere we can, then pretty-print. This should give an unambiguous representation of // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't // relying on the correctness of the very thing we're testing. - let e1 = AddParens.fold_expr(RemoveParens.fold_expr(e)); - let text1 = pprust::expr_to_string(&e1); - let e2 = AddParens.fold_expr(RemoveParens.fold_expr(parsed)); - let text2 = pprust::expr_to_string(&e2); + RemoveParens.visit_expr(&mut e); + AddParens.visit_expr(&mut e); + let text1 = pprust::expr_to_string(&e); + RemoveParens.visit_expr(&mut parsed); + AddParens.visit_expr(&mut parsed); + let text2 = pprust::expr_to_string(&parsed); assert!(text1 == text2, "exprs are not equal:\n e = {:?}\n parsed = {:?}", text1, text2); diff --git a/src/test/ui/issues/issue-49934.rs b/src/test/ui/issues/issue-49934.rs index 59ca6cc292db9..ad410f30c04d4 100644 --- a/src/test/ui/issues/issue-49934.rs +++ b/src/test/ui/issues/issue-49934.rs @@ -30,12 +30,12 @@ fn main() { #[derive(Debug)] //~ WARN unused attribute let _ = "Hello, world!"; - // fold_expr + // visit_expr let _ = #[derive(Debug)] "Hello, world!"; //~^ WARN unused attribute let _ = [ - // fold_opt_expr + // filter_map_expr #[derive(Debug)] //~ WARN unused attribute "Hello, world!" ]; From bfcbd235a28f989c0e3c1f0a7542f4e5caaf6e0d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Feb 2019 09:10:05 +1100 Subject: [PATCH 0630/1064] Rename `fold.rs` as `mut_visit.rs`. --- src/libsyntax/lib.rs | 2 +- src/libsyntax/{fold.rs => mut_visit.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/libsyntax/{fold.rs => mut_visit.rs} (100%) diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index dacb0d811cedb..f2b8f23ee8530 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -151,7 +151,7 @@ pub mod source_map; pub mod config; pub mod entry; pub mod feature_gate; -#[path="fold.rs"] pub mod mut_visit; // temporary +pub mod mut_visit; pub mod parse; pub mod ptr; pub mod show_span; diff --git a/src/libsyntax/fold.rs b/src/libsyntax/mut_visit.rs similarity index 100% rename from src/libsyntax/fold.rs rename to src/libsyntax/mut_visit.rs From f2871a9ce552cd21b1c7b8df69eefe06af6d59da Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Feb 2019 11:57:11 +1100 Subject: [PATCH 0631/1064] Make `intern_lazy_const` actually intern its argument. Currently it just unconditionally allocates it in the arena. For a "Clean Check" build of the the `packed-simd` benchmark, this change reduces both the `max-rss` and `faults` counts by 59%; it slightly (~3%) increases the instruction counts but the `wall-time` is unchanged. For the same builds of a few other benchmarks, `max-rss` and `faults` drop by 1--5%, but instruction counts and `wall-time` changes are in the noise. Fixes #57432, fixes #57829. --- src/librustc/mir/mod.rs | 2 +- src/librustc/traits/project.rs | 4 ++-- src/librustc/traits/query/normalize.rs | 4 ++-- src/librustc/ty/codec.rs | 2 +- src/librustc/ty/context.rs | 22 ++++++++++--------- src/librustc/ty/structural_impls.rs | 2 +- src/librustc_mir/build/expr/as_rvalue.rs | 2 +- src/librustc_mir/build/matches/test.rs | 2 +- src/librustc_mir/build/misc.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 12 +++++----- src/librustc_mir/hair/cx/mod.rs | 6 ++--- src/librustc_mir/shim.rs | 6 ++--- src/librustc_mir/transform/elaborate_drops.rs | 2 +- src/librustc_mir/transform/generator.rs | 4 ++-- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- 17 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 82083b4f69964..eca01d78c2a4d 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2154,7 +2154,7 @@ impl<'tcx> Operand<'tcx> { span, ty, user_ty: None, - literal: tcx.intern_lazy_const( + literal: tcx.mk_lazy_const( ty::LazyConst::Evaluated(ty::Const::zero_sized(ty)), ), }) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index bec45046cb93e..21151276e7299 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -408,7 +408,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { let substs = tcx.lift_to_global(&substs).unwrap(); let evaluated = evaluated.subst(tcx, substs); - return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); } } } else { @@ -420,7 +420,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, promoted: None }; if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { - return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); } } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index be05445cfc61a..9f55bb95d259b 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -203,7 +203,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { let substs = tcx.lift_to_global(&substs).unwrap(); let evaluated = evaluated.subst(tcx, substs); - return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); } } } else { @@ -215,7 +215,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx promoted: None, }; if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { - return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); } } } diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index e0e4d9c362a6c..a4a2471852739 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -252,7 +252,7 @@ pub fn decode_lazy_const<'a, 'tcx, D>(decoder: &mut D) where D: TyDecoder<'a, 'tcx>, 'tcx: 'a, { - Ok(decoder.tcx().intern_lazy_const(Decodable::decode(decoder)?)) + Ok(decoder.tcx().mk_lazy_const(Decodable::decode(decoder)?)) } #[inline] diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b379b5ba02494..87cf52af1d182 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -127,6 +127,7 @@ pub struct CtxtInterners<'tcx> { goal: InternedSet<'tcx, GoalKind<'tcx>>, goal_list: InternedSet<'tcx, List>>, projs: InternedSet<'tcx, List>>, + lazy_const: InternedSet<'tcx, LazyConst<'tcx>>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { @@ -144,6 +145,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { goal: Default::default(), goal_list: Default::default(), projs: Default::default(), + lazy_const: Default::default(), } } @@ -1096,10 +1098,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.global_arenas.adt_def.alloc(def) } - pub fn intern_const_alloc( - self, - alloc: Allocation, - ) -> &'gcx Allocation { + pub fn intern_const_alloc(self, alloc: Allocation) -> &'gcx Allocation { self.allocation_interner.borrow_mut().intern(alloc, |alloc| { self.global_arenas.const_allocs.alloc(alloc) }) @@ -1119,10 +1118,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }) } - pub fn intern_lazy_const(self, c: ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { - self.global_interners.arena.alloc(c) - } - pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails { self.layout_interner.borrow_mut().intern(layout, |layout| { self.global_arenas.layout.alloc(layout) @@ -2271,6 +2266,12 @@ impl<'tcx: 'lcx, 'lcx> Borrow> for Interned<'tcx, GoalKind<'tcx>> } } +impl<'tcx: 'lcx, 'lcx> Borrow> for Interned<'tcx, LazyConst<'tcx>> { + fn borrow<'a>(&'a self) -> &'a LazyConst<'lcx> { + &self.0 + } +} + impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]> for Interned<'tcx, List>> { fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] { @@ -2377,7 +2378,8 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool { direct_interners!('tcx, region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind, - goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx> + goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>, + lazy_const: mk_lazy_const(|c: &LazyConst<'_>| keep_local(&c)) -> LazyConst<'tcx> ); macro_rules! slice_interners { @@ -2562,7 +2564,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { #[inline] pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { - self.mk_ty(Array(ty, self.intern_lazy_const( + self.mk_ty(Array(ty, self.mk_lazy_const( ty::LazyConst::Evaluated(ty::Const::from_usize(self.global_tcx(), n)) ))) } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 28f5a65374d98..f89a6ed2e768e 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1042,7 +1042,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> { ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder)) } }; - folder.tcx().intern_lazy_const(new) + folder.tcx().mk_lazy_const(new) } fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 3de2f47578650..508f6555f4afc 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -268,7 +268,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { span: expr_span, ty: this.hir.tcx().types.u32, user_ty: None, - literal: this.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated( + literal: this.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::from_bits( this.hir.tcx(), 0, diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 696c173b048ad..6e836f7059b83 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -302,7 +302,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap(); let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]); - let method = self.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated(method)); + let method = self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(method)); let re_erased = self.hir.tcx().types.re_erased; // take the argument by reference diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index c849c02242840..a7b201fc0dbc6 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -33,7 +33,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { span, ty, user_ty: None, - literal: self.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated(literal)), + literal: self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(literal)), }; Operand::Constant(constant) } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 8d64c9e9ada89..88512fede333c 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -342,7 +342,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprKind::Lit(ref lit) => ExprKind::Literal { - literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated( cx.const_eval_literal(&lit.node, expr_ty, lit.span, false) )), user_ty: None, @@ -442,7 +442,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } else { if let hir::ExprKind::Lit(ref lit) = arg.node { ExprKind::Literal { - literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated( cx.const_eval_literal(&lit.node, expr_ty, lit.span, true) )), user_ty: None, @@ -702,7 +702,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ty: var_ty, span: expr.span, kind: ExprKind::Literal { - literal: cx.tcx.intern_lazy_const(literal), + literal: cx.tcx.mk_lazy_const(literal), user_ty: None }, }.to_ref(); @@ -856,7 +856,7 @@ fn method_callee<'a, 'gcx, 'tcx>( ty, span, kind: ExprKind::Literal { - literal: cx.tcx().intern_lazy_const(ty::LazyConst::Evaluated( + literal: cx.tcx().mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::zero_sized(ty) )), user_ty, @@ -918,7 +918,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def); debug!("convert_path_expr: user_ty={:?}", user_ty); ExprKind::Literal { - literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized( + literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized( cx.tables().node_id_to_type(expr.hir_id), ))), user_ty, @@ -930,7 +930,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def); debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { - literal: cx.tcx.intern_lazy_const(ty::LazyConst::Unevaluated(def_id, substs)), + literal: cx.tcx.mk_lazy_const(ty::LazyConst::Unevaluated(def_id, substs)), user_ty, } }, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index f514cac6326be..a726b87afa87b 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -110,7 +110,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { } pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::LazyConst<'tcx> { - self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_usize(self.tcx, value))) + self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_usize(self.tcx, value))) } pub fn bool_ty(&mut self) -> Ty<'tcx> { @@ -122,11 +122,11 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { } pub fn true_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> { - self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, true))) + self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, true))) } pub fn false_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> { - self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, false))) + self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, false))) } pub fn const_eval_literal( diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 751815eab287b..15796186063de 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -459,7 +459,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { span: self.span, ty: func_ty, user_ty: None, - literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::zero_sized(func_ty), )), }); @@ -521,7 +521,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { span: self.span, ty: self.tcx.types.usize, user_ty: None, - literal: self.tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::from_usize(self.tcx, value), )), } @@ -759,7 +759,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span, ty, user_ty: None, - literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::zero_sized(ty) )), }), diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 06e16de8b43bc..9b75a70ff41d2 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -533,7 +533,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { span, ty: self.tcx.types.bool, user_ty: None, - literal: self.tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::from_bool(self.tcx, val), )), }))) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index f5cc6a43e28b9..2a1188ed870ba 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -198,7 +198,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { span: source_info.span, ty: self.tcx.types.u32, user_ty: None, - literal: self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits( + literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits( self.tcx, state_disc.into(), ty::ParamEnv::empty().and(self.tcx.types.u32) @@ -731,7 +731,7 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: mir.span, ty: tcx.types.bool, user_ty: None, - literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated( + literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::from_bool(tcx, false), )), }), diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 8b55a4424ae29..eedc42927c126 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -963,7 +963,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> span: self.source_info.span, ty: self.tcx().types.usize, user_ty: None, - literal: self.tcx().intern_lazy_const(ty::LazyConst::Evaluated( + literal: self.tcx().mk_lazy_const(ty::LazyConst::Evaluated( ty::Const::from_usize(self.tcx(), val.into()) )), }) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8da0b6dcbeac3..757385aeb3edc 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1793,7 +1793,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let length_def_id = tcx.hir().local_def_id(length.id); let substs = Substs::identity_for_item(tcx, length_def_id); let length = ty::LazyConst::Unevaluated(length_def_id, substs); - let length = tcx.intern_lazy_const(length); + let length = tcx.mk_lazy_const(length); let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(&ty), length)); self.normalize_ty(ast_ty.span, array_ty) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3e2a9d720f1c1..fb8f608812197 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4597,7 +4597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if element_ty.references_error() { tcx.types.err } else if let Ok(count) = count { - tcx.mk_ty(ty::Array(t, tcx.intern_lazy_const(ty::LazyConst::Evaluated(count)))) + tcx.mk_ty(ty::Array(t, tcx.mk_lazy_const(ty::LazyConst::Evaluated(count)))) } else { tcx.types.err } From 8e7ef03141c40e34bd740bfe521b656387af9d56 Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Tue, 5 Feb 2019 20:32:35 -0800 Subject: [PATCH 0632/1064] Move ArcWake in common test file. --- src/test/run-pass/async-await.rs | 60 ++---------------------- src/test/run-pass/auxiliary/arc_wake.rs | 62 +++++++++++++++++++++++++ src/test/run-pass/futures-api.rs | 61 +++--------------------- 3 files changed, 73 insertions(+), 110 deletions(-) create mode 100644 src/test/run-pass/auxiliary/arc_wake.rs diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 2def62a6ba60c..1843feed927a2 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -1,7 +1,10 @@ // edition:2018 +// aux-build:arc_wake.rs #![feature(arbitrary_self_types, async_await, await_macro, futures_api)] +extern crate arc_wake; + use std::pin::Pin; use std::future::Future; use std::sync::{ @@ -9,62 +12,9 @@ use std::sync::{ atomic::{self, AtomicUsize}, }; use std::task::{ - Poll, Waker, RawWaker, RawWakerVTable, + Poll, Waker, }; - -macro_rules! waker_vtable { - ($ty:ident) => { - &RawWakerVTable { - clone: clone_arc_raw::<$ty>, - drop: drop_arc_raw::<$ty>, - wake: wake_arc_raw::<$ty>, - } - }; -} - -pub trait ArcWake { - fn wake(arc_self: &Arc); - - fn into_waker(wake: Arc) -> Waker where Self: Sized - { - let ptr = Arc::into_raw(wake) as *const(); - - unsafe { - Waker::new_unchecked(RawWaker{ - data: ptr, - vtable: waker_vtable!(Self), - }) - } - } -} - -unsafe fn increase_refcount(data: *const()) { - // Retain Arc by creating a copy - let arc: Arc = Arc::from_raw(data as *const T); - let arc_clone = arc.clone(); - // Forget the Arcs again, so that the refcount isn't decrased - let _ = Arc::into_raw(arc); - let _ = Arc::into_raw(arc_clone); -} - -unsafe fn clone_arc_raw(data: *const()) -> RawWaker { - increase_refcount::(data); - RawWaker { - data: data, - vtable: waker_vtable!(T), - } -} - -unsafe fn drop_arc_raw(data: *const()) { - // Drop Arc - let _: Arc = Arc::from_raw(data as *const T); -} - -unsafe fn wake_arc_raw(data: *const()) { - let arc: Arc = Arc::from_raw(data as *const T); - ArcWake::wake(&arc); - let _ = Arc::into_raw(arc); -} +use arc_wake::ArcWake; struct Counter { wakes: AtomicUsize, diff --git a/src/test/run-pass/auxiliary/arc_wake.rs b/src/test/run-pass/auxiliary/arc_wake.rs new file mode 100644 index 0000000000000..0baaa378046f3 --- /dev/null +++ b/src/test/run-pass/auxiliary/arc_wake.rs @@ -0,0 +1,62 @@ +// edition:2018 + +#![feature(arbitrary_self_types, futures_api)] + +use std::sync::Arc; +use std::task::{ + Poll, Waker, RawWaker, RawWakerVTable, +}; + +macro_rules! waker_vtable { + ($ty:ident) => { + &RawWakerVTable { + clone: clone_arc_raw::<$ty>, + drop: drop_arc_raw::<$ty>, + wake: wake_arc_raw::<$ty>, + } + }; +} + +pub trait ArcWake { + fn wake(arc_self: &Arc); + + fn into_waker(wake: Arc) -> Waker where Self: Sized + { + let ptr = Arc::into_raw(wake) as *const(); + + unsafe { + Waker::new_unchecked(RawWaker{ + data: ptr, + vtable: waker_vtable!(Self), + }) + } + } +} + +unsafe fn increase_refcount(data: *const()) { + // Retain Arc by creating a copy + let arc: Arc = Arc::from_raw(data as *const T); + let arc_clone = arc.clone(); + // Forget the Arcs again, so that the refcount isn't decrased + let _ = Arc::into_raw(arc); + let _ = Arc::into_raw(arc_clone); +} + +unsafe fn clone_arc_raw(data: *const()) -> RawWaker { + increase_refcount::(data); + RawWaker { + data: data, + vtable: waker_vtable!(T), + } +} + +unsafe fn drop_arc_raw(data: *const()) { + // Drop Arc + let _: Arc = Arc::from_raw(data as *const T); +} + +unsafe fn wake_arc_raw(data: *const()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake(&arc); + let _ = Arc::into_raw(arc); +} diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index 8ada7d4fa7416..fd4b585d34572 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -1,6 +1,10 @@ +// aux-build:arc_wake.rs + #![feature(arbitrary_self_types, futures_api)] #![allow(unused)] +extern crate arc_wake; + use std::future::Future; use std::pin::Pin; use std::sync::{ @@ -8,62 +12,9 @@ use std::sync::{ atomic::{self, AtomicUsize}, }; use std::task::{ - Poll, Waker, RawWaker, RawWakerVTable, + Poll, Waker, }; - -macro_rules! waker_vtable { - ($ty:ident) => { - &RawWakerVTable { - clone: clone_arc_raw::<$ty>, - drop: drop_arc_raw::<$ty>, - wake: wake_arc_raw::<$ty>, - } - }; -} - -pub trait ArcWake { - fn wake(arc_self: &Arc); - - fn into_waker(wake: Arc) -> Waker where Self: Sized - { - let ptr = Arc::into_raw(wake) as *const(); - - unsafe { - Waker::new_unchecked(RawWaker{ - data: ptr, - vtable: waker_vtable!(Self), - }) - } - } -} - -unsafe fn increase_refcount(data: *const()) { - // Retain Arc by creating a copy - let arc: Arc = Arc::from_raw(data as *const T); - let arc_clone = arc.clone(); - // Forget the Arcs again, so that the refcount isn't decrased - let _ = Arc::into_raw(arc); - let _ = Arc::into_raw(arc_clone); -} - -unsafe fn clone_arc_raw(data: *const()) -> RawWaker { - increase_refcount::(data); - RawWaker { - data: data, - vtable: waker_vtable!(T), - } -} - -unsafe fn drop_arc_raw(data: *const()) { - // Drop Arc - let _: Arc = Arc::from_raw(data as *const T); -} - -unsafe fn wake_arc_raw(data: *const()) { - let arc: Arc = Arc::from_raw(data as *const T); - ArcWake::wake(&arc); - let _ = Arc::into_raw(arc); -} +use arc_wake::ArcWake; struct Counter { wakes: AtomicUsize, From f7ed6e18160bc8fccf27a73c05f3935c9e8f672e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Feb 2019 18:02:32 +1100 Subject: [PATCH 0633/1064] Make an assert debug-only in `find_constraint_paths_between_regions`. This reduces instruction counts for NLL builds of `wg-grammar` by over 20%. --- .../borrow_check/nll/region_infer/error_reporting/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index ec68ddaf3c852..550668a7ceece 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -205,7 +205,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { for constraint in self.constraint_graph .outgoing_edges(r, &self.constraints, fr_static) { - assert_eq!(constraint.sup, r); + debug_assert_eq!(constraint.sup, r); let sub_region = constraint.sub; if let Trace::NotVisited = context[sub_region] { context[sub_region] = Trace::FromOutlivesConstraint(constraint); From f3eede6870c817e2e22782ad08d31fcaa8c6b640 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Feb 2019 11:14:12 +0100 Subject: [PATCH 0634/1064] fix doctests --- src/libcore/mem.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 18302e36ff762..930fe737a7264 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1045,7 +1045,7 @@ impl DerefMut for ManuallyDrop { /// ```rust,no_run /// use std::mem; /// -/// let x: &i32 = mem::zeroed(); // undefined behavior! +/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! /// ``` /// This is exploited by the compiler for various optimizations, such as eliding /// run-time checks and optimizing `enum` layout. @@ -1058,6 +1058,7 @@ impl DerefMut for ManuallyDrop { /// it is a signal to the compiler indicating that the data here might *not* /// be initialized: /// ```rust +/// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// /// // Create an explicitly uninitialized reference. From 57c92696a9727a51831bef53cebc13108a379900 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 6 Feb 2019 11:13:06 +0100 Subject: [PATCH 0635/1064] Add embedded book to test such that checktools works --- src/bootstrap/test.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 1a46ebfcabb95..bb00f6f625130 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1383,6 +1383,7 @@ test_book!( RustdocBook, "src/doc/rustdoc", "rustdoc", default=true; RustcBook, "src/doc/rustc", "rustc", default=true; RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false; + EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false; TheBook, "src/doc/book", "book", default=false; UnstableBook, "src/doc/unstable-book", "unstable-book", default=true; ); From 13bbba273c2a3d6a83c081ba3c2129f8d572c1b7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Feb 2019 11:23:10 +0100 Subject: [PATCH 0636/1064] remove now-unneeded raw ptr casts --- src/libcore/str/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index b01cb688ee5c6..8c8f280f84794 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1759,7 +1759,7 @@ mod traits { unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { let ptr = slice.as_mut_ptr().add(self.start); let len = self.end - self.start; - super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len)) + super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len)) } #[inline] fn index(self, slice: &str) -> &Self::Output { @@ -1822,7 +1822,7 @@ mod traits { #[inline] unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { let ptr = slice.as_mut_ptr(); - super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end)) + super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, self.end)) } #[inline] fn index(self, slice: &str) -> &Self::Output { @@ -1885,7 +1885,7 @@ mod traits { unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { let ptr = slice.as_mut_ptr().add(self.start); let len = slice.len() - self.start; - super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len)) + super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len)) } #[inline] fn index(self, slice: &str) -> &Self::Output { From a996f2c8dcfd08b545374a0b6c0cc0c0c349ad30 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Feb 2019 12:55:50 +0100 Subject: [PATCH 0637/1064] add tracking issue --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 8c8f280f84794..f95cd0dab43ab 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2223,7 +2223,7 @@ impl str { /// modified in a way that it remains valid UTF-8. /// /// [`u8`]: primitive.u8.html - #[unstable(feature = "str_as_mut_ptr", issue = "0")] + #[unstable(feature = "str_as_mut_ptr", issue = "58215")] #[inline] pub fn as_mut_ptr(&mut self) -> *mut u8 { self as *mut str as *mut u8 From 20022f8b912f26cea45ae2dc1ed15e14d5f6b996 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 22:28:47 +0900 Subject: [PATCH 0638/1064] librustc_tsan => 2018 --- src/librustc_tsan/Cargo.toml | 1 + src/librustc_tsan/build.rs | 3 --- src/librustc_tsan/lib.rs | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml index f0618275f2f6a..d805833a7efc1 100644 --- a/src/librustc_tsan/Cargo.toml +++ b/src/librustc_tsan/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] build = "build.rs" name = "rustc_tsan" version = "0.0.0" +edition = "2018" [lib] name = "rustc_tsan" diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs index 0db3db392dddc..ed9c37087c7e5 100644 --- a/src/librustc_tsan/build.rs +++ b/src/librustc_tsan/build.rs @@ -1,6 +1,3 @@ -extern crate build_helper; -extern crate cmake; - use std::env; use build_helper::sanitizer_lib_boilerplate; diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs index d6c8e54c18db7..568bb540c4719 100644 --- a/src/librustc_tsan/lib.rs +++ b/src/librustc_tsan/lib.rs @@ -1,8 +1,9 @@ #![sanitizer_runtime] -#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] + +#![deny(rust_2018_idioms)] From fb0f0bfea6a9123ebfd057e10b87fad013ffd6ed Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 22:36:25 +0900 Subject: [PATCH 0639/1064] librustc_msan => 2018 --- src/librustc_msan/Cargo.toml | 1 + src/librustc_msan/build.rs | 3 --- src/librustc_msan/lib.rs | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml index 78c39d03e45a9..7d88aa59b3adb 100644 --- a/src/librustc_msan/Cargo.toml +++ b/src/librustc_msan/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] build = "build.rs" name = "rustc_msan" version = "0.0.0" +edition = "2018" [lib] name = "rustc_msan" diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs index 085514b5a0108..1c66b0a9cd3cf 100644 --- a/src/librustc_msan/build.rs +++ b/src/librustc_msan/build.rs @@ -1,6 +1,3 @@ -extern crate build_helper; -extern crate cmake; - use std::env; use build_helper::sanitizer_lib_boilerplate; diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index d6c8e54c18db7..568bb540c4719 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -1,8 +1,9 @@ #![sanitizer_runtime] -#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] + +#![deny(rust_2018_idioms)] From 30fab05bed13c497182e0cf3cf18ea2ea12af997 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 22:40:09 +0900 Subject: [PATCH 0640/1064] librustc_asan => 2018 --- src/librustc_asan/Cargo.toml | 1 + src/librustc_asan/build.rs | 3 --- src/librustc_asan/lib.rs | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml index 836caf22abfa5..7d9641c83ee7d 100644 --- a/src/librustc_asan/Cargo.toml +++ b/src/librustc_asan/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] build = "build.rs" name = "rustc_asan" version = "0.0.0" +edition = "2018" [lib] name = "rustc_asan" diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs index b42d775deb393..a2b4b090efb4f 100644 --- a/src/librustc_asan/build.rs +++ b/src/librustc_asan/build.rs @@ -1,6 +1,3 @@ -extern crate build_helper; -extern crate cmake; - use std::env; use build_helper::sanitizer_lib_boilerplate; diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index d6c8e54c18db7..568bb540c4719 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -1,8 +1,9 @@ #![sanitizer_runtime] -#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] + +#![deny(rust_2018_idioms)] From 3893b2f04e90366a9ebad4d90b05ac51600992c7 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 22:46:01 +0900 Subject: [PATCH 0641/1064] libprofiler_builtins => 2018 --- src/libprofiler_builtins/Cargo.toml | 1 + src/libprofiler_builtins/build.rs | 2 -- src/libprofiler_builtins/lib.rs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libprofiler_builtins/Cargo.toml b/src/libprofiler_builtins/Cargo.toml index 7c95cf0a0542a..0d36bd0b39d76 100644 --- a/src/libprofiler_builtins/Cargo.toml +++ b/src/libprofiler_builtins/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] build = "build.rs" name = "profiler_builtins" version = "0.0.0" +edition = "2018" [lib] name = "profiler_builtins" diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index b66cd66448748..ff52a03d9dd97 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -2,8 +2,6 @@ //! //! See the build.rs for libcompiler_builtins crate for details. -extern crate cc; - use std::env; use std::path::Path; diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index 0d12ba01c87a2..9c8d3a13b0812 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -5,5 +5,5 @@ reason = "internal implementation detail of rustc right now", issue = "0")] #![allow(unused_features)] -#![feature(nll)] #![feature(staged_api)] +#![deny(rust_2018_idioms)] From 44b2cc0941e63cb8b12fd3a361d8eb8564504a73 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 22:55:03 +0900 Subject: [PATCH 0642/1064] librustc_allocator => 2018 --- src/librustc_allocator/Cargo.toml | 1 + src/librustc_allocator/expand.rs | 10 +++++----- src/librustc_allocator/lib.rs | 11 +---------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/librustc_allocator/Cargo.toml b/src/librustc_allocator/Cargo.toml index 03d33f413c807..cf6c598bfb17b 100644 --- a/src/librustc_allocator/Cargo.toml +++ b/src/librustc_allocator/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_allocator" version = "0.0.0" +edition = "2018" [lib] path = "lib.rs" diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 1fb1794d5147d..d302e7646d168 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -1,6 +1,6 @@ +use log::debug; use rustc::middle::allocator::AllocatorKind; -use rustc_errors; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use syntax::{ ast::{ self, Arg, Attribute, Crate, Expr, FnHeader, Generics, Ident, Item, ItemKind, @@ -23,7 +23,7 @@ use syntax::{ }; use syntax_pos::Span; -use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; +use crate::{AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; pub fn modify( sess: &ParseSess, @@ -54,7 +54,7 @@ struct ExpandAllocatorDirectives<'a> { in_submod: isize, } -impl<'a> MutVisitor for ExpandAllocatorDirectives<'a> { +impl MutVisitor for ExpandAllocatorDirectives<'_> { fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { debug!("in submodule {}", self.in_submod); @@ -168,7 +168,7 @@ struct AllocFnFactory<'a> { cx: ExtCtxt<'a>, } -impl<'a> AllocFnFactory<'a> { +impl AllocFnFactory<'_> { fn allocator_fn(&self, method: &AllocatorMethod) -> P { let mut abi_args = Vec::new(); let mut i = 0; diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs index 41c0be615956e..16b9ccfda8010 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/librustc_allocator/lib.rs @@ -1,15 +1,6 @@ -#![feature(nll)] #![feature(rustc_private)] -#[macro_use] extern crate log; -extern crate rustc; -extern crate rustc_data_structures; -extern crate rustc_errors; -extern crate rustc_target; -extern crate syntax; -extern crate syntax_pos; -#[macro_use] -extern crate smallvec; +#![deny(rust_2018_idioms)] pub mod expand; From ea46f5b2d06bd4f106d67245cf2260ca33526f2b Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 23:12:47 +0900 Subject: [PATCH 0643/1064] librustc_lsan => 2018 --- src/librustc_lsan/Cargo.toml | 1 + src/librustc_lsan/build.rs | 3 --- src/librustc_lsan/lib.rs | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml index a8e11df7670cf..9ad53ee6d0958 100644 --- a/src/librustc_lsan/Cargo.toml +++ b/src/librustc_lsan/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] build = "build.rs" name = "rustc_lsan" version = "0.0.0" +edition = "2018" [lib] name = "rustc_lsan" diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs index ad528bb03902c..b8c7b7c2d5537 100644 --- a/src/librustc_lsan/build.rs +++ b/src/librustc_lsan/build.rs @@ -1,6 +1,3 @@ -extern crate build_helper; -extern crate cmake; - use std::env; use build_helper::sanitizer_lib_boilerplate; diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index d6c8e54c18db7..568bb540c4719 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -1,8 +1,9 @@ #![sanitizer_runtime] -#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] + +#![deny(rust_2018_idioms)] From 4f20348fd338609bc8101b39781fed7646b734cb Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 6 Feb 2019 15:16:50 +0100 Subject: [PATCH 0644/1064] Revert "Rollup merge of #58162 - pietroalbini:track-259, r=alexcrichton" This reverts commit 4c243e2c3d8f02cdcd22fe68acf6a0b3edca2078, reversing changes made to 64f0032a3739b18ae45387744340d9c7ce48b145. --- appveyor.yml | 5 +---- src/ci/run.sh | 8 +------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0ec4210af98b2..d70ad54b1c812 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -207,10 +207,7 @@ test_script: - sh src/ci/init_repo.sh . /c/cache/rustsrc - set SRC=. - set NO_CCACHE=1 - # Added this debugging code to try tracking down https://github.com/rust-lang/rust/issues/58160 - # Replace it with the commented line below after the issue with AppVeyor is fixed - - "sh src/ci/run.sh & set ret=%errorlevel% & echo exit code in appveyor.yml: %ret% & exit %ret%" -# - sh src/ci/run.sh + - sh src/ci/run.sh on_failure: # Dump crash log diff --git a/src/ci/run.sh b/src/ci/run.sh index 0841e70a6ed29..0f2517c7d1f55 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -127,13 +127,7 @@ if [ ! -z "$SCRIPT" ]; then set +e sh -x -c "$SCRIPT" ret=$? - echo "exit code in src/ci/run.sh: $ret" - - echo "tasklist:" - tasklist - echo -n "location of sh: " - where sh - + echo "script exited with $ret" exit $ret else do_make() { From 99599245a3cbf056ea090e34e2a3741ef8e0ae88 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 6 Feb 2019 15:17:15 +0100 Subject: [PATCH 0645/1064] Revert "Auto merge of #57975 - alexcrichton:debug-exit-appveyor, r=pietroalbini" This reverts commit d3d0bf0e9f4d748b95ed143cc636d159bfcb4a6f, reversing changes made to 40e6a0bd766ca7b1c582b964131400b8c3e89d76. --- src/ci/run.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 0f2517c7d1f55..42d0d7db5964c 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -121,14 +121,7 @@ fi travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then - # This `set +e` followed by capturing the return value is a temporary measure - # to help debug "error with exit 259" on AppVeyor temporarily, otherwise all - # that's needed here is the `sh` - set +e sh -x -c "$SCRIPT" - ret=$? - echo "script exited with $ret" - exit $ret else do_make() { travis_fold start "make-$1" From d4a60e01d158d508b50427167c399ef2a964bddd Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 23:18:33 +0900 Subject: [PATCH 0646/1064] librustc_fs_util => 2018 --- src/librustc_fs_util/Cargo.toml | 1 + src/librustc_fs_util/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/librustc_fs_util/Cargo.toml b/src/librustc_fs_util/Cargo.toml index e40b44204b349..47918643f31fe 100644 --- a/src/librustc_fs_util/Cargo.toml +++ b/src/librustc_fs_util/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_fs_util" version = "0.0.0" +edition = "2018" [lib] name = "rustc_fs_util" diff --git a/src/librustc_fs_util/lib.rs b/src/librustc_fs_util/lib.rs index 74ff121f80385..340681d65c383 100644 --- a/src/librustc_fs_util/lib.rs +++ b/src/librustc_fs_util/lib.rs @@ -1,3 +1,5 @@ +#![deny(rust_2018_idioms)] + use std::path::{Path, PathBuf}; use std::ffi::CString; use std::fs; From 4deb5959a3a2cbc189e26cb4b0c59a6707a10b45 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 5 Feb 2019 10:12:43 -0500 Subject: [PATCH 0647/1064] display sugared return types for async functions --- src/librustdoc/clean/mod.rs | 39 +++++++++++++++++++++++++++++++++++ src/librustdoc/html/format.rs | 23 ++++++++++++++------- src/librustdoc/html/render.rs | 8 ++++--- src/test/rustdoc/async-fn.rs | 35 ++++++++++++++++++++++++------- 4 files changed, 88 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6eea95b61c990..9ef723db40833 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1707,6 +1707,30 @@ impl FnDecl { pub fn self_type(&self) -> Option { self.inputs.values.get(0).and_then(|v| v.to_self()) } + + /// Returns the sugared return type for an async function. + /// + /// For example, if the return type is `impl std::future::Future`, this function + /// will return `i32`. + /// + /// # Panics + /// + /// This function will panic if the return type does not match the expected sugaring for async + /// functions. + pub fn sugared_async_return_type(&self) -> FunctionRetTy { + match &self.output { + FunctionRetTy::Return(Type::ImplTrait(bounds)) => { + match &bounds[0] { + GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => { + let bindings = trait_.bindings().unwrap(); + FunctionRetTy::Return(bindings[0].ty.clone()) + } + _ => panic!("unexpected desugaring of async function"), + } + } + _ => panic!("unexpected desugaring of async function"), + } + } } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] @@ -2265,6 +2289,21 @@ impl Type { _ => None, } } + + pub fn bindings(&self) -> Option<&[TypeBinding]> { + match *self { + ResolvedPath { ref path, .. } => { + path.segments.last().and_then(|seg| { + if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args { + Some(&**bindings) + } else { + None + } + }) + } + _ => None + } + } } impl GetDefId for Type { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 5a3e6984859a2..c03e679bc5194 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -5,6 +5,7 @@ //! assume that HTML output is desired, although it may be possible to redesign //! them in the future to instead emit any format desired. +use std::borrow::Cow; use std::fmt; use rustc::hir::def_id::DefId; @@ -44,14 +45,16 @@ pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]); pub struct CommaSep<'a, T: 'a>(pub &'a [T]); pub struct AbiSpace(pub Abi); -/// Wrapper struct for properly emitting a method declaration. -pub struct Method<'a> { +/// Wrapper struct for properly emitting a function or method declaration. +pub struct Function<'a> { /// The declaration to emit. pub decl: &'a clean::FnDecl, /// The length of the function's "name", used to determine line-wrapping. pub name_len: usize, /// The number of spaces to indent each successive line with, if line-wrapping is necessary. pub indent: usize, + /// Whether the function is async or not. + pub asyncness: hir::IsAsync, } /// Wrapper struct for emitting a where clause from Generics. @@ -829,9 +832,9 @@ impl fmt::Display for clean::FnDecl { } } -impl<'a> fmt::Display for Method<'a> { +impl<'a> fmt::Display for Function<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let &Method { decl, name_len, indent } = self; + let &Function { decl, name_len, indent, asyncness } = self; let amp = if f.alternate() { "&" } else { "&" }; let mut args = String::new(); let mut args_plain = String::new(); @@ -891,11 +894,17 @@ impl<'a> fmt::Display for Method<'a> { args_plain.push_str(", ..."); } - let arrow_plain = format!("{:#}", decl.output); + let output = if let hir::IsAsync::Async = asyncness { + Cow::Owned(decl.sugared_async_return_type()) + } else { + Cow::Borrowed(&decl.output) + }; + + let arrow_plain = format!("{:#}", &output); let arrow = if f.alternate() { - format!("{:#}", decl.output) + format!("{:#}", &output) } else { - decl.output.to_string() + output.to_string() }; let pad = " ".repeat(name_len); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..c8bda66d84170 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -62,7 +62,7 @@ use fold::DocFolder; use html::escape::Escape; use html::format::{AsyncSpace, ConstnessSpace}; use html::format::{GenericBounds, WhereClause, href, AbiSpace}; -use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace}; +use html::format::{VisSpace, Function, UnsafetySpace, MutableSpace}; use html::format::fmt_impl_for_trait_page; use html::item_type::ItemType; use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap}; @@ -2963,10 +2963,11 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, name = it.name.as_ref().unwrap(), generics = f.generics, where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true }, - decl = Method { + decl = Function { decl: &f.decl, name_len, indent: 0, + asyncness: f.header.asyncness, })?; document(w, cx, it) } @@ -3410,10 +3411,11 @@ fn render_assoc_item(w: &mut fmt::Formatter, href = href, name = name, generics = *g, - decl = Method { + decl = Function { decl: d, name_len: head_len, indent, + asyncness: header.asyncness, }, where_clause = WhereClause { gens: g, diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index a0b6c29126092..ba4997a7f9b5b 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -1,14 +1,35 @@ // edition:2018 -// compile-flags:-Z unstable-options - -// FIXME: once `--edition` is stable in rustdoc, remove that `compile-flags` directive #![feature(async_await, futures_api)] -// @has async_fn/struct.S.html -// @has - '//code' 'pub async fn f()' -pub struct S; +// @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option' +pub async fn foo() -> Option { + None +} + +// @has async_fn/fn.bar.html '//pre[@class="rust fn"]' 'pub async fn bar(a: i32, b: i32) -> i32' +pub async fn bar(a: i32, b: i32) -> i32 { + 0 +} + +// @has async_fn/fn.baz.html '//pre[@class="rust fn"]' 'pub async fn baz(a: T) -> T' +pub async fn baz(a: T) -> T { + a +} + +trait Bar {} + +impl Bar for () {} + +// @has async_fn/fn.quux.html '//pre[@class="rust fn"]' 'pub async fn quux() -> impl Bar' +pub async fn quux() -> impl Bar { + () +} + +// @has async_fn/struct.Foo.html +// @matches - '//code' 'pub async fn f\(\)$' +pub struct Foo; -impl S { +impl Foo { pub async fn f() {} } From 9f4a11c63732c2bdc623b4e66ee9bcc3f0159e95 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Feb 2019 23:56:39 +0900 Subject: [PATCH 0648/1064] librustc_plugin => 2018 --- src/librustc_plugin/Cargo.toml | 1 + src/librustc_plugin/diagnostics.rs | 2 ++ src/librustc_plugin/lib.rs | 10 ++-------- src/librustc_plugin/load.rs | 5 +++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/librustc_plugin/Cargo.toml b/src/librustc_plugin/Cargo.toml index d8fa1da1ce219..5e23aa0d7f74e 100644 --- a/src/librustc_plugin/Cargo.toml +++ b/src/librustc_plugin/Cargo.toml @@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"] name = "rustc_plugin" version = "0.0.0" build = false +edition = "2018" [lib] name = "rustc_plugin" diff --git a/src/librustc_plugin/diagnostics.rs b/src/librustc_plugin/diagnostics.rs index 382a1edb43c4a..68462bd83ef60 100644 --- a/src/librustc_plugin/diagnostics.rs +++ b/src/librustc_plugin/diagnostics.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; + register_long_diagnostics! { } diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index 7bdeae3e97854..9a31bddc1eded 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -54,19 +54,13 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(nll)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] -#[macro_use] extern crate syntax; +#![deny(rust_2018_idioms)] -extern crate rustc; -extern crate rustc_metadata; -extern crate syntax_pos; -extern crate rustc_errors as errors; - -pub use self::registry::Registry; +pub use registry::Registry; mod diagnostics; pub mod registry; diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 39f580420cf03..1b88cf05f40d5 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -3,18 +3,19 @@ use rustc::session::Session; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::CStore; -use registry::Registry; +use crate::registry::Registry; use std::borrow::ToOwned; use std::env; use std::mem; use std::path::PathBuf; use syntax::ast; +use syntax::span_err; use syntax_pos::{Span, DUMMY_SP}; /// Pointer to a registrar function. pub type PluginRegistrarFun = - fn(&mut Registry); + fn(&mut Registry<'_>); pub struct PluginRegistrar { pub fun: PluginRegistrarFun, From ba0fbd763d8d6b88457c0c06f1a3f583b69fcd19 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 7 Feb 2019 01:02:00 +0900 Subject: [PATCH 0649/1064] librustc_save_analysis => 2018 --- src/librustc_save_analysis/Cargo.toml | 1 + src/librustc_save_analysis/dump_visitor.rs | 73 ++++++++++++---------- src/librustc_save_analysis/json_dumper.rs | 4 +- src/librustc_save_analysis/lib.rs | 30 +++------ src/librustc_save_analysis/sig.rs | 51 ++++++++------- src/librustc_save_analysis/span_utils.rs | 2 +- 6 files changed, 79 insertions(+), 82 deletions(-) diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index e47f89c64ff07..8bb2e722b5794 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_save_analysis" version = "0.0.0" +edition = "2018" [lib] name = "rustc_save_analysis" diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 995df3802aabd..4d8bc0ad5ddf0 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -16,6 +16,7 @@ use rustc::hir::def::Def as HirDef; use rustc::hir::def_id::DefId; use rustc::session::config::Input; +use rustc::span_bug; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashSet; @@ -32,16 +33,20 @@ use syntax::print::pprust::{ }; use syntax::ptr::P; use syntax::source_map::{Spanned, DUMMY_SP, respan}; +use syntax::walk_list; use syntax_pos::*; -use {escape, generated_code, lower_attributes, PathCollector, SaveContext}; -use json_dumper::{Access, DumpOutput, JsonDumper}; -use span_utils::SpanUtils; -use sig; +use crate::{escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes, + PathCollector, SaveContext}; +use crate::json_dumper::{Access, DumpOutput, JsonDumper}; +use crate::span_utils::SpanUtils; +use crate::sig; use rls_data::{CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, RefKind, Relation, RelationKind, SpanData}; +use log::{debug, error}; + macro_rules! down_cast_data { ($id:ident, $kind:ident, $sp:expr) => { let $id = if let super::Data::$kind(data) = $id { @@ -68,7 +73,7 @@ macro_rules! access_from { }; } -pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> { +pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput> { save_ctxt: SaveContext<'l, 'tcx>, tcx: TyCtxt<'l, 'tcx, 'tcx>, dumper: &'ll mut JsonDumper, @@ -245,7 +250,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { None => continue, }; if !self.span.filter_generated(ident.span) { - let id = ::id_from_node_id(id, &self.save_ctxt); + let id = id_from_node_id(id, &self.save_ctxt); let span = self.span_from_span(ident.span); self.dumper.dump_def( @@ -286,7 +291,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { debug!("process_method: {}:{}", id, ident); if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) { - let sig_str = ::make_signature(&sig.decl, &generics); + let sig_str = crate::make_signature(&sig.decl, &generics); if body.is_some() { self.nest_tables( id, @@ -339,7 +344,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // Append $id to name to make sure each one is unique. let qualname = format!("{}::{}${}", prefix, name, id); if !self.span.filter_generated(param_ss) { - let id = ::id_from_node_id(param.id, &self.save_ctxt); + let id = id_from_node_id(param.id, &self.save_ctxt); let span = self.span_from_span(param_ss); self.dumper.dump_def( @@ -433,12 +438,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { &access_from!(self.save_ctxt, vis, id), Def { kind: DefKind::Const, - id: ::id_from_node_id(id, &self.save_ctxt), + id: id_from_node_id(id, &self.save_ctxt), span, name: ident.name.to_string(), qualname, value: ty_to_string(&typ), - parent: Some(::id_from_def_id(parent_id)), + parent: Some(id_from_def_id(parent_id)), children: vec![], decl_id: None, docs: self.save_ctxt.docs_for_attrs(attrs), @@ -495,7 +500,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { value, fields .iter() - .map(|f| ::id_from_node_id(f.id, &self.save_ctxt)) + .map(|f| id_from_node_id(f.id, &self.save_ctxt)) .collect(), ) } @@ -508,7 +513,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { &access_from!(self.save_ctxt, item), Def { kind, - id: ::id_from_node_id(item.id, &self.save_ctxt), + id: id_from_node_id(item.id, &self.save_ctxt), span, name, qualname: qualname.clone(), @@ -564,8 +569,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str); if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); - let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt); - let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); + let id = id_from_node_id(variant.node.data.id(), &self.save_ctxt); + let parent = Some(id_from_node_id(item.id, &self.save_ctxt)); self.dumper.dump_def( &access, @@ -602,8 +607,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); - let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt); - let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); + let id = id_from_node_id(variant.node.data.id(), &self.save_ctxt); + let parent = Some(id_from_node_id(item.id, &self.save_ctxt)); self.dumper.dump_def( &access, @@ -686,11 +691,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { val.push_str(&bounds_to_string(trait_refs)); } if !self.span.filter_generated(item.ident.span) { - let id = ::id_from_node_id(item.id, &self.save_ctxt); + let id = id_from_node_id(item.id, &self.save_ctxt); let span = self.span_from_span(item.ident.span); let children = methods .iter() - .map(|i| ::id_from_node_id(i.id, &self.save_ctxt)) + .map(|i| id_from_node_id(i.id, &self.save_ctxt)) .collect(); self.dumper.dump_def( &access_from!(self.save_ctxt, item), @@ -726,14 +731,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.dumper.dump_ref(Ref { kind: RefKind::Type, span: span.clone(), - ref_id: ::id_from_def_id(id), + ref_id: id_from_def_id(id), }); self.dumper.dump_relation(Relation { kind: RelationKind::SuperTrait, span, - from: ::id_from_def_id(id), - to: ::id_from_node_id(item.id, &self.save_ctxt), + from: id_from_def_id(id), + to: id_from_node_id(item.id, &self.save_ctxt), }); } } @@ -873,7 +878,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.dumper.dump_ref(Ref { kind: RefKind::Variable, span, - ref_id: ::id_from_def_id(variant.fields[index].did), + ref_id: id_from_def_id(variant.fields[index].did), }); } } @@ -912,7 +917,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if !self.span.filter_generated(ident.span) { let qualname = format!("{}${}", ident.to_string(), id); - let id = ::id_from_node_id(id, &self.save_ctxt); + let id = id_from_node_id(id, &self.save_ctxt); let span = self.span_from_span(ident.span); self.dumper.dump_def( @@ -988,7 +993,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // Rust uses the id of the pattern for var lookups, so we'll use it too. if !self.span.filter_generated(ident.span) { let qualname = format!("{}${}", ident.to_string(), id); - let id = ::id_from_node_id(id, &self.save_ctxt); + let id = id_from_node_id(id, &self.save_ctxt); let span = self.span_from_span(ident.span); self.dumper.dump_def( @@ -1091,7 +1096,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if !self.span.filter_generated(trait_item.ident.span) { let span = self.span_from_span(trait_item.ident.span); - let id = ::id_from_node_id(trait_item.id, &self.save_ctxt); + let id = id_from_node_id(trait_item.id, &self.save_ctxt); self.dumper.dump_def( &Access { @@ -1105,7 +1110,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { name, qualname, value: self.span.snippet(trait_item.span), - parent: Some(::id_from_def_id(trait_id)), + parent: Some(id_from_def_id(trait_id)), children: vec![], decl_id: None, docs: self.save_ctxt.docs_for_attrs(&trait_item.attrs), @@ -1196,7 +1201,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // The parent def id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id) .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) - .map(::id_from_def_id); + .map(id_from_def_id); match use_tree.kind { ast::UseTreeKind::Simple(alias, ..) => { @@ -1212,7 +1217,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let sub_span = path.segments.last().unwrap().ident.span; if !self.span.filter_generated(sub_span) { - let ref_id = self.lookup_def_id(id).map(|id| ::id_from_def_id(id)); + let ref_id = self.lookup_def_id(id).map(|id| id_from_def_id(id)); let alias_span = alias.map(|i| self.span_from_span(i.span)); let span = self.span_from_span(sub_span); self.dumper.import(&access, Import { @@ -1298,10 +1303,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(span); - let data_id = ::id_from_node_id(id, &self.save_ctxt); + let data_id = id_from_node_id(id, &self.save_ctxt); let children = m.items .iter() - .map(|i| ::id_from_node_id(i.id, &self.save_ctxt)) + .map(|i| id_from_node_id(i.id, &self.save_ctxt)) .collect(); let span = self.span_from_span(span); @@ -1345,7 +1350,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let span = self.span_from_span(name_span); let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id) .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) - .map(::id_from_def_id); + .map(id_from_def_id); self.dumper.import( &Access { public: false, @@ -1387,7 +1392,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let value = ty_to_string(&ty); if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); - let id = ::id_from_node_id(item.id, &self.save_ctxt); + let id = id_from_node_id(item.id, &self.save_ctxt); self.dumper.dump_def( &access_from!(self.save_ctxt, item), @@ -1417,7 +1422,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc let value = String::new(); if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); - let id = ::id_from_node_id(item.id, &self.save_ctxt); + let id = id_from_node_id(item.id, &self.save_ctxt); self.dumper.dump_def( &access_from!(self.save_ctxt, item), @@ -1476,7 +1481,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.dumper.dump_ref(Ref { kind: RefKind::Type, span, - ref_id: ::id_from_def_id(id), + ref_id: id_from_def_id(id), }); } diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 3627c5577a626..1840cf652e1d5 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -7,6 +7,8 @@ use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKin MacroRef, Ref, RefKind, Relation}; use rls_span::{Column, Row}; +use log::error; + #[derive(Debug)] pub struct Access { pub reachable: bool, @@ -23,7 +25,7 @@ pub trait DumpOutput { fn dump(&mut self, result: &Analysis); } -pub struct WriteOutput<'b, W: Write + 'b> { +pub struct WriteOutput<'b, W: Write> { output: &'b mut W, } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 73eb5de5c76f0..04ff1faf032cc 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -2,28 +2,11 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(custom_attribute)] -#![feature(nll)] +#![deny(rust_2018_idioms)] #![allow(unused_attributes)] #![recursion_limit="256"] -#[macro_use] -extern crate rustc; - -#[macro_use] -extern crate log; -extern crate rustc_data_structures; -extern crate rustc_codegen_utils; -extern crate rustc_serialize; -extern crate rustc_target; -extern crate rustc_typeck; -#[macro_use] -extern crate syntax; -extern crate syntax_pos; - -extern crate rls_data; -extern crate rls_span; - mod json_dumper; mod dump_visitor; @@ -39,6 +22,7 @@ use rustc::middle::privacy::AccessLevels; use rustc::middle::cstore::ExternCrate; use rustc::session::config::{CrateType, Input, OutputType}; use rustc::ty::{self, TyCtxt}; +use rustc::{bug, span_bug}; use rustc_typeck::hir_ty_to_ty; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; use rustc_data_structures::sync::Lrc; @@ -66,6 +50,8 @@ use rls_data::{Def, DefKind, ExternalCrateData, GlobalCrateId, MacroRef, Ref, Re RelationKind, SpanData, Impl, ImplKind}; use rls_data::config::Config; +use log::{debug, error, info}; + pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, @@ -172,7 +158,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ast::ForeignItemKind::Static(ref ty, _) => { filter!(self.span_utils, item.ident.span); - let id = ::id_from_node_id(item.id, self); + let id = id_from_node_id(item.id, self); let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { @@ -1029,7 +1015,7 @@ impl<'a> DumpHandler<'a> { } } - fn output_file(&self, ctx: &SaveContext) -> File { + fn output_file(&self, ctx: &SaveContext<'_, '_>) -> File { let sess = &ctx.tcx.sess; let file_name = match ctx.config.output_file { Some(ref s) => PathBuf::from(s), @@ -1180,7 +1166,7 @@ fn id_from_def_id(id: DefId) -> rls_data::Id { } } -fn id_from_node_id(id: NodeId, scx: &SaveContext) -> rls_data::Id { +fn id_from_node_id(id: NodeId, scx: &SaveContext<'_, '_>) -> rls_data::Id { let def_id = scx.tcx.hir().opt_local_def_id(id); def_id.map(|id| id_from_def_id(id)).unwrap_or_else(|| { // Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId` @@ -1200,7 +1186,7 @@ fn null_id() -> rls_data::Id { } } -fn lower_attributes(attrs: Vec, scx: &SaveContext) -> Vec { +fn lower_attributes(attrs: Vec, scx: &SaveContext<'_, '_>) -> Vec { attrs.into_iter() // Only retain real attributes. Doc comments are lowered separately. .filter(|attr| attr.path != "doc") diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 7d4c0d0f9f56f..fcd6ad07cd88f 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -25,7 +25,7 @@ // // FIXME where clauses need implementing, defs/refs in generics are mostly missing. -use {id_from_def_id, id_from_node_id, SaveContext}; +use crate::{id_from_def_id, id_from_node_id, SaveContext}; use rls_data::{SigElement, Signature}; @@ -34,14 +34,17 @@ use syntax::ast::{self, NodeId}; use syntax::print::pprust; -pub fn item_signature(item: &ast::Item, scx: &SaveContext) -> Option { +pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option { if !scx.config.signatures { return None; } item.make(0, None, scx).ok() } -pub fn foreign_item_signature(item: &ast::ForeignItem, scx: &SaveContext) -> Option { +pub fn foreign_item_signature( + item: &ast::ForeignItem, + scx: &SaveContext<'_, '_> +) -> Option { if !scx.config.signatures { return None; } @@ -50,7 +53,7 @@ pub fn foreign_item_signature(item: &ast::ForeignItem, scx: &SaveContext) -> Opt /// Signature for a struct or tuple field declaration. /// Does not include a trailing comma. -pub fn field_signature(field: &ast::StructField, scx: &SaveContext) -> Option { +pub fn field_signature(field: &ast::StructField, scx: &SaveContext<'_, '_>) -> Option { if !scx.config.signatures { return None; } @@ -58,7 +61,7 @@ pub fn field_signature(field: &ast::StructField, scx: &SaveContext) -> Option Option { +pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext<'_, '_>) -> Option { if !scx.config.signatures { return None; } @@ -70,7 +73,7 @@ pub fn method_signature( ident: ast::Ident, generics: &ast::Generics, m: &ast::MethodSig, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { return None; @@ -83,7 +86,7 @@ pub fn assoc_const_signature( ident: ast::Name, ty: &ast::Ty, default: Option<&ast::Expr>, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { return None; @@ -96,7 +99,7 @@ pub fn assoc_type_signature( ident: ast::Ident, bounds: Option<&ast::GenericBounds>, default: Option<&ast::Ty>, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { return None; @@ -104,10 +107,10 @@ pub fn assoc_type_signature( make_assoc_type_signature(id, ident, bounds, default, scx).ok() } -type Result = ::std::result::Result; +type Result = std::result::Result; trait Sig { - fn make(&self, offset: usize, id: Option, scx: &SaveContext) -> Result; + fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_, '_>) -> Result; } fn extend_sig( @@ -155,7 +158,7 @@ fn text_sig(text: String) -> Signature { } impl Sig for ast::Ty { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let id = Some(self.id); match self.node { ast::TyKind::Slice(ref ty) => { @@ -227,7 +230,7 @@ impl Sig for ast::Ty { if f.unsafety == ast::Unsafety::Unsafe { text.push_str("unsafe "); } - if f.abi != ::rustc_target::spec::abi::Abi::Rust { + if f.abi != rustc_target::spec::abi::Abi::Rust { text.push_str("extern"); text.push_str(&f.abi.to_string()); text.push(' '); @@ -317,7 +320,7 @@ impl Sig for ast::Ty { } impl Sig for ast::Item { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let id = Some(self.id); match self.node { @@ -381,7 +384,7 @@ impl Sig for ast::Item { if header.unsafety == ast::Unsafety::Unsafe { text.push_str("unsafe "); } - if header.abi != ::rustc_target::spec::abi::Abi::Rust { + if header.abi != rustc_target::spec::abi::Abi::Rust { text.push_str("extern"); text.push_str(&header.abi.to_string()); text.push(' '); @@ -571,7 +574,7 @@ impl Sig for ast::Item { } impl Sig for ast::Path { - fn make(&self, offset: usize, id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_, '_>) -> Result { let def = scx.get_path_def(id.ok_or("Missing id for Path")?); let (name, start, end) = match def { @@ -613,7 +616,7 @@ impl Sig for ast::Path { // This does not cover the where clause, which must be processed separately. impl Sig for ast::Generics { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { if self.params.is_empty() { return Ok(text_sig(String::new())); } @@ -662,7 +665,7 @@ impl Sig for ast::Generics { } impl Sig for ast::StructField { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let mut text = String::new(); let mut defs = None; if let Some(ident) = self.ident { @@ -685,7 +688,7 @@ impl Sig for ast::StructField { impl Sig for ast::Variant_ { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let mut text = self.ident.to_string(); match self.data { ast::VariantData::Struct(ref fields, id) => { @@ -743,7 +746,7 @@ impl Sig for ast::Variant_ { } impl Sig for ast::ForeignItem { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> Result { + fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let id = Some(self.id); match self.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { @@ -827,7 +830,7 @@ fn name_and_generics( generics: &ast::Generics, id: NodeId, name: ast::Ident, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Result { let name = name.to_string(); let def = SigElement { @@ -848,7 +851,7 @@ fn make_assoc_type_signature( ident: ast::Ident, bounds: Option<&ast::GenericBounds>, default: Option<&ast::Ty>, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Result { let mut text = "type ".to_owned(); let name = ident.to_string(); @@ -882,7 +885,7 @@ fn make_assoc_const_signature( ident: ast::Name, ty: &ast::Ty, default: Option<&ast::Expr>, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Result { let mut text = "const ".to_owned(); let name = ident.to_string(); @@ -915,7 +918,7 @@ fn make_method_signature( ident: ast::Ident, generics: &ast::Generics, m: &ast::MethodSig, - scx: &SaveContext, + scx: &SaveContext<'_, '_>, ) -> Result { // FIXME code dup with function signature let mut text = String::new(); @@ -928,7 +931,7 @@ fn make_method_signature( if m.header.unsafety == ast::Unsafety::Unsafe { text.push_str("unsafe "); } - if m.header.abi != ::rustc_target::spec::abi::Abi::Rust { + if m.header.abi != rustc_target::spec::abi::Abi::Rust { text.push_str("extern"); text.push_str(&m.header.abi.to_string()); text.push(' '); diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index 88c6012f71f69..e2c93b6d33158 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -1,6 +1,6 @@ use rustc::session::Session; -use generated_code; +use crate::generated_code; use std::cell::Cell; From edbd8a36c8820fb8a128675859c1fa76feab2bea Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 7 Feb 2019 02:15:23 +0900 Subject: [PATCH 0650/1064] librustc_resolve => 2018 --- src/librustc_resolve/Cargo.toml | 1 + src/librustc_resolve/build_reduced_graph.rs | 22 +++-- src/librustc_resolve/check_unused.rs | 6 +- src/librustc_resolve/diagnostics.rs | 2 + src/librustc_resolve/error_reporting.rs | 8 +- src/librustc_resolve/lib.rs | 93 ++++++++++----------- src/librustc_resolve/macros.rs | 23 ++--- src/librustc_resolve/resolve_imports.rs | 30 ++++--- 8 files changed, 96 insertions(+), 89 deletions(-) diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 3a8e84a3280c6..0ce82f2ce521b 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_resolve" version = "0.0.0" +edition = "2018" [lib] name = "rustc_resolve" diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c5401ac3f5560..750eb35a98854 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -3,14 +3,15 @@ //! Here we build the "reduced graph": the graph of the module tree without //! any imports resolved. -use macros::{InvocationData, ParentScope, LegacyScope}; -use resolve_imports::ImportDirective; -use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; -use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; -use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; -use Namespace::{self, TypeNS, ValueNS, MacroNS}; -use {resolve_error, resolve_struct_error, ResolutionError}; - +use crate::macros::{InvocationData, ParentScope, LegacyScope}; +use crate::resolve_imports::ImportDirective; +use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; +use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; +use crate::{ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; +use crate::Namespace::{self, TypeNS, ValueNS, MacroNS}; +use crate::{resolve_error, resolve_struct_error, ResolutionError}; + +use rustc::bug; use rustc::hir::def::*; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::ty; @@ -21,7 +22,7 @@ use std::cell::Cell; use std::ptr; use rustc_data_structures::sync::Lrc; -use errors::Applicability; +use crate::errors::Applicability; use syntax::ast::{Name, Ident}; use syntax::attr; @@ -34,12 +35,15 @@ use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; use syntax::feature_gate::is_builtin_attr; use syntax::parse::token::{self, Token}; +use syntax::span_err; use syntax::std_inject::injected_crate_name; use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax_pos::{Span, DUMMY_SP}; +use log::debug; + impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 16d8a95c003f7..639960827c996 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -10,8 +10,8 @@ use std::ops::{Deref, DerefMut}; -use Resolver; -use resolve_imports::ImportDirectiveSubclass; +use crate::Resolver; +use crate::resolve_imports::ImportDirectiveSubclass; use rustc::{lint, ty}; use rustc::util::nodemap::NodeMap; @@ -113,7 +113,7 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> { } } -pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) { +pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) { for directive in resolver.potentially_unused_imports.iter() { match directive.subclass { _ if directive.used.get() || diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 3f9c5f4fd273c..0db8689c0c17c 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; + // Error messages for EXXXX errors. Each message should start and end with a // new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and // use `gq` to wrap paragraphs. Use `:set tw=0` to disable. diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 2a8e95536b8c7..b131a6b62f9bf 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -1,10 +1,12 @@ -use {CrateLint, PathResult, Segment}; -use macros::ParentScope; +use crate::{CrateLint, PathResult, Segment}; +use crate::macros::ParentScope; +use crate::resolve_imports::ImportResolver; use syntax::symbol::keywords; use syntax_pos::Span; -use resolve_imports::ImportResolver; +use log::debug; + use std::cmp::Reverse; impl<'a, 'b:'a> ImportResolver<'a, 'b> { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 3973bc2ad62de..b166b1be02f45 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4,30 +4,19 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] -#![feature(nll)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![recursion_limit="256"] -#[macro_use] -extern crate bitflags; -#[macro_use] -extern crate log; -#[macro_use] -extern crate syntax; -extern crate syntax_pos; -extern crate rustc_errors as errors; -extern crate arena; -#[macro_use] -extern crate rustc; -extern crate rustc_data_structures; -extern crate rustc_metadata; +#![deny(rust_2018_idioms)] + +use rustc_errors as errors; pub use rustc::hir::def::{Namespace, PerNS}; -use self::TypeParameters::*; -use self::RibKind::*; +use TypeParameters::*; +use RibKind::*; use rustc::hir::map::{Definitions, DefCollector}; use rustc::hir::{self, PrimTy, Bool, Char, Float, Int, Uint, Str}; @@ -41,6 +30,7 @@ use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::session::config::nightly_options; use rustc::ty; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; +use rustc::{bug, span_bug}; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::CStore; @@ -62,10 +52,13 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind}; use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path}; use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind}; use syntax::ptr::P; +use syntax::{span_err, struct_span_err, unwrap_or, walk_list}; use syntax_pos::{BytePos, Span, DUMMY_SP, MultiSpan}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use log::debug; + use std::cell::{Cell, RefCell}; use std::{cmp, fmt, iter, mem, ptr}; use std::collections::BTreeSet; @@ -191,13 +184,13 @@ enum ResolutionError<'a> { /// /// This takes the error provided, combines it with the span and any additional spans inside the /// error and emits it. -fn resolve_error<'sess, 'a>(resolver: &'sess Resolver, +fn resolve_error<'sess, 'a>(resolver: &'sess Resolver<'_>, span: Span, resolution_error: ResolutionError<'a>) { resolve_struct_error(resolver, span, resolution_error).emit(); } -fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, +fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, span: Span, resolution_error: ResolutionError<'a>) -> DiagnosticBuilder<'sess> { @@ -1192,7 +1185,7 @@ impl<'a> ModuleData<'a> { } impl<'a> fmt::Debug for ModuleData<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.def()) } } @@ -1416,7 +1409,7 @@ impl<'a> NameBinding<'a> { // in some later round and screw up our previously found resolution. // See more detailed explanation in // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 - fn may_appear_after(&self, invoc_parent_expansion: Mark, binding: &NameBinding) -> bool { + fn may_appear_after(&self, invoc_parent_expansion: Mark, binding: &NameBinding<'_>) -> bool { // self > max(invoc, binding) => !(self <= invoc || self <= binding) // Expansions are partially ordered, so "may appear after" is an inversion of // "certainly appears before or simultaneously" and includes unordered cases. @@ -1630,14 +1623,14 @@ impl<'a> ResolverArenas<'a> { } module } - fn local_modules(&'a self) -> ::std::cell::Ref<'a, Vec>> { + fn local_modules(&'a self) -> std::cell::Ref<'a, Vec>> { self.local_modules.borrow() } fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> { self.name_bindings.alloc(name_binding) } fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>) - -> &'a ImportDirective { + -> &'a ImportDirective<'_> { self.import_directives.alloc(import_directive) } fn alloc_name_resolution(&'a self) -> &'a RefCell> { @@ -1754,7 +1747,7 @@ impl<'a> Resolver<'a> { is_value: bool, error_callback: F, ) -> hir::Path - where F: for<'c, 'b> FnOnce(&'c mut Resolver, Span, ResolutionError<'b>) + where F: for<'c, 'b> FnOnce(&'c mut Resolver<'_>, Span, ResolutionError<'b>) { let namespace = if is_value { ValueNS } else { TypeNS }; let span = path.span; @@ -1819,7 +1812,7 @@ impl<'a> Resolver<'a> { DefCollector::new(&mut definitions, Mark::root()) .collect_root(crate_name, session.local_crate_disambiguator()); - let mut extern_prelude: FxHashMap = + let mut extern_prelude: FxHashMap> = session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default())) .collect(); @@ -2315,7 +2308,7 @@ impl<'a> Resolver<'a> { // implementations thus found, for compatibility with old resolve pass. pub fn with_scope(&mut self, id: NodeId, f: F) -> T - where F: FnOnce(&mut Resolver) -> T + where F: FnOnce(&mut Resolver<'_>) -> T { let id = self.definitions.local_def_id(id); let module = self.module_map.get(&id).cloned(); // clones a reference @@ -2342,7 +2335,7 @@ impl<'a> Resolver<'a> { /// /// Stops after meeting a closure. fn search_label(&self, mut ident: Ident, pred: P) -> Option - where P: Fn(&Rib, Ident) -> Option + where P: Fn(&Rib<'_>, Ident) -> Option { for rib in self.label_ribs.iter().rev() { match rib.kind { @@ -2527,7 +2520,7 @@ impl<'a> Resolver<'a> { } fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F) - where F: FnOnce(&mut Resolver) + where F: FnOnce(&mut Resolver<'_>) { match type_parameters { HasTypeParameters(generics, rib_kind) => { @@ -2573,7 +2566,7 @@ impl<'a> Resolver<'a> { } fn with_label_rib(&mut self, f: F) - where F: FnOnce(&mut Resolver) + where F: FnOnce(&mut Resolver<'_>) { self.label_ribs.push(Rib::new(NormalRibKind)); f(self); @@ -2581,7 +2574,7 @@ impl<'a> Resolver<'a> { } fn with_item_rib(&mut self, f: F) - where F: FnOnce(&mut Resolver) + where F: FnOnce(&mut Resolver<'_>) { self.ribs[ValueNS].push(Rib::new(ItemRibKind)); self.ribs[TypeNS].push(Rib::new(ItemRibKind)); @@ -2591,7 +2584,7 @@ impl<'a> Resolver<'a> { } fn with_constant_rib(&mut self, f: F) - where F: FnOnce(&mut Resolver) + where F: FnOnce(&mut Resolver<'_>) { self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind)); self.label_ribs.push(Rib::new(ConstantItemRibKind)); @@ -2601,7 +2594,7 @@ impl<'a> Resolver<'a> { } fn with_current_self_type(&mut self, self_type: &Ty, f: F) -> T - where F: FnOnce(&mut Resolver) -> T + where F: FnOnce(&mut Resolver<'_>) -> T { // Handle nested impls (inside fn bodies) let previous_value = replace(&mut self.current_self_type, Some(self_type.clone())); @@ -2611,7 +2604,7 @@ impl<'a> Resolver<'a> { } fn with_current_self_item(&mut self, self_item: &Item, f: F) -> T - where F: FnOnce(&mut Resolver) -> T + where F: FnOnce(&mut Resolver<'_>) -> T { let previous_value = replace(&mut self.current_self_item, Some(self_item.id)); let result = f(self); @@ -2621,7 +2614,7 @@ impl<'a> Resolver<'a> { /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`) fn with_optional_trait_ref(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T - where F: FnOnce(&mut Resolver, Option) -> T + where F: FnOnce(&mut Resolver<'_>, Option) -> T { let mut new_val = None; let mut new_id = None; @@ -2658,7 +2651,7 @@ impl<'a> Resolver<'a> { } fn with_self_rib(&mut self, self_def: Def, f: F) - where F: FnOnce(&mut Resolver) + where F: FnOnce(&mut Resolver<'_>) { let mut self_type_rib = Rib::new(NormalRibKind); @@ -2670,7 +2663,7 @@ impl<'a> Resolver<'a> { } fn with_self_struct_ctor_rib(&mut self, impl_id: DefId, f: F) - where F: FnOnce(&mut Resolver) + where F: FnOnce(&mut Resolver<'_>) { let self_def = Def::SelfCtor(impl_id); let mut self_type_rib = Rib::new(NormalRibKind); @@ -2771,7 +2764,7 @@ impl<'a> Resolver<'a> { } fn check_trait_item(&mut self, ident: Ident, ns: Namespace, span: Span, err: F) - where F: FnOnce(Name, &str) -> ResolutionError + where F: FnOnce(Name, &str) -> ResolutionError<'_> { // If there is a TraitRef in scope for an impl, then the method must be in the // trait. @@ -3102,7 +3095,7 @@ impl<'a> Resolver<'a> { id: NodeId, qself: Option<&QSelf>, path: &Path, - source: PathSource) + source: PathSource<'_>) -> PathResolution { self.smart_resolve_path_with_crate_lint(id, qself, path, source, CrateLint::SimplePath(id)) } @@ -3120,7 +3113,7 @@ impl<'a> Resolver<'a> { id: NodeId, qself: Option<&QSelf>, path: &Path, - source: PathSource, + source: PathSource<'_>, crate_lint: CrateLint ) -> PathResolution { self.smart_resolve_path_fragment( @@ -3138,7 +3131,7 @@ impl<'a> Resolver<'a> { qself: Option<&QSelf>, path: &[Segment], span: Span, - source: PathSource, + source: PathSource<'_>, crate_lint: CrateLint) -> PathResolution { let ident_span = path.last().map_or(span, |ident| ident.ident.span); @@ -3581,7 +3574,7 @@ impl<'a> Resolver<'a> { } fn type_ascription_suggestion(&self, - err: &mut DiagnosticBuilder, + err: &mut DiagnosticBuilder<'_>, base_span: Span) { debug!("type_ascription_suggetion {:?}", base_span); let cm = self.session.source_map(); @@ -4040,7 +4033,7 @@ impl<'a> Resolver<'a> { crate_lint: CrateLint, path: &[Segment], path_span: Span, - second_binding: Option<&NameBinding>, + second_binding: Option<&NameBinding<'_>>, ) { let (diag_id, diag_span) = match crate_lint { CrateLint::No => return, @@ -4266,7 +4259,7 @@ impl<'a> Resolver<'a> { where FilterFn: Fn(Def) -> bool, { - let add_module_candidates = |module: Module, names: &mut Vec| { + let add_module_candidates = |module: Module<'_>, names: &mut Vec| { for (&(ident, _), resolution) in module.resolutions.borrow().iter() { if let Some(binding) = resolution.borrow().binding { if filter_fn(binding.def()) { @@ -4361,7 +4354,7 @@ impl<'a> Resolver<'a> { } fn with_resolved_label(&mut self, label: Option { fn outer(&self) { enum Foo { Variance(A) - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } } @@ -14,21 +14,21 @@ trait TraitA { trait TraitB { fn outer(&self) { struct Foo(A); - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } trait TraitC { fn outer(&self) { struct Foo { a: A } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } trait TraitD { fn outer(&self) { fn foo(a: A) { } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 8eca720d88e8c..f6b8abf4057e5 100644 --- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -1,44 +1,44 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:8:22 | LL | trait TraitA { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | enum Foo { LL | Variance(A) - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 | LL | trait TraitB { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | struct Foo(A); - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 | LL | trait TraitC { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | struct Foo { a: A } - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 | LL | trait TraitD { | - type variable from outer function LL | fn outer(&self) { LL | fn foo(a: A) { } - | ------ ^ use of type variable from outer function + | ------ ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `foo` + | help: try using a local generic parameter instead: `foo` error: aborting due to 4 previous errors diff --git a/src/test/ui/type/type-arg-out-of-scope.rs b/src/test/ui/type/type-arg-out-of-scope.rs index b96c9bf6a0e41..d5b815f6a95e9 100644 --- a/src/test/ui/type/type-arg-out-of-scope.rs +++ b/src/test/ui/type/type-arg-out-of-scope.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use type parameters from outer function +// error-pattern:can't use generic parameters from outer function fn foo(x: T) { fn bar(f: Box T>) { } } diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr index 62b6a86662d04..645cbb33abec1 100644 --- a/src/test/ui/type/type-arg-out-of-scope.stderr +++ b/src/test/ui/type/type-arg-out-of-scope.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:25 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bar(f: Box T>) { } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:31 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bar(f: Box T>) { } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` error: aborting due to 2 previous errors diff --git a/src/test/ui/use-self-in-inner-fn.rs b/src/test/ui/use-self-in-inner-fn.rs index cde96dc778bbe..eccb315feb1e2 100644 --- a/src/test/ui/use-self-in-inner-fn.rs +++ b/src/test/ui/use-self-in-inner-fn.rs @@ -4,8 +4,8 @@ impl A { //~^ NOTE `Self` type implicitly declared here, by this `impl` fn banana(&mut self) { fn peach(this: &Self) { - //~^ ERROR can't use type parameters from outer function - //~| NOTE use of type variable from outer function + //~^ ERROR can't use generic parameters from outer function + //~| NOTE use of generic parameter from outer function //~| NOTE use a type here instead } } diff --git a/src/test/ui/use-self-in-inner-fn.stderr b/src/test/ui/use-self-in-inner-fn.stderr index a613804b8038b..966093499241d 100644 --- a/src/test/ui/use-self-in-inner-fn.stderr +++ b/src/test/ui/use-self-in-inner-fn.stderr @@ -1,4 +1,4 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/use-self-in-inner-fn.rs:6:25 | LL | impl A { @@ -7,7 +7,7 @@ LL | impl A { LL | fn peach(this: &Self) { | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | use a type here instead error: aborting due to previous error From 1b933a5ce911616a2bf64c54c34693387eedb7e1 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 15:00:14 +0100 Subject: [PATCH 0711/1064] Add a test forbidding the use of const parameters in inner items --- .../const-param-from-outer-fn.rs | 11 ++++++++ .../const-param-from-outer-fn.stderr | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/test/ui/const-generics/const-param-from-outer-fn.rs create mode 100644 src/test/ui/const-generics/const-param-from-outer-fn.stderr diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.rs b/src/test/ui/const-generics/const-param-from-outer-fn.rs new file mode 100644 index 0000000000000..5a8dd92086f85 --- /dev/null +++ b/src/test/ui/const-generics/const-param-from-outer-fn.rs @@ -0,0 +1,11 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn foo() { + //~^ ERROR const generics in any position are currently unsupported + fn bar() -> u32 { + X //~ ERROR can't use generic parameters from outer function + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.stderr b/src/test/ui/const-generics/const-param-from-outer-fn.stderr new file mode 100644 index 0000000000000..b238b3a2aa453 --- /dev/null +++ b/src/test/ui/const-generics/const-param-from-outer-fn.stderr @@ -0,0 +1,26 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-param-from-outer-fn.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error[E0401]: can't use generic parameters from outer function + --> $DIR/const-param-from-outer-fn.rs:7:9 + | +LL | fn foo() { + | - const variable from outer function +LL | //~^ ERROR const generics in any position are currently unsupported +LL | fn bar() -> u32 { + | --- try adding a local generic parameter in this method instead +LL | X //~ ERROR can't use generic parameters from outer function + | ^ use of generic parameter from outer function + +error: const generics in any position are currently unsupported + --> $DIR/const-param-from-outer-fn.rs:4:14 + | +LL | fn foo() { + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0401`. From c54b230fa1a7365dd648e9dece87e40e838b45f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Feb 2019 06:20:23 -0800 Subject: [PATCH 0712/1064] Add fixme --- src/libsyntax/parse/parser.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6dd4bfbb8d5f5..0ac3b8f6bd018 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -721,7 +721,9 @@ impl<'a> Parser<'a> { // the most sense, which is immediately after the last token: // // {foo(bar {}} - // - ^ help: `)` may belong here + // - ^ + // | | + // | help: `)` may belong here (FIXME: #58270) // | // unclosed delimiter if let Some(sp) = unmatched.unclosed_span { From f2fe71c02ac7ecb29106b1a826d657ff5705ad6c Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 16:03:12 +0100 Subject: [PATCH 0713/1064] Resolve incorrect diagnostic for using a non-const value in a constant --- src/librustc_resolve/lib.rs | 18 +++++++++---- src/test/ui/impl-trait/bindings.rs | 8 +++--- src/test/ui/impl-trait/bindings.stderr | 26 +++++++------------ src/test/ui/issues/issue-27433.rs | 2 +- src/test/ui/issues/issue-27433.stderr | 8 +++--- src/test/ui/issues/issue-3521-2.rs | 2 +- src/test/ui/issues/issue-3521-2.stderr | 8 +++--- src/test/ui/issues/issue-3668-2.rs | 2 +- src/test/ui/issues/issue-3668-2.stderr | 8 +++--- src/test/ui/issues/issue-3668.rs | 2 +- src/test/ui/issues/issue-3668.stderr | 8 +++--- .../ui/type/type-dependent-def-issue-49241.rs | 2 +- .../type-dependent-def-issue-49241.stderr | 10 +++---- 13 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 365ba974d5aea..0d1f6328105b3 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4164,6 +4164,9 @@ impl<'a> Resolver<'a> { span_bug!(span, "unexpected {:?} in bindings", def) } Def::Local(node_id) => { + use ResolutionError::*; + let mut res_err = None; + for rib in ribs { match rib.kind { NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) | @@ -4199,21 +4202,26 @@ impl<'a> Resolver<'a> { // named function item. This is not allowed, so we // report an error. if record_used { - resolve_error(self, span, - ResolutionError::CannotCaptureDynamicEnvironmentInFnItem); + // We don't immediately trigger a resolve error, because + // we want certain other resolution errors (namely those + // emitted for `ConstantItemRibKind` below) to take + // precedence. + res_err = Some(CannotCaptureDynamicEnvironmentInFnItem); } - return Def::Err; } ConstantItemRibKind => { // Still doesn't deal with upvars if record_used { - resolve_error(self, span, - ResolutionError::AttemptToUseNonConstantValueInConstant); + resolve_error(self, span, AttemptToUseNonConstantValueInConstant); } return Def::Err; } } } + if let Some(res_err) = res_err { + resolve_error(self, span, res_err); + return Def::Err; + } } Def::TyParam(..) | Def::SelfTy(..) => { for rib in ribs { diff --git a/src/test/ui/impl-trait/bindings.rs b/src/test/ui/impl-trait/bindings.rs index 899303646d671..91d092634a901 100644 --- a/src/test/ui/impl-trait/bindings.rs +++ b/src/test/ui/impl-trait/bindings.rs @@ -2,27 +2,27 @@ fn a(x: T) { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant } fn b(x: T) { let _ = move || { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant }; } trait Foo { fn a(x: T) { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant } } impl Foo for i32 { fn a(x: T) { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant } } diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index 2a9be7a270a73..a5bf583afeaf6 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -1,35 +1,27 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:4:29 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:10:33 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:17:33 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:24:33 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-27433.rs b/src/test/ui/issues/issue-27433.rs index 2cc7d05e7c691..156ae68efe2c5 100644 --- a/src/test/ui/issues/issue-27433.rs +++ b/src/test/ui/issues/issue-27433.rs @@ -1,5 +1,5 @@ fn main() { let foo = 42u32; const FOO : u32 = foo; - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant } diff --git a/src/test/ui/issues/issue-27433.stderr b/src/test/ui/issues/issue-27433.stderr index 78a193dd99a7f..e232d17e6d7a6 100644 --- a/src/test/ui/issues/issue-27433.stderr +++ b/src/test/ui/issues/issue-27433.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-27433.rs:3:23 | LL | const FOO : u32 = foo; - | ^^^ - | - = help: use the `|| { ... }` closure form instead + | ^^^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-3521-2.rs b/src/test/ui/issues/issue-3521-2.rs index 39f7fcb833756..871394f9eaeb9 100644 --- a/src/test/ui/issues/issue-3521-2.rs +++ b/src/test/ui/issues/issue-3521-2.rs @@ -2,7 +2,7 @@ fn main() { let foo = 100; static y: isize = foo + 1; - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant println!("{}", y); } diff --git a/src/test/ui/issues/issue-3521-2.stderr b/src/test/ui/issues/issue-3521-2.stderr index 1464fd74bba69..d54bbbcdc3325 100644 --- a/src/test/ui/issues/issue-3521-2.stderr +++ b/src/test/ui/issues/issue-3521-2.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3521-2.rs:4:23 | LL | static y: isize = foo + 1; - | ^^^ - | - = help: use the `|| { ... }` closure form instead + | ^^^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-3668-2.rs b/src/test/ui/issues/issue-3668-2.rs index 265a884ded7aa..525f6f5684e70 100644 --- a/src/test/ui/issues/issue-3668-2.rs +++ b/src/test/ui/issues/issue-3668-2.rs @@ -1,6 +1,6 @@ fn f(x:isize) { static child: isize = x + 1; - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant } fn main() {} diff --git a/src/test/ui/issues/issue-3668-2.stderr b/src/test/ui/issues/issue-3668-2.stderr index 8dd6f49d8de5a..d6a6e8379602d 100644 --- a/src/test/ui/issues/issue-3668-2.stderr +++ b/src/test/ui/issues/issue-3668-2.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3668-2.rs:2:27 | LL | static child: isize = x + 1; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-3668.rs b/src/test/ui/issues/issue-3668.rs index 3f61b1b02e779..0e1f19a75baeb 100644 --- a/src/test/ui/issues/issue-3668.rs +++ b/src/test/ui/issues/issue-3668.rs @@ -6,7 +6,7 @@ trait PTrait { impl PTrait for P { fn getChildOption(&self) -> Option> { static childVal: Box

    = self.child.get(); - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant panic!(); } } diff --git a/src/test/ui/issues/issue-3668.stderr b/src/test/ui/issues/issue-3668.stderr index 7f974de9da8ea..98cd3631a5365 100644 --- a/src/test/ui/issues/issue-3668.stderr +++ b/src/test/ui/issues/issue-3668.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3668.rs:8:34 | LL | static childVal: Box

    ")?;
    +    render_attributes(w, it)?;
    +    write!(w, "trait {}{}{} = {};
    ", + it.name.as_ref().unwrap(), + t.generics, + WhereClause { gens: &t.generics, indent: 0, end_newline: true }, + bounds(&t.bounds, true))?; document(w, cx, it)?; @@ -4844,6 +4863,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) { ItemType::Existential => ("existentials", "Existentials"), ItemType::ProcAttribute => ("attributes", "Attribute Macros"), ItemType::ProcDerive => ("derives", "Derive Macros"), + ItemType::TraitAlias => ("trait-alias", "Trait aliases"), } } diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index c9a3a2c003fe0..5f3da4c7b33e0 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -224,6 +224,7 @@ impl<'a> fold::DocFolder for Stripper<'a> { | clean::ConstantItem(..) | clean::UnionItem(..) | clean::AssociatedConstItem(..) + | clean::TraitAliasItem(..) | clean::ForeignTypeItem => { if i.def_id.is_local() { if !self.access_levels.is_exported(i.def_id) { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index b8eb777a54ba4..352ff788eedae 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -547,8 +547,19 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { }; om.traits.push(t); }, - hir::ItemKind::TraitAlias(..) => { - unimplemented!("trait objects are not yet implemented") + hir::ItemKind::TraitAlias(ref gen, ref b) => { + let t = TraitAlias { + name: ident.name, + generics: gen.clone(), + bounds: b.iter().cloned().collect(), + id: item.id, + attrs: item.attrs.clone(), + whence: item.span, + vis: item.vis.clone(), + stab: self.stability(item.id), + depr: self.deprecation(item.id), + }; + om.trait_aliases.push(t); }, hir::ItemKind::Impl(unsafety, diff --git a/src/test/rustdoc/trait_alias.rs b/src/test/rustdoc/trait_alias.rs new file mode 100644 index 0000000000000..2614eda6cca01 --- /dev/null +++ b/src/test/rustdoc/trait_alias.rs @@ -0,0 +1,21 @@ +#![feature(trait_alias)] + +#![crate_name = "foo"] + +use std::fmt::Debug; + +// @has foo/all.html '//a[@href="traitalias.CopyAlias.html"]' 'CopyAlias' +// @has foo/all.html '//a[@href="traitalias.Alias2.html"]' 'Alias2' +// @has foo/all.html '//a[@href="traitalias.Foo.html"]' 'Foo' + +// @has foo/index.html '//h2[@id="trait-alias"]' 'Trait aliases' +// @has foo/index.html '//a[@class="traitalias"]' 'CopyAlias' +// @has foo/index.html '//a[@class="traitalias"]' 'Alias2' +// @has foo/index.html '//a[@class="traitalias"]' 'Foo' + +// @has foo/traitalias.CopyAlias.html '//section[@id="main"]/pre' 'trait CopyAlias = Copy;' +pub trait CopyAlias = Copy; +// @has foo/traitalias.Alias2.html '//section[@id="main"]/pre' 'trait Alias2 = Copy + Debug;' +pub trait Alias2 = Copy + Debug; +// @has foo/traitalias.Foo.html '//section[@id="main"]/pre' 'trait Foo = Into + Debug;' +pub trait Foo = Into + Debug; From 29354ddc15efb0ae7d6a45ca333b780bbe0ed501 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Feb 2019 01:02:09 +0100 Subject: [PATCH 0803/1064] Add style for trait aliases --- src/librustdoc/html/static/themes/dark.css | 2 ++ src/librustdoc/html/static/themes/light.css | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 6935ecde791f8..333fe76a8a4a9 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -94,6 +94,7 @@ pre { } .content .highlighted a, .content .highlighted span { color: #eee !important; } .content .highlighted.trait { background-color: #013191; } +.content .highlighted.traitalias { background-color: #013191; } .content .highlighted.mod, .content .highlighted.externcrate { background-color: #afc6e4; } .content .highlighted.mod { background-color: #803a1b; } @@ -128,6 +129,7 @@ pre { .content span.externcrate, .content span.mod, .content a.mod, .block a.current.mod { color: #bda000; } .content span.trait, .content a.trait, .block a.current.trait { color: #b78cf2; } +.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #b397da; } .content span.fn, .content a.fn, .block a.current.fn, .content span.method, .content a.method, .block a.current.method, .content span.tymethod, .content a.tymethod, .block a.current.tymethod, diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 306e8dc15d893..19ae67b29881f 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -96,6 +96,7 @@ pre { } .content .highlighted a, .content .highlighted span { color: #000 !important; } .content .highlighted.trait { background-color: #c7b6ff; } +.content .highlighted.traitalias { background-color: #c7b6ff; } .content .highlighted.mod, .content .highlighted.externcrate { background-color: #afc6e4; } .content .highlighted.enum { background-color: #b4d1b9; } @@ -128,6 +129,7 @@ pre { .content span.externcrate, .content span.mod, .content a.mod, .block a.current.mod { color: #4d76ae; } .content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; } +.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #6841f1; } .content span.fn, .content a.fn, .block a.current.fn, .content span.method, .content a.method, .block a.current.method, .content span.tymethod, .content a.tymethod, .block a.current.tymethod, From c20357a62aae335b045f61ba01b4a9a1776db992 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Feb 2019 01:02:23 +0100 Subject: [PATCH 0804/1064] Add trait aliases to js types --- src/librustdoc/html/static/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 877ac9a62bbec..3625848dd85c4 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -68,7 +68,8 @@ if (!DOMTokenList.prototype.remove) { "keyword", "existential", "attr", - "derive"]; + "derive", + "traitalias"]; var search_input = document.getElementsByClassName("search-input")[0]; @@ -1786,6 +1787,7 @@ if (!DOMTokenList.prototype.remove) { block("type", "Type Definitions"); block("foreigntype", "Foreign Types"); block("keyword", "Keywords"); + block("traitalias", "Trait Aliases"); } window.initSidebarItems = initSidebarItems; From eaf81c2e3ef174c0e257e010e8ee833772c9ec05 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Feb 2019 15:16:25 +0100 Subject: [PATCH 0805/1064] miri value visitor: use in macro --- src/librustc_mir/interpret/visitor.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index 930bcb44374aa..4ff5cde08d086 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -125,14 +125,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M> } macro_rules! make_value_visitor { - ($visitor_trait_name:ident, $($mutability:ident)*) => { + ($visitor_trait_name:ident, $($mutability:ident)?) => { // How to traverse a value and what to do when we are at the leaves. pub trait $visitor_trait_name<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Sized { type V: Value<'a, 'mir, 'tcx, M>; /// The visitor must have an `EvalContext` in it. - fn ecx(&$($mutability)* self) - -> &$($mutability)* EvalContext<'a, 'mir, 'tcx, M>; + fn ecx(&$($mutability)? self) + -> &$($mutability)? EvalContext<'a, 'mir, 'tcx, M>; // Recursive actions, ready to be overloaded. /// Visit the given value, dispatching as appropriate to more specialized visitors. From 4853ce660e38f6dd2e686e2c6292f6e004f51d91 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Feb 2019 15:27:59 +0100 Subject: [PATCH 0806/1064] it is okay not to use into_inner --- src/libcore/mem.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 930fe737a7264..3e081b4f0a46a 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1147,6 +1147,7 @@ impl MaybeUninit { /// Deprecated alternative to `into_initialized`. Will never get stabilized. /// Exists only to transition stdsimd to `into_initialized`. #[inline(always)] + #[allow(unused)] pub(crate) unsafe fn into_inner(self) -> T { self.into_initialized() } From 18089df7e8c5c3178049ce5ac3d0680d90aa97a4 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 Feb 2019 15:44:24 +0000 Subject: [PATCH 0807/1064] Fix ICE and invalid filenames in MIR printing code --- src/librustc_mir/util/pretty.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 1357f8fe79a0d..8177de50776d6 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -197,7 +197,7 @@ fn dump_path( .chars() .filter_map(|c| match c { ' ' => None, - ':' => Some('_'), + ':' | '<' | '>' => Some('_'), c => Some(c) })); s @@ -603,7 +603,8 @@ fn write_mir_sig( match (descr, src.promoted) { (_, Some(i)) => write!(w, "{:?} in ", i)?, (Some(Def::StructCtor(..)), _) => write!(w, "struct ")?, - (Some(Def::Const(_)), _) => write!(w, "const ")?, + (Some(Def::Const(_)), _) + | (Some(Def::AssociatedConst(_)), _) => write!(w, "const ")?, (Some(Def::Static(_, /*is_mutbl*/false)), _) => write!(w, "static ")?, (Some(Def::Static(_, /*is_mutbl*/true)), _) => write!(w, "static mut ")?, (_, _) if is_function => write!(w, "fn ")?, From b1d82ac6ed5f224914c7b89b780663bdfd46eb99 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Feb 2019 16:56:21 +0100 Subject: [PATCH 0808/1064] Remove spotlight for trait aliases and fix nits --- src/librustdoc/clean/mod.rs | 3 --- src/librustdoc/html/render.rs | 4 ++-- src/test/rustdoc/trait_alias.rs | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 64395da74211f..0e607490b643f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1899,13 +1899,11 @@ impl Clean for doctree::Trait { pub struct TraitAlias { pub generics: Generics, pub bounds: Vec, - pub is_spotlight: bool, } impl Clean for doctree::TraitAlias { fn clean(&self, cx: &DocContext) -> Item { let attrs = self.attrs.clean(cx); - let is_spotlight = attrs.has_doc_flag("spotlight"); Item { name: Some(self.name.clean(cx)), attrs, @@ -1917,7 +1915,6 @@ impl Clean for doctree::TraitAlias { inner: TraitAliasItem(TraitAlias { generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), - is_spotlight, }), } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9bcf574651539..1bd5e00ec9d8c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1925,7 +1925,7 @@ impl fmt::Display for AllTypes { print_entries(f, &self.derives, "Derive Macros", "derives")?; print_entries(f, &self.functions, "Functions", "functions")?; print_entries(f, &self.typedefs, "Typedefs", "typedefs")?; - print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-alias")?; + print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?; print_entries(f, &self.existentials, "Existentials", "existentials")?; print_entries(f, &self.statics, "Statics", "statics")?; print_entries(f, &self.constants, "Constants", "constants") @@ -4863,7 +4863,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) { ItemType::Existential => ("existentials", "Existentials"), ItemType::ProcAttribute => ("attributes", "Attribute Macros"), ItemType::ProcDerive => ("derives", "Derive Macros"), - ItemType::TraitAlias => ("trait-alias", "Trait aliases"), + ItemType::TraitAlias => ("trait-aliases", "Trait aliases"), } } diff --git a/src/test/rustdoc/trait_alias.rs b/src/test/rustdoc/trait_alias.rs index 2614eda6cca01..98b8d879ac078 100644 --- a/src/test/rustdoc/trait_alias.rs +++ b/src/test/rustdoc/trait_alias.rs @@ -8,7 +8,7 @@ use std::fmt::Debug; // @has foo/all.html '//a[@href="traitalias.Alias2.html"]' 'Alias2' // @has foo/all.html '//a[@href="traitalias.Foo.html"]' 'Foo' -// @has foo/index.html '//h2[@id="trait-alias"]' 'Trait aliases' +// @has foo/index.html '//h2[@id="trait-aliases"]' 'Trait aliases' // @has foo/index.html '//a[@class="traitalias"]' 'CopyAlias' // @has foo/index.html '//a[@class="traitalias"]' 'Alias2' // @has foo/index.html '//a[@class="traitalias"]' 'Foo' From d7afd3ebfb490c3c3905812a93cbc08b6d45d26b Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 Feb 2019 17:24:18 +0000 Subject: [PATCH 0809/1064] Add test for MIR printing changes --- src/test/mir-opt/unusual-item-types.rs | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/test/mir-opt/unusual-item-types.rs diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs new file mode 100644 index 0000000000000..fe85baa048e39 --- /dev/null +++ b/src/test/mir-opt/unusual-item-types.rs @@ -0,0 +1,66 @@ +// Test that we don't ICE when trying to dump MIR for unusual item types and +// that we don't create filenames containing `<` and `>` + +struct A; + +impl A { + const ASSOCIATED_CONSTANT: i32 = 2; +} + +enum E { + V = 5, +} + +fn main() { + let v = Vec::::new(); +} + +// END RUST SOURCE + +// START rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir +// bb0: { +// _0 = const 2i32; +// return; +// } +// bb1: { +// resume; +// } +// END rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir + +// START rustc.E-V-{{constant}}.mir_map.0.mir +// bb0: { +// _0 = const 5isize; +// return; +// } +// bb1: { +// resume; +// } +// END rustc.E-V-{{constant}}.mir_map.0.mir + +// START rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir +// bb0: { +// goto -> bb7; +// } +// bb1: { +// return; +// } +// bb2: { +// resume; +// } +// bb3: { +// goto -> bb1; +// } +// bb4: { +// goto -> bb2; +// } +// bb5: { +// drop(((*_1).0: alloc::raw_vec::RawVec)) -> bb4; +// } +// bb6: { +// drop(((*_1).0: alloc::raw_vec::RawVec)) -> [return: bb3, unwind: bb4]; +// } +// bb7: { +// _2 = &mut (*_1); +// _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5]; +// } +// END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir From 6156defd516aad7002fb88f3003cd549fca9f084 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 11 Feb 2019 01:58:47 +0900 Subject: [PATCH 0810/1064] librustc_mir: use ? in impl_snapshot_for! macro --- src/librustc_mir/interpret/snapshot.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index ee295116ba962..0168e1301fa7a 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -101,9 +101,8 @@ macro_rules! __impl_snapshot_field { // This assumes the type has two type parameters, first for the tag (set to `()`), // then for the id macro_rules! impl_snapshot_for { - // FIXME(mark-i-m): Some of these should be `?` rather than `*`. (enum $enum_name:ident { - $( $variant:ident $( ( $($field:ident $(-> $delegate:expr)*),* ) )* ),* $(,)* + $( $variant:ident $( ( $($field:ident $(-> $delegate:expr)?),* ) )? ),* $(,)? }) => { impl<'a, Ctx> self::Snapshot<'a, Ctx> for $enum_name @@ -115,18 +114,17 @@ macro_rules! impl_snapshot_for { fn snapshot(&self, __ctx: &'a Ctx) -> Self::Item { match *self { $( - $enum_name::$variant $( ( $(ref $field),* ) )* => + $enum_name::$variant $( ( $(ref $field),* ) )? => $enum_name::$variant $( - ( $( __impl_snapshot_field!($field, __ctx $(, $delegate)*) ),* ), - )* + ( $( __impl_snapshot_field!($field, __ctx $(, $delegate)?) ),* ), + )? )* } } } }; - // FIXME(mark-i-m): same here. - (struct $struct_name:ident { $($field:ident $(-> $delegate:expr)*),* $(,)* }) => { + (struct $struct_name:ident { $($field:ident $(-> $delegate:expr)?),* $(,)? }) => { impl<'a, Ctx> self::Snapshot<'a, Ctx> for $struct_name where Ctx: self::SnapshotContext<'a>, { @@ -139,7 +137,7 @@ macro_rules! impl_snapshot_for { } = *self; $struct_name { - $( $field: __impl_snapshot_field!($field, __ctx $(, $delegate)*) ),* + $( $field: __impl_snapshot_field!($field, __ctx $(, $delegate)?) ),* } } } From 998e58452238056adfdf9c12542dd777a8dd0bb0 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sun, 10 Feb 2019 18:36:00 +0100 Subject: [PATCH 0811/1064] bump cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 4e74e2fc09085..865cb70106a6b 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 4e74e2fc0908524d17735c768067117d3e84ee9c +Subproject commit 865cb70106a6b1171a500ff68f93ab52eea56e72 From 4833074a9a47c12bcfeee4435bf981981ede689c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Feb 2019 19:08:49 +0100 Subject: [PATCH 0812/1064] fix SGX build failures --- src/libstd/sys/sgx/ext/arch.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs index 3bd87b5d26574..97f7d9181a539 100644 --- a/src/libstd/sys/sgx/ext/arch.rs +++ b/src/libstd/sys/sgx/ext/arch.rs @@ -41,7 +41,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result, u32> ); match error { - 0 => Ok(out.into_inner()), + 0 => Ok(out.into_initialized()), err => Err(err), } } @@ -69,6 +69,6 @@ pub fn ereport( "{rdx}"(report.as_mut_ptr()) ); - report.into_inner() + report.into_initialized() } } From c3e182cf43aea2c010a1915eb37293a458df2228 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Fri, 8 Feb 2019 14:53:55 +0100 Subject: [PATCH 0813/1064] rustc: doc comments --- src/bootstrap/builder.rs | 10 +- src/bootstrap/cache.rs | 4 +- src/bootstrap/check.rs | 2 +- src/bootstrap/clean.rs | 2 +- src/bootstrap/compile.rs | 8 +- src/bootstrap/dist.rs | 2 +- src/bootstrap/doc.rs | 8 +- src/bootstrap/lib.rs | 18 +- src/bootstrap/test.rs | 16 +- src/bootstrap/tool.rs | 4 +- src/bootstrap/util.rs | 2 +- src/build_helper/lib.rs | 6 +- src/libcore/str/mod.rs | 4 +- src/libcore/str/pattern.rs | 4 +- src/libgraphviz/lib.rs | 4 +- src/libpanic_unwind/dummy.rs | 4 +- src/libpanic_unwind/dwarf/eh.rs | 2 +- src/libpanic_unwind/dwarf/mod.rs | 2 +- src/libpanic_unwind/emcc.rs | 6 +- src/libpanic_unwind/gcc.rs | 10 +- src/librustc/dep_graph/debug.rs | 2 +- src/librustc/dep_graph/dep_node.rs | 6 +- src/librustc/dep_graph/dep_tracking_map.rs | 2 +- src/librustc/dep_graph/graph.rs | 46 +-- src/librustc/hir/check_attr.rs | 10 +- src/librustc/hir/def.rs | 2 +- src/librustc/hir/def_id.rs | 2 +- src/librustc/hir/intravisit.rs | 16 +- src/librustc/hir/lowering.rs | 26 +- src/librustc/hir/map/blocks.rs | 6 +- src/librustc/hir/map/def_collector.rs | 2 +- src/librustc/hir/map/definitions.rs | 52 +-- src/librustc/hir/map/mod.rs | 24 +- src/librustc/hir/mod.rs | 331 +++++++++--------- src/librustc/hir/pat_util.rs | 10 +- src/librustc/infer/at.rs | 24 +- src/librustc/infer/canonical/canonicalizer.rs | 10 +- src/librustc/infer/canonical/mod.rs | 4 +- .../infer/canonical/query_response.rs | 6 +- src/librustc/infer/combine.rs | 10 +- src/librustc/infer/error_reporting/mod.rs | 4 +- .../nice_region_error/different_lifetimes.rs | 2 +- src/librustc/infer/fudge.rs | 4 +- src/librustc/infer/higher_ranked/mod.rs | 2 +- src/librustc/infer/lattice.rs | 4 +- .../infer/lexical_region_resolve/mod.rs | 10 +- src/librustc/infer/mod.rs | 38 +- src/librustc/infer/nll_relate/mod.rs | 16 +- src/librustc/infer/opaque_types/mod.rs | 23 +- src/librustc/infer/outlives/env.rs | 2 +- .../infer/outlives/free_region_map.rs | 2 +- src/librustc/infer/outlives/obligations.rs | 2 +- src/librustc/infer/outlives/verify.rs | 8 +- src/librustc/infer/region_constraints/mod.rs | 80 +++-- src/librustc/infer/type_variable.rs | 8 +- src/librustc/lint/context.rs | 10 +- src/librustc/lint/mod.rs | 18 +- src/librustc/middle/expr_use_visitor.rs | 6 +- src/librustc/middle/free_region.rs | 22 +- src/librustc/middle/liveness.rs | 56 +-- src/librustc/middle/mem_categorization.rs | 16 +- src/librustc/middle/region.rs | 46 +-- src/librustc/middle/resolve_lifetime.rs | 22 +- src/librustc/middle/stability.rs | 4 +- src/librustc/middle/weak_lang_items.rs | 2 +- src/librustc/mir/interpret/allocation.rs | 20 +- src/librustc/mir/interpret/error.rs | 4 +- src/librustc/mir/interpret/mod.rs | 14 +- src/librustc/mir/interpret/value.rs | 15 +- src/librustc/mir/mod.rs | 66 ++-- src/librustc/mir/mono.rs | 2 +- src/librustc/mir/tcx.rs | 2 +- src/librustc/session/config.rs | 10 +- src/librustc/session/mod.rs | 30 +- src/librustc/traits/auto_trait.rs | 2 +- src/librustc/traits/codegen/mod.rs | 4 +- src/librustc/traits/coherence.rs | 10 +- src/librustc/traits/error_reporting.rs | 4 +- src/librustc/traits/fulfill.rs | 6 +- src/librustc/traits/mod.rs | 73 ++-- src/librustc/traits/object_safety.rs | 40 ++- src/librustc/traits/project.rs | 23 +- src/librustc/traits/query/dropck_outlives.rs | 2 +- src/librustc/traits/query/normalize.rs | 2 +- .../traits/query/normalize_erasing_regions.rs | 2 +- src/librustc/traits/query/outlives_bounds.rs | 4 +- .../traits/query/type_op/normalize.rs | 2 +- src/librustc/traits/select.rs | 47 ++- src/librustc/traits/specialize/mod.rs | 8 +- .../traits/specialize/specialization_graph.rs | 4 +- src/librustc/ty/adjustment.rs | 22 +- src/librustc/ty/constness.rs | 2 +- src/librustc/ty/context.rs | 22 +- src/librustc/ty/fold.rs | 46 +-- .../ty/inhabitedness/def_id_forest.rs | 10 +- src/librustc/ty/instance.rs | 12 +- src/librustc/ty/item_path.rs | 12 +- src/librustc/ty/layout.rs | 6 +- src/librustc/ty/mod.rs | 130 +++---- src/librustc/ty/query/job.rs | 19 +- src/librustc/ty/query/mod.rs | 38 +- src/librustc/ty/query/on_disk_cache.rs | 10 +- src/librustc/ty/query/plumbing.rs | 36 +- src/librustc/ty/relate.rs | 2 +- src/librustc/ty/steal.rs | 6 +- src/librustc/ty/sty.rs | 94 ++--- src/librustc/ty/subst.rs | 24 +- src/librustc/ty/trait_def.rs | 6 +- src/librustc/ty/util.rs | 43 +-- src/librustc/ty/wf.rs | 4 +- src/librustc/util/common.rs | 8 +- src/librustc/util/nodemap.rs | 2 +- src/librustc/util/ppaux.rs | 31 +- src/librustc_apfloat/ieee.rs | 20 +- src/librustc_apfloat/lib.rs | 30 +- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- .../borrowck/gather_loans/lifetime.rs | 2 +- .../borrowck/gather_loans/mod.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 4 +- src/librustc_borrowck/borrowck/move_data.rs | 8 +- src/librustc_borrowck/dataflow.rs | 2 +- src/librustc_codegen_llvm/abi.rs | 4 +- src/librustc_codegen_llvm/back/archive.rs | 2 +- src/librustc_codegen_llvm/back/link.rs | 2 +- src/librustc_codegen_llvm/back/lto.rs | 2 +- src/librustc_codegen_llvm/back/wasm.rs | 2 +- src/librustc_codegen_llvm/base.rs | 10 +- src/librustc_codegen_llvm/callee.rs | 4 +- src/librustc_codegen_llvm/context.rs | 4 +- .../debuginfo/create_scope_map.rs | 2 +- src/librustc_codegen_llvm/debuginfo/doc.rs | 4 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 2 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 2 +- src/librustc_codegen_llvm/llvm/ffi.rs | 2 +- src/librustc_codegen_llvm/type_of.rs | 2 +- src/librustc_codegen_ssa/back/linker.rs | 4 +- src/librustc_codegen_ssa/back/write.rs | 4 +- src/librustc_codegen_ssa/base.rs | 16 +- src/librustc_codegen_ssa/lib.rs | 4 +- src/librustc_codegen_ssa/mir/block.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 2 +- src/librustc_codegen_ssa/mir/place.rs | 10 +- src/librustc_codegen_ssa/traits/declare.rs | 6 +- src/librustc_codegen_ssa/traits/type_.rs | 4 +- src/librustc_data_structures/base_n.rs | 2 +- src/librustc_data_structures/bit_set.rs | 40 +-- .../graph/implementation/mod.rs | 4 +- src/librustc_data_structures/graph/scc/mod.rs | 2 +- src/librustc_data_structures/indexed_vec.rs | 10 +- .../obligation_forest/graphviz.rs | 4 +- .../obligation_forest/mod.rs | 20 +- .../owning_ref/mod.rs | 14 +- src/librustc_data_structures/sip128.rs | 4 +- src/librustc_data_structures/svh.rs | 2 +- .../transitive_relation.rs | 14 +- src/librustc_data_structures/work_queue.rs | 6 +- src/librustc_driver/driver.rs | 6 +- src/librustc_driver/lib.rs | 8 +- src/librustc_driver/test.rs | 10 +- src/librustc_errors/diagnostic.rs | 2 +- src/librustc_errors/diagnostic_builder.rs | 4 +- src/librustc_errors/emitter.rs | 6 +- src/librustc_errors/lib.rs | 2 +- src/librustc_fs_util/lib.rs | 2 +- src/librustc_incremental/assert_dep_graph.rs | 2 +- .../persist/dirty_clean.rs | 23 +- .../persist/file_format.rs | 6 +- src/librustc_incremental/persist/fs.rs | 4 +- src/librustc_lint/builtin.rs | 29 +- src/librustc_lint/types.rs | 2 +- src/librustc_metadata/creader.rs | 2 +- src/librustc_metadata/cstore.rs | 6 +- src/librustc_metadata/decoder.rs | 2 +- src/librustc_metadata/dynamic_lib.rs | 2 +- src/librustc_metadata/index_builder.rs | 10 +- src/librustc_metadata/locator.rs | 4 +- src/librustc_mir/borrow_check/borrow_set.rs | 12 +- .../borrow_check/error_reporting.rs | 10 +- src/librustc_mir/borrow_check/mod.rs | 30 +- .../borrow_check/mutability_errors.rs | 2 +- .../borrow_check/nll/constraints/graph.rs | 4 +- .../borrow_check/nll/constraints/mod.rs | 4 +- .../borrow_check/nll/explain_borrow/mod.rs | 4 +- src/librustc_mir/borrow_check/nll/facts.rs | 2 +- .../borrow_check/nll/invalidation.rs | 12 +- .../borrow_check/nll/region_infer/dump_mir.rs | 2 +- .../nll/region_infer/error_reporting/mod.rs | 4 +- .../error_reporting/region_name.rs | 16 +- .../borrow_check/nll/region_infer/mod.rs | 30 +- .../borrow_check/nll/region_infer/values.rs | 14 +- .../nll/type_check/free_region_relations.rs | 12 +- .../nll/type_check/liveness/liveness_map.rs | 2 +- .../nll/type_check/liveness/mod.rs | 4 +- .../nll/type_check/liveness/trace.rs | 10 +- .../borrow_check/nll/type_check/mod.rs | 4 +- .../borrow_check/nll/type_check/relate_tys.rs | 2 +- .../borrow_check/nll/universal_regions.rs | 32 +- src/librustc_mir/borrow_check/path_utils.rs | 2 +- src/librustc_mir/borrow_check/place_ext.rs | 2 +- .../borrow_check/places_conflict.rs | 4 +- src/librustc_mir/build/matches/mod.rs | 10 +- src/librustc_mir/build/matches/test.rs | 2 +- src/librustc_mir/build/misc.rs | 2 +- src/librustc_mir/build/mod.rs | 50 +-- src/librustc_mir/build/scope.rs | 6 +- src/librustc_mir/const_eval.rs | 10 +- src/librustc_mir/dataflow/at_location.rs | 4 +- .../dataflow/drop_flag_effects.rs | 4 +- src/librustc_mir/dataflow/graphviz.rs | 4 +- src/librustc_mir/dataflow/impls/mod.rs | 7 - src/librustc_mir/dataflow/mod.rs | 26 +- .../dataflow/move_paths/abs_domain.rs | 10 +- src/librustc_mir/hair/cx/mod.rs | 14 +- src/librustc_mir/hair/mod.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 22 +- src/librustc_mir/hair/pattern/check_match.rs | 7 +- src/librustc_mir/hair/pattern/mod.rs | 24 +- src/librustc_mir/interpret/eval_context.rs | 10 +- src/librustc_mir/interpret/intrinsics.rs | 6 +- src/librustc_mir/interpret/machine.rs | 24 +- src/librustc_mir/interpret/memory.rs | 14 +- src/librustc_mir/interpret/operand.rs | 8 +- src/librustc_mir/interpret/place.rs | 18 +- src/librustc_mir/interpret/step.rs | 2 +- src/librustc_mir/interpret/traits.rs | 2 +- src/librustc_mir/interpret/validity.rs | 2 +- src/librustc_mir/interpret/visitor.rs | 22 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 2 +- src/librustc_mir/shim.rs | 4 +- src/librustc_mir/transform/check_unsafety.rs | 4 +- src/librustc_mir/transform/elaborate_drops.rs | 2 +- src/librustc_mir/transform/erase_regions.rs | 4 +- src/librustc_mir/transform/mod.rs | 2 +- src/librustc_mir/transform/promote_consts.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 6 +- .../transform/qualify_min_const_fn.rs | 2 +- .../transform/remove_noop_landing_pads.rs | 2 +- src/librustc_mir/util/alignment.rs | 2 +- src/librustc_mir/util/def_use.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 14 +- src/librustc_mir/util/liveness.rs | 29 +- src/librustc_passes/ast_validation.rs | 30 +- src/librustc_passes/rvalue_promotion.rs | 8 +- src/librustc_plugin/build.rs | 2 +- src/librustc_plugin/lib.rs | 2 +- src/librustc_plugin/registry.rs | 2 +- src/librustc_privacy/lib.rs | 8 +- src/librustc_resolve/build_reduced_graph.rs | 6 +- src/librustc_resolve/lib.rs | 96 ++--- src/librustc_resolve/macros.rs | 20 +- src/librustc_resolve/resolve_imports.rs | 8 +- src/librustc_save_analysis/dump_visitor.rs | 8 +- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_target/abi/call/mod.rs | 12 +- src/librustc_target/abi/mod.rs | 22 +- src/librustc_target/lib.rs | 2 +- src/librustc_target/spec/mod.rs | 10 +- src/librustc_traits/chalk_context/mod.rs | 12 +- src/librustc_traits/dropck_outlives.rs | 2 +- src/librustc_typeck/astconv.rs | 14 +- src/librustc_typeck/check/callee.rs | 6 +- src/librustc_typeck/check/cast.rs | 4 +- src/librustc_typeck/check/closure.rs | 4 +- src/librustc_typeck/check/coercion.rs | 22 +- src/librustc_typeck/check/compare_method.rs | 8 +- src/librustc_typeck/check/dropck.rs | 11 +- src/librustc_typeck/check/intrinsic.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 14 +- src/librustc_typeck/check/method/probe.rs | 6 +- src/librustc_typeck/check/method/suggest.rs | 4 +- src/librustc_typeck/check/mod.rs | 54 +-- src/librustc_typeck/check/op.rs | 8 +- src/librustc_typeck/check/regionck.rs | 36 +- src/librustc_typeck/check/wfcheck.rs | 6 +- src/librustc_typeck/check_unused.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/coherence/orphan.rs | 2 +- src/librustc_typeck/collect.rs | 24 +- .../constrained_type_params.rs | 8 +- src/librustc_typeck/impl_wf_check.rs | 6 +- src/librustc_typeck/lib.rs | 2 +- .../outlives/implicit_infer.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/cfg.rs | 4 +- src/librustdoc/clean/mod.rs | 10 +- src/librustdoc/clean/simplify.rs | 6 +- src/librustdoc/config.rs | 14 +- src/librustdoc/core.rs | 2 +- src/librustdoc/html/escape.rs | 4 +- src/librustdoc/html/format.rs | 6 +- src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/html/markdown.rs | 10 +- src/librustdoc/html/render.rs | 16 +- src/librustdoc/html/toc.rs | 2 +- src/librustdoc/markdown.rs | 2 +- .../passes/collect_intra_doc_links.rs | 4 +- src/librustdoc/passes/mod.rs | 2 +- src/librustdoc/visit_ast.rs | 2 +- src/libserialize/hex.rs | 2 +- src/libserialize/json.rs | 70 ++-- src/libserialize/serialize.rs | 2 +- src/libsyntax/ast.rs | 29 +- src/libsyntax/attr/builtin.rs | 6 +- src/libsyntax/attr/mod.rs | 6 +- src/libsyntax/config.rs | 8 +- src/libsyntax/diagnostics/metadata.rs | 4 +- src/libsyntax/ext/base.rs | 34 +- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 18 +- src/libsyntax/ext/tt/macro_rules.rs | 8 +- src/libsyntax/ext/tt/quoted.rs | 18 +- src/libsyntax/feature_gate.rs | 7 +- src/libsyntax/json.rs | 2 +- src/libsyntax/parse/lexer/comments.rs | 6 +- src/libsyntax/parse/lexer/mod.rs | 12 +- src/libsyntax/parse/mod.rs | 43 ++- src/libsyntax/parse/parser.rs | 319 +++++++++-------- src/libsyntax/parse/token.rs | 20 +- src/libsyntax/print/pp.rs | 4 +- src/libsyntax/ptr.rs | 2 +- src/libsyntax/source_map.rs | 18 +- src/libsyntax/tokenstream.rs | 5 +- src/libsyntax/util/lev_distance.rs | 4 +- src/libsyntax/util/parser.rs | 4 +- src/libsyntax/util/parser_testing.rs | 2 +- src/libsyntax/visit.rs | 6 +- src/libsyntax_ext/deriving/decodable.rs | 2 +- src/libsyntax_ext/deriving/encodable.rs | 4 +- src/libsyntax_ext/deriving/generic/mod.rs | 16 +- src/libsyntax_ext/format.rs | 6 +- src/libsyntax_ext/format_foreign.rs | 2 +- src/libsyntax_pos/analyze_source_file.rs | 4 +- src/libsyntax_pos/hygiene.rs | 4 +- src/libsyntax_pos/lib.rs | 42 +-- src/libsyntax_pos/symbol.rs | 12 +- src/libterm/lib.rs | 12 +- src/libterm/terminfo/mod.rs | 8 +- src/libterm/terminfo/parm.rs | 2 +- src/libterm/terminfo/parser/compiled.rs | 2 +- src/libterm/terminfo/searcher.rs | 2 +- src/libterm/win.rs | 5 +- 343 files changed, 2260 insertions(+), 2241 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index f512e1d7a0c62..78ba1d376be79 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -60,17 +60,17 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash { /// Run this rule for all hosts without cross compiling. const ONLY_HOSTS: bool = false; - /// Primary function to execute this rule. Can call `builder.ensure(...)` + /// Primary function to execute this rule. Can call `builder.ensure()` /// with other steps to run those. fn run(self, builder: &Builder) -> Self::Output; /// When bootstrap is passed a set of paths, this controls whether this rule /// will execute. However, it does not get called in a "default" context - /// when we are not passed any paths; in that case, make_run is called + /// when we are not passed any paths; in that case, `make_run` is called /// directly. fn should_run(run: ShouldRun) -> ShouldRun; - /// Build up a "root" rule, either as a default rule or from a path passed + /// Builds up a "root" rule, either as a default rule or from a path passed /// to us. /// /// When path is `None`, we are executing in a context where no paths were @@ -648,7 +648,7 @@ impl<'a> Builder<'a> { add_lib_path(vec![self.rustc_libdir(compiler)], cmd); } - /// Get a path to the compiler specified. + /// Gets a path to the compiler specified. pub fn rustc(&self, compiler: Compiler) -> PathBuf { if compiler.is_snapshot(self) { self.initial_rustc.clone() @@ -659,7 +659,7 @@ impl<'a> Builder<'a> { } } - /// Get the paths to all of the compiler's codegen backends. + /// Gets the paths to all of the compiler's codegen backends. fn codegen_backends(&self, compiler: Compiler) -> impl Iterator { fs::read_dir(self.sysroot_codegen_backends(compiler)) .into_iter() diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index ea8bc657a57aa..5f84816789a68 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -227,10 +227,10 @@ lazy_static! { pub static ref INTERNER: Interner = Interner::default(); } -/// This is essentially a HashMap which allows storing any type in its input and +/// This is essentially a `HashMap` which allows storing any type in its input and /// any type in its output. It is a write-once cache; values are never evicted, /// which means that references to the value can safely be returned from the -/// get() method. +/// `get()` method. #[derive(Debug)] pub struct Cache( RefCell String { let mut features = "panic-unwind".to_string(); @@ -521,7 +521,7 @@ impl Build { features } - /// Get the space-separated set of activated features for the compiler. + /// Gets the space-separated set of activated features for the compiler. fn rustc_features(&self) -> String { let mut features = String::new(); if self.config.jemalloc { @@ -609,7 +609,7 @@ impl Build { self.out.join(&*target).join("crate-docs") } - /// Returns true if no custom `llvm-config` is set for the specified target. + /// Returns `true` if no custom `llvm-config` is set for the specified target. /// /// If no custom `llvm-config` was specified then Rust's llvm will be used. fn is_rust_llvm(&self, target: Interned) -> bool { @@ -857,13 +857,13 @@ impl Build { .map(|p| &**p) } - /// Returns true if this is a no-std `target`, if defined + /// Returns `true` if this is a no-std `target`, if defined fn no_std(&self, target: Interned) -> Option { self.config.target_config.get(&target) .map(|t| t.no_std) } - /// Returns whether the target will be tested using the `remote-test-client` + /// Returns `true` if the target will be tested using the `remote-test-client` /// and `remote-test-server` binaries. fn remote_tested(&self, target: Interned) -> bool { self.qemu_rootfs(target).is_some() || target.contains("android") || @@ -1059,7 +1059,7 @@ impl Build { self.rust_info.version(self, channel::CFG_RELEASE_NUM) } - /// Return the full commit hash + /// Returns the full commit hash. fn rust_sha(&self) -> Option<&str> { self.rust_info.sha() } @@ -1079,7 +1079,7 @@ impl Build { panic!("failed to find version in {}'s Cargo.toml", package) } - /// Returns whether unstable features should be enabled for the compiler + /// Returns `true` if unstable features should be enabled for the compiler /// we're building. fn unstable_features(&self) -> bool { match &self.config.channel[..] { @@ -1327,7 +1327,7 @@ impl<'a> Compiler { self } - /// Returns whether this is a snapshot compiler for `build`'s configuration + /// Returns `true` if this is a snapshot compiler for `build`'s configuration pub fn is_snapshot(&self, build: &Build) -> bool { self.stage == 0 && self.host == build.build } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index bb00f6f625130..a882550f734f4 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -30,9 +30,9 @@ const ADB_TEST_DIR: &str = "/data/tmp/work"; /// The two modes of the test runner; tests or benchmarks. #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord)] pub enum TestKind { - /// Run `cargo test` + /// Run `cargo test`. Test, - /// Run `cargo bench` + /// Run `cargo bench`. Bench, } @@ -1288,7 +1288,7 @@ impl Step for DocTest { run.never() } - /// Run `rustdoc --test` for all documentation in `src/doc`. + /// Runs `rustdoc --test` for all documentation in `src/doc`. /// /// This will run all tests in our markdown documentation (e.g., the book) /// located in `src/doc`. The `rustdoc` that's run is the one that sits next to @@ -1408,7 +1408,7 @@ impl Step for ErrorIndex { }); } - /// Run the error index generator tool to execute the tests located in the error + /// Runs the error index generator tool to execute the tests located in the error /// index. /// /// The `error_index_generator` tool lives in `src/tools` and is used to @@ -1614,7 +1614,7 @@ impl Step for Crate { } } - /// Run all unit tests plus documentation tests for a given crate defined + /// Runs all unit tests plus documentation tests for a given crate defined /// by a `Cargo.toml` (single manifest) /// /// This is what runs tests for crates like the standard library, compiler, etc. @@ -1833,7 +1833,7 @@ fn envify(s: &str) -> String { /// the standard library and such to the emulator ahead of time. This step /// represents this and is a dependency of all test suites. /// -/// Most of the time this is a noop. For some steps such as shipping data to +/// Most of the time this is a no-op. For some steps such as shipping data to /// QEMU we have to build our own tools so we've got conditional dependencies /// on those programs as well. Note that the remote test client is built for /// the build target (us) and the server is built for the target. @@ -1904,7 +1904,7 @@ impl Step for Distcheck { run.builder.ensure(Distcheck); } - /// Run "distcheck", a 'make check' from a tarball + /// Runs "distcheck", a 'make check' from a tarball fn run(self, builder: &Builder) { builder.info("Distcheck"); let dir = builder.out.join("tmp").join("distcheck"); @@ -1965,7 +1965,7 @@ impl Step for Bootstrap { const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; - /// Test the build system itself + /// Tests the build system itself. fn run(self, builder: &Builder) { let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("test") diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index cd3afc59e560c..c09e9332895d8 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -40,7 +40,7 @@ impl Step for ToolBuild { run.never() } - /// Build a tool in `src/tools` + /// Builds a tool in `src/tools` /// /// This will build the specified tool with the specified `host` compiler in /// `stage` into the normal cargo output directory. @@ -621,7 +621,7 @@ tool_extended!((self, builder), ); impl<'a> Builder<'a> { - /// Get a `Command` which is ready to run `tool` in `stage` built for + /// Gets a `Command` which is ready to run `tool` in `stage` built for /// `host`. pub fn tool_cmd(&self, tool: Tool) -> Command { let mut cmd = Command::new(self.tool_exe(tool)); diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 37c6c040da8e8..29aa98971fb56 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -33,7 +33,7 @@ pub fn exe(name: &str, target: &str) -> String { } } -/// Returns whether the file name given looks like a dynamic library. +/// Returns `true` if the file name given looks like a dynamic library. pub fn is_dylib(name: &str) -> bool { name.ends_with(".dylib") || name.ends_with(".so") || name.ends_with(".dll") } diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 93aa91768121c..bd99dc118e66a 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -163,7 +163,7 @@ pub fn mtime(path: &Path) -> SystemTime { .unwrap_or(UNIX_EPOCH) } -/// Returns whether `dst` is up to date given that the file or files in `src` +/// Returns `true` if `dst` is up to date given that the file or files in `src` /// are used to generate it. /// /// Uses last-modified time checks to verify this. @@ -190,12 +190,12 @@ pub struct NativeLibBoilerplate { } impl NativeLibBoilerplate { - /// On OSX we don't want to ship the exact filename that compiler-rt builds. + /// On macOS we don't want to ship the exact filename that compiler-rt builds. /// This conflicts with the system and ours is likely a wildly different /// version, so they can't be substituted. /// /// As a result, we rename it here but we need to also use - /// `install_name_tool` on OSX to rename the commands listed inside of it to + /// `install_name_tool` on macOS to rename the commands listed inside of it to /// ensure it's linked against correctly. pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) { if env::var("TARGET").unwrap() != "x86_64-apple-darwin" { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index e9190cc3ddf1b..81c351be30502 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1,6 +1,6 @@ -//! String manipulation +//! String manipulation. //! -//! For more details, see std::str +//! For more details, see the `std::str` module. #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 55a7ba181e527..e5a75cdbbcce0 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -1,7 +1,7 @@ //! The string Pattern API. //! -//! For more details, see the traits `Pattern`, `Searcher`, -//! `ReverseSearcher` and `DoubleEndedSearcher`. +//! For more details, see the traits [`Pattern`], [`Searcher`], +//! [`ReverseSearcher`], and [`DoubleEndedSearcher`]. #![unstable(feature = "pattern", reason = "API not fully fleshed out and ready to be stabilized", diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 8ce0f755df035..a445e70ca995a 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -392,7 +392,7 @@ impl<'a> Id<'a> { /// digit (i.e., the regular expression `[a-zA-Z_][a-zA-Z_0-9]*`). /// /// (Note: this format is a strict subset of the `ID` format - /// defined by the DOT language. This function may change in the + /// defined by the DOT language. This function may change in the /// future to accept a broader subset, or the entirety, of DOT's /// `ID` format.) /// @@ -529,7 +529,7 @@ impl<'a> LabelText<'a> { } /// Decomposes content into string suitable for making EscStr that - /// yields same content as self. The result obeys the law + /// yields same content as self. The result obeys the law /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for /// all `lt: LabelText`. fn pre_escaped_content(self) -> Cow<'a, str> { diff --git a/src/libpanic_unwind/dummy.rs b/src/libpanic_unwind/dummy.rs index b052f76e2a3a8..3a00d6376658c 100644 --- a/src/libpanic_unwind/dummy.rs +++ b/src/libpanic_unwind/dummy.rs @@ -1,6 +1,6 @@ -//! Unwinding for wasm32 +//! Unwinding for *wasm32* target. //! -//! Right now we don't support this, so this is just stubs +//! Right now we don't support this, so this is just stubs. use alloc::boxed::Box; use core::any::Any; diff --git a/src/libpanic_unwind/dwarf/eh.rs b/src/libpanic_unwind/dwarf/eh.rs index ce7fab8584a28..ce24406b55642 100644 --- a/src/libpanic_unwind/dwarf/eh.rs +++ b/src/libpanic_unwind/dwarf/eh.rs @@ -6,7 +6,7 @@ //! http://www.airs.com/blog/archives/464 //! //! A reference implementation may be found in the GCC source tree -//! (/libgcc/unwind-c.c as of this writing) +//! (`/libgcc/unwind-c.c` as of this writing). #![allow(non_upper_case_globals)] #![allow(unused)] diff --git a/src/libpanic_unwind/dwarf/mod.rs b/src/libpanic_unwind/dwarf/mod.rs index eb5fb81f61b83..0360696426dc9 100644 --- a/src/libpanic_unwind/dwarf/mod.rs +++ b/src/libpanic_unwind/dwarf/mod.rs @@ -1,5 +1,5 @@ //! Utilities for parsing DWARF-encoded data streams. -//! See http://www.dwarfstd.org, +//! See , //! DWARF-4 standard, Section 7 - "Data Representation" // This module is used only by x86_64-pc-windows-gnu for now, but we diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 45c9244a46fcd..1f5ccfb0f1210 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -1,9 +1,9 @@ -//! Unwinding for emscripten +//! Unwinding for *emscripten* target. //! //! Whereas Rust's usual unwinding implementation for Unix platforms -//! calls into the libunwind APIs directly, on emscripten we instead +//! calls into the libunwind APIs directly, on Emscripten we instead //! call into the C++ unwinding APIs. This is just an expedience since -//! emscripten's runtime always implements those APIs and does not +//! Emscripten's runtime always implements those APIs and does not //! implement libunwind. #![allow(private_no_mangle_fns)] diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 065403aba1b98..607fe28e3f28d 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -1,4 +1,4 @@ -//! Implementation of panics backed by libgcc/libunwind (in some form) +//! Implementation of panics backed by libgcc/libunwind (in some form). //! //! For background on exception handling and stack unwinding please see //! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and @@ -23,14 +23,14 @@ //! //! In the search phase, the job of a personality routine is to examine //! exception object being thrown, and to decide whether it should be caught at -//! that stack frame. Once the handler frame has been identified, cleanup phase +//! that stack frame. Once the handler frame has been identified, cleanup phase //! begins. //! //! In the cleanup phase, the unwinder invokes each personality routine again. //! This time it decides which (if any) cleanup code needs to be run for -//! the current stack frame. If so, the control is transferred to a special +//! the current stack frame. If so, the control is transferred to a special //! branch in the function body, the "landing pad", which invokes destructors, -//! frees memory, etc. At the end of the landing pad, control is transferred +//! frees memory, etc. At the end of the landing pad, control is transferred //! back to the unwinder and unwinding resumes. //! //! Once stack has been unwound down to the handler frame level, unwinding stops @@ -39,7 +39,7 @@ //! ## `eh_personality` and `eh_unwind_resume` //! //! These language items are used by the compiler when generating unwind info. -//! The first one is the personality routine described above. The second one +//! The first one is the personality routine described above. The second one //! allows compilation target to customize the process of resuming unwind at the //! end of the landing pads. `eh_unwind_resume` is used only if //! `custom_unwind_resume` flag in the target options is set. diff --git a/src/librustc/dep_graph/debug.rs b/src/librustc/dep_graph/debug.rs index a9ad22c5e913e..f18ee3dced72d 100644 --- a/src/librustc/dep_graph/debug.rs +++ b/src/librustc/dep_graph/debug.rs @@ -22,7 +22,7 @@ impl DepNodeFilter { } } - /// True if all nodes always pass the filter. + /// Returns `true` if all nodes always pass the filter. pub fn accepts_all(&self) -> bool { self.text.is_empty() } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 58087b76266b5..796739c872174 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -302,7 +302,7 @@ macro_rules! define_dep_nodes { } } - /// Create a new, parameterless DepNode. This method will assert + /// Creates a new, parameterless DepNode. This method will assert /// that the DepNode corresponding to the given DepKind actually /// does not require any parameters. #[inline(always)] @@ -314,7 +314,7 @@ macro_rules! define_dep_nodes { } } - /// Extract the DefId corresponding to this DepNode. This will work + /// Extracts the DefId corresponding to this DepNode. This will work /// if two conditions are met: /// /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and @@ -798,7 +798,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for HirId { } /// A "work product" corresponds to a `.o` (or other) file that we -/// save in between runs. These ids do not have a DefId but rather +/// save in between runs. These IDs do not have a `DefId` but rather /// some independent path or string that persists between runs without /// the need to be mapped or unmapped. (This ensures we can serialize /// them even in the absence of a tcx.) diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs index a296a3379c2ac..94b832bea628e 100644 --- a/src/librustc/dep_graph/dep_tracking_map.rs +++ b/src/librustc/dep_graph/dep_tracking_map.rs @@ -43,7 +43,7 @@ impl MemoizationMap for RefCell> { /// /// Here, `[op]` represents whatever nodes `op` reads in the /// course of execution; `Map(key)` represents the node for this - /// map; and `CurrentTask` represents the current task when + /// map, and `CurrentTask` represents the current task when /// `memoize` is invoked. /// /// **Important:** when `op` is invoked, the current task will be diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index e8c1cd36064e1..59ec459de9641 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -61,13 +61,13 @@ struct DepGraphData { colors: DepNodeColorMap, - /// A set of loaded diagnostics which has been emitted. + /// A set of loaded diagnostics that have been emitted. emitted_diagnostics: Mutex>, /// Used to wait for diagnostics to be emitted. emitted_diagnostics_cond_var: Condvar, - /// When we load, there may be `.o` files, cached mir, or other such + /// When we load, there may be `.o` files, cached MIR, or other such /// things available to us. If we find that they are not dirty, we /// load the path to the file storing those work-products here into /// this map. We can later look for and extract that data. @@ -115,7 +115,7 @@ impl DepGraph { } } - /// True if we are actually building the full dep-graph. + /// Returns `true` if we are actually building the full dep-graph, and `false` otherwise. #[inline] pub fn is_fully_enabled(&self) -> bool { self.data.is_some() @@ -320,8 +320,8 @@ impl DepGraph { } } - /// Execute something within an "anonymous" task, that is, a task the - /// DepNode of which is determined by the list of inputs it read from. + /// Executes something within an "anonymous" task, that is, a task the + /// `DepNode` of which is determined by the list of inputs it read from. pub fn with_anon_task(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeIndex) where OP: FnOnce() -> R { @@ -356,8 +356,8 @@ impl DepGraph { } } - /// Execute something within an "eval-always" task which is a task - // that runs whenever anything changes. + /// Executes something within an "eval-always" task which is a task + /// that runs whenever anything changes. pub fn with_eval_always_task<'a, C, A, R>( &self, key: DepNode, @@ -438,7 +438,7 @@ impl DepGraph { self.data.as_ref().unwrap().previous.node_to_index(dep_node) } - /// Check whether a previous work product exists for `v` and, if + /// Checks whether a previous work product exists for `v` and, if /// so, return the path that leads to it. Used to skip doing work. pub fn previous_work_product(&self, v: &WorkProductId) -> Option { self.data @@ -589,7 +589,7 @@ impl DepGraph { } } - /// Try to mark a dep-node which existed in the previous compilation session as green + /// Try to mark a dep-node which existed in the previous compilation session as green. fn try_mark_previous_green<'tcx>( &self, tcx: TyCtxt<'_, 'tcx, 'tcx>, @@ -773,8 +773,8 @@ impl DepGraph { Some(dep_node_index) } - /// Atomically emits some loaded diagnotics assuming that this only gets called with - /// did_allocation set to true on one thread + /// Atomically emits some loaded diagnotics, assuming that this only gets called with + /// `did_allocation` set to `true` on a single thread. #[cold] #[inline(never)] fn emit_diagnostics<'tcx>( @@ -913,7 +913,7 @@ impl DepGraph { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct WorkProduct { pub cgu_name: String, - /// Saved files associated with this CGU + /// Saved files associated with this CGU. pub saved_files: Vec<(WorkProductFileKind, String)>, } @@ -937,17 +937,17 @@ pub(super) struct CurrentDepGraph { #[allow(dead_code)] forbidden_edge: Option, - // Anonymous DepNodes are nodes the ID of which we compute from the list of - // their edges. This has the beneficial side-effect that multiple anonymous - // nodes can be coalesced into one without changing the semantics of the - // dependency graph. However, the merging of nodes can lead to a subtle - // problem during red-green marking: The color of an anonymous node from - // the current session might "shadow" the color of the node with the same - // ID from the previous session. In order to side-step this problem, we make - // sure that anon-node IDs allocated in different sessions don't overlap. - // This is implemented by mixing a session-key into the ID fingerprint of - // each anon node. The session-key is just a random number generated when - // the DepGraph is created. + /// Anonymous `DepNode`s are nodes whose IDs we compute from the list of + /// their edges. This has the beneficial side-effect that multiple anonymous + /// nodes can be coalesced into one without changing the semantics of the + /// dependency graph. However, the merging of nodes can lead to a subtle + /// problem during red-green marking: The color of an anonymous node from + /// the current session might "shadow" the color of the node with the same + /// ID from the previous session. In order to side-step this problem, we make + /// sure that anonymous `NodeId`s allocated in different sessions don't overlap. + /// This is implemented by mixing a session-key into the ID fingerprint of + /// each anon node. The session-key is just a random number generated when + /// the `DepGraph` is created. anon_id_seed: Fingerprint, total_read_count: u64, diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index ba340ad251f2a..ddc1eebe645ae 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -91,7 +91,7 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { - /// Check any attribute. + /// Checks any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { if target == Target::Fn || target == Target::Const { self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.id)); @@ -115,7 +115,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { self.check_used(item, target); } - /// Check if an `#[inline]` is applied to a function or a closure. + /// Checks if an `#[inline]` is applied to a function or a closure. fn check_inline(&self, attr: &hir::Attribute, span: &Span, target: Target) { if target != Target::Fn && target != Target::Closure { struct_span_err!(self.tcx.sess, @@ -127,7 +127,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } } - /// Check if the `#[non_exhaustive]` attribute on an `item` is valid. + /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. fn check_non_exhaustive(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { match target { Target::Struct | Target::Enum => { /* Valid */ }, @@ -143,7 +143,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } } - /// Check if the `#[marker]` attribute on an `item` is valid. + /// Checks if the `#[marker]` attribute on an `item` is valid. fn check_marker(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { match target { Target::Trait => { /* Valid */ }, @@ -157,7 +157,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } } - /// Check if the `#[repr]` attributes on `item` are valid. + /// Checks if the `#[repr]` attributes on `item` are valid. fn check_repr(&self, item: &hir::Item, target: Target) { // Extract the names of all repr hints, e.g., [foo, bar, align] for: // ``` diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 15efa7650293c..b15bea017762e 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -182,7 +182,7 @@ impl ::std::ops::IndexMut for PerNS { } impl PerNS> { - /// Returns whether all the items in this collection are `None`. + /// Returns `true` if all the items in this collection are `None`. pub fn is_empty(&self) -> bool { self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none() } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index e06f09e21cbf3..ed1c15a73c260 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -229,7 +229,7 @@ impl fmt::Debug for DefId { } impl DefId { - /// Make a local `DefId` with the given index. + /// Makes a local `DefId` from the given `DefIndex`. #[inline] pub fn local(index: DefIndex) -> DefId { DefId { krate: LOCAL_CRATE, index: index } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 86c3fb9e4fcd7..9436c600c9fd3 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -4,7 +4,7 @@ //! `super::itemlikevisit::ItemLikeVisitor` trait.** //! //! If you have decided to use this visitor, here are some general -//! notes on how to do it: +//! notes on how to do so: //! //! Each overridden visit method has full control over what //! happens with its node, it can do its own traversal of the node's children, @@ -86,7 +86,7 @@ pub enum NestedVisitorMap<'this, 'tcx: 'this> { /// using this setting. OnlyBodies(&'this Map<'tcx>), - /// Visit all nested things, including item-likes. + /// Visits all nested things, including item-likes. /// /// **This is an unusual choice.** It is used when you want to /// process everything within their lexical context. Typically you @@ -96,7 +96,7 @@ pub enum NestedVisitorMap<'this, 'tcx: 'this> { impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { /// Returns the map to use for an "intra item-like" thing (if any). - /// e.g., function body. + /// E.g., function body. pub fn intra(self) -> Option<&'this Map<'tcx>> { match self { NestedVisitorMap::None => None, @@ -106,7 +106,7 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { } /// Returns the map to use for an "item-like" thing (if any). - /// e.g., item, impl-item. + /// E.g., item, impl-item. pub fn inter(self) -> Option<&'this Map<'tcx>> { match self { NestedVisitorMap::None => None, @@ -117,7 +117,7 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { } /// Each method of the Visitor trait is a hook to be potentially -/// overridden. Each method's default implementation recursively visits +/// overridden. Each method's default implementation recursively visits /// the substructure of the input via the corresponding `walk` method; /// e.g., the `visit_mod` method by default calls `intravisit::walk_mod`. /// @@ -129,7 +129,7 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { /// on `visit_nested_item` for details on how to visit nested items. /// /// If you want to ensure that your code handles every variant -/// explicitly, you need to override each method. (And you also need +/// explicitly, you need to override each method. (And you also need /// to monitor future changes to `Visitor` in case a new method with a /// new default implementation gets introduced.) pub trait Visitor<'v> : Sized { @@ -203,7 +203,7 @@ pub trait Visitor<'v> : Sized { } } - /// Visit the top-level item and (optionally) nested items / impl items. See + /// Visits the top-level item and (optionally) nested items / impl items. See /// `visit_nested_item` for details. fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) @@ -214,7 +214,7 @@ pub trait Visitor<'v> : Sized { } /// When invoking `visit_all_item_likes()`, you need to supply an - /// item-like visitor. This method converts a "intra-visit" + /// item-like visitor. This method converts a "intra-visit" /// visitor into an item-like visitor that walks the entire tree. /// If you use this, you probably don't want to process the /// contents of nested item-like things, since the outer loop will diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 3de41b1665d6d..8ce6d14012223 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3,24 +3,24 @@ //! Since the AST and HIR are fairly similar, this is mostly a simple procedure, //! much like a fold. Where lowering involves a bit more work things get more //! interesting and there are some invariants you should know about. These mostly -//! concern spans and ids. +//! concern spans and IDs. //! //! Spans are assigned to AST nodes during parsing and then are modified during //! expansion to indicate the origin of a node and the process it went through -//! being expanded. Ids are assigned to AST nodes just before lowering. +//! being expanded. IDs are assigned to AST nodes just before lowering. //! -//! For the simpler lowering steps, ids and spans should be preserved. Unlike +//! For the simpler lowering steps, IDs and spans should be preserved. Unlike //! expansion we do not preserve the process of lowering in the spans, so spans //! should not be modified here. When creating a new node (as opposed to -//! 'folding' an existing one), then you create a new id using `next_id()`. +//! 'folding' an existing one), then you create a new ID using `next_id()`. //! -//! You must ensure that ids are unique. That means that you should only use the -//! id from an AST node in a single HIR node (you can assume that AST node ids -//! are unique). Every new node must have a unique id. Avoid cloning HIR nodes. -//! If you do, you must then set the new node's id to a fresh one. +//! You must ensure that IDs are unique. That means that you should only use the +//! ID from an AST node in a single HIR node (you can assume that AST node IDs +//! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes. +//! If you do, you must then set the new node's ID to a fresh one. //! //! Spans are used for error messages and for tools to map semantics back to -//! source code. It is therefore not as important with spans as ids to be strict +//! source code. It is therefore not as important with spans as IDs to be strict //! about use (you can't break the compiler by screwing up a span). Obviously, a //! HIR node can only have a single span. But multiple nodes can have the same //! span and spans don't need to be kept in order, etc. Where code is preserved @@ -144,7 +144,7 @@ pub trait Resolver { is_value: bool, ) -> hir::Path; - /// Obtain the resolution for a node-id. + /// Obtain the resolution for a `NodeId`. fn get_resolution(&mut self, id: NodeId) -> Option; /// Obtain the possible resolutions for the given `use` statement. @@ -273,10 +273,10 @@ enum ParenthesizedGenericArgs { } /// What to do when we encounter an **anonymous** lifetime -/// reference. Anonymous lifetime references come in two flavors. You +/// reference. Anonymous lifetime references come in two flavors. You /// have implicit, or fully elided, references to lifetimes, like the /// one in `&T` or `Ref`, and you have `'_` lifetimes, like `&'_ T` -/// or `Ref<'_, T>`. These often behave the same, but not always: +/// or `Ref<'_, T>`. These often behave the same, but not always: /// /// - certain usages of implicit references are deprecated, like /// `Ref`, and we sometimes just give hard errors in those cases @@ -3287,7 +3287,7 @@ impl<'a> LoweringContext<'a> { /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated /// many times in the HIR tree; for each occurrence, we need to assign distinct - /// node-ids. (See e.g., #56128.) + /// `NodeId`s. (See, e.g., #56128.) fn renumber_segment_ids(&mut self, path: &P) -> P { debug!("renumber_segment_ids(path = {:?})", path); let mut path = path.clone(); diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index d5fb578d8d492..6919628c76755 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -1,9 +1,9 @@ //! This module provides a simplified abstraction for working with -//! code blocks identified by their integer node-id. In particular, +//! code blocks identified by their integer `NodeId`. In particular, //! it captures a common set of attributes that all "function-like -//! things" (represented by `FnLike` instances) share. For example, +//! things" (represented by `FnLike` instances) share. For example, //! all `FnLike` instances have a type signature (be it explicit or -//! inferred). And all `FnLike` instances have a body, i.e., the code +//! inferred). And all `FnLike` instances have a body, i.e., the code //! that is run when the function-like thing it represents is invoked. //! //! With the above abstraction in place, one can treat the program diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 02fb503e752b5..8fe10a85ef380 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -12,7 +12,7 @@ use syntax_pos::Span; use crate::hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE}; -/// Creates def ids for nodes in the AST. +/// Creates `DefId`s for nodes in the AST. pub struct DefCollector<'a> { definitions: &'a mut Definitions, parent_def: Option, diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 84e9cde6df160..f454d691d4188 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -1,5 +1,5 @@ -//! For each definition, we track the following data. A definition -//! here is defined somewhat circularly as "something with a def-id", +//! For each definition, we track the following data. A definition +//! here is defined somewhat circularly as "something with a `DefId`", //! but it generally corresponds to things like structs, enums, etc. //! There are also some rather random cases (like const initializer //! expressions) that are mostly just leftovers. @@ -163,10 +163,10 @@ pub struct Definitions { /// any) with a `DisambiguatedDefPathData`. #[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)] pub struct DefKey { - /// Parent path. + /// The parent path. pub parent: Option, - /// Identifier of this node. + /// The identifier of this node. pub disambiguated_data: DisambiguatedDefPathData, } @@ -207,12 +207,12 @@ impl DefKey { } } -/// Pair of `DefPathData` and an integer disambiguator. The integer is +/// A pair of `DefPathData` and an integer disambiguator. The integer is /// normally 0, but in the event that there are multiple defs with the /// same `parent` and `data`, we use this field to disambiguate /// between them. This introduces some artificial ordering dependency /// but means that if you have (e.g.) two impls for the same type in -/// the same module, they do get distinct def-ids. +/// the same module, they do get distinct `DefId`s. #[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)] pub struct DisambiguatedDefPathData { pub data: DefPathData, @@ -221,10 +221,10 @@ pub struct DisambiguatedDefPathData { #[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable)] pub struct DefPath { - /// the path leading from the crate root to the item + /// The path leading from the crate root to the item. pub data: Vec, - /// what krate root is this path relative to? + /// The crate root this path is relative to. pub krate: CrateNum, } @@ -260,9 +260,9 @@ impl DefPath { DefPath { data: data, krate: krate } } - /// Returns a string representation of the DefPath without + /// Returns a string representation of the `DefPath` without /// the crate-prefix. This method is useful if you don't have - /// a TyCtxt available. + /// a `TyCtxt` available. pub fn to_string_no_crate(&self) -> String { let mut s = String::with_capacity(self.data.len() * 16); @@ -277,7 +277,7 @@ impl DefPath { s } - /// Return filename friendly string of the DefPah with the + /// Returns a filename-friendly string for the `DefPath`, with the /// crate-prefix. pub fn to_string_friendly(&self, crate_imported_name: F) -> String where F: FnOnce(CrateNum) -> Symbol @@ -302,9 +302,9 @@ impl DefPath { s } - /// Return filename friendly string of the DefPah without + /// Returns a filename-friendly string of the `DefPath`, without /// the crate-prefix. This method is useful if you don't have - /// a TyCtxt available. + /// a `TyCtxt` available. pub fn to_filename_friendly_no_crate(&self) -> String { let mut s = String::with_capacity(self.data.len() * 16); @@ -394,18 +394,18 @@ impl Borrow for DefPathHash { } impl Definitions { - /// Create new empty definition map. + /// Creates new empty definition map. /// - /// The DefIndex returned from a new Definitions are as follows: - /// 1. At DefIndexAddressSpace::Low, + /// The `DefIndex` returned from a new `Definitions` are as follows: + /// 1. At `DefIndexAddressSpace::Low`, /// CRATE_ROOT has index 0:0, and then new indexes are allocated in /// ascending order. - /// 2. At DefIndexAddressSpace::High, - /// the first FIRST_FREE_HIGH_DEF_INDEX indexes are reserved for - /// internal use, then 1:FIRST_FREE_HIGH_DEF_INDEX are allocated in + /// 2. At `DefIndexAddressSpace::High`, + /// the first `FIRST_FREE_HIGH_DEF_INDEX` indexes are reserved for + /// internal use, then `1:FIRST_FREE_HIGH_DEF_INDEX` are allocated in /// ascending order. - /// - /// FIXME: there is probably a better place to put this comment. + // + // FIXME: there is probably a better place to put this comment. pub fn new() -> Self { Self::default() } @@ -414,7 +414,7 @@ impl Definitions { &self.table } - /// Get the number of definitions. + /// Gets the number of definitions. pub fn def_index_counts_lo_hi(&self) -> (usize, usize) { (self.table.index_to_key[DefIndexAddressSpace::Low.index()].len(), self.table.index_to_key[DefIndexAddressSpace::High.index()].len()) @@ -497,8 +497,8 @@ impl Definitions { self.node_to_hir_id[node_id] } - /// Retrieve the span of the given `DefId` if `DefId` is in the local crate, the span exists and - /// it's not DUMMY_SP + /// Retrieves the span of the given `DefId` if `DefId` is in the local crate, the span exists + /// and it's not `DUMMY_SP`. #[inline] pub fn opt_span(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { @@ -508,7 +508,7 @@ impl Definitions { } } - /// Add a definition with a parent definition. + /// Adds a root definition (no parent). pub fn create_root_def(&mut self, crate_name: &str, crate_disambiguator: CrateDisambiguator) @@ -606,7 +606,7 @@ impl Definitions { index } - /// Initialize the ast::NodeId to HirId mapping once it has been generated during + /// Initialize the `ast::NodeId` to `HirId` mapping once it has been generated during /// AST to HIR lowering. pub fn init_node_id_to_hir_id_mapping(&mut self, mapping: IndexVec) { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 955f834e40398..bf89eada4a57f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -36,7 +36,7 @@ mod hir_id_validator; pub const ITEM_LIKE_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::Low; pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High; -/// Represents an entry and its parent NodeId. +/// Represents an entry and its parent `NodeId`. #[derive(Copy, Clone, Debug)] pub struct Entry<'hir> { parent: NodeId, @@ -162,8 +162,7 @@ impl Forest { } } -/// Represents a mapping from Node IDs to AST elements and their parent -/// Node IDs +/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s. #[derive(Clone)] pub struct Map<'hir> { /// The backing storage for all the AST nodes. @@ -473,7 +472,7 @@ impl<'hir> Map<'hir> { self.local_def_id(self.body_owner(id)) } - /// Given a node id, returns the `BodyId` associated with it, + /// Given a `NodeId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. pub fn maybe_body_owned_by(&self, id: NodeId) -> Option { if let Some(entry) = self.find_entry(id) { @@ -558,7 +557,7 @@ impl<'hir> Map<'hir> { self.trait_auto_impl(trait_did).is_some() } - /// Get the attributes on the krate. This is preferable to + /// Gets the attributes on the crate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. pub fn krate_attrs(&self) -> &'hir [ast::Attribute] { @@ -653,8 +652,7 @@ impl<'hir> Map<'hir> { self.get_generics(id).map(|generics| generics.span).filter(|sp| *sp != DUMMY_SP) } - /// Retrieve the Node corresponding to `id`, returning None if - /// cannot be found. + /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. pub fn find(&self, id: NodeId) -> Option> { let result = self.find_entry(id).and_then(|entry| { if let Node::Crate = entry.node { @@ -683,8 +681,8 @@ impl<'hir> Map<'hir> { /// returns the enclosing item. Note that this might not be the actual parent /// node in the AST - some kinds of nodes are not in the map and these will /// never appear as the parent_node. So you can always walk the `parent_nodes` - /// from a node to the root of the ast (unless you get the same id back here - /// that can happen if the id is not in the map itself or is just weird). + /// from a node to the root of the ast (unless you get the same ID back here + /// that can happen if the ID is not in the map itself or is just weird). pub fn get_parent_node(&self, id: NodeId) -> NodeId { if self.dep_graph.is_fully_enabled() { let hir_id_owner = self.node_to_hir_id(id).owner; @@ -725,7 +723,7 @@ impl<'hir> Map<'hir> { /// If there is some error when walking the parents (e.g., a node does not /// have a parent in the map or a node can't be found), then we return the - /// last good node id we found. Note that reaching the crate root (`id == 0`), + /// last good `NodeId` we found. Note that reaching the crate root (`id == 0`), /// is not an error, since items in the crate module have the crate root as /// parent. fn walk_parent_nodes(&self, @@ -761,7 +759,7 @@ impl<'hir> Map<'hir> { } } - /// Retrieve the `NodeId` for `id`'s enclosing method, unless there's a + /// Retrieves the `NodeId` for `id`'s enclosing method, unless there's a /// `while` or `loop` before reaching it, as block tail returns are not /// available in them. /// @@ -809,7 +807,7 @@ impl<'hir> Map<'hir> { self.walk_parent_nodes(id, match_fn, match_non_returning_block).ok() } - /// Retrieve the `NodeId` for `id`'s parent item, or `id` itself if no + /// Retrieves the `NodeId` for `id`'s parent item, or `id` itself if no /// parent item is in this map. The "parent item" is the closest parent node /// in the HIR which is recorded by the map and is an item, either an item /// in a module, trait, or impl. @@ -1122,7 +1120,7 @@ pub struct NodesMatchingSuffix<'a, 'hir:'a> { } impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> { - /// Returns true only if some suffix of the module path for parent + /// Returns `true` only if some suffix of the module path for parent /// matches `self.in_which`. /// /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 3e7dd1432e1e3..d9759da9dfca8 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -62,14 +62,14 @@ pub mod map; pub mod pat_util; pub mod print; -/// A HirId uniquely identifies a node in the HIR of the current crate. It is -/// composed of the `owner`, which is the DefIndex of the directly enclosing -/// hir::Item, hir::TraitItem, or hir::ImplItem (i.e., the closest "item-like"), +/// Uniquely identifies a node in the HIR of the current crate. It is +/// composed of the `owner`, which is the `DefIndex` of the directly enclosing +/// `hir::Item`, `hir::TraitItem`, or `hir::ImplItem` (i.e., the closest "item-like"), /// and the `local_id` which is unique within the given owner. /// /// This two-level structure makes for more stable values: One can move an item /// around within the source code, or add or remove stuff before it, without -/// the local_id part of the HirId changing, which is a very useful property in +/// the `local_id` part of the `HirId` changing, which is a very useful property in /// incremental compilation where we have to persist things through changes to /// the code base. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -130,7 +130,7 @@ mod item_local_id_inner { pub use self::item_local_id_inner::ItemLocalId; -/// The `HirId` corresponding to CRATE_NODE_ID and CRATE_DEF_INDEX +/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_INDEX`. pub const CRATE_HIR_ID: HirId = HirId { owner: CRATE_DEF_INDEX, local_id: ItemLocalId::from_u32_const(0) @@ -149,8 +149,8 @@ pub struct Lifetime { pub hir_id: HirId, pub span: Span, - /// Either "'a", referring to a named lifetime definition, - /// or "" (aka keywords::Invalid), for elision placeholders. + /// Either "`'a`", referring to a named lifetime definition, + /// or "``" (i.e., `keywords::Invalid`), for elision placeholders. /// /// HIR lowering inserts these placeholders in type paths that /// refer to type definitions needing lifetime parameters, @@ -163,8 +163,9 @@ pub enum ParamName { /// Some user-given name like `T` or `'x`. Plain(Ident), - /// Synthetic name generated when user elided a lifetime in an impl header, - /// e.g., the lifetimes in cases like these: + /// Synthetic name generated when user elided a lifetime in an impl header. + /// + /// E.g., the lifetimes in cases like these: /// /// impl Foo for &u32 /// impl Foo<'_> for u32 @@ -180,7 +181,7 @@ pub enum ParamName { /// Indicates an illegal name was given and an error has been /// repored (so we should squelch other derived errors). Occurs - /// when e.g., `'_` is used in the wrong place. + /// when, e.g., `'_` is used in the wrong place. Error, } @@ -205,17 +206,17 @@ pub enum LifetimeName { /// User-given names or fresh (synthetic) names. Param(ParamName), - /// User typed nothing. e.g., the lifetime in `&u32`. + /// User wrote nothing (e.g., the lifetime in `&u32`). Implicit, /// Indicates an error during lowering (usually `'_` in wrong place) /// that was already reported. Error, - /// User typed `'_`. + /// User wrote specifies `'_`. Underscore, - /// User wrote `'static` + /// User wrote `'static`. Static, } @@ -280,7 +281,7 @@ impl Lifetime { } } -/// A "Path" is essentially Rust's notion of a name; for instance: +/// A `Path` is essentially Rust's notion of a name; for instance, /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. #[derive(Clone, RustcEncodable, RustcDecodable)] @@ -340,7 +341,7 @@ pub struct PathSegment { } impl PathSegment { - /// Convert an identifier to the corresponding segment. + /// Converts an identifier to the corresponding segment. pub fn from_ident(ident: Ident) -> PathSegment { PathSegment { ident, @@ -597,14 +598,14 @@ impl Generics { } } -/// Synthetic Type Parameters are converted to an other form during lowering, this allows -/// to track the original form they had. Useful for error messages. +/// Synthetic type parameters are converted to another form during lowering; this allows +/// us to track the original form they had, and is useful for error messages. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum SyntheticTyParamKind { ImplTrait } -/// A `where` clause in a definition +/// A where-clause in a definition. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereClause { pub id: NodeId, @@ -624,7 +625,7 @@ impl WhereClause { } } -/// A single predicate in a `where` clause +/// A single predicate in a where-clause. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum WherePredicate { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). @@ -645,19 +646,19 @@ impl WherePredicate { } } -/// A type bound, eg `for<'c> Foo: Send+Clone+'c` +/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereBoundPredicate { pub span: Span, - /// Any generics from a `for` binding + /// Any generics from a `for` binding. pub bound_generic_params: HirVec, - /// The type being bounded + /// The type being bounded. pub bounded_ty: P, - /// Trait and lifetime bounds (`Clone+Send+'static`) + /// Trait and lifetime bounds (e.g., `Clone + Send + 'static`). pub bounds: GenericBounds, } -/// A lifetime predicate, e.g., `'a: 'b+'c` +/// A lifetime predicate (e.g., `'a: 'b + 'c`). #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereRegionPredicate { pub span: Span, @@ -665,7 +666,7 @@ pub struct WhereRegionPredicate { pub bounds: GenericBounds, } -/// An equality predicate (unsupported), e.g., `T=int` +/// An equality predicate (e.g., `T = int`); currently unsupported. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereEqPredicate { pub id: NodeId, @@ -759,7 +760,7 @@ impl Crate { } } - /// A parallel version of visit_all_item_likes + /// A parallel version of `visit_all_item_likes`. pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V) where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send { @@ -800,14 +801,14 @@ pub struct MacroDef { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Block { - /// Statements in a block + /// Statements in a block. pub stmts: HirVec, /// An expression at the end of the block - /// without a semicolon, if any + /// without a semicolon, if any. pub expr: Option>, pub id: NodeId, pub hir_id: HirId, - /// Distinguishes between `unsafe { ... }` and `{ ... }` + /// Distinguishes between `unsafe { ... }` and `{ ... }`. pub rules: BlockCheckMode, pub span: Span, /// If true, then there may exist `break 'a` values that aim to @@ -874,18 +875,18 @@ impl Pat { } } -/// A single field in a struct pattern +/// A single field in a struct pattern. /// /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` /// are treated the same as` x: x, y: ref y, z: ref mut z`, -/// except is_shorthand is true +/// except `is_shorthand` is true. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct FieldPat { pub id: NodeId, pub hir_id: HirId, - /// The identifier for the field + /// The identifier for the field. pub ident: Ident, - /// The pattern the field is destructured to + /// The pattern the field is destructured to. pub pat: P, pub is_shorthand: bool, } @@ -922,41 +923,41 @@ pub enum RangeEnd { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum PatKind { - /// Represents a wildcard pattern (`_`) + /// Represents a wildcard pattern (i.e., `_`). Wild, /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`. /// The `NodeId` is the canonical ID for the variable being bound, - /// e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID, + /// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID), /// which is the pattern ID of the first `x`. Binding(BindingAnnotation, NodeId, HirId, Ident, Option>), - /// A struct or struct variant pattern, e.g., `Variant {x, y, ..}`. + /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// The `bool` is `true` in the presence of a `..`. Struct(QPath, HirVec>, bool), /// A tuple struct/variant pattern `Variant(x, y, .., z)`. /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// 0 <= position <= subpats.len() + /// `0 <= position <= subpats.len()` TupleStruct(QPath, HirVec>, Option), /// A path pattern for an unit struct/variant or a (maybe-associated) constant. Path(QPath), - /// A tuple pattern `(a, b)`. + /// A tuple pattern (e.g., `(a, b)`). /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// 0 <= position <= subpats.len() + /// `0 <= position <= subpats.len()` Tuple(HirVec>, Option), - /// A `box` pattern + /// A `box` pattern. Box(P), - /// A reference pattern, e.g., `&mut (a, b)` + /// A reference pattern (e.g., `&mut (a, b)`). Ref(P, Mutability), - /// A literal + /// A literal. Lit(P), - /// A range pattern, e.g., `1...2` or `1..2` + /// A range pattern (e.g., `1...2` or `1..2`). Range(P, P, RangeEnd), /// `[a, b, ..i, y, z]` is represented as: - /// `PatKind::Slice(box [a, b], Some(i), box [y, z])` + /// `PatKind::Slice(box [a, b], Some(i), box [y, z])`. Slice(HirVec>, Option>, HirVec>), } @@ -967,7 +968,7 @@ pub enum Mutability { } impl Mutability { - /// Return MutMutable only if both arguments are mutable. + /// Returns `MutMutable` only if both arguments are mutable. pub fn and(self, other: Self) -> Self { match self { MutMutable => other, @@ -978,41 +979,41 @@ impl Mutability { #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash)] pub enum BinOpKind { - /// The `+` operator (addition) + /// The `+` operator (addition). Add, - /// The `-` operator (subtraction) + /// The `-` operator (subtraction). Sub, - /// The `*` operator (multiplication) + /// The `*` operator (multiplication). Mul, - /// The `/` operator (division) + /// The `/` operator (division). Div, - /// The `%` operator (modulus) + /// The `%` operator (modulus). Rem, - /// The `&&` operator (logical and) + /// The `&&` operator (logical and). And, - /// The `||` operator (logical or) + /// The `||` operator (logical or). Or, - /// The `^` operator (bitwise xor) + /// The `^` operator (bitwise xor). BitXor, - /// The `&` operator (bitwise and) + /// The `&` operator (bitwise and). BitAnd, - /// The `|` operator (bitwise or) + /// The `|` operator (bitwise or). BitOr, - /// The `<<` operator (shift left) + /// The `<<` operator (shift left). Shl, - /// The `>>` operator (shift right) + /// The `>>` operator (shift right). Shr, - /// The `==` operator (equality) + /// The `==` operator (equality). Eq, - /// The `<` operator (less than) + /// The `<` operator (less than). Lt, - /// The `<=` operator (less than or equal to) + /// The `<=` operator (less than or equal to). Le, - /// The `!=` operator (not equal to) + /// The `!=` operator (not equal to). Ne, - /// The `>=` operator (greater than or equal to) + /// The `>=` operator (greater than or equal to). Ge, - /// The `>` operator (greater than) + /// The `>` operator (greater than). Gt, } @@ -1077,7 +1078,7 @@ impl BinOpKind { } } - /// Returns `true` if the binary operator takes its arguments by value + /// Returns `true` if the binary operator takes its arguments by value. pub fn is_by_value(self) -> bool { !self.is_comparison() } @@ -1112,11 +1113,11 @@ pub type BinOp = Spanned; #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash)] pub enum UnOp { - /// The `*` operator for dereferencing + /// The `*` operator (deferencing). UnDeref, - /// The `!` operator for logical inversion + /// The `!` operator (logical negation). UnNot, - /// The `-` operator for negation + /// The `-` operator (negation). UnNeg, } @@ -1129,7 +1130,7 @@ impl UnOp { } } - /// Returns `true` if the unary operator takes its argument by value + /// Returns `true` if the unary operator takes its argument by value. pub fn is_by_value(self) -> bool { match self { UnNeg | UnNot => true, @@ -1138,7 +1139,7 @@ impl UnOp { } } -/// A statement +/// A statement. #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct Stmt { pub id: NodeId, @@ -1156,15 +1157,15 @@ impl fmt::Debug for Stmt { #[derive(Clone, RustcEncodable, RustcDecodable)] pub enum StmtKind { - /// A local (let) binding: + /// A local (`let`) binding. Local(P), - /// An item binding: + /// An item binding. Item(P), - /// Expr without trailing semi-colon (must have unit type): + /// An expression without a trailing semi-colon (must have unit type). Expr(P), - /// Expr with trailing semi-colon (may have any type): + /// An expression with a trailing semi-colon (may have any type). Semi(P), } @@ -1179,12 +1180,12 @@ impl StmtKind { } } -/// Local represents a `let` statement, e.g., `let : = ;` +/// Represents a `let` statement (i.e., `let : = ;`). #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Local { pub pat: P, pub ty: Option>, - /// Initializer expression to set the value, if any + /// Initializer expression to set the value, if any. pub init: Option>, pub id: NodeId, pub hir_id: HirId, @@ -1193,7 +1194,7 @@ pub struct Local { pub source: LocalSource, } -/// represents one arm of a 'match' +/// Represents a single arm of a `match` expression. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Arm { pub attrs: HirVec, @@ -1419,16 +1420,16 @@ impl fmt::Debug for Expr { pub enum ExprKind { /// A `box x` expression. Box(P), - /// An array (`[a, b, c, d]`) + /// An array (e.g., `[a, b, c, d]`). Array(HirVec), - /// A function call + /// A function call. /// /// The first field resolves to the function itself (usually an `ExprKind::Path`), /// and the second field is the list of arguments. /// This also represents calling the constructor of /// tuple-like ADTs such as tuple structs and enum variants. Call(P, HirVec), - /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) + /// A method call (e.g., `x.foo::<'static, Bar, Baz>(a, b, c, d)`). /// /// The `PathSegment`/`Span` represent the method name and its generic arguments /// (within the angle brackets). @@ -1438,63 +1439,64 @@ pub enum ExprKind { /// Thus, `x.foo::(a, b, c, d)` is represented as /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. MethodCall(PathSegment, Span, HirVec), - /// A tuple (`(a, b, c ,d)`) + /// A tuple (e.g., `(a, b, c ,d)`). Tup(HirVec), - /// A binary operation (For example: `a + b`, `a * b`) + /// A binary operation (e.g., `a + b`, `a * b`). Binary(BinOp, P, P), - /// A unary operation (For example: `!x`, `*x`) + /// A unary operation (e.g., `!x`, `*x`). Unary(UnOp, P), - /// A literal (For example: `1`, `"foo"`) + /// A literal (e.g., `1`, `"foo"`). Lit(Lit), - /// A cast (`foo as f64`) + /// A cast (e.g., `foo as f64`). Cast(P, P), + /// A type reference (e.g., `Foo`). Type(P, P), - /// An `if` block, with an optional else block + /// An `if` block, with an optional else block. /// - /// `if expr { expr } else { expr }` + /// I.e., `if { } else { }`. If(P, P, Option>), /// A while loop, with an optional label /// - /// `'label: while expr { block }` + /// I.e., `'label: while expr { }`. While(P, P, Option

    = self.child.get(); - | ^^^^ - | - = help: use the `|| { ... }` closure form instead + | ^^^^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index 4c366a863637c..51bd116fbd61c 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -1,6 +1,6 @@ fn main() { let v = vec![0]; - const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item + const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 8783959f45f5f..0af777fdcf907 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -1,10 +1,8 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/type-dependent-def-issue-49241.rs:3:22 | -LL | const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item - | ^ - | - = help: use the `|| { ... }` closure form instead +LL | const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant + | ^ non-constant value error[E0080]: evaluation of constant value failed --> $DIR/type-dependent-def-issue-49241.rs:4:18 @@ -14,5 +12,5 @@ LL | let s: [u32; l] = v.into_iter().collect(); error: aborting due to 2 previous errors -Some errors occurred: E0080, E0434. +Some errors occurred: E0080, E0435. For more information about an error, try `rustc --explain E0080`. From 5681b91fa66213677390820f45339b81c2f4eead Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sat, 8 Dec 2018 12:45:13 +0100 Subject: [PATCH 0714/1064] unused_imports: make the lint machine-applicable --- src/librustc/lint/builtin.rs | 10 ++ src/librustc_resolve/check_unused.rs | 203 ++++++++++++++++++++++++--- 2 files changed, 191 insertions(+), 22 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 6ae7448645a20..a659f7e9b3440 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -467,6 +467,7 @@ pub enum BuiltinLintDiagnostics { MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), ElidedLifetimesInPaths(usize, Span, bool, Span, String), UnknownCrateTypes(Span, String, String), + UnusedImports(String, Vec<(Span, String)>), } impl BuiltinLintDiagnostics { @@ -548,6 +549,15 @@ impl BuiltinLintDiagnostics { BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => { db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect); } + BuiltinLintDiagnostics::UnusedImports(message, replaces) => { + if !replaces.is_empty() { + db.multipart_suggestion( + &message, + replaces, + Applicability::MachineApplicable, + ); + } + } } } } diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 639960827c996..3b6179f78558b 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -7,23 +7,52 @@ // // Unused trait imports can't be checked until the method resolution. We save // candidates here, and do the actual check in librustc_typeck/check_unused.rs. +// +// Checking for unused imports is split into three steps: +// +// - `UnusedImportCheckVisitor` walks the AST to find all the unused imports +// inside of `UseTree`s, recording their `NodeId`s and grouping them by +// the parent `use` item +// +// - `calc_unused_spans` then walks over all the `use` items marked in the +// previous step to collect the spans associated with the `NodeId`s and to +// calculate the spans that can be removed by rustfix; This is done in a +// separate step to be able to collapse the adjacent spans that rustfix +// will remove +// +// - `check_crate` finally emits the diagnostics based on the data generated +// in the last step use std::ops::{Deref, DerefMut}; use crate::Resolver; use crate::resolve_imports::ImportDirectiveSubclass; -use rustc::{lint, ty}; use rustc::util::nodemap::NodeMap; +use rustc::{lint, ty}; +use rustc_data_structures::fx::FxHashSet; use syntax::ast; use syntax::visit::{self, Visitor}; use syntax_pos::{Span, MultiSpan, DUMMY_SP}; +struct UnusedImport<'a> { + use_tree: &'a ast::UseTree, + use_tree_id: ast::NodeId, + item_span: Span, + unused: FxHashSet, +} + +impl<'a> UnusedImport<'a> { + fn add(&mut self, id: ast::NodeId) { + self.unused.insert(id); + } +} struct UnusedImportCheckVisitor<'a, 'b: 'a> { resolver: &'a mut Resolver<'b>, /// All the (so far) unused imports, grouped path list - unused_imports: NodeMap>, + unused_imports: NodeMap>, + base_use_tree: Option<&'a ast::UseTree>, base_id: ast::NodeId, item_span: Span, } @@ -46,7 +75,7 @@ impl<'a, 'b> DerefMut for UnusedImportCheckVisitor<'a, 'b> { impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { // We have information about whether `use` (import) directives are actually // used now. If an import is not used at all, we signal a lint error. - fn check_import(&mut self, item_id: ast::NodeId, id: ast::NodeId, span: Span) { + fn check_import(&mut self, id: ast::NodeId) { let mut used = false; self.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns))); if !used { @@ -54,16 +83,31 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { // Check later. return; } - self.unused_imports.entry(item_id).or_default().insert(id, span); + self.unused_import(self.base_id).add(id); } else { // This trait import is definitely used, in a way other than // method resolution. self.maybe_unused_trait_imports.remove(&id); - if let Some(i) = self.unused_imports.get_mut(&item_id) { - i.remove(&id); + if let Some(i) = self.unused_imports.get_mut(&self.base_id) { + i.unused.remove(&id); } } } + + fn unused_import(&mut self, id: ast::NodeId) -> &mut UnusedImport<'a> { + let use_tree_id = self.base_id; + let use_tree = self.base_use_tree.unwrap(); + let item_span = self.item_span; + + self.unused_imports + .entry(id) + .or_insert_with(|| UnusedImport { + use_tree, + use_tree_id, + item_span, + unused: FxHashSet::default(), + }) + } } impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> { @@ -88,31 +132,112 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> { // This allows the grouping of all the lints in the same item if !nested { self.base_id = id; + self.base_use_tree = Some(use_tree); } if let ast::UseTreeKind::Nested(ref items) = use_tree.kind { - // If it's the parent group, cover the entire use item - let span = if nested { - use_tree.span - } else { - self.item_span - }; - if items.is_empty() { - self.unused_imports - .entry(self.base_id) - .or_default() - .insert(id, span); + self.unused_import(self.base_id).add(id); } } else { - let base_id = self.base_id; - self.check_import(base_id, id, use_tree.span); + self.check_import(id); } visit::walk_use_tree(self, use_tree, id); } } +enum UnusedSpanResult { + Used, + FlatUnused(Span, Span), + NestedFullUnused(Vec, Span), + NestedPartialUnused(Vec, Vec), +} + +fn calc_unused_spans( + unused_import: &UnusedImport<'_>, + use_tree: &ast::UseTree, + use_tree_id: ast::NodeId, +) -> UnusedSpanResult { + // The full span is the whole item's span if this current tree is not nested inside another + // This tells rustfix to remove the whole item if all the imports are unused + let full_span = if unused_import.use_tree.span == use_tree.span { + unused_import.item_span + } else { + use_tree.span + }; + match use_tree.kind { + ast::UseTreeKind::Simple(..) | ast::UseTreeKind::Glob => { + if unused_import.unused.contains(&use_tree_id) { + UnusedSpanResult::FlatUnused(use_tree.span, full_span) + } else { + UnusedSpanResult::Used + } + } + ast::UseTreeKind::Nested(ref nested) => { + if nested.len() == 0 { + return UnusedSpanResult::FlatUnused(use_tree.span, full_span); + } + + let mut unused_spans = Vec::new(); + let mut to_remove = Vec::new(); + let mut all_nested_unused = true; + let mut previous_unused = false; + for (pos, (use_tree, use_tree_id)) in nested.iter().enumerate() { + let remove = match calc_unused_spans(unused_import, use_tree, *use_tree_id) { + UnusedSpanResult::Used => { + all_nested_unused = false; + None + } + UnusedSpanResult::FlatUnused(span, remove) => { + unused_spans.push(span); + Some(remove) + } + UnusedSpanResult::NestedFullUnused(mut spans, remove) => { + unused_spans.append(&mut spans); + Some(remove) + } + UnusedSpanResult::NestedPartialUnused(mut spans, mut to_remove_extra) => { + all_nested_unused = false; + unused_spans.append(&mut spans); + to_remove.append(&mut to_remove_extra); + None + } + }; + if let Some(remove) = remove { + let remove_span = if nested.len() == 1 { + remove + } else if pos == nested.len() - 1 || !all_nested_unused { + // Delete everything from the end of the last import, to delete the + // previous comma + nested[pos - 1].0.span.shrink_to_hi().to(use_tree.span) + } else { + // Delete everything until the next import, to delete the trailing commas + use_tree.span.to(nested[pos + 1].0.span.shrink_to_lo()) + }; + + // Try to collapse adjacent spans into a single one. This prevents all cases of + // overlapping removals, which are not supported by rustfix + if previous_unused && !to_remove.is_empty() { + let previous = to_remove.pop().unwrap(); + to_remove.push(previous.to(remove_span)); + } else { + to_remove.push(remove_span); + } + } + previous_unused = remove.is_some(); + } + if unused_spans.is_empty() { + UnusedSpanResult::Used + } else if all_nested_unused { + UnusedSpanResult::NestedFullUnused(unused_spans, full_span) + } else { + UnusedSpanResult::NestedPartialUnused(unused_spans, to_remove) + } + } + } +} + pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) { for directive in resolver.potentially_unused_imports.iter() { match directive.subclass { @@ -152,14 +277,33 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) { let mut visitor = UnusedImportCheckVisitor { resolver, unused_imports: Default::default(), + base_use_tree: None, base_id: ast::DUMMY_NODE_ID, item_span: DUMMY_SP, }; visit::walk_crate(&mut visitor, krate); - for (id, spans) in &visitor.unused_imports { + for unused in visitor.unused_imports.values() { + let mut fixes = Vec::new(); + let mut spans = match calc_unused_spans(unused, unused.use_tree, unused.use_tree_id) { + UnusedSpanResult::Used => continue, + UnusedSpanResult::FlatUnused(span, remove) => { + fixes.push((remove, String::new())); + vec![span] + } + UnusedSpanResult::NestedFullUnused(spans, remove) => { + fixes.push((remove, String::new())); + spans + } + UnusedSpanResult::NestedPartialUnused(spans, remove) => { + for fix in &remove { + fixes.push((*fix, String::new())); + } + spans + } + }; + let len = spans.len(); - let mut spans = spans.values().cloned().collect::>(); spans.sort(); let ms = MultiSpan::from_spans(spans.clone()); let mut span_snippets = spans.iter() @@ -177,6 +321,21 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) { } else { String::new() }); - visitor.session.buffer_lint(lint::builtin::UNUSED_IMPORTS, *id, ms, &msg); + + let fix_msg = if fixes.len() == 1 && fixes[0].0 == unused.item_span { + "remove the whole `use` item" + } else if spans.len() > 1 { + "remove the unused imports" + } else { + "remove the unused import" + }; + + visitor.session.buffer_lint_with_diagnostic( + lint::builtin::UNUSED_IMPORTS, + unused.use_tree_id, + ms, + &msg, + lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), + ); } } From 66c894e07f95a324a39bb4c281c8db4c8842689b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 7 Feb 2019 17:55:25 +0100 Subject: [PATCH 0715/1064] also fix bad use of shared ref in split_at_mut --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f95cd0dab43ab..6793b16481e01 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2516,7 +2516,7 @@ impl str { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { let len = self.len(); - let ptr = self.as_ptr() as *mut u8; + let ptr = self.as_mut_ptr(); unsafe { (from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), from_utf8_unchecked_mut(slice::from_raw_parts_mut( From 81613ad7cf9889a59d0a7233af9e462715945a72 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 7 Feb 2019 18:23:44 +0100 Subject: [PATCH 0716/1064] disable tests in Miri --- src/liballoc/tests/arc.rs | 2 ++ src/liballoc/tests/binary_heap.rs | 1 + src/liballoc/tests/btree/mod.rs | 2 ++ src/liballoc/tests/heap.rs | 2 ++ src/liballoc/tests/rc.rs | 2 ++ src/liballoc/tests/slice.rs | 2 ++ src/liballoc/tests/str.rs | 21 +++++++++++++++++++++ src/liballoc/tests/string.rs | 2 ++ src/liballoc/tests/vec.rs | 2 ++ src/liballoc/tests/vec_deque.rs | 7 +++++++ src/libcore/tests/cell.rs | 2 ++ src/libcore/tests/fmt/mod.rs | 2 ++ src/libcore/tests/hash/mod.rs | 2 ++ src/libcore/tests/iter.rs | 8 ++++++++ src/libcore/tests/num/mod.rs | 2 ++ src/libcore/tests/option.rs | 3 +++ src/libcore/tests/ptr.rs | 2 ++ src/libcore/tests/result.rs | 3 +++ src/libcore/tests/slice.rs | 12 ++++++++++++ src/libcore/tests/time.rs | 2 ++ 20 files changed, 81 insertions(+) diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index 2759b1b1cac27..7c5a8926126e3 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use std::any::Any; use std::sync::{Arc, Weak}; use std::cell::RefCell; diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 94ae43237d19c..c1a1c5d88781f 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,6 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] +#[cfg(not(miri))] fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/btree/mod.rs b/src/liballoc/tests/btree/mod.rs index 4c704d0f8c28f..653b3f5bcb49d 100644 --- a/src/liballoc/tests/btree/mod.rs +++ b/src/liballoc/tests/btree/mod.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + mod map; mod set; diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs index 24eea1d294965..809d2bc094aee 100644 --- a/src/liballoc/tests/heap.rs +++ b/src/liballoc/tests/heap.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use std::alloc::{Global, Alloc, Layout, System}; /// https://github.com/rust-lang/rust/issues/45955 diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index 18f82e8041008..1be01d1a7ce1a 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use std::any::Any; use std::rc::{Rc, Weak}; use std::cell::RefCell; diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 0300bd7f3f6d4..6d4a30fc36c7a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use std::cell::Cell; use std::cmp::Ordering::{Equal, Greater, Less}; use std::cmp::Ordering; diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 66a1b947a7d3a..b63945ffe972f 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -31,6 +31,7 @@ fn test_rfind() { } #[test] +#[cfg(not(miri))] fn test_collect() { let empty = ""; let s: String = empty.chars().collect(); @@ -118,6 +119,7 @@ fn test_concat_for_different_types() { #[test] fn test_concat_for_different_lengths() { let empty: &[&str] = &[]; + #[cfg(not(miri))] test_concat!("", empty); test_concat!("a", ["a"]); test_concat!("ab", ["a", "b"]); @@ -146,6 +148,7 @@ fn test_join_for_different_types() { #[test] fn test_join_for_different_lengths() { let empty: &[&str] = &[]; + #[cfg(not(miri))] test_join!("", empty, "-"); test_join!("a", ["a"], "-"); test_join!("a-b", ["a", "b"], "-"); @@ -159,6 +162,7 @@ fn test_join_for_different_lengths_with_long_separator() { assert_eq!("~~~~~".len(), 15); let empty: &[&str] = &[]; + #[cfg(not(miri))] test_join!("", empty, "~~~~~"); test_join!("a", ["a"], "~~~~~"); test_join!("a~~~~~b", ["a", "b"], "~~~~~"); @@ -166,6 +170,7 @@ fn test_join_for_different_lengths_with_long_separator() { } #[test] +#[cfg(not(miri))] fn test_unsafe_slice() { assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)}); assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)}); @@ -238,6 +243,7 @@ fn test_replacen() { #[test] fn test_replace() { let a = "a"; + #[cfg(not(miri))] assert_eq!("".replace(a, "b"), ""); assert_eq!("a".replace(a, "b"), "b"); assert_eq!("ab".replace(a, "b"), "bb"); @@ -297,6 +303,7 @@ fn test_replace_pattern() { // The current implementation of SliceIndex fails to handle methods // orthogonally from range types; therefore, it is worth testing // all of the indexing operations on each input. +#[cfg(not(miri))] mod slice_index { // Test a slicing operation **that should succeed,** // testing it on all of the indexing methods. @@ -679,6 +686,7 @@ fn test_str_slice_rangetoinclusive_ok() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; @@ -694,6 +702,7 @@ fn test_str_slicemut_rangetoinclusive_ok() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; @@ -883,6 +892,7 @@ fn test_as_bytes() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_as_bytes_fail() { // Don't double free. (I'm not sure if this exercises the // original problem code path anymore.) @@ -972,6 +982,7 @@ fn test_split_at_mut() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; s.split_at(1); @@ -1066,6 +1077,7 @@ fn test_rev_iterator() { } #[test] +#[cfg(not(miri))] fn test_chars_decoding() { let mut bytes = [0; 4]; for c in (0..0x110000).filter_map(::std::char::from_u32) { @@ -1077,6 +1089,7 @@ fn test_chars_decoding() { } #[test] +#[cfg(not(miri))] fn test_chars_rev_decoding() { let mut bytes = [0; 4]; for c in (0..0x110000).filter_map(::std::char::from_u32) { @@ -1306,6 +1319,7 @@ fn test_splitator() { } #[test] +#[cfg(not(miri))] fn test_str_default() { use std::default::Default; @@ -1365,6 +1379,7 @@ fn test_bool_from_str() { assert_eq!("not even a boolean".parse::().ok(), None); } +#[cfg(not(miri))] fn check_contains_all_substrings(s: &str) { assert!(s.contains("")); for i in 0..s.len() { @@ -1375,6 +1390,7 @@ fn check_contains_all_substrings(s: &str) { } #[test] +#[cfg(not(miri))] fn strslice_issue_16589() { assert!("bananas".contains("nana")); @@ -1384,6 +1400,7 @@ fn strslice_issue_16589() { } #[test] +#[cfg(not(miri))] fn strslice_issue_16878() { assert!(!"1234567ah012345678901ah".contains("hah")); assert!(!"00abc01234567890123456789abc".contains("bcabc")); @@ -1391,6 +1408,7 @@ fn strslice_issue_16878() { #[test] +#[cfg(not(miri))] fn test_strslice_contains() { let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'"; check_contains_all_substrings(x); @@ -1528,6 +1546,7 @@ fn trim_ws() { #[test] fn to_lowercase() { + #[cfg(not(miri))] assert_eq!("".to_lowercase(), ""); assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé "); @@ -1561,6 +1580,7 @@ fn to_lowercase() { #[test] fn to_uppercase() { + #[cfg(not(miri))] assert_eq!("".to_uppercase(), ""); assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ"); } @@ -1592,6 +1612,7 @@ fn test_cow_from() { } #[test] +#[cfg(not(miri))] fn test_repeat() { assert_eq!("".repeat(3), ""); assert_eq!("abc".repeat(0), ""); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 8a5bfca8b7db5..7a03848a776e6 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use std::borrow::Cow; use std::collections::CollectionAllocErr::*; use std::mem::size_of; diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 0fdcf34c783a8..b214051e4883f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use std::borrow::Cow; use std::mem::size_of; use std::{usize, isize}; diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index c9d16a06b4773..43b7351ef3299 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -107,6 +107,7 @@ fn test_index() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { @@ -905,20 +906,24 @@ fn test_append() { // normal append a.append(&mut b); assert_eq!(a.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + #[cfg(not(miri))] assert_eq!(b.iter().cloned().collect::>(), []); // append nothing to something a.append(&mut b); assert_eq!(a.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + #[cfg(not(miri))] assert_eq!(b.iter().cloned().collect::>(), []); // append something to nothing b.append(&mut a); assert_eq!(b.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + #[cfg(not(miri))] assert_eq!(a.iter().cloned().collect::>(), []); } #[test] +#[cfg(not(miri))] fn test_append_permutations() { fn construct_vec_deque( push_back: usize, @@ -1119,6 +1124,7 @@ fn test_reserve_exact_2() { } #[test] +#[cfg(not(miri))] fn test_try_reserve() { // These are the interesting cases: @@ -1220,6 +1226,7 @@ fn test_try_reserve() { } #[test] +#[cfg(not(miri))] fn test_try_reserve_exact() { // This is exactly the same as test_try_reserve with the method changed. diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index 56f295dff8e43..73bdaab5861e6 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use core::cell::*; use core::default::Default; use std::mem::drop; diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs index d86e21cf40b6e..b10b63fc484cb 100644 --- a/src/libcore/tests/fmt/mod.rs +++ b/src/libcore/tests/fmt/mod.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + mod builders; mod float; mod num; diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs index 135f4dfcac7d5..bf3039a7e51e8 100644 --- a/src/libcore/tests/hash/mod.rs +++ b/src/libcore/tests/hash/mod.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + mod sip; use std::hash::{Hash, Hasher}; diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 0fa99745d9065..9b4c78f8d3b02 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -190,6 +190,7 @@ fn test_iterator_step_by() { } #[test] +#[cfg(not(miri))] fn test_iterator_step_by_nth() { let mut it = (0..16).step_by(5); assert_eq!(it.nth(0), Some(0)); @@ -208,6 +209,7 @@ fn test_iterator_step_by_nth() { } #[test] +#[cfg(not(miri))] fn test_iterator_step_by_nth_overflow() { #[cfg(target_pointer_width = "8")] type Bigger = u16; @@ -253,12 +255,14 @@ fn test_iterator_step_by_nth_overflow() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_iterator_step_by_zero() { let mut it = (0..).step_by(0); it.next(); } #[test] +#[cfg(not(miri))] fn test_iterator_step_by_size_hint() { struct StubSizeHint(usize, Option); impl Iterator for StubSizeHint { @@ -1413,6 +1417,7 @@ fn test_rposition() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_rposition_panic() { let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), @@ -1652,6 +1657,7 @@ fn test_range_inclusive_nth() { } #[test] +#[cfg(not(miri))] fn test_range_step() { #![allow(deprecated)] @@ -1675,6 +1681,7 @@ fn test_range_step() { } #[test] +#[cfg(not(miri))] fn test_step_by_skip() { assert_eq!((0..640).step_by(128).skip(1).collect::>(), [128, 256, 384, 512]); assert_eq!((0..=50).step_by(10).nth(3), Some(30)); @@ -1682,6 +1689,7 @@ fn test_step_by_skip() { } #[test] +#[cfg(not(miri))] fn test_range_inclusive_step() { assert_eq!((0..=50).step_by(10).collect::>(), [0, 10, 20, 30, 40, 50]); assert_eq!((0..=5).step_by(1).collect::>(), [0, 1, 2, 3, 4, 5]); diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index a17c094679ea8..ab638e06cc10d 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use core::convert::{TryFrom, TryInto}; use core::cmp::PartialEq; use core::fmt::Debug; diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index b059b134868d9..1ba886ce037ee 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -69,6 +69,7 @@ fn test_option_dance() { } #[test] #[should_panic] +#[cfg(not(miri))] fn test_option_too_much_dance() { struct A; let mut y = Some(A); @@ -129,6 +130,7 @@ fn test_unwrap() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_unwrap_panic1() { let x: Option = None; x.unwrap(); @@ -136,6 +138,7 @@ fn test_unwrap_panic1() { #[test] #[should_panic] +#[cfg(not(miri))] fn test_unwrap_panic2() { let x: Option = None; x.unwrap(); diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 65c1a3e0254d2..5784559082266 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use core::ptr::*; use core::cell::RefCell; diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 1fab07526a07f..7bfd396f68d17 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -117,6 +117,7 @@ fn test_unwrap_or_else() { #[test] #[should_panic] +#[cfg(not(miri))] pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { if msg == "I got this." { @@ -138,6 +139,7 @@ pub fn test_expect_ok() { } #[test] #[should_panic(expected="Got expected error: \"All good\"")] +#[cfg(not(miri))] pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); @@ -151,6 +153,7 @@ pub fn test_expect_err_err() { } #[test] #[should_panic(expected="Got expected ok: \"All good\"")] +#[cfg(not(miri))] pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index e210e83122c47..04d646ea01d03 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -782,6 +782,7 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of range")] + #[cfg(not(miri))] fn assert_range_eq_can_fail_by_panic() { assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]); } @@ -791,6 +792,7 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] + #[cfg(not(miri))] fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]); } @@ -840,6 +842,7 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] + #[cfg(not(miri))] fn index_fail() { let v = $data; let v: &[_] = &v; @@ -848,6 +851,7 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] + #[cfg(not(miri))] fn index_mut_fail() { let mut v = $data; let v: &mut [_] = &mut v; @@ -1011,6 +1015,7 @@ fn test_rotate_right() { #[test] #[cfg(not(target_arch = "wasm32"))] +#[cfg(not(miri))] fn sort_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use core::slice::heapsort; @@ -1166,6 +1171,7 @@ pub mod memchr { } #[test] +#[cfg(not(miri))] fn test_align_to_simple() { let bytes = [1u8, 2, 3, 4, 5, 6, 7]; let (prefix, aligned, suffix) = unsafe { bytes.align_to::() }; @@ -1181,6 +1187,7 @@ fn test_align_to_simple() { } #[test] +#[cfg(not(miri))] fn test_align_to_zst() { let bytes = [1, 2, 3, 4, 5, 6, 7]; let (prefix, aligned, suffix) = unsafe { bytes.align_to::<()>() }; @@ -1189,6 +1196,7 @@ fn test_align_to_zst() { } #[test] +#[cfg(not(miri))] fn test_align_to_non_trivial() { #[repr(align(8))] struct U64(u64, u64); #[repr(align(8))] struct U64U64U32(u64, u64, u32); @@ -1200,6 +1208,7 @@ fn test_align_to_non_trivial() { } #[test] +#[cfg(not(miri))] fn test_align_to_empty_mid() { use core::mem; @@ -1297,6 +1306,7 @@ fn test_copy_within() { #[test] #[should_panic(expected = "src is out of bounds")] +#[cfg(not(miri))] fn test_copy_within_panics_src_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so 14 is out of bounds. @@ -1305,6 +1315,7 @@ fn test_copy_within_panics_src_too_long() { #[test] #[should_panic(expected = "dest is out of bounds")] +#[cfg(not(miri))] fn test_copy_within_panics_dest_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. @@ -1312,6 +1323,7 @@ fn test_copy_within_panics_dest_too_long() { } #[test] #[should_panic(expected = "src end is before src start")] +#[cfg(not(miri))] fn test_copy_within_panics_src_inverted() { let mut bytes = *b"Hello, World!"; // 2 is greater than 1, so this range is invalid. diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 6efd22572dc18..d39bd06930a36 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] + use core::time::Duration; #[test] From 05f0dee04a39912222f7237502e2230f0da1b551 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 7 Feb 2019 16:38:23 +0100 Subject: [PATCH 0717/1064] Improve the error messages for missing stability attributes This makes the capitalisation consistent and provides more context (especially for missing top-level attributes). --- src/librustc/middle/stability.rs | 25 +++++++++++-------- src/test/ui/missing/missing-stability.rs | 4 +-- src/test/ui/missing/missing-stability.stderr | 6 ++--- .../missing-stability-attr-at-top-level.rs | 4 +++ ...missing-stability-attr-at-top-level.stderr | 11 ++++++++ .../stability-attribute-issue-43027.rs | 2 +- .../stability-attribute-issue-43027.stderr | 4 +-- .../stability-attribute-sanity-3.rs | 2 +- .../stability-attribute-sanity-3.stderr | 4 +-- 9 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/stability-attribute/missing-stability-attr-at-top-level.rs create mode 100644 src/test/ui/stability-attribute/missing-stability-attr-at-top-level.stderr diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 34c77d08f5a7e..1f7345dde8e8e 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -322,14 +322,17 @@ struct MissingStabilityAnnotations<'a, 'tcx: 'a> { } impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> { - fn check_missing_stability(&self, id: NodeId, span: Span) { + fn check_missing_stability(&self, id: NodeId, span: Span, name: &str) { let hir_id = self.tcx.hir().node_to_hir_id(id); let stab = self.tcx.stability().local_stability(hir_id); let is_error = !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(id); if is_error { - self.tcx.sess.span_err(span, "This node does not have a stability attribute"); + self.tcx.sess.span_err( + span, + &format!("{} has missing stability attribute", name), + ); } } } @@ -347,42 +350,44 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // optional. They inherit stability from their parents when unannotated. hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {} - _ => self.check_missing_stability(i.id, i.span) + hir::ItemKind::Mod(..) => self.check_missing_stability(i.id, i.span, "module"), + + _ => self.check_missing_stability(i.id, i.span, "node") } intravisit::walk_item(self, i) } fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { - self.check_missing_stability(ti.id, ti.span); + self.check_missing_stability(ti.id, ti.span, "node"); intravisit::walk_trait_item(self, ti); } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { let impl_def_id = self.tcx.hir().local_def_id(self.tcx.hir().get_parent(ii.id)); if self.tcx.impl_trait_ref(impl_def_id).is_none() { - self.check_missing_stability(ii.id, ii.span); + self.check_missing_stability(ii.id, ii.span, "node"); } intravisit::walk_impl_item(self, ii); } fn visit_variant(&mut self, var: &'tcx Variant, g: &'tcx Generics, item_id: NodeId) { - self.check_missing_stability(var.node.data.id(), var.span); + self.check_missing_stability(var.node.data.id(), var.span, "variant"); intravisit::walk_variant(self, var, g, item_id); } fn visit_struct_field(&mut self, s: &'tcx StructField) { - self.check_missing_stability(s.id, s.span); + self.check_missing_stability(s.id, s.span, "field"); intravisit::walk_struct_field(self, s); } fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) { - self.check_missing_stability(i.id, i.span); + self.check_missing_stability(i.id, i.span, "node"); intravisit::walk_foreign_item(self, i); } fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) { - self.check_missing_stability(md.id, md.span); + self.check_missing_stability(md.id, md.span, "macro"); } } @@ -867,7 +872,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx, access_levels, }; - missing.check_missing_stability(ast::CRATE_NODE_ID, krate.span); + missing.check_missing_stability(ast::CRATE_NODE_ID, krate.span, "crate"); intravisit::walk_crate(&mut missing, krate); krate.visit_all_item_likes(&mut missing.as_deep_visitor()); } diff --git a/src/test/ui/missing/missing-stability.rs b/src/test/ui/missing/missing-stability.rs index 86841706325f7..c7d721e836d1f 100644 --- a/src/test/ui/missing/missing-stability.rs +++ b/src/test/ui/missing/missing-stability.rs @@ -6,7 +6,7 @@ #![stable(feature = "stable_test_feature", since = "1.0.0")] pub fn unmarked() { - //~^ ERROR This node does not have a stability attribute + //~^ ERROR node has missing stability attribute () } @@ -20,5 +20,5 @@ pub mod foo { pub mod bar { // #[stable] is not inherited pub fn unmarked() {} - //~^ ERROR This node does not have a stability attribute + //~^ ERROR node has missing stability attribute } diff --git a/src/test/ui/missing/missing-stability.stderr b/src/test/ui/missing/missing-stability.stderr index e55bd00e2c673..bced3efd83da3 100644 --- a/src/test/ui/missing/missing-stability.stderr +++ b/src/test/ui/missing/missing-stability.stderr @@ -1,13 +1,13 @@ -error: This node does not have a stability attribute +error: node has missing stability attribute --> $DIR/missing-stability.rs:8:1 | LL | / pub fn unmarked() { -LL | | //~^ ERROR This node does not have a stability attribute +LL | | //~^ ERROR node has missing stability attribute LL | | () LL | | } | |_^ -error: This node does not have a stability attribute +error: node has missing stability attribute --> $DIR/missing-stability.rs:22:5 | LL | pub fn unmarked() {} diff --git a/src/test/ui/stability-attribute/missing-stability-attr-at-top-level.rs b/src/test/ui/stability-attribute/missing-stability-attr-at-top-level.rs new file mode 100644 index 0000000000000..8f750ae62f5e4 --- /dev/null +++ b/src/test/ui/stability-attribute/missing-stability-attr-at-top-level.rs @@ -0,0 +1,4 @@ +#![feature(staged_api)] +//~^ ERROR crate has missing stability attribute + +fn main() {} diff --git a/src/test/ui/stability-attribute/missing-stability-attr-at-top-level.stderr b/src/test/ui/stability-attribute/missing-stability-attr-at-top-level.stderr new file mode 100644 index 0000000000000..f674797694557 --- /dev/null +++ b/src/test/ui/stability-attribute/missing-stability-attr-at-top-level.stderr @@ -0,0 +1,11 @@ +error: crate has missing stability attribute + --> $DIR/missing-stability-attr-at-top-level.rs:1:1 + | +LL | / #![feature(staged_api)] +LL | | //~^ ERROR crate has missing stability attribute +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + diff --git a/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs b/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs index 596a6eb6ed366..0b243bb52119b 100644 --- a/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs +++ b/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs @@ -2,7 +2,7 @@ #![stable(feature = "test", since = "0")] #[stable(feature = "test", since = "0")] -pub struct Reverse(pub T); //~ ERROR This node does not have a stability attribute +pub struct Reverse(pub T); //~ ERROR field has missing stability attribute fn main() { // Make sure the field is used to fill the stability cache diff --git a/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr b/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr index e123f42023324..7ffb4bb487a7b 100644 --- a/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr @@ -1,7 +1,7 @@ -error: This node does not have a stability attribute +error: field has missing stability attribute --> $DIR/stability-attribute-issue-43027.rs:5:23 | -LL | pub struct Reverse(pub T); //~ ERROR This node does not have a stability attribute +LL | pub struct Reverse(pub T); //~ ERROR field has missing stability attribute | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-3.rs b/src/test/ui/stability-attribute/stability-attribute-sanity-3.rs index 0c132e8857550..13ef3d3f53d2b 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity-3.rs +++ b/src/test/ui/stability-attribute/stability-attribute-sanity-3.rs @@ -5,7 +5,7 @@ #![stable(feature = "stable_test_feature", since = "1.0.0")] #[macro_export] -macro_rules! mac { //~ ERROR This node does not have a stability attribute +macro_rules! mac { //~ ERROR macro has missing stability attribute () => () } diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-3.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity-3.stderr index d42dcc0c778a7..1c759d49b9947 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity-3.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-sanity-3.stderr @@ -1,7 +1,7 @@ -error: This node does not have a stability attribute +error: macro has missing stability attribute --> $DIR/stability-attribute-sanity-3.rs:8:1 | -LL | / macro_rules! mac { //~ ERROR This node does not have a stability attribute +LL | / macro_rules! mac { //~ ERROR macro has missing stability attribute LL | | () => () LL | | } | |_^ From 17998961d4d08d08be3cee5e09ca62b75b832f1a Mon Sep 17 00:00:00 2001 From: Patrick McCarter Date: Thu, 7 Feb 2019 13:12:17 -0500 Subject: [PATCH 0718/1064] Refactor const saturating intrinsics emulation and add unstable feature attribute #58030 --- src/libcore/num/mod.rs | 2 + src/librustc_mir/interpret/intrinsics.rs | 64 ++++++++----------- .../run-pass/const-int-saturating-arith.rs | 2 + 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 104b124bad491..d4fade7613848 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -909,6 +909,7 @@ $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_saturating_int_methods")] #[inline] #[cfg(not(stage0))] pub const fn saturating_add(self, rhs: Self) -> Self { @@ -957,6 +958,7 @@ assert_eq!(", stringify!($SelfT), "::min_value().saturating_sub(100), ", stringi $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_saturating_int_methods")] #[inline] #[cfg(not(stage0))] pub const fn saturating_sub(self, rhs: Self) -> Self { diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 5ec18d133c665..e8dc22b8a596f 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -122,55 +122,41 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> self.binop_with_overflow(bin_op, lhs, rhs, dest)?; } } - "saturating_add" => { + "saturating_add" | "saturating_sub" => { let l = self.read_immediate(args[0])?; let r = self.read_immediate(args[1])?; - let (val, overflowed) = self.binary_op_imm(BinOp::Add, l, r)?; - if overflowed { - let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?; - let num_bits = l.layout.size.bits(); - let val = if l.layout.abi.is_signed() { - // For signed addition the saturated value depends on the - // sign of either term - if first_term & (1 << (num_bits-1)) == 0 { // signed term is positive - Scalar::from_uint((1u128 << (num_bits - 1)) - 1, - Size::from_bits(num_bits)) - } else { // signed term is negative - Scalar::from_uint(1u128 << (num_bits - 1), Size::from_bits(num_bits)) - } - } else { - Scalar::from_uint(u128::max_value() >> (128 - num_bits), - Size::from_bits(num_bits)) - }; - self.write_scalar(val, dest)?; + let is_add = intrinsic_name == "saturating_add"; + let (val, overflowed) = self.binary_op_imm(if is_add { + BinOp::Add } else { - self.write_scalar(val, dest)?; - } - } - "saturating_sub" => { - let l = self.read_immediate(args[0])?; - let r = self.read_immediate(args[1])?; - let (val, overflowed) = self.binary_op_imm(BinOp::Sub, l, r)?; - if overflowed { + BinOp::Sub + }, l, r)?; + let val = if overflowed { + // For signed ints the saturated value depends on the + // sign of the first term let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?; let num_bits = l.layout.size.bits(); - let val = if l.layout.abi.is_signed() { + if l.layout.abi.is_signed() { if first_term & (1 << (num_bits-1)) == 0 { // first term is positive - // so overflow is positive - Scalar::from_uint((1u128 << (num_bits - 1)) - 1, + Scalar::from_uint((1u128 << (num_bits - 1)) - 1, // max positive Size::from_bits(num_bits)) - } else { - // if first term negative, overflow must be negative + } else { // first term is negative + // max negative Scalar::from_uint(1u128 << (num_bits - 1), Size::from_bits(num_bits)) } - } else { - // unsigned underflow saturates to 0 - Scalar::from_uint(0u128, Size::from_bits(num_bits)) - }; - self.write_scalar(val, dest)?; + } else { // unsigned + if is_add { + // max unsigned + Scalar::from_uint(u128::max_value() >> (128 - num_bits), + Size::from_bits(num_bits)) + } else { // underflow to 0 + Scalar::from_uint(0u128, Size::from_bits(num_bits)) + } + } } else { - self.write_scalar(val, dest)?; - } + val + }; + self.write_scalar(val, dest)?; } "unchecked_shl" | "unchecked_shr" => { let l = self.read_immediate(args[0])?; diff --git a/src/test/run-pass/const-int-saturating-arith.rs b/src/test/run-pass/const-int-saturating-arith.rs index 92372e073cf2e..4f586a276f0d2 100644 --- a/src/test/run-pass/const-int-saturating-arith.rs +++ b/src/test/run-pass/const-int-saturating-arith.rs @@ -1,3 +1,5 @@ +#![feature(const_saturating_int_methods)] + const INT_U32_NO: u32 = (42 as u32).saturating_add(2); const INT_U32: u32 = u32::max_value().saturating_add(1); const INT_U128: u128 = u128::max_value().saturating_add(1); From 1b41c9a42e3d5231df8621ae4b900cddecc12a75 Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 14 Jan 2019 19:14:02 -0600 Subject: [PATCH 0719/1064] error on duplicate matcher bindings --- src/libsyntax/ext/tt/macro_rules.rs | 54 ++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index b3ecaeaedbb7a..61a5b2cb0d200 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -17,10 +17,10 @@ use crate::parse::token::Token::*; use crate::symbol::Symbol; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::{Span, DUMMY_SP, symbol::Ident}; use log::debug; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap}; use std::borrow::Cow; use std::collections::hash_map::Entry; @@ -246,8 +246,12 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt<'_>, // Holy self-referential! /// Converts a `macro_rules!` invocation into a syntax extension. -pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: Edition) - -> SyntaxExtension { +pub fn compile( + sess: &ParseSess, + features: &Features, + def: &ast::Item, + edition: Edition +) -> SyntaxExtension { let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs")); let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs")); @@ -355,7 +359,9 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: // don't abort iteration early, so that errors for multiple lhses can be reported for lhs in &lhses { - valid &= check_lhs_no_empty_seq(sess, &[lhs.clone()]) + valid &= check_lhs_no_empty_seq(sess, &[lhs.clone()]); + valid &= + check_lhs_duplicate_matcher_bindings(sess, &[lhs.clone()], &mut FxHashMap::default()); } let expander: Box<_> = Box::new(MacroRulesMacroExpander { @@ -456,6 +462,44 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { true } +/// Check that the LHS contains no duplicate matcher bindings. e.g. `$a:expr, $a:expr` would be +/// illegal, since it would be ambiguous which `$a` to use if we ever needed to. +fn check_lhs_duplicate_matcher_bindings( + sess: &ParseSess, + tts: &[quoted::TokenTree], + metavar_names: &mut FxHashMap +) -> bool { + use self::quoted::TokenTree; + for tt in tts { + match *tt { + TokenTree::MetaVarDecl(span, name, _kind) => { + if let Some(&prev_span) = metavar_names.get(&name) { + sess.span_diagnostic + .struct_span_err(span, "duplicate matcher binding") + .span_note(prev_span, "previous declaration was here") + .emit(); + return false; + } else { + metavar_names.insert(name, span); + } + } + TokenTree::Delimited(_, ref del) => { + if !check_lhs_duplicate_matcher_bindings(sess, &del.tts, metavar_names) { + return false; + } + }, + TokenTree::Sequence(_, ref seq) => { + if !check_lhs_duplicate_matcher_bindings(sess, &seq.tts, metavar_names) { + return false; + } + } + _ => {} + } + } + + true +} + fn check_rhs(sess: &ParseSess, rhs: "ed::TokenTree) -> bool { match *rhs { quoted::TokenTree::Delimited(..) => return true, From 1d94cc2a2249b65f62e78e4998761193c3bfed23 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 12:25:41 -0600 Subject: [PATCH 0720/1064] fix existing tests --- src/test/run-pass/macros/macro-follow.rs | 16 ++++++------ src/test/ui/macros/macro-follow.rs | 16 ++++++------ src/test/ui/macros/macro-follow.stderr | 32 ++++++++++++------------ 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/test/run-pass/macros/macro-follow.rs b/src/test/run-pass/macros/macro-follow.rs index f90afce90ee30..488339b025dce 100644 --- a/src/test/run-pass/macros/macro-follow.rs +++ b/src/test/run-pass/macros/macro-follow.rs @@ -73,7 +73,7 @@ macro_rules! follow_block { ($b:block $t:ty) => {}; ($b:block $s:stmt) => {}; ($b:block $p:path) => {}; - ($b:block $b:block) => {}; + ($b:block $c:block) => {}; ($b:block $i:ident) => {}; ($b:block $t:tt) => {}; ($b:block $i:item) => {}; @@ -99,9 +99,9 @@ macro_rules! follow_ident { ($i:ident $s:stmt) => {}; ($i:ident $p:path) => {}; ($i:ident $b:block) => {}; - ($i:ident $i:ident) => {}; + ($i:ident $j:ident) => {}; ($i:ident $t:tt) => {}; - ($i:ident $i:item) => {}; + ($i:ident $j:item) => {}; ($i:ident $m:meta) => {}; } // FOLLOW(tt) = any token @@ -120,12 +120,12 @@ macro_rules! follow_tt { ($t:tt ident) => {}; ($t:tt $p:pat) => {}; ($t:tt $e:expr) => {}; - ($t:tt $t:ty) => {}; + ($t:tt $v:ty) => {}; ($t:tt $s:stmt) => {}; ($t:tt $p:path) => {}; ($t:tt $b:block) => {}; ($t:tt $i:ident) => {}; - ($t:tt $t:tt) => {}; + ($t:tt $v:tt) => {}; ($t:tt $i:item) => {}; ($t:tt $m:meta) => {}; } @@ -149,9 +149,9 @@ macro_rules! follow_item { ($i:item $s:stmt) => {}; ($i:item $p:path) => {}; ($i:item $b:block) => {}; - ($i:item $i:ident) => {}; + ($i:item $j:ident) => {}; ($i:item $t:tt) => {}; - ($i:item $i:item) => {}; + ($i:item $j:item) => {}; ($i:item $m:meta) => {}; } // FOLLOW(meta) = any token @@ -177,7 +177,7 @@ macro_rules! follow_meta { ($m:meta $i:ident) => {}; ($m:meta $t:tt) => {}; ($m:meta $i:item) => {}; - ($m:meta $m:meta) => {}; + ($m:meta $n:meta) => {}; } fn main() {} diff --git a/src/test/ui/macros/macro-follow.rs b/src/test/ui/macros/macro-follow.rs index f4a1931da5aec..10b44e0017532 100644 --- a/src/test/ui/macros/macro-follow.rs +++ b/src/test/ui/macros/macro-follow.rs @@ -12,11 +12,11 @@ macro_rules! follow_pat { ($p:pat >) => {}; //~ERROR `$p:pat` is followed by `>` ($p:pat +) => {}; //~ERROR `$p:pat` is followed by `+` ($p:pat ident) => {}; //~ERROR `$p:pat` is followed by `ident` - ($p:pat $p:pat) => {}; //~ERROR `$p:pat` is followed by `$p:pat` + ($p:pat $q:pat) => {}; //~ERROR `$p:pat` is followed by `$q:pat` ($p:pat $e:expr) => {}; //~ERROR `$p:pat` is followed by `$e:expr` ($p:pat $t:ty) => {}; //~ERROR `$p:pat` is followed by `$t:ty` ($p:pat $s:stmt) => {}; //~ERROR `$p:pat` is followed by `$s:stmt` - ($p:pat $p:path) => {}; //~ERROR `$p:pat` is followed by `$p:path` + ($p:pat $q:path) => {}; //~ERROR `$p:pat` is followed by `$q:path` ($p:pat $b:block) => {}; //~ERROR `$p:pat` is followed by `$b:block` ($p:pat $i:ident) => {}; //~ERROR `$p:pat` is followed by `$i:ident` ($p:pat $t:tt) => {}; //~ERROR `$p:pat` is followed by `$t:tt` @@ -37,7 +37,7 @@ macro_rules! follow_expr { ($e:expr if) => {}; //~ERROR `$e:expr` is followed by `if` ($e:expr in) => {}; //~ERROR `$e:expr` is followed by `in` ($e:expr $p:pat) => {}; //~ERROR `$e:expr` is followed by `$p:pat` - ($e:expr $e:expr) => {}; //~ERROR `$e:expr` is followed by `$e:expr` + ($e:expr $f:expr) => {}; //~ERROR `$e:expr` is followed by `$f:expr` ($e:expr $t:ty) => {}; //~ERROR `$e:expr` is followed by `$t:ty` ($e:expr $s:stmt) => {}; //~ERROR `$e:expr` is followed by `$s:stmt` ($e:expr $p:path) => {}; //~ERROR `$e:expr` is followed by `$p:path` @@ -57,12 +57,12 @@ macro_rules! follow_ty { ($t:ty if) => {}; //~ERROR `$t:ty` is followed by `if` ($t:ty $p:pat) => {}; //~ERROR `$t:ty` is followed by `$p:pat` ($t:ty $e:expr) => {}; //~ERROR `$t:ty` is followed by `$e:expr` - ($t:ty $t:ty) => {}; //~ERROR `$t:ty` is followed by `$t:ty` + ($t:ty $r:ty) => {}; //~ERROR `$t:ty` is followed by `$r:ty` ($t:ty $s:stmt) => {}; //~ERROR `$t:ty` is followed by `$s:stmt` ($t:ty $p:path) => {}; //~ERROR `$t:ty` is followed by `$p:path` ($t:ty $b:block) => {}; // ok (RFC 1494) ($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident` - ($t:ty $t:tt) => {}; //~ERROR `$t:ty` is followed by `$t:tt` + ($t:ty $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r:tt` ($t:ty $i:item) => {}; //~ERROR `$t:ty` is followed by `$i:item` ($t:ty $m:meta) => {}; //~ERROR `$t:ty` is followed by `$m:meta` } @@ -82,7 +82,7 @@ macro_rules! follow_stmt { ($s:stmt $p:pat) => {}; //~ERROR `$s:stmt` is followed by `$p:pat` ($s:stmt $e:expr) => {}; //~ERROR `$s:stmt` is followed by `$e:expr` ($s:stmt $t:ty) => {}; //~ERROR `$s:stmt` is followed by `$t:ty` - ($s:stmt $s:stmt) => {}; //~ERROR `$s:stmt` is followed by `$s:stmt` + ($s:stmt $t:stmt) => {}; //~ERROR `$s:stmt` is followed by `$t:stmt` ($s:stmt $p:path) => {}; //~ERROR `$s:stmt` is followed by `$p:path` ($s:stmt $b:block) => {}; //~ERROR `$s:stmt` is followed by `$b:block` ($s:stmt $i:ident) => {}; //~ERROR `$s:stmt` is followed by `$i:ident` @@ -97,11 +97,11 @@ macro_rules! follow_path { ($p:path +) => {}; //~ERROR `$p:path` is followed by `+` ($p:path ident) => {}; //~ERROR `$p:path` is followed by `ident` ($p:path if) => {}; //~ERROR `$p:path` is followed by `if` - ($p:path $p:pat) => {}; //~ERROR `$p:path` is followed by `$p:pat` + ($p:path $q:pat) => {}; //~ERROR `$p:path` is followed by `$q:pat` ($p:path $e:expr) => {}; //~ERROR `$p:path` is followed by `$e:expr` ($p:path $t:ty) => {}; //~ERROR `$p:path` is followed by `$t:ty` ($p:path $s:stmt) => {}; //~ERROR `$p:path` is followed by `$s:stmt` - ($p:path $p:path) => {}; //~ERROR `$p:path` is followed by `$p:path` + ($p:path $q:path) => {}; //~ERROR `$p:path` is followed by `$q:path` ($p:path $b:block) => {}; // ok (RFC 1494) ($p:path $i:ident) => {}; //~ERROR `$p:path` is followed by `$i:ident` ($p:path $t:tt) => {}; //~ERROR `$p:path` is followed by `$t:tt` diff --git a/src/test/ui/macros/macro-follow.stderr b/src/test/ui/macros/macro-follow.stderr index 4aea5cc5de6bd..e3302eac4ac08 100644 --- a/src/test/ui/macros/macro-follow.stderr +++ b/src/test/ui/macros/macro-follow.stderr @@ -54,10 +54,10 @@ LL | ($p:pat ident) => {}; //~ERROR `$p:pat` is followed by `ident` | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` -error: `$p:pat` is followed by `$p:pat`, which is not allowed for `pat` fragments +error: `$p:pat` is followed by `$q:pat`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:15:13 | -LL | ($p:pat $p:pat) => {}; //~ERROR `$p:pat` is followed by `$p:pat` +LL | ($p:pat $q:pat) => {}; //~ERROR `$p:pat` is followed by `$q:pat` | ^^^^^^ not allowed after `pat` fragments | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` @@ -86,10 +86,10 @@ LL | ($p:pat $s:stmt) => {}; //~ERROR `$p:pat` is followed by `$s:stmt` | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` -error: `$p:pat` is followed by `$p:path`, which is not allowed for `pat` fragments +error: `$p:pat` is followed by `$q:path`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:19:13 | -LL | ($p:pat $p:path) => {}; //~ERROR `$p:pat` is followed by `$p:path` +LL | ($p:pat $q:path) => {}; //~ERROR `$p:pat` is followed by `$q:path` | ^^^^^^^ not allowed after `pat` fragments | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` @@ -230,10 +230,10 @@ LL | ($e:expr $p:pat) => {}; //~ERROR `$e:expr` is followed by `$p:pat` | = note: allowed there are: `=>`, `,` or `;` -error: `$e:expr` is followed by `$e:expr`, which is not allowed for `expr` fragments +error: `$e:expr` is followed by `$f:expr`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:40:14 | -LL | ($e:expr $e:expr) => {}; //~ERROR `$e:expr` is followed by `$e:expr` +LL | ($e:expr $f:expr) => {}; //~ERROR `$e:expr` is followed by `$f:expr` | ^^^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` @@ -350,10 +350,10 @@ LL | ($t:ty $e:expr) => {}; //~ERROR `$t:ty` is followed by `$e:expr` | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` -error: `$t:ty` is followed by `$t:ty`, which is not allowed for `ty` fragments +error: `$t:ty` is followed by `$r:ty`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:60:12 | -LL | ($t:ty $t:ty) => {}; //~ERROR `$t:ty` is followed by `$t:ty` +LL | ($t:ty $r:ty) => {}; //~ERROR `$t:ty` is followed by `$r:ty` | ^^^^^ not allowed after `ty` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` @@ -382,10 +382,10 @@ LL | ($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident` | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` -error: `$t:ty` is followed by `$t:tt`, which is not allowed for `ty` fragments +error: `$t:ty` is followed by `$r:tt`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:65:12 | -LL | ($t:ty $t:tt) => {}; //~ERROR `$t:ty` is followed by `$t:tt` +LL | ($t:ty $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r:tt` | ^^^^^ not allowed after `ty` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` @@ -518,10 +518,10 @@ LL | ($s:stmt $t:ty) => {}; //~ERROR `$s:stmt` is followed by `$t:ty` | = note: allowed there are: `=>`, `,` or `;` -error: `$s:stmt` is followed by `$s:stmt`, which is not allowed for `stmt` fragments +error: `$s:stmt` is followed by `$t:stmt`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:85:14 | -LL | ($s:stmt $s:stmt) => {}; //~ERROR `$s:stmt` is followed by `$s:stmt` +LL | ($s:stmt $t:stmt) => {}; //~ERROR `$s:stmt` is followed by `$t:stmt` | ^^^^^^^ not allowed after `stmt` fragments | = note: allowed there are: `=>`, `,` or `;` @@ -606,10 +606,10 @@ LL | ($p:path if) => {}; //~ERROR `$p:path` is followed by `if` | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` -error: `$p:path` is followed by `$p:pat`, which is not allowed for `path` fragments +error: `$p:path` is followed by `$q:pat`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:100:14 | -LL | ($p:path $p:pat) => {}; //~ERROR `$p:path` is followed by `$p:pat` +LL | ($p:path $q:pat) => {}; //~ERROR `$p:path` is followed by `$q:pat` | ^^^^^^ not allowed after `path` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` @@ -638,10 +638,10 @@ LL | ($p:path $s:stmt) => {}; //~ERROR `$p:path` is followed by `$s:stmt` | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` -error: `$p:path` is followed by `$p:path`, which is not allowed for `path` fragments +error: `$p:path` is followed by `$q:path`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:104:14 | -LL | ($p:path $p:path) => {}; //~ERROR `$p:path` is followed by `$p:path` +LL | ($p:path $q:path) => {}; //~ERROR `$p:path` is followed by `$q:path` | ^^^^^^^ not allowed after `path` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` From 3e790a7c304b3bcb182c4fcb745ea288d3dc56f2 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Jan 2019 16:55:23 -0600 Subject: [PATCH 0721/1064] add a test --- .../macros/macro-multiple-matcher-bindings.rs | 19 +++++++ .../macro-multiple-matcher-bindings.stderr | 50 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/test/ui/macros/macro-multiple-matcher-bindings.rs create mode 100644 src/test/ui/macros/macro-multiple-matcher-bindings.stderr diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.rs b/src/test/ui/macros/macro-multiple-matcher-bindings.rs new file mode 100644 index 0000000000000..ea57d66b565d9 --- /dev/null +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.rs @@ -0,0 +1,19 @@ +// Test that duplicate matcher binding names are caught at declaration time, rather than at macro +// invocation time. + +macro_rules! foo1 { + ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding + ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding +} + +macro_rules! foo2 { + ($a:ident) => {}; // OK + ($a:path) => {}; // OK +} + +macro_rules! foo3 { + ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding + ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding +} + +fn main() {} diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr new file mode 100644 index 0000000000000..3e3e10245870f --- /dev/null +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr @@ -0,0 +1,50 @@ +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:5:16 + | +LL | ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:5:6 + | +LL | ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^^ + +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:6:16 + | +LL | ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:6:6 + | +LL | ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^^ + +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:15:18 + | +LL | ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:15:6 + | +LL | ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^^ + +error: duplicate matcher binding + --> $DIR/macro-multiple-matcher-bindings.rs:16:25 + | +LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^ + | +note: previous declaration was here + --> $DIR/macro-multiple-matcher-bindings.rs:16:8 + | +LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding + | ^^^^^^^^ + +error: aborting due to 4 previous errors + From 802b256283fe7dd0f0e72499ba77d18f2838e817 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 17 Jan 2019 21:19:56 -0600 Subject: [PATCH 0722/1064] Make it an incompatibility lint for now --- src/librustc/lint/builtin.rs | 6 ++ src/librustc/lint/mod.rs | 3 +- src/librustc_lint/lib.rs | 5 ++ src/libsyntax/early_buffered_lints.rs | 2 + src/libsyntax/ext/tt/macro_rules.rs | 31 +++++--- .../macros/macro-multiple-matcher-bindings.rs | 10 +-- .../macro-multiple-matcher-bindings.stderr | 71 ++++++++----------- 7 files changed, 72 insertions(+), 56 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 6ae7448645a20..3ff76e98d7b89 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -352,6 +352,12 @@ declare_lint! { "outlives requirements can be inferred" } +declare_lint! { + pub DUPLICATE_MATCHER_BINDING_NAME, + Warn, + "duplicate macro matcher binding name" +} + /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. pub mod parser { declare_lint! { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 4e6bf753b01aa..8952ae98e597e 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -27,7 +27,7 @@ use crate::errors::{DiagnosticBuilder, DiagnosticId}; use crate::hir::def_id::{CrateNum, LOCAL_CRATE}; use crate::hir::intravisit; use crate::hir; -use crate::lint::builtin::BuiltinLintDiagnostics; +use crate::lint::builtin::{BuiltinLintDiagnostics, DUPLICATE_MATCHER_BINDING_NAME}; use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT}; use crate::session::{Session, DiagnosticMessageId}; use std::{hash, ptr}; @@ -82,6 +82,7 @@ impl Lint { match lint_id { BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP, BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT, + BufferedEarlyLintId::DuplicateMacroMatcherBindingName => DUPLICATE_MATCHER_BINDING_NAME, } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index fd5e68d5ae60a..460cb977346a9 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -354,6 +354,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #57644 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(DUPLICATE_MATCHER_BINDING_NAME), + reference: "issue #57593 ", + edition: None, + }, ]); // Register renamed and removed lints. diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs index 977e6d4587709..29cb9cd7f30b5 100644 --- a/src/libsyntax/early_buffered_lints.rs +++ b/src/libsyntax/early_buffered_lints.rs @@ -12,6 +12,8 @@ pub enum BufferedEarlyLintId { /// Usage of `?` as a macro separator is deprecated. QuestionMarkMacroSep, IllFormedAttributeInput, + /// Usage of a duplicate macro matcher binding name. + DuplicateMacroMatcherBindingName, } /// Stores buffered lint info which can later be passed to `librustc`. diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 61a5b2cb0d200..33ea675f9d1bb 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -360,8 +360,12 @@ pub fn compile( // don't abort iteration early, so that errors for multiple lhses can be reported for lhs in &lhses { valid &= check_lhs_no_empty_seq(sess, &[lhs.clone()]); - valid &= - check_lhs_duplicate_matcher_bindings(sess, &[lhs.clone()], &mut FxHashMap::default()); + valid &= check_lhs_duplicate_matcher_bindings( + sess, + &[lhs.clone()], + &mut FxHashMap::default(), + def.id + ); } let expander: Box<_> = Box::new(MacroRulesMacroExpander { @@ -467,29 +471,38 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { fn check_lhs_duplicate_matcher_bindings( sess: &ParseSess, tts: &[quoted::TokenTree], - metavar_names: &mut FxHashMap + metavar_names: &mut FxHashMap, + node_id: ast::NodeId, ) -> bool { use self::quoted::TokenTree; + use crate::early_buffered_lints::BufferedEarlyLintId; for tt in tts { match *tt { TokenTree::MetaVarDecl(span, name, _kind) => { if let Some(&prev_span) = metavar_names.get(&name) { - sess.span_diagnostic - .struct_span_err(span, "duplicate matcher binding") - .span_note(prev_span, "previous declaration was here") - .emit(); + // FIXME(mark-i-m): in a few cycles, make this a hard error. + // sess.span_diagnostic + // .struct_span_err(span, "duplicate matcher binding") + // .span_note(prev_span, "previous declaration was here") + // .emit(); + sess.buffer_lint( + BufferedEarlyLintId::DuplicateMacroMatcherBindingName, + crate::source_map::MultiSpan::from(vec![prev_span, span]), + node_id, + "duplicate matcher binding" + ); return false; } else { metavar_names.insert(name, span); } } TokenTree::Delimited(_, ref del) => { - if !check_lhs_duplicate_matcher_bindings(sess, &del.tts, metavar_names) { + if !check_lhs_duplicate_matcher_bindings(sess, &del.tts, metavar_names, node_id) { return false; } }, TokenTree::Sequence(_, ref seq) => { - if !check_lhs_duplicate_matcher_bindings(sess, &seq.tts, metavar_names) { + if !check_lhs_duplicate_matcher_bindings(sess, &seq.tts, metavar_names, node_id) { return false; } } diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.rs b/src/test/ui/macros/macro-multiple-matcher-bindings.rs index ea57d66b565d9..3deae3eacecb2 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.rs +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.rs @@ -1,9 +1,11 @@ // Test that duplicate matcher binding names are caught at declaration time, rather than at macro // invocation time. +#![allow(unused_macros)] + macro_rules! foo1 { - ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding - ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding + ($a:ident, $a:ident) => {}; //~WARN duplicate matcher binding + ($a:ident, $a:path) => {}; //~WARN duplicate matcher binding } macro_rules! foo2 { @@ -12,8 +14,8 @@ macro_rules! foo2 { } macro_rules! foo3 { - ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding - ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding + ($a:ident, $($a:ident),*) => {}; //~WARN duplicate matcher binding + ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARN duplicate matcher binding } fn main() {} diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr index 3e3e10245870f..04b27e88a1f05 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr @@ -1,50 +1,37 @@ -error: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:5:16 - | -LL | ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^^ - | -note: previous declaration was here - --> $DIR/macro-multiple-matcher-bindings.rs:5:6 - | -LL | ($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^^ +warning: duplicate matcher binding + --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:7:6 + | +7 | ($a:ident, $a:ident) => {}; //~WARN duplicate matcher binding + | ^^^^^^^^ ^^^^^^^^ + | + = note: #[warn(duplicate_matcher_binding_name)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57593 -error: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:6:16 - | -LL | ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^ - | -note: previous declaration was here - --> $DIR/macro-multiple-matcher-bindings.rs:6:6 - | -LL | ($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^^ +warning: duplicate matcher binding + --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:8:6 + | +8 | ($a:ident, $a:path) => {}; //~WARN duplicate matcher binding + | ^^^^^^^^ ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57593 -error: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:15:18 - | -LL | ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^^ +warning: duplicate matcher binding + --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:17:6 | -note: previous declaration was here - --> $DIR/macro-multiple-matcher-bindings.rs:15:6 +LL | ($a:ident, $($a:ident),*) => {}; //~WARN duplicate matcher binding + | ^^^^^^^^ ^^^^^^^^ | -LL | ($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57593 -error: duplicate matcher binding - --> $DIR/macro-multiple-matcher-bindings.rs:16:25 +warning: duplicate matcher binding + --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:18:8 | -LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^ +LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARN duplicate matcher binding + | ^^^^^^^^ ^^^^^^^ | -note: previous declaration was here - --> $DIR/macro-multiple-matcher-bindings.rs:16:8 - | -LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding - | ^^^^^^^^ - -error: aborting due to 4 previous errors + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57593 From c25d6b83441e0c060ee0273193ef27b29e1318cd Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 17 Jan 2019 21:30:06 -0600 Subject: [PATCH 0723/1064] update test --- .../macros/macro-multiple-matcher-bindings.rs | 12 ++++-- .../macro-multiple-matcher-bindings.stderr | 38 +++++++++---------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.rs b/src/test/ui/macros/macro-multiple-matcher-bindings.rs index 3deae3eacecb2..9e0fa3887163d 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.rs +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.rs @@ -1,11 +1,15 @@ // Test that duplicate matcher binding names are caught at declaration time, rather than at macro // invocation time. +// +// FIXME(mark-i-m): Update this when it becomes a hard error. + +// compile-pass #![allow(unused_macros)] macro_rules! foo1 { - ($a:ident, $a:ident) => {}; //~WARN duplicate matcher binding - ($a:ident, $a:path) => {}; //~WARN duplicate matcher binding + ($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding + ($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding } macro_rules! foo2 { @@ -14,8 +18,8 @@ macro_rules! foo2 { } macro_rules! foo3 { - ($a:ident, $($a:ident),*) => {}; //~WARN duplicate matcher binding - ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARN duplicate matcher binding + ($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding + ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding } fn main() {} diff --git a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr index 04b27e88a1f05..bc78b471a2d1e 100644 --- a/src/test/ui/macros/macro-multiple-matcher-bindings.stderr +++ b/src/test/ui/macros/macro-multiple-matcher-bindings.stderr @@ -1,35 +1,35 @@ warning: duplicate matcher binding - --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:7:6 - | -7 | ($a:ident, $a:ident) => {}; //~WARN duplicate matcher binding - | ^^^^^^^^ ^^^^^^^^ - | - = note: #[warn(duplicate_matcher_binding_name)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57593 + --> $DIR/macro-multiple-matcher-bindings.rs:11:6 + | +LL | ($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding + | ^^^^^^^^ ^^^^^^^^ + | + = note: #[warn(duplicate_matcher_binding_name)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57593 warning: duplicate matcher binding - --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:8:6 - | -8 | ($a:ident, $a:path) => {}; //~WARN duplicate matcher binding - | ^^^^^^^^ ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57593 + --> $DIR/macro-multiple-matcher-bindings.rs:12:6 + | +LL | ($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding + | ^^^^^^^^ ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57593 warning: duplicate matcher binding - --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:17:6 + --> $DIR/macro-multiple-matcher-bindings.rs:21:6 | -LL | ($a:ident, $($a:ident),*) => {}; //~WARN duplicate matcher binding +LL | ($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding | ^^^^^^^^ ^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57593 warning: duplicate matcher binding - --> src/test/ui/macros/macro-multiple-matcher-bindings.rs:18:8 + --> $DIR/macro-multiple-matcher-bindings.rs:22:8 | -LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARN duplicate matcher binding +LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding | ^^^^^^^^ ^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! From da13fbda5e28482d01205d791f38a645a396ea65 Mon Sep 17 00:00:00 2001 From: Patrick McCarter Date: Thu, 7 Feb 2019 13:46:20 -0500 Subject: [PATCH 0724/1064] Add unstable feature attribute for unsigned const saturating add/sub intrinsics #58030 --- src/libcore/num/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d4fade7613848..d34173dafb351 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2816,6 +2816,7 @@ assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_saturating_int_methods")] #[inline] #[cfg(not(stage0))] pub const fn saturating_add(self, rhs: Self) -> Self { @@ -2859,6 +2860,7 @@ Basic usage: assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_saturating_int_methods")] #[inline] #[cfg(not(stage0))] pub const fn saturating_sub(self, rhs: Self) -> Self { From f753d304c6c5d7f2c10147d783d58db7db4ffc4c Mon Sep 17 00:00:00 2001 From: Igor Sadikov Date: Tue, 5 Feb 2019 15:21:03 -0500 Subject: [PATCH 0725/1064] Suggest removing parentheses surrounding lifetimes --- src/libsyntax/parse/parser.rs | 17 +++++++++++++++-- .../parser/trait-object-lifetime-parens.stderr | 8 ++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cacdab980facd..1dbe3fb7ea620 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5371,6 +5371,7 @@ impl<'a> Parser<'a> { if is_bound_start { let lo = self.span; let has_parens = self.eat(&token::OpenDelim(token::Paren)); + let inner_lo = self.span; let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None }; if self.token.is_lifetime() { if let Some(question_span) = question { @@ -5379,9 +5380,21 @@ impl<'a> Parser<'a> { } bounds.push(GenericBound::Outlives(self.expect_lifetime())); if has_parens { + let inner_span = inner_lo.to(self.prev_span); self.expect(&token::CloseDelim(token::Paren))?; - self.span_err(self.prev_span, - "parenthesized lifetime bounds are not supported"); + let mut err = self.struct_span_err( + lo.to(self.prev_span), + "parenthesized lifetime bounds are not supported" + ); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(inner_span) { + err.span_suggestion_short( + lo.to(self.prev_span), + "remove the parentheses", + snippet.to_owned(), + Applicability::MachineApplicable + ); + } + err.emit(); } } else { let lifetime_defs = self.parse_late_bound_lifetime_defs()?; diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr index a9b542ddcc4d3..94ca66aef729b 100644 --- a/src/test/ui/parser/trait-object-lifetime-parens.stderr +++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr @@ -1,14 +1,14 @@ error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:5:24 + --> $DIR/trait-object-lifetime-parens.rs:5:21 | LL | fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:8:27 + --> $DIR/trait-object-lifetime-parens.rs:8:24 | LL | let _: Box; //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: expected type, found `'a` --> $DIR/trait-object-lifetime-parens.rs:9:17 From 725af308093818dc4386a06457eb1e452c7afee1 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 06:28:15 +0900 Subject: [PATCH 0726/1064] librustc_mir => 2018 --- src/librustc_mir/Cargo.toml | 3 +- src/librustc_mir/borrow_check/borrow_set.rs | 10 ++--- .../borrow_check/error_reporting.rs | 38 ++++++++++------- src/librustc_mir/borrow_check/flows.rs | 18 ++++---- src/librustc_mir/borrow_check/mod.rs | 26 ++++++------ src/librustc_mir/borrow_check/move_errors.rs | 12 +++--- .../borrow_check/mutability_errors.rs | 12 +++--- .../borrow_check/nll/constraint_generation.rs | 10 ++--- .../borrow_check/nll/constraints/graph.rs | 6 +-- .../borrow_check/nll/constraints/mod.rs | 4 +- .../nll/explain_borrow/find_use.rs | 6 +-- .../borrow_check/nll/explain_borrow/mod.rs | 20 ++++----- src/librustc_mir/borrow_check/nll/facts.rs | 4 +- .../borrow_check/nll/invalidation.rs | 24 +++++------ src/librustc_mir/borrow_check/nll/mod.rs | 38 ++++++++--------- .../nll/region_infer/error_reporting/mod.rs | 12 +++--- .../error_reporting/region_name.rs | 8 ++-- .../region_infer/error_reporting/var_name.rs | 4 +- .../borrow_check/nll/region_infer/graphviz.rs | 3 +- .../borrow_check/nll/region_infer/mod.rs | 12 +++--- .../nll/type_check/constraint_conversion.rs | 10 ++--- .../nll/type_check/free_region_relations.rs | 8 ++-- .../nll/type_check/input_output.rs | 2 +- .../nll/type_check/liveness/liveness_map.rs | 6 +-- .../nll/type_check/liveness/local_use_map.rs | 6 +-- .../nll/type_check/liveness/mod.rs | 16 +++---- .../nll/type_check/liveness/trace.rs | 20 ++++----- .../borrow_check/nll/type_check/mod.rs | 42 +++++++++---------- .../borrow_check/nll/type_check/relate_tys.rs | 4 +- src/librustc_mir/borrow_check/path_utils.rs | 10 ++--- src/librustc_mir/borrow_check/place_ext.rs | 2 +- .../borrow_check/places_conflict.rs | 6 +-- src/librustc_mir/borrow_check/used_muts.rs | 2 +- src/librustc_mir/build/block.rs | 8 ++-- src/librustc_mir/build/cfg.rs | 2 +- src/librustc_mir/build/expr/as_constant.rs | 4 +- src/librustc_mir/build/expr/as_operand.rs | 6 +-- src/librustc_mir/build/expr/as_place.rs | 8 ++-- src/librustc_mir/build/expr/as_rvalue.rs | 6 +-- src/librustc_mir/build/expr/as_temp.rs | 4 +- src/librustc_mir/build/expr/category.rs | 2 +- src/librustc_mir/build/expr/into.rs | 6 +-- src/librustc_mir/build/expr/stmt.rs | 6 +-- src/librustc_mir/build/into.rs | 6 +-- src/librustc_mir/build/matches/mod.rs | 10 ++--- src/librustc_mir/build/matches/simplify.rs | 6 +-- src/librustc_mir/build/matches/test.rs | 8 ++-- src/librustc_mir/build/matches/util.rs | 6 +-- src/librustc_mir/build/misc.rs | 2 +- src/librustc_mir/build/mod.rs | 18 ++++---- src/librustc_mir/build/scope.rs | 4 +- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/dataflow/at_location.rs | 8 ++-- .../dataflow/drop_flag_effects.rs | 2 +- src/librustc_mir/dataflow/graphviz.rs | 22 +++++----- .../dataflow/impls/borrowed_locals.rs | 6 +-- src/librustc_mir/dataflow/impls/borrows.rs | 26 ++++++------ src/librustc_mir/dataflow/impls/mod.rs | 24 +++++------ .../dataflow/impls/storage_liveness.rs | 6 +-- src/librustc_mir/dataflow/mod.rs | 12 +++--- src/librustc_mir/dataflow/move_paths/mod.rs | 19 +++++---- src/librustc_mir/hair/cx/block.rs | 6 +-- src/librustc_mir/hair/cx/expr.rs | 10 ++--- src/librustc_mir/hair/cx/mod.rs | 8 ++-- src/librustc_mir/hair/cx/to_ref.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 8 ++-- src/librustc_mir/hair/pattern/check_match.rs | 22 +++++----- src/librustc_mir/hair/pattern/mod.rs | 8 ++-- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/interpret/snapshot.rs | 14 +++---- src/librustc_mir/interpret/terminator.rs | 6 +-- src/librustc_mir/interpret/traits.rs | 2 +- src/librustc_mir/interpret/visitor.rs | 2 +- src/librustc_mir/lib.rs | 20 +++------ src/librustc_mir/lints.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 4 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 22 +++++----- src/librustc_mir/shim.rs | 14 +++---- src/librustc_mir/transform/add_call_guards.rs | 4 +- .../transform/add_moves_for_packed_drops.rs | 6 +-- src/librustc_mir/transform/add_retag.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 10 +++-- .../transform/cleanup_post_borrowck.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 8 ++-- src/librustc_mir/transform/copy_prop.rs | 6 +-- src/librustc_mir/transform/deaggregator.rs | 2 +- src/librustc_mir/transform/dump_mir.rs | 6 +-- src/librustc_mir/transform/elaborate_drops.rs | 24 +++++------ src/librustc_mir/transform/erase_regions.rs | 2 +- src/librustc_mir/transform/generator.rs | 20 ++++----- src/librustc_mir/transform/inline.rs | 6 +-- src/librustc_mir/transform/instcombine.rs | 2 +- src/librustc_mir/transform/lower_128bit.rs | 5 +-- src/librustc_mir/transform/mod.rs | 6 +-- src/librustc_mir/transform/no_landing_pads.rs | 2 +- src/librustc_mir/transform/promote_consts.rs | 3 +- src/librustc_mir/transform/qualify_consts.rs | 8 ++-- .../transform/remove_noop_landing_pads.rs | 8 ++-- src/librustc_mir/transform/rustc_peek.rs | 26 ++++++------ src/librustc_mir/transform/simplify.rs | 6 +-- .../transform/simplify_branches.rs | 2 +- .../transform/uniform_array_move_out.rs | 4 +- src/librustc_mir/util/borrowck_errors.rs | 6 +-- src/librustc_mir/util/def_use.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_mir/util/graphviz.rs | 11 +++-- src/librustc_mir/util/liveness.rs | 4 +- src/librustc_mir/util/patch.rs | 4 +- src/librustc_mir/util/pretty.rs | 23 ++++++---- 110 files changed, 514 insertions(+), 505 deletions(-) diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index f0234c48c3eca..44a6b41cdfe45 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_mir" version = "0.0.0" +edition = "2018" [lib] name = "rustc_mir" @@ -12,7 +13,7 @@ crate-type = ["dylib"] arena = { path = "../libarena" } bitflags = "1.0" either = "1.5.0" -graphviz = { path = "../libgraphviz" } +dot = { path = "../libgraphviz", package = "graphviz" } log = "0.4" log_settings = "0.1.1" polonius-engine = "0.6.2" diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index ecbc6118bc37c..2788f5d4325a9 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -1,7 +1,7 @@ -use borrow_check::place_ext::PlaceExt; -use borrow_check::nll::ToRegionVid; -use dataflow::indexes::BorrowIndex; -use dataflow::move_paths::MoveData; +use crate::borrow_check::place_ext::PlaceExt; +use crate::borrow_check::nll::ToRegionVid; +use crate::dataflow::indexes::BorrowIndex; +use crate::dataflow::move_paths::MoveData; use rustc::mir::traversal; use rustc::mir::visit::{ PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext @@ -72,7 +72,7 @@ crate struct BorrowData<'tcx> { } impl<'tcx> fmt::Display for BorrowData<'tcx> { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { let kind = match self.kind { mir::BorrowKind::Shared => "", mir::BorrowKind::Shallow => "shallow ", diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index b070031756798..afb26963217ff 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1,7 +1,7 @@ -use borrow_check::nll::explain_borrow::BorrowExplanation; -use borrow_check::nll::region_infer::{RegionName, RegionNameSource}; -use borrow_check::prefixes::IsPrefixOf; -use borrow_check::WriteKind; +use crate::borrow_check::nll::explain_borrow::BorrowExplanation; +use crate::borrow_check::nll::region_infer::{RegionName, RegionNameSource}; +use crate::borrow_check::prefixes::IsPrefixOf; +use crate::borrow_check::WriteKind; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::middle::region::ScopeTree; @@ -22,10 +22,10 @@ use syntax_pos::Span; use super::borrow_set::BorrowData; use super::{Context, MirBorrowckCtxt}; use super::{InitializationRequiringAction, PrefixSet}; -use dataflow::drop_flag_effects; -use dataflow::move_paths::indexes::MoveOutIndex; -use dataflow::move_paths::MovePathIndex; -use util::borrowck_errors::{BorrowckErrors, Origin}; +use crate::dataflow::drop_flag_effects; +use crate::dataflow::move_paths::indexes::MoveOutIndex; +use crate::dataflow::move_paths::MovePathIndex; +use crate::util::borrowck_errors::{BorrowckErrors, Origin}; #[derive(Debug)] struct MoveSite { @@ -1726,7 +1726,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } /// End-user visible description of the `field`nth field of `base` - fn describe_field(&self, base: &Place, field: Field) -> String { + fn describe_field(&self, base: &Place<'_>, field: Field) -> String { match *base { Place::Local(local) => { let local = &self.mir.local_decls[local]; @@ -1751,7 +1751,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } /// End-user visible description of the `field_index`nth field of `ty` - fn describe_field_from_ty(&self, ty: &ty::Ty, field: Field) -> String { + fn describe_field_from_ty(&self, ty: &ty::Ty<'_>, field: Field) -> String { if ty.is_box() { // If the type is a box, the field is described from the boxed type self.describe_field_from_ty(&ty.boxed_ty(), field) @@ -1860,7 +1860,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn annotate_argument_and_return_for_borrow( &self, borrow: &BorrowData<'tcx>, - ) -> Option { + ) -> Option> { // Define a fallback for when we can't match a closure. let fallback = || { let is_closure = self.infcx.tcx.is_closure(self.mir_def_id); @@ -2081,7 +2081,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { &self, did: DefId, sig: ty::PolyFnSig<'tcx>, - ) -> Option { + ) -> Option> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); let is_closure = self.infcx.tcx.is_closure(did); let fn_node_id = self.infcx.tcx.hir().as_local_node_id(did)?; @@ -2368,14 +2368,22 @@ impl UseSpans { } // Add a span label to the arguments of the closure, if it exists. - pub(super) fn args_span_label(self, err: &mut DiagnosticBuilder, message: impl Into) { + pub(super) fn args_span_label( + self, + err: &mut DiagnosticBuilder<'_>, + message: impl Into, + ) { if let UseSpans::ClosureUse { args_span, .. } = self { err.span_label(args_span, message); } } // Add a span label to the use of the captured variable, if it exists. - pub(super) fn var_span_label(self, err: &mut DiagnosticBuilder, message: impl Into) { + pub(super) fn var_span_label( + self, + err: &mut DiagnosticBuilder<'_>, + message: impl Into, + ) { if let UseSpans::ClosureUse { var_span, .. } = self { err.span_label(var_span, message); } @@ -2563,7 +2571,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Helper to retrieve span(s) of given borrow from the current MIR /// representation - pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData) -> UseSpans { + pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData<'_>) -> UseSpans { let span = self.mir.source_info(borrow.reserve_location).span; self.borrow_spans(span, borrow.reserve_location) } diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs index 4eeb19c4e7a67..8de39f0efc1a5 100644 --- a/src/librustc_mir/borrow_check/flows.rs +++ b/src/librustc_mir/borrow_check/flows.rs @@ -7,16 +7,16 @@ use rustc::mir::{BasicBlock, Location}; use rustc::ty::RegionVid; use rustc_data_structures::bit_set::BitIter; -use borrow_check::location::LocationIndex; +use crate::borrow_check::location::LocationIndex; use polonius_engine::Output; -use dataflow::move_paths::indexes::BorrowIndex; -use dataflow::move_paths::HasMoveData; -use dataflow::Borrows; -use dataflow::EverInitializedPlaces; -use dataflow::{FlowAtLocation, FlowsAtLocation}; -use dataflow::MaybeUninitializedPlaces; +use crate::dataflow::move_paths::indexes::BorrowIndex; +use crate::dataflow::move_paths::HasMoveData; +use crate::dataflow::Borrows; +use crate::dataflow::EverInitializedPlaces; +use crate::dataflow::{FlowAtLocation, FlowsAtLocation}; +use crate::dataflow::MaybeUninitializedPlaces; use either::Either; use std::fmt; use std::rc::Rc; @@ -57,7 +57,7 @@ impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> { } } - crate fn with_outgoing_borrows(&self, op: impl FnOnce(BitIter)) { + crate fn with_outgoing_borrows(&self, op: impl FnOnce(BitIter<'_, BorrowIndex>)) { self.borrows.with_iter_outgoing(op) } } @@ -93,7 +93,7 @@ impl<'b, 'gcx, 'tcx> FlowsAtLocation for Flows<'b, 'gcx, 'tcx> { } impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let mut s = String::new(); s.push_str("borrows in effect: ["); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 5597e4a6c597e..45a8c9e8e6909 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1,6 +1,6 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -use borrow_check::nll::region_infer::RegionInferenceContext; +use crate::borrow_check::nll::region_infer::RegionInferenceContext; use rustc::hir; use rustc::hir::Node; use rustc::hir::def_id::DefId; @@ -25,16 +25,16 @@ use std::collections::BTreeMap; use syntax_pos::Span; -use dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex}; -use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError}; -use dataflow::Borrows; -use dataflow::DataflowResultsConsumer; -use dataflow::FlowAtLocation; -use dataflow::MoveDataParamEnv; -use dataflow::{do_dataflow, DebugFormatted}; -use dataflow::EverInitializedPlaces; -use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; -use util::borrowck_errors::{BorrowckErrors, Origin}; +use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex}; +use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError}; +use crate::dataflow::Borrows; +use crate::dataflow::DataflowResultsConsumer; +use crate::dataflow::FlowAtLocation; +use crate::dataflow::MoveDataParamEnv; +use crate::dataflow::{do_dataflow, DebugFormatted}; +use crate::dataflow::EverInitializedPlaces; +use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; +use crate::util::borrowck_errors::{BorrowckErrors, Origin}; use self::borrow_set::{BorrowData, BorrowSet}; use self::flows::Flows; @@ -59,7 +59,7 @@ mod used_muts; pub(crate) mod nll; -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { mir_borrowck, ..*providers @@ -108,7 +108,7 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowC } let opt_closure_req = tcx.infer_ctxt().enter(|infcx| { - let input_mir: &Mir = &input_mir.borrow(); + let input_mir: &Mir<'_> = &input_mir.borrow(); do_mir_borrowck(&infcx, input_mir, def_id) }); debug!("mir_borrowck done"); diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index 8539b5c26cee8..f7d46925e17df 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -6,13 +6,13 @@ use rustc::ty; use rustc_errors::{DiagnosticBuilder,Applicability}; use syntax_pos::Span; -use borrow_check::MirBorrowckCtxt; -use borrow_check::prefixes::PrefixSet; -use dataflow::move_paths::{ +use crate::borrow_check::MirBorrowckCtxt; +use crate::borrow_check::prefixes::PrefixSet; +use crate::dataflow::move_paths::{ IllegalMoveOrigin, IllegalMoveOriginKind, InitLocation, LookupResult, MoveError, MovePathIndex, }; -use util::borrowck_errors::{BorrowckErrors, Origin}; +use crate::util::borrowck_errors::{BorrowckErrors, Origin}; // Often when desugaring a pattern match we may have many individual moves in // MIR that are all part of one operation from the user's point-of-view. For @@ -63,7 +63,7 @@ enum BorrowedContentSource { } impl Display for BorrowedContentSource { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { BorrowedContentSource::Arc => write!(f, "an `Arc`"), BorrowedContentSource::Rc => write!(f, "an `Rc`"), @@ -240,7 +240,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { fn report(&mut self, error: GroupedMoveError<'tcx>) { let (mut err, err_span) = { - let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind) = + let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) = match error { GroupedMoveError::MovesFromPlace { span, diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 9d3ce7693ea86..dad8d903cf9fe 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -8,11 +8,11 @@ use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; use syntax_pos::symbol::keywords; -use dataflow::move_paths::InitLocation; -use borrow_check::MirBorrowckCtxt; -use util::borrowck_errors::{BorrowckErrors, Origin}; -use util::collect_writes::FindAssignments; -use util::suggest_ref_mut; +use crate::dataflow::move_paths::InitLocation; +use crate::borrow_check::MirBorrowckCtxt; +use crate::util::borrowck_errors::{BorrowckErrors, Origin}; +use crate::util::collect_writes::FindAssignments; +use crate::util::suggest_ref_mut; use rustc_errors::Applicability; #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -611,7 +611,7 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>( }) } -fn is_closure_or_generator(ty: ty::Ty) -> bool { +fn is_closure_or_generator(ty: ty::Ty<'_>) -> bool { ty.is_closure() || ty.is_generator() } diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 588f46cb77fe2..c02c2b4934cf4 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -1,8 +1,8 @@ -use borrow_check::borrow_set::BorrowSet; -use borrow_check::location::LocationTable; -use borrow_check::nll::ToRegionVid; -use borrow_check::nll::facts::AllFacts; -use borrow_check::nll::region_infer::values::LivenessValues; +use crate::borrow_check::borrow_set::BorrowSet; +use crate::borrow_check::location::LocationTable; +use crate::borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::facts::AllFacts; +use crate::borrow_check::nll::region_infer::values::LivenessValues; use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs index fe9ccb489e425..2479dfd1c7093 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs @@ -1,6 +1,6 @@ -use borrow_check::nll::type_check::Locations; -use borrow_check::nll::constraints::ConstraintIndex; -use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::type_check::Locations; +use crate::borrow_check::nll::constraints::ConstraintIndex; +use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph; diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs index 146bd65dd1143..d3f9743dfed77 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs @@ -2,7 +2,7 @@ use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use borrow_check::nll::type_check::Locations; +use crate::borrow_check::nll::type_check::Locations; use std::fmt; use std::ops::Deref; @@ -84,7 +84,7 @@ pub struct OutlivesConstraint { } impl fmt::Debug for OutlivesConstraint { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!( formatter, "({:?}: {:?}) due to {:?}", diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs index 53035dae4f35c..c5aaf5b811ed7 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs @@ -1,13 +1,13 @@ use std::collections::VecDeque; use std::rc::Rc; -use borrow_check::nll::region_infer::{Cause, RegionInferenceContext}; -use borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::region_infer::{Cause, RegionInferenceContext}; +use crate::borrow_check::nll::ToRegionVid; +use crate::util::liveness::{self, DefUse}; use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor}; use rustc::mir::{Local, Location, Mir}; use rustc::ty::{RegionVid, TyCtxt}; use rustc_data_structures::fx::FxHashSet; -use util::liveness::{self, DefUse}; crate fn find<'tcx>( mir: &Mir<'tcx>, diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 968c0f53a4852..8e57d107aa61e 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -1,8 +1,8 @@ -use borrow_check::borrow_set::BorrowData; -use borrow_check::error_reporting::UseSpans; -use borrow_check::nll::ConstraintDescription; -use borrow_check::nll::region_infer::{Cause, RegionName}; -use borrow_check::{Context, MirBorrowckCtxt, WriteKind}; +use crate::borrow_check::borrow_set::BorrowData; +use crate::borrow_check::error_reporting::UseSpans; +use crate::borrow_check::nll::ConstraintDescription; +use crate::borrow_check::nll::region_infer::{Cause, RegionName}; +use crate::borrow_check::{Context, MirBorrowckCtxt, WriteKind}; use rustc::ty::{self, TyCtxt}; use rustc::mir::{ CastKind, ConstraintCategory, FakeReadCause, Local, Location, Mir, Operand, @@ -14,7 +14,7 @@ use syntax_pos::Span; mod find_use; -pub(in borrow_check) enum BorrowExplanation { +pub(in crate::borrow_check) enum BorrowExplanation { UsedLater(LaterUseKind, Span), UsedLaterInLoop(LaterUseKind, Span), UsedLaterWhenDropped { @@ -33,7 +33,7 @@ pub(in borrow_check) enum BorrowExplanation { } #[derive(Clone, Copy)] -pub(in borrow_check) enum LaterUseKind { +pub(in crate::borrow_check) enum LaterUseKind { TraitCapture, ClosureCapture, Call, @@ -42,13 +42,13 @@ pub(in borrow_check) enum LaterUseKind { } impl BorrowExplanation { - pub(in borrow_check) fn is_explained(&self) -> bool { + pub(in crate::borrow_check) fn is_explained(&self) -> bool { match self { BorrowExplanation::Unexplained => false, _ => true, } } - pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>( + pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>( &self, tcx: TyCtxt<'cx, 'gcx, 'tcx>, mir: &Mir<'tcx>, @@ -187,7 +187,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// - second half is the place being accessed /// /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points - pub(in borrow_check) fn explain_why_borrow_contains_point( + pub(in crate::borrow_check) fn explain_why_borrow_contains_point( &self, context: Context, borrow: &BorrowData<'tcx>, diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs index bc33a1c9c65aa..9672d3e78cd50 100644 --- a/src/librustc_mir/borrow_check/nll/facts.rs +++ b/src/librustc_mir/borrow_check/nll/facts.rs @@ -1,5 +1,5 @@ -use borrow_check::location::{LocationIndex, LocationTable}; -use dataflow::indexes::BorrowIndex; +use crate::borrow_check::location::{LocationIndex, LocationTable}; +use crate::dataflow::indexes::BorrowIndex; use polonius_engine::AllFacts as PoloniusAllFacts; use polonius_engine::Atom; use rustc::ty::{RegionVid, TyCtxt}; diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 112b39952559b..3df6b797a44fb 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -1,15 +1,15 @@ -use borrow_check::borrow_set::BorrowSet; -use borrow_check::location::LocationTable; -use borrow_check::{JustWrite, WriteAndRead}; -use borrow_check::{AccessDepth, Deep, Shallow}; -use borrow_check::{ReadOrWrite, Activation, Read, Reservation, Write}; -use borrow_check::{Context, ContextKind}; -use borrow_check::{LocalMutationIsAllowed, MutateMode}; -use borrow_check::ArtificialField; -use borrow_check::{ReadKind, WriteKind}; -use borrow_check::nll::facts::AllFacts; -use borrow_check::path_utils::*; -use dataflow::move_paths::indexes::BorrowIndex; +use crate::borrow_check::borrow_set::BorrowSet; +use crate::borrow_check::location::LocationTable; +use crate::borrow_check::{JustWrite, WriteAndRead}; +use crate::borrow_check::{AccessDepth, Deep, Shallow}; +use crate::borrow_check::{ReadOrWrite, Activation, Read, Reservation, Write}; +use crate::borrow_check::{Context, ContextKind}; +use crate::borrow_check::{LocalMutationIsAllowed, MutateMode}; +use crate::borrow_check::ArtificialField; +use crate::borrow_check::{ReadKind, WriteKind}; +use crate::borrow_check::nll::facts::AllFacts; +use crate::borrow_check::path_utils::*; +use crate::dataflow::move_paths::indexes::BorrowIndex; use rustc::ty::TyCtxt; use rustc::mir::visit::Visitor; use rustc::mir::{BasicBlock, Location, Mir, Place, Rvalue}; diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index a092c3b8ecde2..128d54c9f49d7 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -1,13 +1,14 @@ -use borrow_check::borrow_set::BorrowSet; -use borrow_check::location::{LocationIndex, LocationTable}; -use borrow_check::nll::facts::AllFactsExt; -use borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints}; -use borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap; -use borrow_check::nll::region_infer::values::RegionValueElements; -use dataflow::indexes::BorrowIndex; -use dataflow::move_paths::MoveData; -use dataflow::FlowAtLocation; -use dataflow::MaybeInitializedPlaces; +use crate::borrow_check::borrow_set::BorrowSet; +use crate::borrow_check::location::{LocationIndex, LocationTable}; +use crate::borrow_check::nll::facts::AllFactsExt; +use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints}; +use crate::borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap; +use crate::borrow_check::nll::region_infer::values::RegionValueElements; +use crate::dataflow::indexes::BorrowIndex; +use crate::dataflow::move_paths::MoveData; +use crate::dataflow::FlowAtLocation; +use crate::dataflow::MaybeInitializedPlaces; +use crate::transform::MirSource; use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir}; @@ -19,12 +20,11 @@ use std::io; use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; -use transform::MirSource; use self::mir_util::PassWhere; use polonius_engine::{Algorithm, Output}; -use util as mir_util; -use util::pretty; +use crate::util as mir_util; +use crate::util::pretty; mod constraint_generation; pub mod explain_borrow; @@ -45,7 +45,7 @@ use self::universal_regions::UniversalRegions; /// scraping out the set of universal regions (e.g., region parameters) /// declared on the function. That set will need to be given to /// `compute_regions`. -pub(in borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>( +pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>( infcx: &InferCtxt<'cx, 'gcx, 'tcx>, def_id: DefId, param_env: ty::ParamEnv<'tcx>, @@ -68,7 +68,7 @@ pub(in borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>( /// Computes the (non-lexical) regions from the input MIR. /// /// This may result in errors being reported. -pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( +pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( infcx: &InferCtxt<'cx, 'gcx, 'tcx>, def_id: DefId, universal_regions: UniversalRegions<'tcx>, @@ -211,8 +211,8 @@ fn dump_mir_results<'a, 'gcx, 'tcx>( infcx: &InferCtxt<'a, 'gcx, 'tcx>, source: MirSource, mir: &Mir<'tcx>, - regioncx: &RegionInferenceContext, - closure_region_requirements: &Option, + regioncx: &RegionInferenceContext<'_>, + closure_region_requirements: &Option>, ) { if !mir_util::dump_enabled(infcx.tcx, "nll", source) { return; @@ -273,7 +273,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>( mir: &Mir<'tcx>, mir_def_id: DefId, regioncx: &RegionInferenceContext<'tcx>, - closure_region_requirements: &Option, + closure_region_requirements: &Option>, errors_buffer: &mut Vec, ) { let tcx = infcx.tcx; @@ -322,7 +322,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>( } fn for_each_region_constraint( - closure_region_requirements: &ClosureRegionRequirements, + closure_region_requirements: &ClosureRegionRequirements<'_>, with_msg: &mut dyn FnMut(&str) -> io::Result<()>, ) -> io::Result<()> { for req in &closure_region_requirements.outlives_requirements { diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 550668a7ceece..3498e3437676c 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -1,8 +1,9 @@ -use borrow_check::nll::constraints::OutlivesConstraint; -use borrow_check::nll::region_infer::RegionInferenceContext; -use borrow_check::nll::type_check::Locations; -use borrow_check::nll::universal_regions::DefiningTy; -use borrow_check::nll::ConstraintDescription; +use crate::borrow_check::nll::constraints::OutlivesConstraint; +use crate::borrow_check::nll::region_infer::RegionInferenceContext; +use crate::borrow_check::nll::type_check::Locations; +use crate::borrow_check::nll::universal_regions::DefiningTy; +use crate::borrow_check::nll::ConstraintDescription; +use crate::util::borrowck_errors::{BorrowckErrors, Origin}; use rustc::hir::def_id::DefId; use rustc::infer::error_reporting::nice_region_error::NiceRegionError; use rustc::infer::InferCtxt; @@ -15,7 +16,6 @@ use std::collections::VecDeque; use syntax::errors::Applicability; use syntax::symbol::keywords; use syntax_pos::Span; -use util::borrowck_errors::{BorrowckErrors, Origin}; mod region_name; mod var_name; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index bff8015511242..2c4f359f65fa5 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -1,7 +1,7 @@ use std::fmt::{self, Display}; -use borrow_check::nll::region_infer::RegionInferenceContext; -use borrow_check::nll::universal_regions::DefiningTy; -use borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::region_infer::RegionInferenceContext; +use crate::borrow_check::nll::universal_regions::DefiningTy; +use crate::borrow_check::nll::ToRegionVid; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; @@ -109,7 +109,7 @@ impl RegionName { } impl Display for RegionName { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name) } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs index c2f2e99c0a55b..bd7b8829c7b4f 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs @@ -1,5 +1,5 @@ -use borrow_check::nll::region_infer::RegionInferenceContext; -use borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::region_infer::RegionInferenceContext; +use crate::borrow_check::nll::ToRegionVid; use rustc::mir::{Local, Mir}; use rustc::ty::{RegionVid, TyCtxt}; use rustc_data_structures::indexed_vec::Idx; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs index 2da158be432be..cffc66ac7ddfd 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs @@ -3,8 +3,7 @@ //! data to rendered labels. use super::*; -use borrow_check::nll::constraints::OutlivesConstraint; -use dot; +use crate::borrow_check::nll::constraints::OutlivesConstraint; use std::borrow::Cow; use std::io::{self, Write}; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index fee5dc8646587..7fe657702d756 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -1,9 +1,11 @@ use super::universal_regions::UniversalRegions; -use borrow_check::nll::constraints::graph::NormalConstraintGraph; -use borrow_check::nll::constraints::{ConstraintSccIndex, ConstraintSet, OutlivesConstraint}; -use borrow_check::nll::region_infer::values::{PlaceholderIndices, RegionElement, ToElementIndex}; -use borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations; -use borrow_check::nll::type_check::Locations; +use crate::borrow_check::nll::constraints::graph::NormalConstraintGraph; +use crate::borrow_check::nll::constraints::{ConstraintSccIndex, ConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::region_infer::values::{ + PlaceholderIndices, RegionElement, ToElementIndex +}; +use crate::borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations; +use crate::borrow_check::nll::type_check::Locations; use rustc::hir::def_id::DefId; use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound}; diff --git a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs index b7555e57a62bb..1a72205ad7ae1 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs @@ -1,8 +1,8 @@ -use borrow_check::nll::constraints::OutlivesConstraint; -use borrow_check::nll::region_infer::TypeTest; -use borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; -use borrow_check::nll::universal_regions::UniversalRegions; -use borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::constraints::OutlivesConstraint; +use crate::borrow_check::nll::region_infer::TypeTest; +use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; +use crate::borrow_check::nll::universal_regions::UniversalRegions; +use crate::borrow_check::nll::ToRegionVid; use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; diff --git a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs index b19dc9091cb86..f549aea81f69f 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs @@ -1,7 +1,7 @@ -use borrow_check::nll::type_check::constraint_conversion; -use borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; -use borrow_check::nll::universal_regions::UniversalRegions; -use borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::type_check::constraint_conversion; +use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; +use crate::borrow_check::nll::universal_regions::UniversalRegions; +use crate::borrow_check::nll::ToRegionVid; use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::outlives::free_region_map::FreeRegionRelations; use rustc::infer::region_constraints::GenericKind; diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index ef0f7e1b217a9..50828c294fa1b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -7,7 +7,7 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). -use borrow_check::nll::universal_regions::UniversalRegions; +use crate::borrow_check::nll::universal_regions::UniversalRegions; use rustc::infer::LateBoundRegionConversionTime; use rustc::mir::*; use rustc::ty::Ty; diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs index dda74e6a6a688..5e2e4407cbecd 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs @@ -6,13 +6,13 @@ //! liveness code so that it only operates over variables with regions in their //! types, instead of all variables. -use borrow_check::nll::ToRegionVid; -use borrow_check::nll::facts::{AllFacts, AllFactsExt}; +use crate::borrow_check::nll::ToRegionVid; +use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt}; +use crate::util::liveness::LiveVariableMap; use rustc::mir::{Local, Mir}; use rustc::ty::{RegionVid, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use util::liveness::LiveVariableMap; /// Map between Local and LiveVar indices: the purpose of this /// map is to define the subset of local variables for which we need diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs index 3f13cc8b64778..e9765d2798cd7 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs @@ -1,10 +1,10 @@ -use borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements}; -use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap}; +use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements}; +use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap}; +use crate::util::liveness::{categorize, DefUse, LiveVariableMap}; use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::mir::{Local, Location, Mir}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::vec_linked_list as vll; -use util::liveness::{categorize, DefUse, LiveVariableMap}; /// A map that cross references each local with the locations where it /// is defined (assigned), used, or dropped. Used during liveness diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs index 633695a9b9ce5..a5510ba6936cc 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs @@ -1,11 +1,11 @@ -use borrow_check::location::LocationTable; -use borrow_check::nll::region_infer::values::RegionValueElements; -use borrow_check::nll::constraints::ConstraintSet; -use borrow_check::nll::NllLivenessMap; -use borrow_check::nll::universal_regions::UniversalRegions; -use dataflow::move_paths::MoveData; -use dataflow::MaybeInitializedPlaces; -use dataflow::FlowAtLocation; +use crate::borrow_check::location::LocationTable; +use crate::borrow_check::nll::region_infer::values::RegionValueElements; +use crate::borrow_check::nll::constraints::ConstraintSet; +use crate::borrow_check::nll::NllLivenessMap; +use crate::borrow_check::nll::universal_regions::UniversalRegions; +use crate::dataflow::move_paths::MoveData; +use crate::dataflow::MaybeInitializedPlaces; +use crate::dataflow::FlowAtLocation; use rustc::mir::Mir; use rustc::ty::RegionVid; use rustc_data_structures::fx::FxHashSet; diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 77e8dd9d130e3..d058be03f55e6 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -1,12 +1,13 @@ -use borrow_check::location::LocationTable; -use borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements}; -use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap}; -use borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap; -use borrow_check::nll::type_check::NormalizeLocation; -use borrow_check::nll::type_check::TypeChecker; -use dataflow::move_paths::indexes::MovePathIndex; -use dataflow::move_paths::MoveData; -use dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces}; +use crate::borrow_check::location::LocationTable; +use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements}; +use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap}; +use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap; +use crate::borrow_check::nll::type_check::NormalizeLocation; +use crate::borrow_check::nll::type_check::TypeChecker; +use crate::dataflow::move_paths::indexes::MovePathIndex; +use crate::dataflow::move_paths::MoveData; +use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces}; +use crate::util::liveness::LiveVariableMap; use rustc::infer::canonical::QueryRegionConstraint; use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Mir}; use rustc::traits::query::dropck_outlives::DropckOutlivesResult; @@ -16,7 +17,6 @@ use rustc::ty::{Ty, TypeFoldable}; use rustc_data_structures::bit_set::HybridBitSet; use rustc_data_structures::fx::FxHashMap; use std::rc::Rc; -use util::liveness::LiveVariableMap; /// This is the heart of the liveness computation. For each variable X /// that requires a liveness computation, it walks over all the uses diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 3e6aa358ee0d1..19ff47f9c390d 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -2,24 +2,25 @@ #![allow(unreachable_code)] -use borrow_check::borrow_set::BorrowSet; -use borrow_check::location::LocationTable; -use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; -use borrow_check::nll::facts::AllFacts; -use borrow_check::nll::region_infer::values::LivenessValues; -use borrow_check::nll::region_infer::values::PlaceholderIndex; -use borrow_check::nll::region_infer::values::PlaceholderIndices; -use borrow_check::nll::region_infer::values::RegionValueElements; -use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest}; -use borrow_check::nll::renumber; -use borrow_check::nll::type_check::free_region_relations::{ +use crate::borrow_check::borrow_set::BorrowSet; +use crate::borrow_check::location::LocationTable; +use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::facts::AllFacts; +use crate::borrow_check::nll::region_infer::values::LivenessValues; +use crate::borrow_check::nll::region_infer::values::PlaceholderIndex; +use crate::borrow_check::nll::region_infer::values::PlaceholderIndices; +use crate::borrow_check::nll::region_infer::values::RegionValueElements; +use crate::borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest}; +use crate::borrow_check::nll::renumber; +use crate::borrow_check::nll::type_check::free_region_relations::{ CreateResult, UniversalRegionRelations, }; -use borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions}; -use borrow_check::nll::ToRegionVid; -use dataflow::move_paths::MoveData; -use dataflow::FlowAtLocation; -use dataflow::MaybeInitializedPlaces; +use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions}; +use crate::borrow_check::nll::ToRegionVid; +use crate::dataflow::move_paths::MoveData; +use crate::dataflow::FlowAtLocation; +use crate::dataflow::MaybeInitializedPlaces; +use crate::transform::{MirPass, MirSource}; use either::Either; use rustc::hir; use rustc::hir::def_id::DefId; @@ -46,7 +47,6 @@ use rustc::ty::layout::VariantIdx; use std::rc::Rc; use std::{fmt, iter}; use syntax_pos::{Span, DUMMY_SP}; -use transform::{MirPass, MirSource}; macro_rules! span_mirbug { ($context:expr, $elem:expr, $($message:tt)*) => ({ @@ -210,7 +210,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>( extra(&mut checker) } -fn translate_outlives_facts(cx: &mut BorrowCheckContext) { +fn translate_outlives_facts(cx: &mut BorrowCheckContext<'_, '_>) { if let Some(facts) = cx.all_facts { let location_table = cx.location_table; facts @@ -235,7 +235,7 @@ fn translate_outlives_facts(cx: &mut BorrowCheckContext) { } } -fn mirbug(tcx: TyCtxt, span: Span, msg: &str) { +fn mirbug(tcx: TyCtxt<'_, '_, '_>, span: Span, msg: &str) { // We sometimes see MIR failures (notably predicate failures) due to // the fact that we check rvalue sized predicates here. So use `delay_span_bug` // to avoid reporting bugs in those cases. @@ -266,7 +266,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { } } - fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext<'_>, location: Location) { self.sanitize_place(place, location, context); } @@ -447,7 +447,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { &mut self, place: &Place<'tcx>, location: Location, - context: PlaceContext, + context: PlaceContext<'_>, ) -> PlaceTy<'tcx> { debug!("sanitize_place: {:?}", place); let place_ty = match *place { diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 74ad7d988cc1a..1748e30089021 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -1,5 +1,5 @@ -use borrow_check::nll::constraints::OutlivesConstraint; -use borrow_check::nll::type_check::{BorrowCheckContext, Locations}; +use crate::borrow_check::nll::constraints::OutlivesConstraint; +use crate::borrow_check::nll::type_check::{BorrowCheckContext, Locations}; use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate, NormalizationStrategy}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::mir::ConstraintCategory; diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 6875aced8d231..1cea9f662d351 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -1,8 +1,8 @@ -use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation}; -use borrow_check::places_conflict; -use borrow_check::Context; -use borrow_check::AccessDepth; -use dataflow::indexes::BorrowIndex; +use crate::borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation}; +use crate::borrow_check::places_conflict; +use crate::borrow_check::Context; +use crate::borrow_check::AccessDepth; +use crate::dataflow::indexes::BorrowIndex; use rustc::mir::{BasicBlock, Location, Mir, Place}; use rustc::mir::{ProjectionElem, BorrowKind}; use rustc::ty::TyCtxt; diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 4d0b25b1024a3..bad236a6f5256 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -2,7 +2,7 @@ use rustc::hir; use rustc::mir::ProjectionElem; use rustc::mir::{Local, Mir, Place, Mutability}; use rustc::ty::{self, TyCtxt}; -use borrow_check::borrow_set::LocalsStateAtExit; +use crate::borrow_check::borrow_set::LocalsStateAtExit; /// Extension methods for the `Place` type. crate trait PlaceExt<'tcx> { diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index ac7182abb36da..cd33f22bf3cb7 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -1,6 +1,6 @@ -use borrow_check::ArtificialField; -use borrow_check::Overlap; -use borrow_check::{Deep, Shallow, AccessDepth}; +use crate::borrow_check::ArtificialField; +use crate::borrow_check::Overlap; +use crate::borrow_check::{Deep, Shallow, AccessDepth}; use rustc::hir; use rustc::mir::{BorrowKind, Mir, Place}; use rustc::mir::{Projection, ProjectionElem}; diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index 0ff7ff4de10de..8c7359bdee768 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -3,7 +3,7 @@ use rustc::mir::{BasicBlock, Local, Location, Place, Statement, StatementKind, T use rustc_data_structures::fx::FxHashSet; -use borrow_check::MirBorrowckCtxt; +use crate::borrow_check::MirBorrowckCtxt; impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index f3d89a7a02515..7d93e131a6ca9 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -1,7 +1,7 @@ -use build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use build::ForGuard::OutsideGuard; -use build::matches::ArmHasGuard; -use hair::*; +use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; +use crate::build::ForGuard::OutsideGuard; +use crate::build::matches::ArmHasGuard; +use crate::hair::*; use rustc::mir::*; use rustc::hir; use syntax_pos::Span; diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index a9e468db1d1b7..778d1e71cedfc 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -1,6 +1,6 @@ //! Routines for manipulating the control-flow graph. -use build::CFG; +use crate::build::CFG; use rustc::mir::*; impl<'tcx> CFG<'tcx> { diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index 31e0c0daa3fa6..614668170d5be 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -1,7 +1,7 @@ //! See docs in build/expr/mod.rs -use build::Builder; -use hair::*; +use crate::build::Builder; +use crate::hair::*; use rustc::mir::*; use rustc::ty::CanonicalUserTypeAnnotation; diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index 1f653575a7fbf..38fae8539c8d7 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -1,8 +1,8 @@ //! See docs in build/expr/mod.rs -use build::expr::category::Category; -use build::{BlockAnd, BlockAndExtension, Builder}; -use hair::*; +use crate::build::expr::category::Category; +use crate::build::{BlockAnd, BlockAndExtension, Builder}; +use crate::hair::*; use rustc::middle::region; use rustc::mir::*; diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 6bd61ab53fd21..ed444191226a1 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -1,9 +1,9 @@ //! See docs in build/expr/mod.rs -use build::expr::category::Category; -use build::ForGuard::{OutsideGuard, RefWithinGuard}; -use build::{BlockAnd, BlockAndExtension, Builder}; -use hair::*; +use crate::build::expr::category::Category; +use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; +use crate::build::{BlockAnd, BlockAndExtension, Builder}; +use crate::hair::*; use rustc::mir::interpret::EvalErrorKind::BoundsCheck; use rustc::mir::*; use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 3de2f47578650..06658675f70f4 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -3,9 +3,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; -use build::expr::category::{Category, RvalueFunc}; -use build::{BlockAnd, BlockAndExtension, Builder}; -use hair::*; +use crate::build::expr::category::{Category, RvalueFunc}; +use crate::build::{BlockAnd, BlockAndExtension, Builder}; +use crate::hair::*; use rustc::middle::region; use rustc::mir::interpret::EvalErrorKind; use rustc::mir::*; diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index df271ff6e4016..efa1a4895e0c0 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -1,7 +1,7 @@ //! See docs in build/expr/mod.rs -use build::{BlockAnd, BlockAndExtension, Builder}; -use hair::*; +use crate::build::{BlockAnd, BlockAndExtension, Builder}; +use crate::hair::*; use rustc::middle::region; use rustc::mir::*; diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 53f84a495696c..ca7d435e62229 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -1,4 +1,4 @@ -use hair::*; +use crate::hair::*; #[derive(Debug, PartialEq)] pub enum Category { diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 2ffff68137dd2..05231bc7b3f16 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -1,8 +1,8 @@ //! See docs in build/expr/mod.rs -use build::expr::category::{Category, RvalueFunc}; -use build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use hair::*; +use crate::build::expr::category::{Category, RvalueFunc}; +use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; +use crate::hair::*; use rustc::mir::*; use rustc::ty; diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 1cbc60586c356..aadc2368f5aec 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -1,6 +1,6 @@ -use build::scope::BreakableScope; -use build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use hair::*; +use crate::build::scope::BreakableScope; +use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; +use crate::hair::*; use rustc::mir::*; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir/build/into.rs index 1b29126082067..67b6540febea8 100644 --- a/src/librustc_mir/build/into.rs +++ b/src/librustc_mir/build/into.rs @@ -4,11 +4,11 @@ //! wrapped up as expressions (e.g., blocks). To make this ergonomic, we use this //! latter `EvalInto` trait. -use build::{BlockAnd, Builder}; -use hair::*; +use crate::build::{BlockAnd, Builder}; +use crate::hair::*; use rustc::mir::*; -pub(in build) trait EvalInto<'tcx> { +pub(in crate::build) trait EvalInto<'tcx> { fn eval_into<'a, 'gcx>(self, builder: &mut Builder<'a, 'gcx, 'tcx>, destination: &Place<'tcx>, diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 2f1e8c03f2f7e..cf051ba2e0fa6 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -3,11 +3,11 @@ //! includes the high-level algorithm, the submodules contain the //! details. -use build::scope::{CachedBlock, DropKind}; -use build::ForGuard::{self, OutsideGuard, RefWithinGuard, ValWithinGuard}; -use build::{BlockAnd, BlockAndExtension, Builder}; -use build::{GuardFrame, GuardFrameLocal, LocalsForNode}; -use hair::*; +use crate::build::scope::{CachedBlock, DropKind}; +use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard, ValWithinGuard}; +use crate::build::{BlockAnd, BlockAndExtension, Builder}; +use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode}; +use crate::hair::*; use rustc::mir::*; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty}; use rustc::ty::layout::VariantIdx; diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index c219fd2218223..6be9ccb27036e 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -12,9 +12,9 @@ //! sort of test: for example, testing which variant an enum is, or //! testing a value against a constant. -use build::Builder; -use build::matches::{Ascription, Binding, MatchPair, Candidate}; -use hair::*; +use crate::build::Builder; +use crate::build::matches::{Ascription, Binding, MatchPair, Candidate}; +use crate::hair::*; use rustc::ty; use rustc::ty::layout::{Integer, IntegerExt, Size}; use syntax::attr::{SignedInt, UnsignedInt}; diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 696c173b048ad..395858c07b606 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -5,10 +5,10 @@ // identify what tests are needed, perform the tests, and then filter // the candidates based on the result. -use build::Builder; -use build::matches::{Candidate, MatchPair, Test, TestKind}; -use hair::*; -use hair::pattern::compare_const_vals; +use crate::build::Builder; +use crate::build::matches::{Candidate, MatchPair, Test, TestKind}; +use crate::hair::*; +use crate::hair::pattern::compare_const_vals; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::fx::FxHashMap; use rustc::ty::{self, Ty}; diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index b5a1a388e9cbc..ed12c1b3bc9c1 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -1,6 +1,6 @@ -use build::Builder; -use build::matches::MatchPair; -use hair::*; +use crate::build::Builder; +use crate::build::matches::MatchPair; +use crate::hair::*; use rustc::mir::*; use std::u32; use std::convert::TryInto; diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index c849c02242840..1634c36d34acf 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -1,7 +1,7 @@ //! Miscellaneous builder routines that are not specific to building any particular //! kind of thing. -use build::Builder; +use crate::build::Builder; use rustc::ty::{self, Ty}; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f38648fda0e36..a52b032aeb508 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -1,7 +1,10 @@ -use build; -use build::scope::{CachedBlock, DropKind}; -use hair::cx::Cx; -use hair::{LintLevel, BindingMode, PatternKind}; +use crate::build; +use crate::build::scope::{CachedBlock, DropKind}; +use crate::hair::cx::Cx; +use crate::hair::{LintLevel, BindingMode, PatternKind}; +use crate::shim; +use crate::transform::MirSource; +use crate::util as mir_util; use rustc::hir; use rustc::hir::Node; use rustc::hir::def_id::DefId; @@ -13,7 +16,6 @@ use rustc::ty::subst::Substs; use rustc::util::nodemap::NodeMap; use rustc_target::spec::PanicStrategy; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -use shim; use std::mem; use std::u32; use rustc_target::spec::abi::Abi; @@ -21,8 +23,6 @@ use syntax::ast; use syntax::attr::{self, UnwindAttr}; use syntax::symbol::keywords; use syntax_pos::Span; -use transform::MirSource; -use util as mir_util; use super::lints; @@ -161,7 +161,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t }; globalizer.visit_mir(&mut mir); let mir = unsafe { - mem::transmute::>(mir) + mem::transmute::, Mir<'tcx>>(mir) }; mir_util::dump_mir(tcx, None, "mir_map", &0, @@ -241,7 +241,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; globalizer.visit_mir(&mut mir); let mir = unsafe { - mem::transmute::>(mir) + mem::transmute::, Mir<'tcx>>(mir) }; mir_util::dump_mir(tcx, None, "mir_map", &0, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 78abba5f885b2..3872f5db26278 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -77,8 +77,8 @@ should go to. */ -use build::{BlockAnd, BlockAndExtension, Builder, CFG}; -use hair::LintLevel; +use crate::build::{BlockAnd, BlockAndExtension, Builder, CFG}; +use crate::hair::LintLevel; use rustc::middle::region; use rustc::ty::Ty; use rustc::hir; diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index f83a930353b73..d1b4486dd9345 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -190,7 +190,7 @@ enum ConstEvalError { } impl fmt::Display for ConstEvalError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::ConstEvalError::*; match *self { NeedsRfc(ref msg) => { diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index 375bc4fead443..d0b9fbc99f03f 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -4,8 +4,8 @@ use rustc::mir::{BasicBlock, Location}; use rustc_data_structures::bit_set::{BitIter, BitSet, HybridBitSet}; -use dataflow::{BitDenotation, BlockSets, DataflowResults}; -use dataflow::move_paths::{HasMoveData, MovePathIndex}; +use crate::dataflow::{BitDenotation, BlockSets, DataflowResults}; +use crate::dataflow::move_paths::{HasMoveData, MovePathIndex}; use std::iter; @@ -115,7 +115,7 @@ where } /// Returns an iterator over the elements present in the current state. - pub fn iter_incoming(&self) -> iter::Peekable> { + pub fn iter_incoming(&self) -> iter::Peekable> { self.curr_state.iter().peekable() } @@ -124,7 +124,7 @@ where /// Invokes `f` with an iterator over the resulting state. pub fn with_iter_outgoing(&self, f: F) where - F: FnOnce(BitIter), + F: FnOnce(BitIter<'_, BD::Idx>), { let mut curr_state = self.curr_state.clone(); curr_state.union(&self.stmt_gen); diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs index 22fb7a3bc470e..49499cf928d74 100644 --- a/src/librustc_mir/dataflow/drop_flag_effects.rs +++ b/src/librustc_mir/dataflow/drop_flag_effects.rs @@ -1,6 +1,6 @@ use rustc::mir::{self, Mir, Location}; use rustc::ty::{self, TyCtxt}; -use util::elaborate_drops::DropFlagState; +use crate::util::elaborate_drops::DropFlagState; use super::{MoveDataParamEnv}; use super::indexes::MovePathIndex; diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index 34752baa020e2..9d9f18d4b0dcf 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -3,8 +3,6 @@ use syntax::ast::NodeId; use rustc::mir::{BasicBlock, Mir}; -use dot; - use std::fs; use std::io; use std::marker::PhantomData; @@ -59,7 +57,7 @@ pub type Node = BasicBlock; #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Edge { source: BasicBlock, index: usize } -fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec { +fn outgoing(mir: &Mir<'_>, bb: BasicBlock) -> Vec { (0..mir[bb].terminator().successors().count()) .map(|index| Edge { source: bb, index: index}).collect() } @@ -70,18 +68,18 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> { type Node = Node; type Edge = Edge; - fn graph_id(&self) -> dot::Id { + fn graph_id(&self) -> dot::Id<'_> { dot::Id::new(format!("graph_for_node_{}", self.mbcx.node_id())) .unwrap() } - fn node_id(&self, n: &Node) -> dot::Id { + fn node_id(&self, n: &Node) -> dot::Id<'_> { dot::Id::new(format!("bb_{}", n.index())) .unwrap() } - fn node_label(&self, n: &Node) -> dot::LabelText { + fn node_label(&self, n: &Node) -> dot::LabelText<'_> { // Node label is something like this: // +---------+----------------------------------+------------------+------------------+ // | ENTRY | MIR | GEN | KILL | @@ -105,7 +103,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> } - fn node_shape(&self, _n: &Node) -> Option { + fn node_shape(&self, _n: &Node) -> Option> { Some(dot::LabelText::label("none")) } @@ -125,7 +123,7 @@ where MWF: MirWithFlowState<'tcx>, n: &Node, w: &mut W, block: BasicBlock, - mir: &Mir) -> io::Result<()> { + mir: &Mir<'_>) -> io::Result<()> { // Header rows const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"]; const HDR_FMT: &str = "bgcolor=\"grey\""; @@ -150,7 +148,7 @@ where MWF: MirWithFlowState<'tcx>, n: &Node, w: &mut W, block: BasicBlock, - mir: &Mir) + mir: &Mir<'_>) -> io::Result<()> { let i = n.index(); @@ -200,7 +198,7 @@ where MWF: MirWithFlowState<'tcx>, n: &Node, w: &mut W, block: BasicBlock, - mir: &Mir) + mir: &Mir<'_>) -> io::Result<()> { let i = n.index(); @@ -241,7 +239,7 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P> { type Node = Node; type Edge = Edge; - fn nodes(&self) -> dot::Nodes { + fn nodes(&self) -> dot::Nodes<'_, Node> { self.mbcx.mir() .basic_blocks() .indices() @@ -249,7 +247,7 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P> .into() } - fn edges(&self) -> dot::Edges { + fn edges(&self) -> dot::Edges<'_, Edge> { let mir = self.mbcx.mir(); mir.basic_blocks() diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 9d03e35a35069..51d628ce6c5c2 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -2,7 +2,7 @@ pub use super::*; use rustc::mir::*; use rustc::mir::visit::Visitor; -use dataflow::BitDenotation; +use crate::dataflow::BitDenotation; /// This calculates if any part of a MIR local could have previously been borrowed. /// This means that once a local has been borrowed, its bit will be set @@ -38,7 +38,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> { } fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, Local>, loc: Location) { let stmt = &self.mir[loc.block].statements[loc.statement_index]; @@ -54,7 +54,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> { } fn terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, Local>, loc: Location) { BorrowedLocalsVisitor { sets, diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 72218e29cfd20..beb0b3187082b 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -1,5 +1,5 @@ -use borrow_check::borrow_set::{BorrowSet, BorrowData}; -use borrow_check::place_ext::PlaceExt; +use crate::borrow_check::borrow_set::{BorrowSet, BorrowData}; +use crate::borrow_check::place_ext::PlaceExt; use rustc::mir::{self, Location, Place, Mir}; use rustc::ty::TyCtxt; @@ -9,11 +9,11 @@ use rustc_data_structures::bit_set::{BitSet, BitSetOperator}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use dataflow::{BitDenotation, BlockSets, InitialFlow}; -pub use dataflow::indexes::BorrowIndex; -use borrow_check::nll::region_infer::RegionInferenceContext; -use borrow_check::nll::ToRegionVid; -use borrow_check::places_conflict; +use crate::dataflow::{BitDenotation, BlockSets, InitialFlow}; +pub use crate::dataflow::indexes::BorrowIndex; +use crate::borrow_check::nll::region_infer::RegionInferenceContext; +use crate::borrow_check::nll::ToRegionVid; +use crate::borrow_check::places_conflict; use std::rc::Rc; @@ -163,7 +163,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { /// Add all borrows to the kill set, if those borrows are out of scope at `location`. /// That means they went out of a nonlexical scope fn kill_loans_out_of_scope_at_location(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, BorrowIndex>, location: Location) { // NOTE: The state associated with a given `location` // reflects the dataflow on entry to the statement. @@ -184,7 +184,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { /// Kill any borrows that conflict with `place`. fn kill_borrows_on_place( &self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, BorrowIndex>, place: &Place<'tcx> ) { debug!("kill_borrows_on_place: place={:?}", place); @@ -243,13 +243,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> { } fn before_statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, BorrowIndex>, location: Location) { debug!("Borrows::before_statement_effect sets: {:?} location: {:?}", sets, location); self.kill_loans_out_of_scope_at_location(sets, location); } - fn statement_effect(&self, sets: &mut BlockSets, location: Location) { + fn statement_effect(&self, sets: &mut BlockSets<'_, BorrowIndex>, location: Location) { debug!("Borrows::statement_effect: sets={:?} location={:?}", sets, location); let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| { @@ -307,13 +307,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> { } fn before_terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, BorrowIndex>, location: Location) { debug!("Borrows::before_terminator_effect sets: {:?} location: {:?}", sets, location); self.kill_loans_out_of_scope_at_location(sets, location); } - fn terminator_effect(&self, _: &mut BlockSets, _: Location) {} + fn terminator_effect(&self, _: &mut BlockSets<'_, BorrowIndex>, _: Location) {} fn propagate_call_return( &self, diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index 1ccda3a12e433..c8965b9f7f4c7 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -9,7 +9,7 @@ use rustc_data_structures::indexed_vec::Idx; use super::MoveDataParamEnv; -use util::elaborate_drops::DropFlagState; +use crate::util::elaborate_drops::DropFlagState; use super::move_paths::{HasMoveData, MoveData, MovePathIndex, InitIndex}; use super::move_paths::{LookupResult, InitKind}; @@ -251,7 +251,7 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tcx> impl<'a, 'gcx, 'tcx> MaybeInitializedPlaces<'a, 'gcx, 'tcx> { - fn update_bits(sets: &mut BlockSets, path: MovePathIndex, + fn update_bits(sets: &mut BlockSets<'_, MovePathIndex>, path: MovePathIndex, state: DropFlagState) { match state { @@ -262,7 +262,7 @@ impl<'a, 'gcx, 'tcx> MaybeInitializedPlaces<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'tcx> MaybeUninitializedPlaces<'a, 'gcx, 'tcx> { - fn update_bits(sets: &mut BlockSets, path: MovePathIndex, + fn update_bits(sets: &mut BlockSets<'_, MovePathIndex>, path: MovePathIndex, state: DropFlagState) { match state { @@ -273,7 +273,7 @@ impl<'a, 'gcx, 'tcx> MaybeUninitializedPlaces<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'tcx> DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> { - fn update_bits(sets: &mut BlockSets, path: MovePathIndex, + fn update_bits(sets: &mut BlockSets<'_, MovePathIndex>, path: MovePathIndex, state: DropFlagState) { match state { @@ -300,7 +300,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 't } fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, MovePathIndex>, location: Location) { drop_flag_effects_for_location( @@ -311,7 +311,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 't } fn terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, MovePathIndex>, location: Location) { drop_flag_effects_for_location( @@ -358,7 +358,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx, } fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, MovePathIndex>, location: Location) { drop_flag_effects_for_location( @@ -369,7 +369,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx, } fn terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, MovePathIndex>, location: Location) { drop_flag_effects_for_location( @@ -414,7 +414,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gc } fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, MovePathIndex>, location: Location) { drop_flag_effects_for_location( @@ -425,7 +425,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gc } fn terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, MovePathIndex>, location: Location) { drop_flag_effects_for_location( @@ -464,7 +464,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc } fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, InitIndex>, location: Location) { let (_, mir, move_data) = (self.tcx, self.mir, self.move_data()); let stmt = &mir[location.block].statements[location.statement_index]; @@ -511,7 +511,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc } fn terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, InitIndex>, location: Location) { let (mir, move_data) = (self.mir, self.move_data()); diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index 9c17076e6fde0..6b8eb6f17f6c1 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -1,7 +1,7 @@ pub use super::*; use rustc::mir::*; -use dataflow::BitDenotation; +use crate::dataflow::BitDenotation; #[derive(Copy, Clone)] pub struct MaybeStorageLive<'a, 'tcx: 'a> { @@ -31,7 +31,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { } fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, Local>, loc: Location) { let stmt = &self.mir[loc.block].statements[loc.statement_index]; @@ -43,7 +43,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { } fn terminator_effect(&self, - _sets: &mut BlockSets, + _sets: &mut BlockSets<'_, Local>, _loc: Location) { // Terminators have no effect } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index f09db970b7353..1853b60efd7e6 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -58,7 +58,7 @@ impl DebugFormatted { } impl fmt::Debug for DebugFormatted { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { write!(w, "{}", self.0) } } @@ -525,7 +525,7 @@ impl<'a, E:Idx> BlockSets<'a, E> { impl AllSets { pub fn bits_per_block(&self) -> usize { self.bits_per_block } - pub fn for_block(&mut self, block_idx: usize) -> BlockSets { + pub fn for_block(&mut self, block_idx: usize) -> BlockSets<'_, E> { BlockSets { on_entry: &mut self.on_entry_sets[block_idx], gen_set: &mut self.gen_sets[block_idx], @@ -616,7 +616,7 @@ pub trait BitDenotation<'tcx>: BitSetOperator { /// applied, in that order, before moving for the next /// statement. fn before_statement_effect(&self, - _sets: &mut BlockSets, + _sets: &mut BlockSets<'_, Self::Idx>, _location: Location) {} /// Mutates the block-sets (the flow sets for the given @@ -630,7 +630,7 @@ pub trait BitDenotation<'tcx>: BitSetOperator { /// `bb_data` is the sequence of statements identified by `bb` in /// the MIR. fn statement_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, Self::Idx>, location: Location); /// Similar to `terminator_effect`, except it applies @@ -645,7 +645,7 @@ pub trait BitDenotation<'tcx>: BitSetOperator { /// applied, in that order, before moving for the next /// terminator. fn before_terminator_effect(&self, - _sets: &mut BlockSets, + _sets: &mut BlockSets<'_, Self::Idx>, _location: Location) {} /// Mutates the block-sets (the flow sets for the given @@ -659,7 +659,7 @@ pub trait BitDenotation<'tcx>: BitSetOperator { /// The effects applied here cannot depend on which branch the /// terminator took. fn terminator_effect(&self, - sets: &mut BlockSets, + sets: &mut BlockSets<'_, Self::Idx>, location: Location); /// Mutates the block-sets according to the (flow-dependent) diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index d77216220ac2b..efd979a7da4fb 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -37,7 +37,7 @@ pub(crate) mod indexes { } impl fmt::Debug for $Index { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "{}{}", $debug_name, self.index()) } } @@ -62,7 +62,7 @@ pub use self::indexes::MoveOutIndex; pub use self::indexes::InitIndex; impl MoveOutIndex { - pub fn move_path_index(&self, move_data: &MoveData) -> MovePathIndex { + pub fn move_path_index(&self, move_data: &MoveData<'_>) -> MovePathIndex { move_data.moves[*self].path } } @@ -88,7 +88,10 @@ pub struct MovePath<'tcx> { } impl<'tcx> MovePath<'tcx> { - pub fn parents(&self, move_paths: &IndexVec) -> Vec { + pub fn parents( + &self, + move_paths: &IndexVec>, + ) -> Vec { let mut parents = Vec::new(); let mut curr_parent = self.parent; @@ -102,7 +105,7 @@ impl<'tcx> MovePath<'tcx> { } impl<'tcx> fmt::Debug for MovePath<'tcx> { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { write!(w, "MovePath {{")?; if let Some(parent) = self.parent { write!(w, " parent: {:?},", parent)?; @@ -118,7 +121,7 @@ impl<'tcx> fmt::Debug for MovePath<'tcx> { } impl<'tcx> fmt::Display for MovePath<'tcx> { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { write!(w, "{:?}", self.place) } } @@ -166,7 +169,7 @@ impl IndexMut for LocationMap { } impl LocationMap where T: Default + Clone { - fn new(mir: &Mir) -> Self { + fn new(mir: &Mir<'_>) -> Self { LocationMap { map: mir.basic_blocks().iter().map(|block| { vec![T::default(); block.statements.len()+1] @@ -190,7 +193,7 @@ pub struct MoveOut { } impl fmt::Debug for MoveOut { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "{:?}@{:?}", self.path, self.source) } } @@ -227,7 +230,7 @@ pub enum InitKind { } impl fmt::Debug for Init { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "{:?}@{:?} ({:?})", self.path, self.location, self.kind) } } diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 518ae978ae17a..c24cf956504da 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -1,6 +1,6 @@ -use hair::*; -use hair::cx::Cx; -use hair::cx::to_ref::ToRef; +use crate::hair::*; +use crate::hair::cx::Cx; +use crate::hair::cx::to_ref::ToRef; use rustc::middle::region; use rustc::hir; use rustc::ty; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 8d64c9e9ada89..0759b95a78ff4 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -1,9 +1,9 @@ -use hair::*; +use crate::hair::*; +use crate::hair::cx::Cx; +use crate::hair::cx::block; +use crate::hair::cx::to_ref::ToRef; +use crate::hair::util::UserAnnotatedTyHelpers; use rustc_data_structures::indexed_vec::Idx; -use hair::cx::Cx; -use hair::cx::block; -use hair::cx::to_ref::ToRef; -use hair::util::UserAnnotatedTyHelpers; use rustc::hir::def::{Def, CtorKind}; use rustc::mir::interpret::{GlobalId, ErrorHandled}; use rustc::ty::{self, AdtKind, Ty}; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index f514cac6326be..6d61801fc7162 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -4,8 +4,8 @@ //! work. //! -use hair::*; -use hair::util::UserAnnotatedTyHelpers; +use crate::hair::*; +use crate::hair::util::UserAnnotatedTyHelpers; use rustc_data_structures::indexed_vec::Idx; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; @@ -21,7 +21,7 @@ use syntax::attr; use syntax::symbol::Symbol; use rustc::hir; use rustc_data_structures::sync::Lrc; -use hair::constant::{lit_to_const, LitToConstError}; +use crate::hair::constant::{lit_to_const, LitToConstError}; #[derive(Clone)] pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { @@ -239,7 +239,7 @@ impl UserAnnotatedTyHelpers<'gcx, 'tcx> for Cx<'_, 'gcx, 'tcx> { } } -fn lint_level_for_hir_id(tcx: TyCtxt, mut id: ast::NodeId) -> ast::NodeId { +fn lint_level_for_hir_id(tcx: TyCtxt<'_, '_, '_>, mut id: ast::NodeId) -> ast::NodeId { // Right now we insert a `with_ignore` node in the dep graph here to // ignore the fact that `lint_levels` below depends on the entire crate. // For now this'll prevent false positives of recompiling too much when diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs index 1b87e4450c56e..a462c61c2acba 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir/hair/cx/to_ref.rs @@ -1,4 +1,4 @@ -use hair::*; +use crate::hair::*; use rustc::hir; use syntax::ptr::P; diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 7f5b1a761d261..5779a032acc4d 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -307,7 +307,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> { /// + _ + [_, _, ..tail] + /// ++++++++++++++++++++++++++ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "\n")?; let &Matrix(ref m) = self; @@ -442,7 +442,7 @@ impl<'tcx> Constructor<'tcx> { VariantIdx::new(0) } &ConstantValue(c) => { - ::const_eval::const_variant_index( + crate::const_eval::const_variant_index( cx.tcx, cx.param_env, c, @@ -1115,7 +1115,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, } else { debug!("is_useful - expanding wildcard"); - let used_ctors: Vec = rows.iter().flat_map(|row| { + let used_ctors: Vec> = rows.iter().flat_map(|row| { pat_constructors(cx, row[0], pcx).unwrap_or(vec![]) }).collect(); debug!("used_ctors = {:#?}", used_ctors); @@ -1302,7 +1302,7 @@ fn is_useful_specialized<'p, 'a: 'p, 'tcx: 'a>( /// Returns None in case of a catch-all, which can't be specialized. fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>, pat: &Pattern<'tcx>, - pcx: PatternContext) + pcx: PatternContext<'_>) -> Option>> { match *pat.kind { diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index a47d64319bdc5..978051aab591b 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { return; } - let matrix: Matrix = inlined_arms + let matrix: Matrix<'_, '_> = inlined_arms .iter() .filter(|&&(_, guard)| guard.is_none()) .flat_map(|arm| &arm.0) @@ -248,7 +248,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { self.tables); let pattern = patcx.lower_pattern(pat); let pattern_ty = pattern.ty; - let pats: Matrix = vec![smallvec![ + let pats: Matrix<'_, '_> = vec![smallvec![ expand_pattern(cx, pattern) ]].into_iter().collect(); @@ -283,7 +283,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } } -fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor, pat: &Pat) { +fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) { pat.walk(|p| { if let PatKind::Binding(_, _, _, ident, None) = p.node { if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { @@ -462,7 +462,7 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, } // Legality of move bindings checking -fn check_legality_of_move_bindings(cx: &MatchVisitor, +fn check_legality_of_move_bindings(cx: &MatchVisitor<'_, '_>, has_guard: bool, pats: &[P]) { let mut by_ref_span = None; @@ -541,7 +541,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, /// assign. /// /// FIXME: this should be done by borrowck. -fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Guard) { +fn check_for_mutation_in_guard(cx: &MatchVisitor<'_, '_>, guard: &hir::Guard) { let mut checker = MutationChecker { cx, }; @@ -561,13 +561,13 @@ struct MutationChecker<'a, 'tcx: 'a> { } impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { - fn matched_pat(&mut self, _: &Pat, _: &cmt_, _: euv::MatchMode) {} - fn consume(&mut self, _: ast::NodeId, _: Span, _: &cmt_, _: ConsumeMode) {} - fn consume_pat(&mut self, _: &Pat, _: &cmt_, _: ConsumeMode) {} + fn matched_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: euv::MatchMode) {} + fn consume(&mut self, _: ast::NodeId, _: Span, _: &cmt_<'_>, _: ConsumeMode) {} + fn consume_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: ConsumeMode) {} fn borrow(&mut self, _: ast::NodeId, span: Span, - _: &cmt_, + _: &cmt_<'_>, _: ty::Region<'tcx>, kind:ty:: BorrowKind, _: LoanCause) { @@ -588,7 +588,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { } } fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {} - fn mutate(&mut self, _: ast::NodeId, span: Span, _: &cmt_, mode: MutateMode) { + fn mutate(&mut self, _: ast::NodeId, span: Span, _: &cmt_<'_>, mode: MutateMode) { match mode { MutateMode::JustWrite | MutateMode::WriteAndRead => { struct_span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard") @@ -603,7 +603,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { /// Forbids bindings in `@` patterns. This is necessary for memory safety, /// because of the way rvalues are handled in the borrow check. (See issue /// #14587.) -fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor, pat: &Pat) { +fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { AtBindingPatternVisitor { cx: cx, bindings_allowed: true }.visit_pat(pat); } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 6b7e14161186d..8d32becd439e0 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -6,10 +6,10 @@ mod check_match; pub use self::check_match::check_crate; pub(crate) use self::check_match::check_match; -use const_eval::{const_field, const_variant_index}; +use crate::const_eval::{const_field, const_variant_index}; -use hair::util::UserAnnotatedTyHelpers; -use hair::constant::*; +use crate::hair::util::UserAnnotatedTyHelpers; +use crate::hair::constant::*; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{UserTypeProjection}; @@ -176,7 +176,7 @@ pub struct PatternRange<'tcx> { } impl<'tcx> fmt::Display for Pattern<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self.kind { PatternKind::Wild => write!(f, "_"), PatternKind::AscribeUserType { ref subpattern, .. } => diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 1b976d822ebff..c87338fb0ce94 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -322,7 +322,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc ) -> EvalResult<'tcx, TyLayout<'tcx>> { match frame.locals[local].layout.get() { None => { - let layout = ::interpret::operand::from_known_layout(layout, || { + let layout = crate::interpret::operand::from_known_layout(layout, || { let local_ty = frame.mir.local_decls[local].ty; let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); self.layout_of(local_ty) diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 5fae461bdc203..ee295116ba962 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -25,7 +25,7 @@ use syntax::source_map::Span; use super::eval_context::{LocalState, StackPopCleanup}; use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef, LocalValue}; -use const_eval::CompileTimeInterpreter; +use crate::const_eval::CompileTimeInterpreter; #[derive(Default)] pub(crate) struct InfiniteLoopDetector<'a, 'mir, 'tcx: 'a + 'mir> { @@ -200,7 +200,7 @@ impl_snapshot_for!(enum ScalarMaybeUndef { Undef, }); -impl_stable_hash_for!(struct ::interpret::MemPlace { +impl_stable_hash_for!(struct crate::interpret::MemPlace { ptr, align, meta, @@ -211,7 +211,7 @@ impl_snapshot_for!(struct MemPlace { align -> *align, // just copy alignment verbatim }); -impl_stable_hash_for!(enum ::interpret::Place { +impl_stable_hash_for!(enum crate::interpret::Place { Ptr(mem_place), Local { frame, local }, }); @@ -232,7 +232,7 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for Place } } -impl_stable_hash_for!(enum ::interpret::Immediate { +impl_stable_hash_for!(enum crate::interpret::Immediate { Scalar(x), ScalarPair(x, y), }); @@ -241,7 +241,7 @@ impl_snapshot_for!(enum Immediate { ScalarPair(s, t), }); -impl_stable_hash_for!(enum ::interpret::Operand { +impl_stable_hash_for!(enum crate::interpret::Operand { Immediate(x), Indirect(x), }); @@ -250,7 +250,7 @@ impl_snapshot_for!(enum Operand { Indirect(m), }); -impl_stable_hash_for!(enum ::interpret::LocalValue { +impl_stable_hash_for!(enum crate::interpret::LocalValue { Dead, Live(x), }); @@ -298,7 +298,7 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation } } -impl_stable_hash_for!(enum ::interpret::eval_context::StackPopCleanup { +impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup { Goto(block), None { cleanup }, }); diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 7e823524c180c..be50daa17092f 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -112,7 +112,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let ty = place.layout.ty; trace!("TerminatorKind::drop: {:?}, type {}", location, ty); - let instance = ::monomorphize::resolve_drop_in_place(*self.tcx, ty); + let instance = crate::monomorphize::resolve_drop_in_place(*self.tcx, ty); self.drop_in_place( place, instance, @@ -326,7 +326,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // last incoming argument. These two iterators do not have the same type, // so to keep the code paths uniform we accept an allocation // (for RustCall ABI only). - let caller_args : Cow<[OpTy<'tcx, M::PointerTag>]> = + let caller_args : Cow<'_, [OpTy<'tcx, M::PointerTag>]> = if caller_abi == Abi::RustCall && !args.is_empty() { // Untuple let (&untuple_arg, args) = args.split_last().unwrap(); @@ -335,7 +335,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> .chain((0..untuple_arg.layout.fields.count()).into_iter() .map(|i| self.operand_field(untuple_arg, i as u64)) ) - .collect::>>>()?) + .collect::>>>()?) } else { // Plain arg passing Cow::from(args) diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 642bbc114f562..63253bae9078b 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -52,7 +52,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> ).with_default_tag(); let tcx = &*self.tcx; - let drop = ::monomorphize::resolve_drop_in_place(*tcx, ty); + let drop = crate::monomorphize::resolve_drop_in_place(*tcx, ty); let drop = self.memory.create_fn_alloc(drop).with_default_tag(); // no need to do any alignment checks on the memory accesses below, because we know the // allocation is correctly aligned as we created it above. Also we're only offsetting by diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index 4773f5627d716..930bcb44374aa 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -26,7 +26,7 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>>; /// Create this from an `MPlaceTy`. - fn from_mem_place(MPlaceTy<'tcx, M::PointerTag>) -> Self; + fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self; /// Project to the given enum variant. fn project_downcast( diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index ccfc15bac042c..72a13c791cec0 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -4,7 +4,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! */ -#![feature(nll)] #![feature(in_band_lifetimes)] #![feature(slice_patterns)] #![feature(slice_sort_by_cached_key)] @@ -29,28 +28,19 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![recursion_limit="256"] -extern crate arena; +#![deny(rust_2018_idioms)] +#![allow(explicit_outlives_requirements)] #[macro_use] extern crate bitflags; #[macro_use] extern crate log; -extern crate either; -extern crate graphviz as dot; -extern crate polonius_engine; #[macro_use] extern crate rustc; #[macro_use] extern crate rustc_data_structures; -extern crate serialize as rustc_serialize; -extern crate rustc_errors; +#[allow(unused_extern_crates)] +extern crate serialize as rustc_serialize; // used by deriving #[macro_use] extern crate syntax; -extern crate syntax_pos; -extern crate rustc_target; -extern crate log_settings; -extern crate rustc_apfloat; -extern crate byteorder; -extern crate core; -extern crate smallvec; // Once we can use edition 2018 in the compiler, // replace this with real try blocks. @@ -77,7 +67,7 @@ pub mod const_eval; pub use hair::pattern::check_crate as matchck_crate; use rustc::ty::query::Providers; -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { borrow_check::provide(providers); shim::provide(providers); transform::provide(providers); diff --git a/src/librustc_mir/lints.rs b/src/librustc_mir/lints.rs index 8ded31d89daea..6b6e8fcdc82cf 100644 --- a/src/librustc_mir/lints.rs +++ b/src/librustc_mir/lints.rs @@ -18,7 +18,7 @@ pub fn check(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>, - fn_kind: FnKind, + fn_kind: FnKind<'_>, mir: &Mir<'tcx>, def_id: DefId) { if let FnKind::Closure(_) = fn_kind { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index e713ab17c3af5..7f3c24daf606d 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -189,11 +189,11 @@ use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::MonoItem; use rustc::mir::interpret::{Scalar, GlobalId, AllocKind, ErrorHandled}; -use monomorphize::{self, Instance}; +use crate::monomorphize::{self, Instance}; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; -use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; +use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 431cc0d52b4c8..d3381f463f49e 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -1,4 +1,4 @@ -use monomorphize::Instance; +use crate::monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::session::config::OptLevel; diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 569e4c828f601..d4c7ebefe1753 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -111,9 +111,9 @@ use rustc::util::common::time; use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet}; use rustc::mir::mono::MonoItem; -use monomorphize::collector::InliningMap; -use monomorphize::collector::{self, MonoItemCollectionMode}; -use monomorphize::item::{MonoItemExt, InstantiationMode}; +use crate::monomorphize::collector::InliningMap; +use crate::monomorphize::collector::{self, MonoItemCollectionMode}; +use crate::monomorphize::item::{MonoItemExt, InstantiationMode}; pub use rustc::mir::mono::CodegenUnit; @@ -146,7 +146,7 @@ pub trait CodegenUnitExt<'tcx> { WorkProductId::from_cgu_name(&self.name().as_str()) } - fn work_product(&self, tcx: TyCtxt) -> WorkProduct { + fn work_product(&self, tcx: TyCtxt<'_, '_, '_>) -> WorkProduct { let work_product_id = self.work_product_id(); tcx.dep_graph .previous_work_product(&work_product_id) @@ -213,7 +213,7 @@ impl<'tcx> CodegenUnitExt<'tcx> for CodegenUnit<'tcx> { } // Anything we can't find a proper codegen unit for goes into this. -fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder) -> InternedString { +fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>) -> InternedString { name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu")) } @@ -536,7 +536,7 @@ fn mono_item_visibility( } } -fn default_visibility(tcx: TyCtxt, id: DefId, is_generic: bool) -> Visibility { +fn default_visibility(tcx: TyCtxt<'_, '_, '_>, id: DefId, is_generic: bool) -> Visibility { if !tcx.sess.target.target.options.default_hidden_visibility { return Visibility::Default } @@ -795,8 +795,8 @@ fn characteristic_def_id_of_mono_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, type CguNameCache = FxHashMap<(DefId, bool), InternedString>; -fn compute_codegen_unit_name(tcx: TyCtxt, - name_builder: &mut CodegenUnitNameBuilder, +fn compute_codegen_unit_name(tcx: TyCtxt<'_, '_, '_>, + name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>, def_id: DefId, volatile: bool, cache: &mut CguNameCache) @@ -855,7 +855,7 @@ fn compute_codegen_unit_name(tcx: TyCtxt, }).clone() } -fn numbered_codegen_unit_name(name_builder: &mut CodegenUnitNameBuilder, +fn numbered_codegen_unit_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>, index: usize) -> InternedString { name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index)) @@ -929,7 +929,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( tcx.sess.abort_if_errors(); - ::monomorphize::assert_symbols_are_distinct(tcx, items.iter()); + crate::monomorphize::assert_symbols_are_distinct(tcx, items.iter()); let strategy = if tcx.sess.opts.incremental.is_some() { PartitioningStrategy::PerModule @@ -1013,7 +1013,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( (Arc::new(mono_items), Arc::new(codegen_units)) } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { providers.collect_and_partition_mono_items = collect_and_partition_mono_items; diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 751815eab287b..942e7a1f1bbbd 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -16,12 +16,12 @@ use syntax_pos::Span; use std::fmt; use std::iter; -use transform::{add_moves_for_packed_drops, add_call_guards}; -use transform::{remove_noop_landing_pads, no_landing_pads, simplify}; -use util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode}; -use util::patch::MirPatch; +use crate::transform::{add_moves_for_packed_drops, add_call_guards}; +use crate::transform::{remove_noop_landing_pads, no_landing_pads, simplify}; +use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode}; +use crate::util::patch::MirPatch; -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { providers.mir_shims = make_shim; } @@ -138,7 +138,7 @@ enum CallKind { Direct(DefId), } -fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl { +fn temp_decl(mutability: Mutability, ty: Ty<'_>, span: Span) -> LocalDecl<'_> { let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span }; LocalDecl { mutability, @@ -259,7 +259,7 @@ pub struct DropShimElaborator<'a, 'tcx: 'a> { } impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> { - fn fmt(&self, _f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { Ok(()) } } diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index 3ea1c8e82ff2b..dab96faaa2a5e 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -1,7 +1,7 @@ use rustc::ty::TyCtxt; use rustc::mir::*; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; #[derive(PartialEq)] pub enum AddCallGuards { @@ -40,7 +40,7 @@ impl MirPass for AddCallGuards { } impl AddCallGuards { - pub fn add_call_guards(&self, mir: &mut Mir) { + pub fn add_call_guards(&self, mir: &mut Mir<'_>) { let pred_count: IndexVec<_, _> = mir.predecessors().iter().map(|ps| ps.len()).collect(); diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index 8ec6902cf15fd..1492f0c50a31a 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -2,9 +2,9 @@ use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::ty::TyCtxt; -use transform::{MirPass, MirSource}; -use util::patch::MirPatch; -use util; +use crate::transform::{MirPass, MirSource}; +use crate::util::patch::MirPatch; +use crate::util; // This pass moves values being dropped that are within a packed // struct to a separate local before dropping them, to ensure that diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index 3d5897bca9f52..7bfcd318afe2d 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -6,7 +6,7 @@ use rustc::ty::{self, Ty, TyCtxt}; use rustc::mir::*; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct AddRetag; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index ab8da2f352c1c..b2e1afc519ec5 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -17,7 +17,7 @@ use syntax::symbol::Symbol; use std::ops::Bound; -use util; +use crate::util; pub struct UnsafetyChecker<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, @@ -458,7 +458,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } } -pub(crate) fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers<'_>) { *providers = Providers { unsafety_check_result, unsafe_derive_on_repr_packed, @@ -575,7 +575,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D } /// Return the NodeId for an enclosing scope that is also `unsafe` -fn is_enclosed(tcx: TyCtxt, +fn is_enclosed(tcx: TyCtxt<'_, '_, '_>, used_unsafe: &FxHashSet, id: ast::NodeId) -> Option<(String, ast::NodeId)> { let parent_id = tcx.hir().get_parent_node(id); @@ -598,7 +598,9 @@ fn is_enclosed(tcx: TyCtxt, } } -fn report_unused_unsafe(tcx: TyCtxt, used_unsafe: &FxHashSet, id: ast::NodeId) { +fn report_unused_unsafe(tcx: TyCtxt<'_, '_, '_>, + used_unsafe: &FxHashSet, + id: ast::NodeId) { let span = tcx.sess.source_map().def_span(tcx.hir().span(id)); let msg = "unnecessary `unsafe` block"; let mut db = tcx.struct_span_lint_node(UNUSED_UNSAFE, id, span, msg); diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index e6df6b7fd2724..240ef7c8ba42a 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -26,7 +26,7 @@ use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place}; use rustc::mir::{Statement, StatementKind}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct CleanAscribeUserType; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index dc556a15cd855..dd1f37a591888 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -18,12 +18,12 @@ use rustc::ty::layout::{ HasTyCtxt, TargetDataLayout, HasDataLayout, }; -use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind}; -use const_eval::{ +use crate::interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind}; +use crate::const_eval::{ CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx, lazy_const_to_op, }; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct ConstProp; @@ -486,7 +486,7 @@ struct CanConstProp { impl CanConstProp { /// returns true if `local` can be propagated - fn check(mir: &Mir) -> IndexVec { + fn check(mir: &Mir<'_>) -> IndexVec { let mut cpv = CanConstProp { can_const_prop: IndexVec::from_elem(true, &mir.local_decls), found_assignment: IndexVec::from_elem(false, &mir.local_decls), diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 55e14077c3ed0..4789c35740eb3 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -22,8 +22,8 @@ use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; -use transform::{MirPass, MirSource}; -use util::def_use::DefUseAnalysis; +use crate::transform::{MirPass, MirSource}; +use crate::util::def_use::DefUseAnalysis; pub struct CopyPropagation; @@ -173,7 +173,7 @@ enum Action<'tcx> { } impl<'tcx> Action<'tcx> { - fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_place: &Place<'tcx>) + fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis<'_>, src_place: &Place<'tcx>) -> Option> { // The source must be a local. let src_local = if let Place::Local(local) = *src_place { diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index a2fe9def8eeba..669384e31dac3 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -1,7 +1,7 @@ use rustc::ty::TyCtxt; use rustc::mir::*; use rustc_data_structures::indexed_vec::Idx; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct Deaggregator; diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 8fabb2d11fc46..d7f697a320049 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -8,8 +8,8 @@ use std::io; use rustc::mir::Mir; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::ty::TyCtxt; -use transform::{MirPass, MirSource}; -use util as mir_util; +use crate::transform::{MirPass, MirSource}; +use crate::util as mir_util; pub struct Marker(pub &'static str); @@ -31,7 +31,7 @@ pub struct Disambiguator { } impl fmt::Display for Disambiguator { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let title = if self.is_after { "after" } else { "before" }; write!(formatter, "{}", title) } diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 06e16de8b43bc..4aaa0be7964a4 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -1,10 +1,14 @@ -use dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult}; -use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; -use dataflow::{DataflowResults}; -use dataflow::{on_all_children_bits, on_all_drop_children_bits}; -use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits}; -use dataflow::MoveDataParamEnv; -use dataflow::{self, do_dataflow, DebugFormatted}; +use crate::dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult}; +use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; +use crate::dataflow::{DataflowResults}; +use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits}; +use crate::dataflow::{drop_flag_effects_for_location, on_lookup_result_bits}; +use crate::dataflow::MoveDataParamEnv; +use crate::dataflow::{self, do_dataflow, DebugFormatted}; +use crate::transform::{MirPass, MirSource}; +use crate::util::patch::MirPatch; +use crate::util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop}; +use crate::util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode}; use rustc::ty::{self, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc::mir::*; @@ -13,10 +17,6 @@ use rustc_data_structures::bit_set::BitSet; use std::fmt; use syntax::ast; use syntax_pos::Span; -use transform::{MirPass, MirSource}; -use util::patch::MirPatch; -use util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop}; -use util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode}; pub struct ElaborateDrops; @@ -174,7 +174,7 @@ struct Elaborator<'a, 'b: 'a, 'tcx: 'b> { } impl<'a, 'b, 'tcx> fmt::Debug for Elaborator<'a, 'b, 'tcx> { - fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } } diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index b464b7d65e466..b555a2aa83ee3 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -8,7 +8,7 @@ use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use rustc::mir::*; use rustc::mir::visit::{MutVisitor, TyContext}; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; struct EraseRegionsVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index f5cc6a43e28b9..9897f9833ca62 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -56,19 +56,19 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor}; use rustc::ty::{self, TyCtxt, AdtDef, Ty}; use rustc::ty::layout::VariantIdx; use rustc::ty::subst::Substs; -use util::dump_mir; -use util::liveness::{self, IdentityMap}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::bit_set::BitSet; use std::borrow::Cow; use std::iter::once; use std::mem; -use transform::{MirPass, MirSource}; -use transform::simplify; -use transform::no_landing_pads::no_landing_pads; -use dataflow::{do_dataflow, DebugFormatted, state_for_location}; -use dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals}; +use crate::transform::{MirPass, MirSource}; +use crate::transform::simplify; +use crate::transform::no_landing_pads::no_landing_pads; +use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location}; +use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals}; +use crate::util::dump_mir; +use crate::util::liveness::{self, IdentityMap}; pub struct StateTransform; @@ -581,9 +581,9 @@ fn insert_switch<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, mir: &mut Mir<'tcx>) { - use util::elaborate_drops::{elaborate_drop, Unwind}; - use util::patch::MirPatch; - use shim::DropShimElaborator; + use crate::util::elaborate_drops::{elaborate_drop, Unwind}; + use crate::util::patch::MirPatch; + use crate::shim::DropShimElaborator; // Note that `elaborate_drops` only drops the upvars of a generator, and // this is ok because `open_drop` can only be reached within that own diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 9f0907adc9892..4fddf6f8e09c2 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -13,10 +13,10 @@ use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; use std::iter; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; use super::simplify::{remove_dead_blocks, CfgSimplifier}; -use syntax::{attr}; +use syntax::attr; use rustc_target::spec::abi::Abi; const DEFAULT_THRESHOLD: usize = 50; @@ -426,7 +426,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // Place could result in two different locations if `f` // writes to `i`. To prevent this we need to create a temporary // borrow of the place and pass the destination as `*temp` instead. - fn dest_needs_borrow(place: &Place) -> bool { + fn dest_needs_borrow(place: &Place<'_>) -> bool { match *place { Place::Projection(ref p) => { match p.elem { diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 2b5e761d1d055..21772e1f1cd5b 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -6,7 +6,7 @@ use rustc::ty::{TyCtxt, TyKind}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::Idx; use std::mem; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct InstCombine; diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index d14e0f078e6c6..aa248ba7c53df 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -5,8 +5,7 @@ use rustc::middle::lang_items::LangItem; use rustc::mir::*; use rustc::ty::{List, Ty, TyCtxt, TyKind}; use rustc_data_structures::indexed_vec::{Idx}; -use transform::{MirPass, MirSource}; -use syntax; +use crate::transform::{MirPass, MirSource}; pub struct Lower128Bit; @@ -182,7 +181,7 @@ impl RhsKind { } } -fn sign_of_128bit(ty: Ty) -> Option { +fn sign_of_128bit(ty: Ty<'_>) -> Option { match ty.sty { TyKind::Int(syntax::ast::IntTy::I128) => Some(true), TyKind::Uint(syntax::ast::UintTy::U128) => Some(false), diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index a4f011b2e2ec9..cc37a8381f234 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,5 +1,5 @@ -use borrow_check::nll::type_check; -use build; +use crate::borrow_check::nll::type_check; +use crate::build; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::mir::{Mir, MirPhase, Promoted}; use rustc::ty::TyCtxt; @@ -38,7 +38,7 @@ pub mod inline; pub mod lower_128bit; pub mod uniform_array_move_out; -pub(crate) fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers<'_>) { self::qualify_consts::provide(providers); self::check_unsafety::provide(providers); *providers = Providers { diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index 2d13b066270a2..15b59d36d363c 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -4,7 +4,7 @@ use rustc::ty::TyCtxt; use rustc::mir::*; use rustc::mir::visit::MutVisitor; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct NoLandingPads; diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 1602fc35a2c95..d1dc5cfec994d 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -130,7 +130,8 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> { } } -pub fn collect_temps(mir: &Mir, rpo: &mut ReversePostorder) -> IndexVec { +pub fn collect_temps(mir: &Mir<'_>, + rpo: &mut ReversePostorder<'_, '_>) -> IndexVec { let mut collector = TempCollector { temps: IndexVec::from_elem(TempState::Undefined, &mir.local_decls), span: mir.span, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 7d1943e21b90d..c786e9438af12 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -27,7 +27,7 @@ use syntax_pos::{Span, DUMMY_SP}; use std::fmt; use std::usize; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; use super::promote_consts::{self, Candidate, TempState}; bitflags! { @@ -84,7 +84,7 @@ enum Mode { } impl fmt::Display for Mode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Mode::Const => write!(f, "constant"), Mode::Static | Mode::StaticMut => write!(f, "static"), @@ -1128,7 +1128,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { mir_const_qualif, ..*providers @@ -1317,7 +1317,7 @@ impl MirPass for QualifyAndPromoteConstants { } } -fn args_required_const(tcx: TyCtxt, def_id: DefId) -> Option> { +fn args_required_const(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option> { let attrs = tcx.get_attrs(def_id); let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?; let mut ret = FxHashSet::default(); diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index c8ef2decf2606..4fcb4c10f9e6d 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -1,8 +1,8 @@ use rustc::ty::TyCtxt; use rustc::mir::*; use rustc_data_structures::bit_set::BitSet; -use transform::{MirPass, MirSource}; -use util::patch::MirPatch; +use crate::transform::{MirPass, MirSource}; +use crate::util::patch::MirPatch; /// A pass that removes no-op landing pads and replaces jumps to them with /// `None`. This is important because otherwise LLVM generates terrible @@ -34,7 +34,7 @@ impl RemoveNoopLandingPads { fn is_nop_landing_pad( &self, bb: BasicBlock, - mir: &Mir, + mir: &Mir<'_>, nop_landing_pads: &BitSet, ) -> bool { for stmt in &mir[bb].statements { @@ -86,7 +86,7 @@ impl RemoveNoopLandingPads { } } - fn remove_nop_landing_pads(&self, mir: &mut Mir) { + fn remove_nop_landing_pads(&self, mir: &mut Mir<'_>) { // make sure there's a single resume block let resume_block = { let patch = MirPatch::new(mir); diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 36a6279e50320..806c1c1cca457 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -5,18 +5,20 @@ use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; use rustc::mir::{self, Mir, Location}; use rustc_data_structures::bit_set::BitSet; -use transform::{MirPass, MirSource}; - -use dataflow::{do_dataflow, DebugFormatted}; -use dataflow::MoveDataParamEnv; -use dataflow::BitDenotation; -use dataflow::DataflowResults; -use dataflow::{DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces}; -use dataflow::move_paths::{MovePathIndex, LookupResult}; -use dataflow::move_paths::{HasMoveData, MoveData}; -use dataflow; - -use dataflow::has_rustc_mir_with; +use crate::transform::{MirPass, MirSource}; + +use crate::dataflow::{do_dataflow, DebugFormatted}; +use crate::dataflow::MoveDataParamEnv; +use crate::dataflow::BitDenotation; +use crate::dataflow::DataflowResults; +use crate::dataflow::{ + DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces +}; +use crate::dataflow::move_paths::{MovePathIndex, LookupResult}; +use crate::dataflow::move_paths::{HasMoveData, MoveData}; +use crate::dataflow; + +use crate::dataflow::has_rustc_mir_with; pub struct SanityCheck; diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index ed2da98dd5311..90486d1566413 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -34,7 +34,7 @@ use rustc::mir::*; use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext}; use rustc::session::config::DebugInfo; use std::borrow::Cow; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; pub struct SimplifyCfg { label: String } @@ -44,7 +44,7 @@ impl SimplifyCfg { } } -pub fn simplify_cfg(mir: &mut Mir) { +pub fn simplify_cfg(mir: &mut Mir<'_>) { CfgSimplifier::new(mir).simplify(); remove_dead_blocks(mir); @@ -263,7 +263,7 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> { } } -pub fn remove_dead_blocks(mir: &mut Mir) { +pub fn remove_dead_blocks(mir: &mut Mir<'_>) { let mut seen = BitSet::new_empty(mir.basic_blocks().len()); for (bb, _) in traversal::preorder(mir) { seen.insert(bb.index()); diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index abaea70946383..0dc89bfe14709 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -2,7 +2,7 @@ use rustc::ty::{TyCtxt, ParamEnv}; use rustc::mir::*; -use transform::{MirPass, MirSource}; +use crate::transform::{MirPass, MirSource}; use std::borrow::Cow; diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 5ab9669baaca0..09918436817f3 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -30,9 +30,9 @@ use rustc::ty; use rustc::ty::TyCtxt; use rustc::mir::*; use rustc::mir::visit::{Visitor, PlaceContext, NonUseContext}; -use transform::{MirPass, MirSource}; -use util::patch::MirPatch; use rustc_data_structures::indexed_vec::{IndexVec}; +use crate::transform::{MirPass, MirSource}; +use crate::util::patch::MirPatch; pub struct UniformArrayMoveOut; diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 7ad73aaa3f9a9..fd694ddbbd19f 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -12,7 +12,7 @@ pub enum Origin { } impl fmt::Display for Origin { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { // If the user passed `-Z borrowck=compare`, then include // origin info as part of the error report, // otherwise @@ -437,7 +437,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { fn cannot_move_out_of_interior_noncopy( self, move_from_span: Span, - ty: ty::Ty, + ty: ty::Ty<'_>, is_index: Option, o: Origin, ) -> DiagnosticBuilder<'cx> { @@ -464,7 +464,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { fn cannot_move_out_of_interior_of_drop( self, move_from_span: Span, - container_ty: ty::Ty, + container_ty: ty::Ty<'_>, o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index 057a7c8be88c9..3b9d7c3612a57 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -107,7 +107,7 @@ impl<'tcx> Info<'tcx> { pub fn defs_not_including_drop( &self, - ) -> iter::Filter>, fn(&&Use<'tcx>) -> bool> { + ) -> iter::Filter>, fn(&&Use<'tcx>) -> bool> { self.defs_and_uses.iter().filter(|place_use| { place_use.context.is_mutating_use() && !place_use.context.is_drop() }) diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 8b55a4424ae29..23e92b3e933d3 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -8,7 +8,7 @@ use rustc::ty::layout::VariantIdx; use rustc::ty::subst::Substs; use rustc::ty::util::IntTypeExt; use rustc_data_structures::indexed_vec::Idx; -use util::patch::MirPatch; +use crate::util::patch::MirPatch; use std::u32; diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index b68898f713021..e93b96c12161c 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -1,4 +1,3 @@ -use dot; use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::ty::TyCtxt; @@ -24,7 +23,7 @@ pub fn write_mir_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, /// Write a graphviz DOT graph of the MIR. pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, def_id: DefId, - mir: &Mir, + mir: &Mir<'_>, w: &mut W) -> io::Result<()> where W: Write { @@ -58,7 +57,7 @@ pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, /// `init` and `fini` are callbacks for emitting additional rows of /// data (using HTML enclosed with `` in the emitted text). pub fn write_node_label(block: BasicBlock, - mir: &Mir, + mir: &Mir<'_>, w: &mut W, num_cols: u32, init: INIT, @@ -100,7 +99,7 @@ pub fn write_node_label(block: BasicBlock, } /// Write a graphviz DOT node for the given basic block. -fn write_node(block: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<()> { +fn write_node(block: BasicBlock, mir: &Mir<'_>, w: &mut W) -> io::Result<()> { // Start a new node with the label to follow, in one of DOT's pseudo-HTML tables. write!(w, r#" {} [shape="none", label=<"#, node(block))?; write_node_label(block, mir, w, 1, |_| Ok(()), |_| Ok(()))?; @@ -109,7 +108,7 @@ fn write_node(block: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<( } /// Write graphviz DOT edges with labels between the given basic block and all of its successors. -fn write_edges(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<()> { +fn write_edges(source: BasicBlock, mir: &Mir<'_>, w: &mut W) -> io::Result<()> { let terminator = mir[source].terminator(); let labels = terminator.kind.fmt_successor_labels(); @@ -125,7 +124,7 @@ fn write_edges(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result /// all the variables and temporaries. fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId, - mir: &Mir, + mir: &Mir<'_>, w: &mut W) -> io::Result<()> { write!(w, " label= = BitSet; diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs index 5a1f94677a1d4..366cd71f6d4e9 100644 --- a/src/librustc_mir/util/patch.rs +++ b/src/librustc_mir/util/patch.rs @@ -170,14 +170,14 @@ impl<'tcx> MirPatch<'tcx> { } } - pub fn source_info_for_index(data: &BasicBlockData, loc: Location) -> SourceInfo { + pub fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo { match data.statements.get(loc.statement_index) { Some(stmt) => stmt.source_info, None => data.terminator().source_info } } - pub fn source_info_for_location(&self, mir: &Mir, loc: Location) -> SourceInfo { + pub fn source_info_for_location(&self, mir: &Mir<'_>, loc: Location) -> SourceInfo { let data = match loc.block.index().checked_sub(mir.basic_blocks().len()) { Some(new) => &self.new_blocks[new], None => &mir[loc.block] diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 3a15356806a97..6e1ec31c9372f 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -12,7 +12,7 @@ use std::fs; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use super::graphviz::write_mir_fn_graphviz; -use transform::MirSource; +use crate::transform::MirSource; const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements @@ -446,7 +446,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> { } } -fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String { +fn comment(tcx: TyCtxt<'_, '_, '_>, SourceInfo { span, scope }: SourceInfo) -> String { format!( "scope {} at {}", scope.index(), @@ -458,8 +458,8 @@ fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String { /// /// Returns the total number of variables printed. fn write_scope_tree( - tcx: TyCtxt, - mir: &Mir, + tcx: TyCtxt<'_, '_, '_>, + mir: &Mir<'_>, scope_tree: &FxHashMap>, w: &mut dyn Write, parent: SourceScope, @@ -529,7 +529,7 @@ fn write_scope_tree( pub fn write_mir_intro<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, src: MirSource, - mir: &Mir, + mir: &Mir<'_>, w: &mut dyn Write, ) -> io::Result<()> { write_mir_sig(tcx, src, mir, w)?; @@ -568,7 +568,12 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>( Ok(()) } -fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> io::Result<()> { +fn write_mir_sig( + tcx: TyCtxt<'_, '_, '_>, + src: MirSource, + mir: &Mir<'_>, + w: &mut dyn Write, +) -> io::Result<()> { let id = tcx.hir().as_local_node_id(src.def_id).unwrap(); let body_owner_kind = tcx.hir().body_owner_kind(id); match (body_owner_kind, src.promoted) { @@ -614,7 +619,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> i Ok(()) } -fn write_temp_decls(mir: &Mir, w: &mut dyn Write) -> io::Result<()> { +fn write_temp_decls(mir: &Mir<'_>, w: &mut dyn Write) -> io::Result<()> { // Compiler-introduced temporary types. for temp in mir.temps_iter() { writeln!( @@ -630,7 +635,7 @@ fn write_temp_decls(mir: &Mir, w: &mut dyn Write) -> io::Result<()> { Ok(()) } -fn write_user_type_annotations(mir: &Mir, w: &mut dyn Write) -> io::Result<()> { +fn write_user_type_annotations(mir: &Mir<'_>, w: &mut dyn Write) -> io::Result<()> { if !mir.user_type_annotations.is_empty() { writeln!(w, "| User Type Annotations")?; } @@ -643,7 +648,7 @@ fn write_user_type_annotations(mir: &Mir, w: &mut dyn Write) -> io::Result<()> { Ok(()) } -pub fn dump_mir_def_ids(tcx: TyCtxt, single: Option) -> Vec { +pub fn dump_mir_def_ids(tcx: TyCtxt<'_, '_, '_>, single: Option) -> Vec { if let Some(i) = single { vec![i] } else { From 0e2d96e88c660c574723dfc6cf8aab084917cb8c Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 2 Feb 2019 01:08:15 +0000 Subject: [PATCH 0727/1064] Factored out error reporting from `smart_resolve_path_fragment` fn. --- src/librustc_resolve/lib.rs | 679 ++++++++++++++++++------------------ 1 file changed, 347 insertions(+), 332 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 270f242419714..30772cd0d45a2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3124,391 +3124,405 @@ impl<'a> Resolver<'a> { ) } - fn smart_resolve_path_fragment(&mut self, - id: NodeId, - qself: Option<&QSelf>, - path: &[Segment], - span: Span, - source: PathSource<'_>, - crate_lint: CrateLint) - -> PathResolution { + /// Handles error reporting for `smart_resolve_path_fragment` function. + /// Creates base error and amends it with one short label and possibly some longer helps/notes. + fn smart_resolve_report_errors( + &mut self, + path: &[Segment], + span: Span, + source: PathSource<'_>, + def: Option, + ) -> (DiagnosticBuilder<'a>, Vec) { let ident_span = path.last().map_or(span, |ident| ident.ident.span); let ns = source.namespace(); let is_expected = &|def| source.is_expected(def); let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; - - // Base error is amended with one short label and possibly some longer helps/notes. - let report_errors = |this: &mut Self, def: Option| { - // Make the base error. - let expected = source.descr_expected(); - let path_str = Segment::names_to_string(path); - let item_str = path.last().unwrap().ident; - let code = source.error_code(def.is_some()); - let (base_msg, fallback_label, base_span) = if let Some(def) = def { - (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), - format!("not a {}", expected), - span) + + // Make the base error. + let expected = source.descr_expected(); + let path_str = Segment::names_to_string(path); + let item_str = path.last().unwrap().ident; + let code = source.error_code(def.is_some()); + let (base_msg, fallback_label, base_span) = if let Some(def) = def { + (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), + format!("not a {}", expected), + span) + } else { + let item_span = path.last().unwrap().ident.span; + let (mod_prefix, mod_str) = if path.len() == 1 { + (String::new(), "this scope".to_string()) + } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() { + (String::new(), "the crate root".to_string()) } else { - let item_span = path.last().unwrap().ident.span; - let (mod_prefix, mod_str) = if path.len() == 1 { - (String::new(), "this scope".to_string()) - } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() { - (String::new(), "the crate root".to_string()) - } else { - let mod_path = &path[..path.len() - 1]; - let mod_prefix = match this.resolve_path_without_parent_scope( - mod_path, Some(TypeNS), false, span, CrateLint::No - ) { - PathResult::Module(ModuleOrUniformRoot::Module(module)) => - module.def(), - _ => None, - }.map_or(String::new(), |def| format!("{} ", def.kind_name())); - (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) - }; - (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), - format!("not found in {}", mod_str), - item_span) + let mod_path = &path[..path.len() - 1]; + let mod_prefix = match self.resolve_path_without_parent_scope( + mod_path, Some(TypeNS), false, span, CrateLint::No + ) { + PathResult::Module(ModuleOrUniformRoot::Module(module)) => + module.def(), + _ => None, + }.map_or(String::new(), |def| format!("{} ", def.kind_name())); + (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) }; + (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), + format!("not found in {}", mod_str), + item_span) + }; - let code = DiagnosticId::Error(code.into()); - let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code); + let code = DiagnosticId::Error(code.into()); + let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code); - // Emit help message for fake-self from other languages like `this`(javascript) - if ["this", "my"].contains(&&*item_str.as_str()) - && this.self_value_is_available(path[0].ident.span, span) { - err.span_suggestion( + // Emit help message for fake-self from other languages (e.g., `this` in Javascript). + if ["this", "my"].contains(&&*item_str.as_str()) + && self.self_value_is_available(path[0].ident.span, span) { + err.span_suggestion( + span, + "did you mean", + "self".to_string(), + Applicability::MaybeIncorrect, + ); + } + + // Emit special messages for unresolved `Self` and `self`. + if is_self_type(path, ns) { + __diagnostic_used!(E0411); + err.code(DiagnosticId::Error("E0411".into())); + err.span_label(span, format!("`Self` is only available in impls, traits, \ + and type definitions")); + return (err, Vec::new()); + } + if is_self_value(path, ns) { + debug!("smart_resolve_path_fragment: E0424, source={:?}", source); + + __diagnostic_used!(E0424); + err.code(DiagnosticId::Error("E0424".into())); + err.span_label(span, match source { + PathSource::Pat => { + format!("`self` value is a keyword \ + and may not be bound to \ + variables or shadowed") + } + _ => { + format!("`self` value is a keyword \ + only available in methods \ + with `self` parameter") + } + }); + return (err, Vec::new()); + } + + // Try to lookup name in more relaxed fashion for better error reporting. + let ident = path.last().unwrap().ident; + let candidates = self.lookup_import_candidates(ident, ns, is_expected); + if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { + let enum_candidates = + self.lookup_import_candidates(ident, ns, is_enum_variant); + let mut enum_candidates = enum_candidates.iter() + .map(|suggestion| { + import_candidate_to_enum_paths(&suggestion) + }).collect::>(); + enum_candidates.sort(); + + if !enum_candidates.is_empty() { + // Contextualize for E0412 "cannot find type", but don't belabor the point + // (that it's a variant) for E0573 "expected type, found variant". + let preamble = if def.is_none() { + let others = match enum_candidates.len() { + 1 => String::new(), + 2 => " and 1 other".to_owned(), + n => format!(" and {} others", n) + }; + format!("there is an enum variant `{}`{}; ", + enum_candidates[0].0, others) + } else { + String::new() + }; + let msg = format!("{}try using the variant's enum", preamble); + + err.span_suggestions( span, - "did you mean", - "self".to_string(), - Applicability::MaybeIncorrect, + &msg, + enum_candidates.into_iter() + .map(|(_variant_path, enum_ty_path)| enum_ty_path) + // Variants re-exported in prelude doesn't mean `prelude::v1` is the + // type name! + // FIXME: is there a more principled way to do this that + // would work for other re-exports? + .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1") + // Also write `Option` rather than `std::prelude::v1::Option`. + .map(|enum_ty_path| { + // FIXME #56861: DRYer prelude filtering. + enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned() + }), + Applicability::MachineApplicable, ); } - - // Emit special messages for unresolved `Self` and `self`. - if is_self_type(path, ns) { - __diagnostic_used!(E0411); - err.code(DiagnosticId::Error("E0411".into())); - err.span_label(span, format!("`Self` is only available in impls, traits, \ - and type definitions")); - return (err, Vec::new()); - } - if is_self_value(path, ns) { - debug!("smart_resolve_path_fragment E0424 source:{:?}", source); - - __diagnostic_used!(E0424); - err.code(DiagnosticId::Error("E0424".into())); - err.span_label(span, match source { - PathSource::Pat => { - format!("`self` value is a keyword \ - and may not be bound to \ - variables or shadowed") + } + if path.len() == 1 && self.self_type_is_available(span) { + if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { + let self_is_available = self.self_value_is_available(path[0].ident.span, span); + match candidate { + AssocSuggestion::Field => { + err.span_suggestion( + span, + "try", + format!("self.{}", path_str), + Applicability::MachineApplicable, + ); + if !self_is_available { + err.span_label(span, format!("`self` value is a keyword \ + only available in \ + methods with `self` parameter")); + } } - _ => { - format!("`self` value is a keyword \ - only available in methods \ - with `self` parameter") + AssocSuggestion::MethodWithSelf if self_is_available => { + err.span_suggestion( + span, + "try", + format!("self.{}", path_str), + Applicability::MachineApplicable, + ); } - }); - return (err, Vec::new()); + AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { + err.span_suggestion( + span, + "try", + format!("Self::{}", path_str), + Applicability::MachineApplicable, + ); + } + } + return (err, candidates); } + } - // Try to lookup the name in more relaxed fashion for better error reporting. - let ident = path.last().unwrap().ident; - let candidates = this.lookup_import_candidates(ident, ns, is_expected); - if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { - let enum_candidates = - this.lookup_import_candidates(ident, ns, is_enum_variant); - let mut enum_candidates = enum_candidates.iter() - .map(|suggestion| { - import_candidate_to_enum_paths(&suggestion) - }).collect::>(); - enum_candidates.sort(); - - if !enum_candidates.is_empty() { - // contextualize for E0412 "cannot find type", but don't belabor the point - // (that it's a variant) for E0573 "expected type, found variant" - let preamble = if def.is_none() { - let others = match enum_candidates.len() { - 1 => String::new(), - 2 => " and 1 other".to_owned(), - n => format!(" and {} others", n) - }; - format!("there is an enum variant `{}`{}; ", - enum_candidates[0].0, others) - } else { - String::new() - }; - let msg = format!("{}try using the variant's enum", preamble); + let mut levenshtein_worked = false; - err.span_suggestions( + // Try Levenshtein algorithm. + let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span); + if let Some(suggestion) = suggestion { + let msg = format!( + "{} {} with a similar name exists", + suggestion.article, suggestion.kind + ); + err.span_suggestion( + ident_span, + &msg, + suggestion.candidate.to_string(), + Applicability::MaybeIncorrect, + ); + + levenshtein_worked = true; + } + + // Try context-dependent help if relaxed lookup didn't work. + if let Some(def) = def { + match (def, source) { + (Def::Macro(..), _) => { + err.span_suggestion( span, - &msg, - enum_candidates.into_iter() - .map(|(_variant_path, enum_ty_path)| enum_ty_path) - // variants reëxported in prelude doesn't mean `prelude::v1` is the - // type name! FIXME: is there a more principled way to do this that - // would work for other reëxports? - .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1") - // also say `Option` rather than `std::prelude::v1::Option` - .map(|enum_ty_path| { - // FIXME #56861: DRYer prelude filtering - enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned() - }), - Applicability::MachineApplicable, + "use `!` to invoke the macro", + format!("{}!", path_str), + Applicability::MaybeIncorrect, ); + return (err, candidates); } - } - if path.len() == 1 && this.self_type_is_available(span) { - if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) { - let self_is_available = this.self_value_is_available(path[0].ident.span, span); - match candidate { - AssocSuggestion::Field => { - err.span_suggestion( - span, - "try", - format!("self.{}", path_str), - Applicability::MachineApplicable, - ); - if !self_is_available { - err.span_label(span, format!("`self` value is a keyword \ - only available in \ - methods with `self` parameter")); - } - } - AssocSuggestion::MethodWithSelf if self_is_available => { - err.span_suggestion( - span, - "try", - format!("self.{}", path_str), - Applicability::MachineApplicable, - ); - } - AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { - err.span_suggestion( - span, - "try", - format!("Self::{}", path_str), - Applicability::MachineApplicable, - ); - } + (Def::TyAlias(..), PathSource::Trait(_)) => { + err.span_label(span, "type aliases cannot be used as traits"); + if nightly_options::is_nightly_build() { + err.note("did you mean to use a trait alias?"); } return (err, candidates); } - } - - let mut levenshtein_worked = false; - - // Try Levenshtein algorithm. - let suggestion = this.lookup_typo_candidate(path, ns, is_expected, span); - if let Some(suggestion) = suggestion { - let msg = format!( - "{} {} with a similar name exists", - suggestion.article, suggestion.kind - ); - err.span_suggestion( - ident_span, - &msg, - suggestion.candidate.to_string(), - Applicability::MaybeIncorrect, - ); - - levenshtein_worked = true; - } - - // Try context dependent help if relaxed lookup didn't work. - if let Some(def) = def { - match (def, source) { - (Def::Macro(..), _) => { + (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { + ExprKind::Field(_, ident) => { err.span_suggestion( - span, - "use `!` to invoke the macro", - format!("{}!", path_str), + parent.span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, ident), Applicability::MaybeIncorrect, ); return (err, candidates); } - (Def::TyAlias(..), PathSource::Trait(_)) => { - err.span_label(span, "type aliases cannot be used as traits"); - if nightly_options::is_nightly_build() { - err.note("did you mean to use a trait alias?"); - } + ExprKind::MethodCall(ref segment, ..) => { + let span = parent.span.with_hi(segment.ident.span.hi()); + err.span_suggestion( + span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, segment.ident), + Applicability::MaybeIncorrect, + ); return (err, candidates); } - (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { - ExprKind::Field(_, ident) => { - err.span_suggestion( - parent.span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, ident), - Applicability::MaybeIncorrect, - ); - return (err, candidates); - } - ExprKind::MethodCall(ref segment, ..) => { - let span = parent.span.with_hi(segment.ident.span.hi()); - err.span_suggestion( - span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, segment.ident), - Applicability::MaybeIncorrect, - ); - return (err, candidates); - } - _ => {} - }, - (Def::Enum(..), PathSource::TupleStruct) - | (Def::Enum(..), PathSource::Expr(..)) => { - if let Some(variants) = this.collect_enum_variants(def) { - err.note(&format!("did you mean to use one \ - of the following variants?\n{}", - variants.iter() - .map(|suggestion| path_names_to_string(suggestion)) - .map(|suggestion| format!("- `{}`", suggestion)) - .collect::>() - .join("\n"))); + _ => {} + }, + (Def::Enum(..), PathSource::TupleStruct) + | (Def::Enum(..), PathSource::Expr(..)) => { + if let Some(variants) = self.collect_enum_variants(def) { + err.note(&format!("did you mean to use one \ + of the following variants?\n{}", + variants.iter() + .map(|suggestion| path_names_to_string(suggestion)) + .map(|suggestion| format!("- `{}`", suggestion)) + .collect::>() + .join("\n"))); - } else { - err.note("did you mean to use one of the enum's variants?"); + } else { + err.note("did you mean to use one of the enum's variants?"); + } + return (err, candidates); + }, + (Def::Struct(def_id), _) if ns == ValueNS => { + if let Some((ctor_def, ctor_vis)) + = self.struct_constructors.get(&def_id).cloned() { + let accessible_ctor = self.is_accessible(ctor_vis); + if is_expected(ctor_def) && !accessible_ctor { + err.span_label(span, format!("constructor is not visible \ + here due to private fields")); } - return (err, candidates); - }, - (Def::Struct(def_id), _) if ns == ValueNS => { - if let Some((ctor_def, ctor_vis)) - = this.struct_constructors.get(&def_id).cloned() { - let accessible_ctor = this.is_accessible(ctor_vis); - if is_expected(ctor_def) && !accessible_ctor { - err.span_label(span, format!("constructor is not visible \ - here due to private fields")); - } - } else { - // HACK(estebank): find a better way to figure out that this was a - // parser issue where a struct literal is being used on an expression - // where a brace being opened means a block is being started. Look - // ahead for the next text to see if `span` is followed by a `{`. - let sm = this.session.source_map(); - let mut sp = span; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet.chars().any(|c| { !c.is_whitespace() }) { - break; - } + } else { + // HACK(estebank): find a better way to figure out that this was a + // parser issue where a struct literal is being used on an expression + // where a brace being opened means a block is being started. Look + // ahead for the next text to see if `span` is followed by a `{`. + let sm = self.session.source_map(); + let mut sp = span; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet.chars().any(|c| { !c.is_whitespace() }) { + break; } - _ => break, } + _ => break, } - let followed_by_brace = match sm.span_to_snippet(sp) { - Ok(ref snippet) if snippet == "{" => true, - _ => false, - }; - // In case this could be a struct literal that needs to be surrounded - // by parenthesis, find the appropriate span. - let mut i = 0; - let mut closing_brace = None; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet == "}" { - let sp = span.to(sp); - if let Ok(snippet) = sm.span_to_snippet(sp) { - closing_brace = Some((sp, snippet)); - } - break; + } + let followed_by_brace = match sm.span_to_snippet(sp) { + Ok(ref snippet) if snippet == "{" => true, + _ => false, + }; + // In case this could be a struct literal that needs to be surrounded + // by parenthesis, find the appropriate span. + let mut i = 0; + let mut closing_brace = None; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet == "}" { + let sp = span.to(sp); + if let Ok(snippet) = sm.span_to_snippet(sp) { + closing_brace = Some((sp, snippet)); } + break; } - _ => break, - } - i += 1; - if i > 100 { // The bigger the span the more likely we're - break; // incorrect. Bound it to 100 chars long. } + _ => break, } - match source { - PathSource::Expr(Some(parent)) => { - match parent.node { - ExprKind::MethodCall(ref path_assignment, _) => { - err.span_suggestion( - sm.start_point(parent.span) - .to(path_assignment.ident.span), - "use `::` to access an associated function", - format!("{}::{}", - path_str, - path_assignment.ident), - Applicability::MaybeIncorrect - ); - return (err, candidates); - }, - _ => { - err.span_label( - span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), - ); - return (err, candidates); - }, - } - }, - PathSource::Expr(None) if followed_by_brace == true => { - if let Some((sp, snippet)) = closing_brace { + i += 1; + // The bigger the span, the more likely we're + // incorrect. Bound it to 100 chars long. + if i > 100 { + break; + } + } + match source { + PathSource::Expr(Some(parent)) => { + match parent.node { + ExprKind::MethodCall(ref path_assignment, _) => { err.span_suggestion( - sp, - "surround the struct literal with parenthesis", - format!("({})", snippet), - Applicability::MaybeIncorrect, + sm.start_point(parent.span) + .to(path_assignment.ident.span), + "use `::` to access an associated function", + format!("{}::{}", + path_str, + path_assignment.ident), + Applicability::MaybeIncorrect ); - } else { + return (err, candidates); + }, + _ => { err.span_label( span, - format!("did you mean `({} {{ /* fields */ }})`?", + format!("did you mean `{} {{ /* fields */ }}`?", path_str), ); - } - return (err, candidates); - }, - _ => { + return (err, candidates); + }, + } + }, + PathSource::Expr(None) if followed_by_brace == true => { + if let Some((sp, snippet)) = closing_brace { + err.span_suggestion( + sp, + "surround the struct literal with parenthesis", + format!("({})", snippet), + Applicability::MaybeIncorrect, + ); + } else { err.span_label( span, - format!("did you mean `{} {{ /* fields */ }}`?", + format!("did you mean `({} {{ /* fields */ }})`?", path_str), ); - return (err, candidates); - }, - } + } + return (err, candidates); + }, + _ => { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", + path_str), + ); + return (err, candidates); + }, } - return (err, candidates); } - (Def::Union(..), _) | - (Def::Variant(..), _) | - (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); - return (err, candidates); - } - (Def::SelfTy(..), _) if ns == ValueNS => { - err.span_label(span, fallback_label); - err.note("can't use `Self` as a constructor, you must use the \ - implemented struct"); - return (err, candidates); - } - (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { - err.note("can't use a type alias as a constructor"); - return (err, candidates); - } - _ => {} + return (err, candidates); } + (Def::Union(..), _) | + (Def::Variant(..), _) | + (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); + return (err, candidates); + } + (Def::SelfTy(..), _) if ns == ValueNS => { + err.span_label(span, fallback_label); + err.note("can't use `Self` as a constructor, you must use the \ + implemented struct"); + return (err, candidates); + } + (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { + err.note("can't use a type alias as a constructor"); + return (err, candidates); + } + _ => {} } + } + + // Fallback label. + if !levenshtein_worked { + err.span_label(base_span, fallback_label); + self.type_ascription_suggestion(&mut err, base_span); + } + (err, candidates) + } + + fn smart_resolve_path_fragment(&mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &[Segment], + span: Span, + source: PathSource, + crate_lint: CrateLint) + -> PathResolution { + let ns = source.namespace(); + let is_expected = &|def| source.is_expected(def); - // Fallback label. - if !levenshtein_worked { - err.span_label(base_span, fallback_label); - this.type_ascription_suggestion(&mut err, base_span); - } - (err, candidates) - }; let report_errors = |this: &mut Self, def: Option| { - let (err, candidates) = report_errors(this, def); + let (err, candidates) = this.smart_resolve_report_errors(path, span, source, def); let def_id = this.current_module.normal_ancestor_id; let node_id = this.definitions.as_local_node_id(def_id).unwrap(); let better = def.is_some(); @@ -3579,7 +3593,8 @@ impl<'a> Resolver<'a> { debug!("self.current_type_ascription {:?}", self.current_type_ascription); if let Some(sp) = self.current_type_ascription.last() { let mut sp = *sp; - loop { // try to find the `:`, bail on first non-':'/non-whitespace + loop { + // Try to find the `:`; bail on first non-':' / non-whitespace. sp = cm.next_point(sp); if let Ok(snippet) = cm.span_to_snippet(sp.to(cm.next_point(sp))) { debug!("snippet {:?}", snippet); From 14b674ab9d1f0b71763a168bd764eb7d53154008 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 2 Feb 2019 02:18:32 +0000 Subject: [PATCH 0728/1064] Factored out context-dependent help for error reporting. --- src/librustc_resolve/lib.rs | 378 +++++++++++++++++++----------------- 1 file changed, 195 insertions(+), 183 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 30772cd0d45a2..1a5fce14fa8fd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3124,6 +3124,193 @@ impl<'a> Resolver<'a> { ) } + /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment` + /// function. + /// Returns `true` if able to provide context-dependent help. + fn smart_resolve_context_dep_help( + &mut self, + err: &mut DiagnosticBuilder<'a>, + span: Span, + source: PathSource, + def: Def, + path_str: &str, + fallback_label: &str, + ) -> bool { + let ns = source.namespace(); + let is_expected = &|def| source.is_expected(def); + + match (def, source) { + (Def::Macro(..), _) => { + err.span_suggestion( + span, + "use `!` to invoke the macro", + format!("{}!", path_str), + Applicability::MaybeIncorrect, + ); + } + (Def::TyAlias(..), PathSource::Trait(_)) => { + err.span_label(span, "type aliases cannot be used as traits"); + if nightly_options::is_nightly_build() { + err.note("did you mean to use a trait alias?"); + } + } + (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { + ExprKind::Field(_, ident) => { + err.span_suggestion( + parent.span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, ident), + Applicability::MaybeIncorrect, + ); + } + ExprKind::MethodCall(ref segment, ..) => { + let span = parent.span.with_hi(segment.ident.span.hi()); + err.span_suggestion( + span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, segment.ident), + Applicability::MaybeIncorrect, + ); + } + _ => return false, + }, + (Def::Enum(..), PathSource::TupleStruct) + | (Def::Enum(..), PathSource::Expr(..)) => { + if let Some(variants) = self.collect_enum_variants(def) { + err.note(&format!("did you mean to use one \ + of the following variants?\n{}", + variants.iter() + .map(|suggestion| path_names_to_string(suggestion)) + .map(|suggestion| format!("- `{}`", suggestion)) + .collect::>() + .join("\n"))); + } else { + err.note("did you mean to use one of the enum's variants?"); + } + }, + (Def::Struct(def_id), _) if ns == ValueNS => { + if let Some((ctor_def, ctor_vis)) + = self.struct_constructors.get(&def_id).cloned() { + let accessible_ctor = self.is_accessible(ctor_vis); + if is_expected(ctor_def) && !accessible_ctor { + err.span_label(span, format!("constructor is not visible \ + here due to private fields")); + } + } else { + // HACK(estebank): find a better way to figure out that this was a + // parser issue where a struct literal is being used on an expression + // where a brace being opened means a block is being started. Look + // ahead for the next text to see if `span` is followed by a `{`. + let sm = self.session.source_map(); + let mut sp = span; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet.chars().any(|c| { !c.is_whitespace() }) { + break; + } + } + _ => break, + } + } + let followed_by_brace = match sm.span_to_snippet(sp) { + Ok(ref snippet) if snippet == "{" => true, + _ => false, + }; + // In case this could be a struct literal that needs to be surrounded + // by parenthesis, find the appropriate span. + let mut i = 0; + let mut closing_brace = None; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet == "}" { + let sp = span.to(sp); + if let Ok(snippet) = sm.span_to_snippet(sp) { + closing_brace = Some((sp, snippet)); + } + break; + } + } + _ => break, + } + i += 1; + // The bigger the span, the more likely we're incorrect -- + // bound it to 100 chars long. + if i > 100 { + break; + } + } + match source { + PathSource::Expr(Some(parent)) => { + match parent.node { + ExprKind::MethodCall(ref path_assignment, _) => { + err.span_suggestion( + sm.start_point(parent.span) + .to(path_assignment.ident.span), + "use `::` to access an associated function", + format!("{}::{}", + path_str, + path_assignment.ident), + Applicability::MaybeIncorrect + ); + }, + _ => { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", + path_str), + ); + }, + } + }, + PathSource::Expr(None) if followed_by_brace == true => { + if let Some((sp, snippet)) = closing_brace { + err.span_suggestion( + sp, + "surround the struct literal with parenthesis", + format!("({})", snippet), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label( + span, + format!("did you mean `({} {{ /* fields */ }})`?", + path_str), + ); + } + }, + _ => { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", + path_str), + ); + }, + } + } + } + (Def::Union(..), _) | + (Def::Variant(..), _) | + (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); + } + (Def::SelfTy(..), _) if ns == ValueNS => { + err.span_label(span, fallback_label); + err.note("can't use `Self` as a constructor, you must use the \ + implemented struct"); + } + (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { + err.note("can't use a type alias as a constructor"); + } + _ => return false, + } + true + } + /// Handles error reporting for `smart_resolve_path_fragment` function. /// Creates base error and amends it with one short label and possibly some longer helps/notes. fn smart_resolve_report_errors( @@ -3137,7 +3324,7 @@ impl<'a> Resolver<'a> { let ns = source.namespace(); let is_expected = &|def| source.is_expected(def); let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; - + // Make the base error. let expected = source.descr_expected(); let path_str = Segment::names_to_string(path); @@ -3317,188 +3504,13 @@ impl<'a> Resolver<'a> { // Try context-dependent help if relaxed lookup didn't work. if let Some(def) = def { - match (def, source) { - (Def::Macro(..), _) => { - err.span_suggestion( - span, - "use `!` to invoke the macro", - format!("{}!", path_str), - Applicability::MaybeIncorrect, - ); - return (err, candidates); - } - (Def::TyAlias(..), PathSource::Trait(_)) => { - err.span_label(span, "type aliases cannot be used as traits"); - if nightly_options::is_nightly_build() { - err.note("did you mean to use a trait alias?"); - } - return (err, candidates); - } - (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { - ExprKind::Field(_, ident) => { - err.span_suggestion( - parent.span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, ident), - Applicability::MaybeIncorrect, - ); - return (err, candidates); - } - ExprKind::MethodCall(ref segment, ..) => { - let span = parent.span.with_hi(segment.ident.span.hi()); - err.span_suggestion( - span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, segment.ident), - Applicability::MaybeIncorrect, - ); - return (err, candidates); - } - _ => {} - }, - (Def::Enum(..), PathSource::TupleStruct) - | (Def::Enum(..), PathSource::Expr(..)) => { - if let Some(variants) = self.collect_enum_variants(def) { - err.note(&format!("did you mean to use one \ - of the following variants?\n{}", - variants.iter() - .map(|suggestion| path_names_to_string(suggestion)) - .map(|suggestion| format!("- `{}`", suggestion)) - .collect::>() - .join("\n"))); - - } else { - err.note("did you mean to use one of the enum's variants?"); - } - return (err, candidates); - }, - (Def::Struct(def_id), _) if ns == ValueNS => { - if let Some((ctor_def, ctor_vis)) - = self.struct_constructors.get(&def_id).cloned() { - let accessible_ctor = self.is_accessible(ctor_vis); - if is_expected(ctor_def) && !accessible_ctor { - err.span_label(span, format!("constructor is not visible \ - here due to private fields")); - } - } else { - // HACK(estebank): find a better way to figure out that this was a - // parser issue where a struct literal is being used on an expression - // where a brace being opened means a block is being started. Look - // ahead for the next text to see if `span` is followed by a `{`. - let sm = self.session.source_map(); - let mut sp = span; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet.chars().any(|c| { !c.is_whitespace() }) { - break; - } - } - _ => break, - } - } - let followed_by_brace = match sm.span_to_snippet(sp) { - Ok(ref snippet) if snippet == "{" => true, - _ => false, - }; - // In case this could be a struct literal that needs to be surrounded - // by parenthesis, find the appropriate span. - let mut i = 0; - let mut closing_brace = None; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet == "}" { - let sp = span.to(sp); - if let Ok(snippet) = sm.span_to_snippet(sp) { - closing_brace = Some((sp, snippet)); - } - break; - } - } - _ => break, - } - i += 1; - // The bigger the span, the more likely we're - // incorrect. Bound it to 100 chars long. - if i > 100 { - break; - } - } - match source { - PathSource::Expr(Some(parent)) => { - match parent.node { - ExprKind::MethodCall(ref path_assignment, _) => { - err.span_suggestion( - sm.start_point(parent.span) - .to(path_assignment.ident.span), - "use `::` to access an associated function", - format!("{}::{}", - path_str, - path_assignment.ident), - Applicability::MaybeIncorrect - ); - return (err, candidates); - }, - _ => { - err.span_label( - span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), - ); - return (err, candidates); - }, - } - }, - PathSource::Expr(None) if followed_by_brace == true => { - if let Some((sp, snippet)) = closing_brace { - err.span_suggestion( - sp, - "surround the struct literal with parenthesis", - format!("({})", snippet), - Applicability::MaybeIncorrect, - ); - } else { - err.span_label( - span, - format!("did you mean `({} {{ /* fields */ }})`?", - path_str), - ); - } - return (err, candidates); - }, - _ => { - err.span_label( - span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), - ); - return (err, candidates); - }, - } - } - return (err, candidates); - } - (Def::Union(..), _) | - (Def::Variant(..), _) | - (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); - return (err, candidates); - } - (Def::SelfTy(..), _) if ns == ValueNS => { - err.span_label(span, fallback_label); - err.note("can't use `Self` as a constructor, you must use the \ - implemented struct"); - return (err, candidates); - } - (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { - err.note("can't use a type alias as a constructor"); - return (err, candidates); - } - _ => {} + if self.smart_resolve_context_dep_help(&mut err, + span, + source, + def, + &path_str, + &fallback_label) { + return (err, candidates); } } From 497a772d04731d9e93abb71ae99696684e514bb3 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 4 Feb 2019 11:25:29 +0100 Subject: [PATCH 0729/1064] Addressed review points. --- src/librustc_resolve/error_reporting.rs | 417 +++++++++++++++++++++++- src/librustc_resolve/lib.rs | 399 ----------------------- 2 files changed, 412 insertions(+), 404 deletions(-) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index b131a6b62f9bf..88892ae2cd3d8 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -1,13 +1,420 @@ -use crate::{CrateLint, PathResult, Segment}; -use crate::macros::ParentScope; -use crate::resolve_imports::ImportResolver; +use std::cmp::Reverse; +use log::debug; +use rustc::hir::def::*; +use rustc::hir::def::Namespace::*; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::session::config::nightly_options; +use syntax::ast::{ExprKind}; use syntax::symbol::keywords; use syntax_pos::Span; -use log::debug; +use crate::errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use crate::macros::ParentScope; +use crate::resolve_imports::ImportResolver; +use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string}; +use crate::{AssocSuggestion, CrateLint, ImportSuggestion, ModuleOrUniformRoot, PathResult, + PathSource, Resolver, Segment}; -use std::cmp::Reverse; +impl<'a> Resolver<'a> { + /// Handles error reporting for `smart_resolve_path_fragment` function. + /// Creates base error and amends it with one short label and possibly some longer helps/notes. + pub(crate) fn smart_resolve_report_errors( + &mut self, + path: &[Segment], + span: Span, + source: PathSource, + def: Option, + ) -> (DiagnosticBuilder<'a>, Vec) { + let ident_span = path.last().map_or(span, |ident| ident.ident.span); + let ns = source.namespace(); + let is_expected = &|def| source.is_expected(def); + let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; + + // Make the base error. + let expected = source.descr_expected(); + let path_str = Segment::names_to_string(path); + let item_str = path.last().unwrap().ident; + let code = source.error_code(def.is_some()); + let (base_msg, fallback_label, base_span) = if let Some(def) = def { + (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), + format!("not a {}", expected), + span) + } else { + let item_span = path.last().unwrap().ident.span; + let (mod_prefix, mod_str) = if path.len() == 1 { + (String::new(), "this scope".to_string()) + } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() { + (String::new(), "the crate root".to_string()) + } else { + let mod_path = &path[..path.len() - 1]; + let mod_prefix = match self.resolve_path_without_parent_scope( + mod_path, Some(TypeNS), false, span, CrateLint::No + ) { + PathResult::Module(ModuleOrUniformRoot::Module(module)) => + module.def(), + _ => None, + }.map_or(String::new(), |def| format!("{} ", def.kind_name())); + (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) + }; + (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), + format!("not found in {}", mod_str), + item_span) + }; + + let code = DiagnosticId::Error(code.into()); + let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code); + + // Emit help message for fake-self from other languages (e.g., `this` in Javascript). + if ["this", "my"].contains(&&*item_str.as_str()) + && self.self_value_is_available(path[0].ident.span, span) { + err.span_suggestion( + span, + "did you mean", + "self".to_string(), + Applicability::MaybeIncorrect, + ); + } + + // Emit special messages for unresolved `Self` and `self`. + if is_self_type(path, ns) { + __diagnostic_used!(E0411); + err.code(DiagnosticId::Error("E0411".into())); + err.span_label(span, format!("`Self` is only available in impls, traits, \ + and type definitions")); + return (err, Vec::new()); + } + if is_self_value(path, ns) { + debug!("smart_resolve_path_fragment: E0424, source={:?}", source); + + __diagnostic_used!(E0424); + err.code(DiagnosticId::Error("E0424".into())); + err.span_label(span, match source { + PathSource::Pat => { + format!("`self` value is a keyword \ + and may not be bound to \ + variables or shadowed") + } + _ => { + format!("`self` value is a keyword \ + only available in methods \ + with `self` parameter") + } + }); + return (err, Vec::new()); + } + + // Try to lookup name in more relaxed fashion for better error reporting. + let ident = path.last().unwrap().ident; + let candidates = self.lookup_import_candidates(ident, ns, is_expected); + if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { + let enum_candidates = + self.lookup_import_candidates(ident, ns, is_enum_variant); + let mut enum_candidates = enum_candidates.iter() + .map(|suggestion| { + import_candidate_to_enum_paths(&suggestion) + }).collect::>(); + enum_candidates.sort(); + + if !enum_candidates.is_empty() { + // Contextualize for E0412 "cannot find type", but don't belabor the point + // (that it's a variant) for E0573 "expected type, found variant". + let preamble = if def.is_none() { + let others = match enum_candidates.len() { + 1 => String::new(), + 2 => " and 1 other".to_owned(), + n => format!(" and {} others", n) + }; + format!("there is an enum variant `{}`{}; ", + enum_candidates[0].0, others) + } else { + String::new() + }; + let msg = format!("{}try using the variant's enum", preamble); + + err.span_suggestions( + span, + &msg, + enum_candidates.into_iter() + .map(|(_variant_path, enum_ty_path)| enum_ty_path) + // Variants re-exported in prelude doesn't mean `prelude::v1` is the + // type name! + // FIXME: is there a more principled way to do this that + // would work for other re-exports? + .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1") + // Also write `Option` rather than `std::prelude::v1::Option`. + .map(|enum_ty_path| { + // FIXME #56861: DRY-er prelude filtering. + enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned() + }), + Applicability::MachineApplicable, + ); + } + } + if path.len() == 1 && self.self_type_is_available(span) { + if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { + let self_is_available = self.self_value_is_available(path[0].ident.span, span); + match candidate { + AssocSuggestion::Field => { + err.span_suggestion( + span, + "try", + format!("self.{}", path_str), + Applicability::MachineApplicable, + ); + if !self_is_available { + err.span_label(span, format!("`self` value is a keyword \ + only available in \ + methods with `self` parameter")); + } + } + AssocSuggestion::MethodWithSelf if self_is_available => { + err.span_suggestion( + span, + "try", + format!("self.{}", path_str), + Applicability::MachineApplicable, + ); + } + AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { + err.span_suggestion( + span, + "try", + format!("Self::{}", path_str), + Applicability::MachineApplicable, + ); + } + } + return (err, candidates); + } + } + + let mut levenshtein_worked = false; + + // Try Levenshtein algorithm. + let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span); + if let Some(suggestion) = suggestion { + let msg = format!( + "{} {} with a similar name exists", + suggestion.article, suggestion.kind + ); + err.span_suggestion( + ident_span, + &msg, + suggestion.candidate.to_string(), + Applicability::MaybeIncorrect, + ); + + levenshtein_worked = true; + } + + // Try context-dependent help if relaxed lookup didn't work. + if let Some(def) = def { + if self.smart_resolve_context_dependent_help(&mut err, + span, + source, + def, + &path_str, + &fallback_label) { + return (err, candidates); + } + } + + // Fallback label. + if !levenshtein_worked { + err.span_label(base_span, fallback_label); + self.type_ascription_suggestion(&mut err, base_span); + } + (err, candidates) + } + + /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment` + /// function. + /// Returns `true` if able to provide context-dependent help. + fn smart_resolve_context_dependent_help( + &mut self, + err: &mut DiagnosticBuilder<'a>, + span: Span, + source: PathSource, + def: Def, + path_str: &str, + fallback_label: &str, + ) -> bool { + let ns = source.namespace(); + let is_expected = &|def| source.is_expected(def); + + match (def, source) { + (Def::Macro(..), _) => { + err.span_suggestion( + span, + "use `!` to invoke the macro", + format!("{}!", path_str), + Applicability::MaybeIncorrect, + ); + } + (Def::TyAlias(..), PathSource::Trait(_)) => { + err.span_label(span, "type aliases cannot be used as traits"); + if nightly_options::is_nightly_build() { + err.note("did you mean to use a trait alias?"); + } + } + (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { + ExprKind::Field(_, ident) => { + err.span_suggestion( + parent.span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, ident), + Applicability::MaybeIncorrect, + ); + } + ExprKind::MethodCall(ref segment, ..) => { + let span = parent.span.with_hi(segment.ident.span.hi()); + err.span_suggestion( + span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, segment.ident), + Applicability::MaybeIncorrect, + ); + } + _ => return false, + }, + (Def::Enum(..), PathSource::TupleStruct) + | (Def::Enum(..), PathSource::Expr(..)) => { + if let Some(variants) = self.collect_enum_variants(def) { + err.note(&format!("did you mean to use one \ + of the following variants?\n{}", + variants.iter() + .map(|suggestion| path_names_to_string(suggestion)) + .map(|suggestion| format!("- `{}`", suggestion)) + .collect::>() + .join("\n"))); + } else { + err.note("did you mean to use one of the enum's variants?"); + } + }, + (Def::Struct(def_id), _) if ns == ValueNS => { + if let Some((ctor_def, ctor_vis)) + = self.struct_constructors.get(&def_id).cloned() { + let accessible_ctor = self.is_accessible(ctor_vis); + if is_expected(ctor_def) && !accessible_ctor { + err.span_label(span, format!("constructor is not visible \ + here due to private fields")); + } + } else { + // HACK(estebank): find a better way to figure out that this was a + // parser issue where a struct literal is being used on an expression + // where a brace being opened means a block is being started. Look + // ahead for the next text to see if `span` is followed by a `{`. + let sm = self.session.source_map(); + let mut sp = span; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet.chars().any(|c| { !c.is_whitespace() }) { + break; + } + } + _ => break, + } + } + let followed_by_brace = match sm.span_to_snippet(sp) { + Ok(ref snippet) if snippet == "{" => true, + _ => false, + }; + // In case this could be a struct literal that needs to be surrounded + // by parenthesis, find the appropriate span. + let mut i = 0; + let mut closing_brace = None; + loop { + sp = sm.next_point(sp); + match sm.span_to_snippet(sp) { + Ok(ref snippet) => { + if snippet == "}" { + let sp = span.to(sp); + if let Ok(snippet) = sm.span_to_snippet(sp) { + closing_brace = Some((sp, snippet)); + } + break; + } + } + _ => break, + } + i += 1; + // The bigger the span, the more likely we're incorrect -- + // bound it to 100 chars long. + if i > 100 { + break; + } + } + match source { + PathSource::Expr(Some(parent)) => { + match parent.node { + ExprKind::MethodCall(ref path_assignment, _) => { + err.span_suggestion( + sm.start_point(parent.span) + .to(path_assignment.ident.span), + "use `::` to access an associated function", + format!("{}::{}", + path_str, + path_assignment.ident), + Applicability::MaybeIncorrect + ); + }, + _ => { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", + path_str), + ); + }, + } + }, + PathSource::Expr(None) if followed_by_brace == true => { + if let Some((sp, snippet)) = closing_brace { + err.span_suggestion( + sp, + "surround the struct literal with parenthesis", + format!("({})", snippet), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label( + span, + format!("did you mean `({} {{ /* fields */ }})`?", + path_str), + ); + } + }, + _ => { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", + path_str), + ); + }, + } + } + } + (Def::Union(..), _) | + (Def::Variant(..), _) | + (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); + } + (Def::SelfTy(..), _) if ns == ValueNS => { + err.span_label(span, fallback_label); + err.note("can't use `Self` as a constructor, you must use the \ + implemented struct"); + } + (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { + err.note("can't use a type alias as a constructor"); + } + _ => return false, + } + true + } +} impl<'a, 'b:'a> ImportResolver<'a, 'b> { /// Add suggestions for a path that cannot be resolved. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 1a5fce14fa8fd..590dcb8947db4 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -25,7 +25,6 @@ use rustc::hir::def::*; use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; -use rustc::session::config::nightly_options; use rustc::ty; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; use rustc::{bug, span_bug}; @@ -3124,404 +3123,6 @@ impl<'a> Resolver<'a> { ) } - /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment` - /// function. - /// Returns `true` if able to provide context-dependent help. - fn smart_resolve_context_dep_help( - &mut self, - err: &mut DiagnosticBuilder<'a>, - span: Span, - source: PathSource, - def: Def, - path_str: &str, - fallback_label: &str, - ) -> bool { - let ns = source.namespace(); - let is_expected = &|def| source.is_expected(def); - - match (def, source) { - (Def::Macro(..), _) => { - err.span_suggestion( - span, - "use `!` to invoke the macro", - format!("{}!", path_str), - Applicability::MaybeIncorrect, - ); - } - (Def::TyAlias(..), PathSource::Trait(_)) => { - err.span_label(span, "type aliases cannot be used as traits"); - if nightly_options::is_nightly_build() { - err.note("did you mean to use a trait alias?"); - } - } - (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { - ExprKind::Field(_, ident) => { - err.span_suggestion( - parent.span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, ident), - Applicability::MaybeIncorrect, - ); - } - ExprKind::MethodCall(ref segment, ..) => { - let span = parent.span.with_hi(segment.ident.span.hi()); - err.span_suggestion( - span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, segment.ident), - Applicability::MaybeIncorrect, - ); - } - _ => return false, - }, - (Def::Enum(..), PathSource::TupleStruct) - | (Def::Enum(..), PathSource::Expr(..)) => { - if let Some(variants) = self.collect_enum_variants(def) { - err.note(&format!("did you mean to use one \ - of the following variants?\n{}", - variants.iter() - .map(|suggestion| path_names_to_string(suggestion)) - .map(|suggestion| format!("- `{}`", suggestion)) - .collect::>() - .join("\n"))); - } else { - err.note("did you mean to use one of the enum's variants?"); - } - }, - (Def::Struct(def_id), _) if ns == ValueNS => { - if let Some((ctor_def, ctor_vis)) - = self.struct_constructors.get(&def_id).cloned() { - let accessible_ctor = self.is_accessible(ctor_vis); - if is_expected(ctor_def) && !accessible_ctor { - err.span_label(span, format!("constructor is not visible \ - here due to private fields")); - } - } else { - // HACK(estebank): find a better way to figure out that this was a - // parser issue where a struct literal is being used on an expression - // where a brace being opened means a block is being started. Look - // ahead for the next text to see if `span` is followed by a `{`. - let sm = self.session.source_map(); - let mut sp = span; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet.chars().any(|c| { !c.is_whitespace() }) { - break; - } - } - _ => break, - } - } - let followed_by_brace = match sm.span_to_snippet(sp) { - Ok(ref snippet) if snippet == "{" => true, - _ => false, - }; - // In case this could be a struct literal that needs to be surrounded - // by parenthesis, find the appropriate span. - let mut i = 0; - let mut closing_brace = None; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet == "}" { - let sp = span.to(sp); - if let Ok(snippet) = sm.span_to_snippet(sp) { - closing_brace = Some((sp, snippet)); - } - break; - } - } - _ => break, - } - i += 1; - // The bigger the span, the more likely we're incorrect -- - // bound it to 100 chars long. - if i > 100 { - break; - } - } - match source { - PathSource::Expr(Some(parent)) => { - match parent.node { - ExprKind::MethodCall(ref path_assignment, _) => { - err.span_suggestion( - sm.start_point(parent.span) - .to(path_assignment.ident.span), - "use `::` to access an associated function", - format!("{}::{}", - path_str, - path_assignment.ident), - Applicability::MaybeIncorrect - ); - }, - _ => { - err.span_label( - span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), - ); - }, - } - }, - PathSource::Expr(None) if followed_by_brace == true => { - if let Some((sp, snippet)) = closing_brace { - err.span_suggestion( - sp, - "surround the struct literal with parenthesis", - format!("({})", snippet), - Applicability::MaybeIncorrect, - ); - } else { - err.span_label( - span, - format!("did you mean `({} {{ /* fields */ }})`?", - path_str), - ); - } - }, - _ => { - err.span_label( - span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), - ); - }, - } - } - } - (Def::Union(..), _) | - (Def::Variant(..), _) | - (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); - } - (Def::SelfTy(..), _) if ns == ValueNS => { - err.span_label(span, fallback_label); - err.note("can't use `Self` as a constructor, you must use the \ - implemented struct"); - } - (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { - err.note("can't use a type alias as a constructor"); - } - _ => return false, - } - true - } - - /// Handles error reporting for `smart_resolve_path_fragment` function. - /// Creates base error and amends it with one short label and possibly some longer helps/notes. - fn smart_resolve_report_errors( - &mut self, - path: &[Segment], - span: Span, - source: PathSource<'_>, - def: Option, - ) -> (DiagnosticBuilder<'a>, Vec) { - let ident_span = path.last().map_or(span, |ident| ident.ident.span); - let ns = source.namespace(); - let is_expected = &|def| source.is_expected(def); - let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; - - // Make the base error. - let expected = source.descr_expected(); - let path_str = Segment::names_to_string(path); - let item_str = path.last().unwrap().ident; - let code = source.error_code(def.is_some()); - let (base_msg, fallback_label, base_span) = if let Some(def) = def { - (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), - format!("not a {}", expected), - span) - } else { - let item_span = path.last().unwrap().ident.span; - let (mod_prefix, mod_str) = if path.len() == 1 { - (String::new(), "this scope".to_string()) - } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() { - (String::new(), "the crate root".to_string()) - } else { - let mod_path = &path[..path.len() - 1]; - let mod_prefix = match self.resolve_path_without_parent_scope( - mod_path, Some(TypeNS), false, span, CrateLint::No - ) { - PathResult::Module(ModuleOrUniformRoot::Module(module)) => - module.def(), - _ => None, - }.map_or(String::new(), |def| format!("{} ", def.kind_name())); - (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) - }; - (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), - format!("not found in {}", mod_str), - item_span) - }; - - let code = DiagnosticId::Error(code.into()); - let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code); - - // Emit help message for fake-self from other languages (e.g., `this` in Javascript). - if ["this", "my"].contains(&&*item_str.as_str()) - && self.self_value_is_available(path[0].ident.span, span) { - err.span_suggestion( - span, - "did you mean", - "self".to_string(), - Applicability::MaybeIncorrect, - ); - } - - // Emit special messages for unresolved `Self` and `self`. - if is_self_type(path, ns) { - __diagnostic_used!(E0411); - err.code(DiagnosticId::Error("E0411".into())); - err.span_label(span, format!("`Self` is only available in impls, traits, \ - and type definitions")); - return (err, Vec::new()); - } - if is_self_value(path, ns) { - debug!("smart_resolve_path_fragment: E0424, source={:?}", source); - - __diagnostic_used!(E0424); - err.code(DiagnosticId::Error("E0424".into())); - err.span_label(span, match source { - PathSource::Pat => { - format!("`self` value is a keyword \ - and may not be bound to \ - variables or shadowed") - } - _ => { - format!("`self` value is a keyword \ - only available in methods \ - with `self` parameter") - } - }); - return (err, Vec::new()); - } - - // Try to lookup name in more relaxed fashion for better error reporting. - let ident = path.last().unwrap().ident; - let candidates = self.lookup_import_candidates(ident, ns, is_expected); - if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { - let enum_candidates = - self.lookup_import_candidates(ident, ns, is_enum_variant); - let mut enum_candidates = enum_candidates.iter() - .map(|suggestion| { - import_candidate_to_enum_paths(&suggestion) - }).collect::>(); - enum_candidates.sort(); - - if !enum_candidates.is_empty() { - // Contextualize for E0412 "cannot find type", but don't belabor the point - // (that it's a variant) for E0573 "expected type, found variant". - let preamble = if def.is_none() { - let others = match enum_candidates.len() { - 1 => String::new(), - 2 => " and 1 other".to_owned(), - n => format!(" and {} others", n) - }; - format!("there is an enum variant `{}`{}; ", - enum_candidates[0].0, others) - } else { - String::new() - }; - let msg = format!("{}try using the variant's enum", preamble); - - err.span_suggestions( - span, - &msg, - enum_candidates.into_iter() - .map(|(_variant_path, enum_ty_path)| enum_ty_path) - // Variants re-exported in prelude doesn't mean `prelude::v1` is the - // type name! - // FIXME: is there a more principled way to do this that - // would work for other re-exports? - .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1") - // Also write `Option` rather than `std::prelude::v1::Option`. - .map(|enum_ty_path| { - // FIXME #56861: DRYer prelude filtering. - enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned() - }), - Applicability::MachineApplicable, - ); - } - } - if path.len() == 1 && self.self_type_is_available(span) { - if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { - let self_is_available = self.self_value_is_available(path[0].ident.span, span); - match candidate { - AssocSuggestion::Field => { - err.span_suggestion( - span, - "try", - format!("self.{}", path_str), - Applicability::MachineApplicable, - ); - if !self_is_available { - err.span_label(span, format!("`self` value is a keyword \ - only available in \ - methods with `self` parameter")); - } - } - AssocSuggestion::MethodWithSelf if self_is_available => { - err.span_suggestion( - span, - "try", - format!("self.{}", path_str), - Applicability::MachineApplicable, - ); - } - AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { - err.span_suggestion( - span, - "try", - format!("Self::{}", path_str), - Applicability::MachineApplicable, - ); - } - } - return (err, candidates); - } - } - - let mut levenshtein_worked = false; - - // Try Levenshtein algorithm. - let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span); - if let Some(suggestion) = suggestion { - let msg = format!( - "{} {} with a similar name exists", - suggestion.article, suggestion.kind - ); - err.span_suggestion( - ident_span, - &msg, - suggestion.candidate.to_string(), - Applicability::MaybeIncorrect, - ); - - levenshtein_worked = true; - } - - // Try context-dependent help if relaxed lookup didn't work. - if let Some(def) = def { - if self.smart_resolve_context_dep_help(&mut err, - span, - source, - def, - &path_str, - &fallback_label) { - return (err, candidates); - } - } - - // Fallback label. - if !levenshtein_worked { - err.span_label(base_span, fallback_label); - self.type_ascription_suggestion(&mut err, base_span); - } - (err, candidates) - } - fn smart_resolve_path_fragment(&mut self, id: NodeId, qself: Option<&QSelf>, From 5c87bc85e2d7395d671311a5b8b97013b2e73d87 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 4 Feb 2019 11:24:09 +0100 Subject: [PATCH 0730/1064] Minor cosmetic changes. --- src/librustc_resolve/error_reporting.rs | 12 ++++++------ src/librustc_resolve/lib.rs | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 88892ae2cd3d8..1f7ae7c3034f3 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -417,7 +417,7 @@ impl<'a> Resolver<'a> { } impl<'a, 'b:'a> ImportResolver<'a, 'b> { - /// Add suggestions for a path that cannot be resolved. + /// Adds suggestions for a path that cannot be resolved. pub(crate) fn make_path_suggestion( &mut self, span: Span, @@ -431,7 +431,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // On 2015 `{{root}}` is usually added implicitly. (Some(fst), Some(snd)) if fst.ident.name == keywords::PathRoot.name() && !snd.ident.is_path_segment_keyword() => {} - // `ident::...` on 2018 + // `ident::...` on 2018. (Some(fst), _) if fst.ident.span.rust_2018() && !fst.ident.is_path_segment_keyword() => { // Insert a placeholder that's later replaced by `self`/`super`/etc. @@ -470,7 +470,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } - /// Suggest a missing `crate::` if that resolves to an correct module. + /// Suggests a missing `crate::` if that resolves to an correct module. /// /// ``` /// | @@ -501,7 +501,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } - /// Suggest a missing `super::` if that resolves to an correct module. + /// Suggests a missing `super::` if that resolves to an correct module. /// /// ``` /// | @@ -525,7 +525,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } - /// Suggest a missing external crate name if that resolves to an correct module. + /// Suggests a missing external crate name if that resolves to an correct module. /// /// ``` /// | @@ -546,7 +546,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } // Sort extern crate names in reverse order to get - // 1) some consistent ordering for emitted dignostics and + // 1) some consistent ordering for emitted dignostics, and // 2) `std` suggestions before `core` suggestions. let mut extern_crate_names = self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::>(); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 590dcb8947db4..69f8722a82b9b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1737,7 +1737,7 @@ impl<'a> Resolver<'a> { } } - /// resolve_hir_path, but takes a callback in case there was an error + /// Like `resolve_hir_path`, but takes a callback in case there was an error. fn resolve_hir_path_cb( &mut self, path: &ast::Path, @@ -1750,7 +1750,7 @@ impl<'a> Resolver<'a> { let span = path.span; let segments = &path.segments; let path = Segment::from_path(&path); - // FIXME (Manishearth): Intra doc links won't get warned of epoch changes + // FIXME(Manishearth): intra-doc links won't get warned of epoch changes. let def = match self.resolve_path_without_parent_scope(&path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => @@ -5066,7 +5066,6 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str (variant_path_string, enum_path_string) } - /// When an entity with a given name is not available in scope, we search for /// entities with that name in all crates. This method allows outputting the /// results of this search in a programmer-friendly way From fd70e8e8db6f0a43f9f5bc669e03ab9bbdce7fbc Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 7 Feb 2019 22:25:15 +0100 Subject: [PATCH 0731/1064] WIP --- src/librustc_resolve/error_reporting.rs | 4 ++-- src/librustc_resolve/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 1f7ae7c3034f3..8300e691bbea4 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -23,7 +23,7 @@ impl<'a> Resolver<'a> { &mut self, path: &[Segment], span: Span, - source: PathSource, + source: PathSource<'_>, def: Option, ) -> (DiagnosticBuilder<'a>, Vec) { let ident_span = path.last().map_or(span, |ident| ident.ident.span); @@ -235,7 +235,7 @@ impl<'a> Resolver<'a> { &mut self, err: &mut DiagnosticBuilder<'a>, span: Span, - source: PathSource, + source: PathSource<'_>, def: Def, path_str: &str, fallback_label: &str, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 69f8722a82b9b..611b956035ba7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3128,7 +3128,7 @@ impl<'a> Resolver<'a> { qself: Option<&QSelf>, path: &[Segment], span: Span, - source: PathSource, + source: PathSource<'_>, crate_lint: CrateLint) -> PathResolution { let ns = source.namespace(); From 7eb6a2a9729dd0f948fc30e391e32c0a51d3d0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Feb 2019 16:12:12 -0800 Subject: [PATCH 0732/1064] Add test for type mismatch on first match arm --- src/test/ui/match/match-type-err-first-arm.rs | 27 ++++++++++++++++ .../ui/match/match-type-err-first-arm.stderr | 31 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/test/ui/match/match-type-err-first-arm.rs create mode 100644 src/test/ui/match/match-type-err-first-arm.stderr diff --git a/src/test/ui/match/match-type-err-first-arm.rs b/src/test/ui/match/match-type-err-first-arm.rs new file mode 100644 index 0000000000000..31fa50d2b452b --- /dev/null +++ b/src/test/ui/match/match-type-err-first-arm.rs @@ -0,0 +1,27 @@ +fn main() { + let _ = test_func1(1); + let _ = test_func2(1); +} + +fn test_func1(n: i32) -> i32 { + //~^ NOTE expected `i32` because of return type + match n { + 12 => 'b', + //~^ ERROR mismatched types + //~| NOTE expected i32, found char + _ => 42, + } +} + +fn test_func2(n: i32) -> i32 { + let x = match n { + //~^ NOTE `match` arms have incompatible types + 12 => 'b', + //~^ NOTE this is found to be of type `char` + _ => 42, + //~^ ERROR match arms have incompatible types + //~| NOTE expected char, found integer + //~| NOTE expected type `char` + }; + x +} diff --git a/src/test/ui/match/match-type-err-first-arm.stderr b/src/test/ui/match/match-type-err-first-arm.stderr new file mode 100644 index 0000000000000..8f722343a5875 --- /dev/null +++ b/src/test/ui/match/match-type-err-first-arm.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/match-type-err-first-arm.rs:9:15 + | +LL | fn test_func1(n: i32) -> i32 { + | --- expected `i32` because of return type +... +LL | 12 => 'b', + | ^^^ expected i32, found char + +error[E0308]: match arms have incompatible types + --> $DIR/match-type-err-first-arm.rs:21:14 + | +LL | let x = match n { + | _____________- +LL | | //~^ NOTE `match` arms have incompatible types +LL | | 12 => 'b', + | | --- this is found to be of type `char` +LL | | //~^ NOTE this is found to be of type `char` +LL | | _ => 42, + | | ^^ expected char, found integer +... | +LL | | //~| NOTE expected type `char` +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected type `char` + found type `{integer}` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 34ec9a59423a299a6cd1bedfd4e0a660748f6540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 20 Jan 2019 05:44:02 +0100 Subject: [PATCH 0733/1064] Add a query type which is always marked as red if it runs --- src/librustc/dep_graph/graph.rs | 89 +++++++++++++++++++------------ src/librustc/dep_graph/mod.rs | 2 +- src/librustc/hir/map/collector.rs | 14 ++--- src/librustc/ty/context.rs | 5 +- src/librustc/ty/query/config.rs | 9 +++- src/librustc/ty/query/mod.rs | 13 ++--- src/librustc/ty/query/plumbing.rs | 31 ++++++++--- src/librustc_codegen_llvm/base.rs | 4 +- 8 files changed, 106 insertions(+), 61 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 663c408ac22fd..e8c1cd36064e1 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -79,6 +79,16 @@ struct DepGraphData { loaded_from_cache: Lock>, } +pub fn hash_result(hcx: &mut StableHashingContext<'_>, result: &R) -> Option +where + R: for<'a> HashStable>, +{ + let mut stable_hasher = StableHasher::new(); + result.hash_stable(hcx, &mut stable_hasher); + + Some(stable_hasher.finish()) +} + impl DepGraph { pub fn new(prev_graph: PreviousDepGraph, @@ -178,14 +188,16 @@ impl DepGraph { /// `arg` parameter. /// /// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html - pub fn with_task<'gcx, C, A, R>(&self, - key: DepNode, - cx: C, - arg: A, - task: fn(C, A) -> R) - -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider<'gcx>, - R: HashStable>, + pub fn with_task<'a, C, A, R>( + &self, + key: DepNode, + cx: C, + arg: A, + task: fn(C, A) -> R, + hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option, + ) -> (R, DepNodeIndex) + where + C: DepGraphSafe + StableHashingContextProvider<'a>, { self.with_task_impl(key, cx, arg, false, task, |_key| Some(TaskDeps { @@ -196,17 +208,18 @@ impl DepGraph { }), |data, key, fingerprint, task| { data.borrow_mut().complete_task(key, task.unwrap(), fingerprint) - }) + }, + hash_result) } /// Creates a new dep-graph input with value `input` - pub fn input_task<'gcx, C, R>(&self, + pub fn input_task<'a, C, R>(&self, key: DepNode, cx: C, input: R) -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider<'gcx>, - R: HashStable>, + where C: DepGraphSafe + StableHashingContextProvider<'a>, + R: for<'b> HashStable>, { fn identity_fn(_: C, arg: A) -> A { arg @@ -216,10 +229,11 @@ impl DepGraph { |_| None, |data, key, fingerprint, _| { data.borrow_mut().alloc_node(key, SmallVec::new(), fingerprint) - }) + }, + hash_result::) } - fn with_task_impl<'gcx, C, A, R>( + fn with_task_impl<'a, C, A, R>( &self, key: DepNode, cx: C, @@ -230,11 +244,11 @@ impl DepGraph { finish_task_and_alloc_depnode: fn(&Lock, DepNode, Fingerprint, - Option) -> DepNodeIndex + Option) -> DepNodeIndex, + hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option, ) -> (R, DepNodeIndex) where - C: DepGraphSafe + StableHashingContextProvider<'gcx>, - R: HashStable>, + C: DepGraphSafe + StableHashingContextProvider<'a>, { if let Some(ref data) = self.data { let task_deps = create_task(key).map(|deps| Lock::new(deps)); @@ -269,15 +283,12 @@ impl DepGraph { profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd) }; - let mut stable_hasher = StableHasher::new(); - result.hash_stable(&mut hcx, &mut stable_hasher); - - let current_fingerprint = stable_hasher.finish(); + let current_fingerprint = hash_result(&mut hcx, &result); let dep_node_index = finish_task_and_alloc_depnode( &data.current, key, - current_fingerprint, + current_fingerprint.unwrap_or(Fingerprint::ZERO), task_deps.map(|lock| lock.into_inner()), ); @@ -285,15 +296,20 @@ impl DepGraph { if let Some(prev_index) = data.previous.node_to_index_opt(&key) { let prev_fingerprint = data.previous.fingerprint_by_index(prev_index); - let color = if current_fingerprint == prev_fingerprint { - DepNodeColor::Green(dep_node_index) + let color = if let Some(current_fingerprint) = current_fingerprint { + if current_fingerprint == prev_fingerprint { + DepNodeColor::Green(dep_node_index) + } else { + DepNodeColor::Red + } } else { + // Mark the node as Red if we can't hash the result DepNodeColor::Red }; debug_assert!(data.colors.get(prev_index).is_none(), - "DepGraph::with_task() - Duplicate DepNodeColor \ - insertion for {:?}", key); + "DepGraph::with_task() - Duplicate DepNodeColor \ + insertion for {:?}", key); data.colors.insert(prev_index, color); } @@ -342,14 +358,16 @@ impl DepGraph { /// Execute something within an "eval-always" task which is a task // that runs whenever anything changes. - pub fn with_eval_always_task<'gcx, C, A, R>(&self, - key: DepNode, - cx: C, - arg: A, - task: fn(C, A) -> R) - -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider<'gcx>, - R: HashStable>, + pub fn with_eval_always_task<'a, C, A, R>( + &self, + key: DepNode, + cx: C, + arg: A, + task: fn(C, A) -> R, + hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option, + ) -> (R, DepNodeIndex) + where + C: DepGraphSafe + StableHashingContextProvider<'a>, { self.with_task_impl(key, cx, arg, false, task, |_| None, @@ -359,7 +377,8 @@ impl DepGraph { &DepNode::new_no_params(DepKind::Krate) ]; current.alloc_node(key, smallvec![krate_idx], fingerprint) - }) + }, + hash_result) } #[inline] diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index 022caabcbf3a1..b84d2ad145889 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -10,7 +10,7 @@ pub mod cgu_reuse_tracker; pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig}; pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs}; -pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps}; +pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result}; pub use self::graph::WorkProductFileKind; pub use self::prev::PreviousDepGraph; pub use self::query::DepGraphQuery; diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index f84bb77e29b27..37552f18f4a08 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -48,14 +48,14 @@ pub(super) struct NodeCollector<'a, 'hir> { hir_body_nodes: Vec<(DefPathHash, Fingerprint)>, } -fn input_dep_node_and_hash<'a, I>( +fn input_dep_node_and_hash( dep_graph: &DepGraph, - hcx: &mut StableHashingContext<'a>, + hcx: &mut StableHashingContext<'_>, dep_node: DepNode, input: I, ) -> (DepNodeIndex, Fingerprint) where - I: HashStable>, + I: for<'a> HashStable>, { let dep_node_index = dep_graph.input_task(dep_node, &mut *hcx, &input).1; @@ -70,15 +70,15 @@ where (dep_node_index, hash) } -fn alloc_hir_dep_nodes<'a, I>( +fn alloc_hir_dep_nodes( dep_graph: &DepGraph, - hcx: &mut StableHashingContext<'a>, + hcx: &mut StableHashingContext<'_>, def_path_hash: DefPathHash, item_like: I, hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>, ) -> (DepNodeIndex, DepNodeIndex) where - I: HashStable>, + I: for<'a> HashStable>, { let sig = dep_graph.input_task( def_path_hash.to_dep_node(DepKind::Hir), @@ -286,7 +286,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { self.parent_node = parent_node; } - fn with_dep_node_owner>, + fn with_dep_node_owner HashStable>, F: FnOnce(&mut Self)>(&mut self, dep_node_owner: DefIndex, item_like: &T, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 140c772256d3f..795853a37c758 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1,7 +1,7 @@ //! type context book-keeping use crate::dep_graph::DepGraph; -use crate::dep_graph::{DepNode, DepConstructor}; +use crate::dep_graph::{self, DepNode, DepConstructor}; use crate::errors::DiagnosticBuilder; use crate::session::Session; use crate::session::config::{BorrowckMode, OutputFilenames}; @@ -1435,7 +1435,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.dep_graph.with_task(dep_node, self, crate_hash, - |_, x| x // No transformation needed + |_, x| x, // No transformation needed + dep_graph::hash_result, ); } } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 255e39eaccd6d..a3ee92f8e1263 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -20,7 +20,7 @@ use std::hash::Hash; use std::fmt::Debug; use syntax_pos::symbol::InternedString; use rustc_data_structures::sync::Lock; -use rustc_data_structures::stable_hasher::HashStable; +use rustc_data_structures::fingerprint::Fingerprint; use crate::ich::StableHashingContext; // Query configuration and description traits. @@ -30,7 +30,7 @@ pub trait QueryConfig<'tcx> { const CATEGORY: ProfileCategory; type Key: Eq + Hash + Clone + Debug; - type Value: Clone + for<'a> HashStable>; + type Value: Clone; } pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { @@ -44,6 +44,11 @@ pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value; + fn hash_result( + hcx: &mut StableHashingContext<'_>, + result: &Self::Value + ) -> Option; + fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value; } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 20a700bb58dd1..8211dc50fc6e0 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -1,4 +1,4 @@ -use crate::dep_graph::{DepConstructor, DepNode}; +use crate::dep_graph::{self, DepConstructor, DepNode}; use crate::errors::DiagnosticBuilder; use crate::hir::def_id::{CrateNum, DefId, DefIndex}; use crate::hir::def::{Def, Export}; @@ -49,6 +49,7 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::fingerprint::Fingerprint; use rustc_target::spec::PanicStrategy; use std::borrow::Cow; @@ -227,19 +228,19 @@ define_queries! { <'tcx> /// Fetch the MIR for a given def-id right after it's built - this includes /// unreachable code. - [] fn mir_built: MirBuilt(DefId) -> &'tcx Steal>, + [no_hash] fn mir_built: MirBuilt(DefId) -> &'tcx Steal>, /// Fetch the MIR for a given def-id up till the point where it is /// ready for const evaluation. /// /// See the README for the `mir` module for details. - [] fn mir_const: MirConst(DefId) -> &'tcx Steal>, + [no_hash] fn mir_const: MirConst(DefId) -> &'tcx Steal>, - [] fn mir_validated: MirValidated(DefId) -> &'tcx Steal>, + [no_hash] fn mir_validated: MirValidated(DefId) -> &'tcx Steal>, /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. - [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, + [no_hash] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, }, TypeChecking { @@ -282,7 +283,7 @@ define_queries! { <'tcx> TypeChecking { [] fn typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult, - [] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, + [no_hash] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, }, Other { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index a26b21a1059fe..3dcb939d63606 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -499,7 +499,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { dep_node: &DepNode, dep_node_index: DepNodeIndex, ) { - use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use crate::ich::Fingerprint; assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) == @@ -509,11 +508,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("BEGIN verify_ich({:?})", dep_node); let mut hcx = self.create_stable_hashing_context(); - let mut hasher = StableHasher::new(); - result.hash_stable(&mut hcx, &mut hasher); - - let new_hash: Fingerprint = hasher.finish(); + let new_hash = Q::hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO); debug!("END verify_ich({:?})", dep_node); let old_hash = self.dep_graph.fingerprint_of(dep_node_index); @@ -549,12 +545,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { tcx.dep_graph.with_eval_always_task(dep_node, tcx, key, - Q::compute) + Q::compute, + Q::hash_result) } else { tcx.dep_graph.with_task(dep_node, tcx, key, - Q::compute) + Q::compute, + Q::hash_result) } }) }); @@ -679,6 +677,18 @@ macro_rules! handle_cycle_error { }; } +macro_rules! hash_result { + ([][$hcx:expr, $result:expr]) => {{ + dep_graph::hash_result($hcx, &$result) + }}; + ([no_hash$(, $modifiers:ident)*][$hcx:expr, $result:expr]) => {{ + None + }}; + ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => { + hash_result!([$($modifiers),*][$($args)*]) + }; +} + macro_rules! define_queries { (<$tcx:tt> $($category:tt { $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)* @@ -966,6 +976,13 @@ macro_rules! define_queries_inner { }) } + fn hash_result( + _hcx: &mut StableHashingContext<'_>, + _result: &Self::Value + ) -> Option { + hash_result!([$($modifiers)*][_hcx, _result]) + } + fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value { handle_cycle_error!([$($modifiers)*][tcx]) } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 6e1ef440a3f3f..d9f44ca6e45a3 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -20,6 +20,7 @@ use super::LlvmCodegenBackend; use llvm; use metadata; +use rustc::dep_graph; use rustc::mir::mono::{Linkage, Visibility, Stats}; use rustc::middle::cstore::{EncodedMetadata}; use rustc::ty::TyCtxt; @@ -145,7 +146,8 @@ pub fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let ((stats, module), _) = tcx.dep_graph.with_task(dep_node, tcx, cgu_name, - module_codegen); + module_codegen, + dep_graph::hash_result); let time_to_codegen = start_time.elapsed(); // We assume that the cost to run LLVM on a CGU is proportional to From 8c59b6d1309dbcef7bae87b40d7658d8be60bb5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 20 Jan 2019 16:43:57 +0100 Subject: [PATCH 0734/1064] Remove no_hash from optimized_mir --- src/librustc/ty/query/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 8211dc50fc6e0..6ac2d933c0e7d 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -240,7 +240,7 @@ define_queries! { <'tcx> /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. - [no_hash] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, + [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, }, TypeChecking { From 084704535097b08690b17fe8249271ff92d111c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 21 Jan 2019 03:39:25 +0100 Subject: [PATCH 0735/1064] Remove no_hash from typeck_tables_of --- src/librustc/ty/query/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 6ac2d933c0e7d..5082bc9266473 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -283,7 +283,7 @@ define_queries! { <'tcx> TypeChecking { [] fn typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult, - [no_hash] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, + [] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, }, Other { From 33a9be0650cf5085283c2b4d509dcdd6125c25de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 22 Jan 2019 08:59:17 +0100 Subject: [PATCH 0736/1064] Move no_hash from mir_built to optimized_mir --- src/librustc/ty/query/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 5082bc9266473..66c1695087fa5 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -228,7 +228,7 @@ define_queries! { <'tcx> /// Fetch the MIR for a given def-id right after it's built - this includes /// unreachable code. - [no_hash] fn mir_built: MirBuilt(DefId) -> &'tcx Steal>, + [] fn mir_built: MirBuilt(DefId) -> &'tcx Steal>, /// Fetch the MIR for a given def-id up till the point where it is /// ready for const evaluation. @@ -240,7 +240,7 @@ define_queries! { <'tcx> /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. - [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, + [no_hash] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, }, TypeChecking { From 6ec66df7737a5378a3db72223e93c4567e229829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 22 Jan 2019 15:24:00 +0100 Subject: [PATCH 0737/1064] Remove no_hash from optimized_mir --- src/librustc/ty/query/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 66c1695087fa5..d002b99f385a3 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -240,7 +240,7 @@ define_queries! { <'tcx> /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. - [no_hash] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, + [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, }, TypeChecking { From a0f02cdba0050bba5a963dc14643d6ca7b7cd396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 26 Jan 2019 16:52:34 +0100 Subject: [PATCH 0738/1064] Update tests --- .../persist/dirty_clean.rs | 4 +- .../incremental/hashes/call_expressions.rs | 16 +++--- .../incremental/hashes/closure_expressions.rs | 8 +-- .../incremental/hashes/enum_constructors.rs | 28 +++++----- .../incremental/hashes/exported_vs_not.rs | 6 +- src/test/incremental/hashes/for_loops.rs | 16 +++--- .../incremental/hashes/function_interfaces.rs | 14 ++--- src/test/incremental/hashes/if_expressions.rs | 12 ++-- src/test/incremental/hashes/inherent_impls.rs | 20 +++---- src/test/incremental/hashes/inline_asm.rs | 12 ++-- .../incremental/hashes/let_expressions.rs | 24 ++++---- .../incremental/hashes/loop_expressions.rs | 10 ++-- .../incremental/hashes/match_expressions.rs | 26 ++++----- src/test/incremental/hashes/panic_exprs.rs | 18 +++--- .../incremental/hashes/struct_constructors.rs | 16 +++--- .../hashes/unary_and_binary_exprs.rs | 56 +++++++++---------- .../incremental/hashes/while_let_loops.rs | 12 ++-- src/test/incremental/hashes/while_loops.rs | 12 ++-- 18 files changed, 155 insertions(+), 155 deletions(-) diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 3ff4d2ec38dff..105623e5e4e3c 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -67,11 +67,11 @@ const BASE_IMPL: &[&str] = &[ label_strs::ImplTraitRef, ]; -/// DepNodes for MirValidated/Optimized, which is relevant in "executable" +/// DepNodes for MirBuilt/Optimized, which is relevant in "executable" /// code, i.e., functions+methods const BASE_MIR: &[&str] = &[ label_strs::MirOptimized, - label_strs::MirValidated, + label_strs::MirBuilt, ]; /// Struct, Enum and Union DepNodes diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs index 52de065598965..f0f1f09a8388b 100644 --- a/src/test/incremental/hashes/call_expressions.rs +++ b/src/test/incremental/hashes/call_expressions.rs @@ -25,7 +25,7 @@ pub fn change_callee_function() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_callee_function() { callee2(1, 2) @@ -40,7 +40,7 @@ pub fn change_argument_function() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_argument_function() { callee1(1, 3) @@ -81,7 +81,7 @@ pub fn change_callee_method() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_callee_method() { let s = Struct; @@ -98,7 +98,7 @@ pub fn change_argument_method() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_argument_method() { let s = Struct; @@ -115,7 +115,7 @@ pub fn change_ufcs_callee_method() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_ufcs_callee_method() { let s = Struct; @@ -132,7 +132,7 @@ pub fn change_argument_method_ufcs() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_argument_method_ufcs() { let s = Struct; @@ -149,7 +149,7 @@ pub fn change_to_ufcs() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] // One might think this would be expanded in the HirBody/Mir, but it actually // results in slightly different Hir/Mir. @@ -171,7 +171,7 @@ pub mod change_ufcs_callee_indirectly { #[cfg(not(cfail1))] use super::Struct2 as Struct; - #[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index 0e8cf80b88981..4e82729aa3be1 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -37,7 +37,7 @@ pub fn add_parameter() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_parameter() { let x = 0u32; @@ -53,7 +53,7 @@ pub fn change_parameter_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_parameter_pattern() { let _ = |&x: &u32| x; @@ -84,7 +84,7 @@ pub fn add_type_ascription_to_parameter() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_type_ascription_to_parameter() { let closure = |x: u32| x + 1u32; @@ -101,7 +101,7 @@ pub fn change_parameter_type() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_parameter_type() { let closure = |x: u16| (x as u64) + 1; diff --git a/src/test/incremental/hashes/enum_constructors.rs b/src/test/incremental/hashes/enum_constructors.rs index e9b557bde20f7..a74c3ab04e2af 100644 --- a/src/test/incremental/hashes/enum_constructors.rs +++ b/src/test/incremental/hashes/enum_constructors.rs @@ -34,7 +34,7 @@ pub fn change_field_value_struct_like() -> Enum { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_struct_like() -> Enum { Enum::Struct { @@ -96,7 +96,7 @@ pub fn change_constructor_path_struct_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_struct_like() { let _ = Enum2::Struct { @@ -119,7 +119,7 @@ pub fn change_constructor_variant_struct_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_variant_struct_like() { let _ = Enum2::Struct2 { @@ -139,7 +139,7 @@ pub mod change_constructor_path_indirectly_struct_like { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirValidated,\ + except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\ TypeckTables" )] #[rustc_clean(cfg="cfail3")] @@ -161,7 +161,7 @@ pub mod change_constructor_variant_indirectly_struct_like { #[cfg(not(cfail1))] use super::Enum2::Struct2 as Variant; - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Enum2 { Variant { @@ -180,7 +180,7 @@ pub fn change_field_value_tuple_like() -> Enum { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_tuple_like() -> Enum { Enum::Tuple(0, 1, 3) @@ -197,7 +197,7 @@ pub fn change_constructor_path_tuple_like() { #[cfg(not(cfail1))] #[rustc_clean( cfg="cfail2", - except="HirBody,MirOptimized,MirValidated,TypeckTables" + except="HirBody,MirOptimized,MirBuilt,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_tuple_like() { @@ -215,7 +215,7 @@ pub fn change_constructor_variant_tuple_like() { #[cfg(not(cfail1))] #[rustc_clean( cfg="cfail2", - except="HirBody,MirOptimized,MirValidated,TypeckTables" + except="HirBody,MirOptimized,MirBuilt,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_variant_tuple_like() { @@ -232,7 +232,7 @@ pub mod change_constructor_path_indirectly_tuple_like { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirValidated,\ + except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\ TypeckTables" )] #[rustc_clean(cfg="cfail3")] @@ -251,7 +251,7 @@ pub mod change_constructor_variant_indirectly_tuple_like { #[cfg(not(cfail1))] use super::Enum2::Tuple2 as Variant; - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Enum2 { Variant(0, 1, 2) @@ -278,7 +278,7 @@ pub fn change_constructor_path_c_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_c_like() { let _ = Clike2::B; @@ -293,7 +293,7 @@ pub fn change_constructor_variant_c_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_variant_c_like() { let _ = Clike::C; @@ -309,7 +309,7 @@ pub mod change_constructor_path_indirectly_c_like { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirValidated,\ + except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\ TypeckTables" )] #[rustc_clean(cfg="cfail3")] @@ -328,7 +328,7 @@ pub mod change_constructor_variant_indirectly_c_like { #[cfg(not(cfail1))] use super::Clike::B as Variant; - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Clike { Variant diff --git a/src/test/incremental/hashes/exported_vs_not.rs b/src/test/incremental/hashes/exported_vs_not.rs index 1880dd2fb0d7c..c9f844f96ebd7 100644 --- a/src/test/incremental/hashes/exported_vs_not.rs +++ b/src/test/incremental/hashes/exported_vs_not.rs @@ -16,7 +16,7 @@ pub fn body_not_exported_to_metadata() -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn body_not_exported_to_metadata() -> u32 { 2 @@ -35,7 +35,7 @@ pub fn body_exported_to_metadata_because_of_inline() -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] #[inline] pub fn body_exported_to_metadata_because_of_inline() -> u32 { @@ -55,7 +55,7 @@ pub fn body_exported_to_metadata_because_of_generic() -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] #[inline] pub fn body_exported_to_metadata_because_of_generic() -> u32 { diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs index 90c1ecf10c707..da093ded63566 100644 --- a/src/test/incremental/hashes/for_loops.rs +++ b/src/test/incremental/hashes/for_loops.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -48,7 +48,7 @@ pub fn change_iteration_variable_name() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_iteration_variable_name() { let mut _x = 0; @@ -71,7 +71,7 @@ pub fn change_iteration_variable_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_iteration_variable_pattern() { let mut _x = 0; @@ -94,7 +94,7 @@ pub fn change_iterable() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_iterable() { let mut _x = 0; @@ -116,7 +116,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -187,7 +187,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -237,7 +237,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -262,7 +262,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 21263c8b6c614..8a0af2b0044a4 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -24,7 +24,7 @@ pub fn add_parameter() {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn add_parameter(p: i32) {} @@ -47,7 +47,7 @@ pub fn type_of_parameter(p: i32) {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn type_of_parameter(p: i64) {} @@ -59,7 +59,7 @@ pub fn type_of_parameter_ref(p: &i32) {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn type_of_parameter_ref(p: &mut i32) {} @@ -71,7 +71,7 @@ pub fn order_of_parameters(p1: i32, p2: i64) {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn order_of_parameters(p2: i64, p1: i32) {} @@ -83,7 +83,7 @@ pub fn make_unsafe() {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub unsafe fn make_unsafe() {} @@ -292,7 +292,7 @@ pub mod change_return_type_indirectly { use super::ReferencedType2 as ReturnType; #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn indirect_return_type() -> ReturnType { ReturnType {} @@ -309,7 +309,7 @@ pub mod change_parameter_type_indirectly { use super::ReferencedType2 as ParameterType; #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirValidated, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn indirect_parameter_type(p: ParameterType) {} } diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs index 18dba63072bad..a01247ff4243c 100644 --- a/src/test/incremental/hashes/if_expressions.rs +++ b/src/test/incremental/hashes/if_expressions.rs @@ -25,7 +25,7 @@ pub fn change_condition(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_condition(x: bool) -> u32 { if !x { @@ -46,7 +46,7 @@ pub fn change_then_branch(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_then_branch(x: bool) -> u32 { if x { @@ -69,7 +69,7 @@ pub fn change_else_branch(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_else_branch(x: bool) -> u32 { if x { @@ -120,7 +120,7 @@ pub fn change_condition_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_condition_if_let(x: Option) -> u32 { if let Some(_) = x { @@ -143,7 +143,7 @@ pub fn change_then_branch_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_then_branch_if_let(x: Option) -> u32 { if let Some(x) = x { @@ -166,7 +166,7 @@ pub fn change_else_branch_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_else_branch_if_let(x: Option) -> u32 { if let Some(x) = x { diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 92ce5a606bf90..3abc6c4d2e23e 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -42,7 +42,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn method_body() { println!("Hello, world!"); @@ -63,7 +63,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] #[inline] pub fn method_body_inlined() { @@ -114,7 +114,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirValidated" + except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt" )] #[rustc_clean(cfg="cfail3")] pub fn method_selfmutness(&mut self) { } @@ -154,7 +154,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirValidated" + except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt" )] #[rustc_clean(cfg="cfail3")] pub fn add_method_parameter(&self, _: i32) { } @@ -172,7 +172,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_method_parameter_name(&self, b: i64) { } } @@ -191,7 +191,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,MirOptimized,MirValidated,TypeckTables")] + except="Hir,HirBody,FnSignature,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_method_return_type(&self) -> u8 { 0 } } @@ -226,7 +226,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] + #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_method_parameter_order(&self, b: i64, a: i64) { } } @@ -245,7 +245,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirValidated" + except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt" )] #[rustc_clean(cfg="cfail3")] pub unsafe fn make_method_unsafe(&self) { } @@ -447,7 +447,7 @@ impl Bar { impl Bar { #[rustc_clean( cfg="cfail2", - except="GenericsOfItem,FnSignature,TypeckTables,TypeOfItem,MirOptimized,MirValidated" + except="GenericsOfItem,FnSignature,TypeckTables,TypeOfItem,MirOptimized,MirBuilt" )] #[rustc_clean(cfg="cfail3")] pub fn add_type_parameter_to_impl(&self) { } @@ -465,7 +465,7 @@ impl Bar { #[rustc_clean(cfg="cfail2", except="Hir,HirBody")] #[rustc_clean(cfg="cfail3")] impl Bar { - #[rustc_clean(cfg="cfail2", except="FnSignature,MirOptimized,MirValidated,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="FnSignature,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_impl_self_type(&self) { } } diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs index e73aa89a8374d..c5e7f525fd0fb 100644 --- a/src/test/incremental/hashes/inline_asm.rs +++ b/src/test/incremental/hashes/inline_asm.rs @@ -33,7 +33,7 @@ pub fn change_template(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_template(a: i32) -> i32 { @@ -69,7 +69,7 @@ pub fn change_output(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_output(a: i32) -> i32 { @@ -105,7 +105,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_input(_a: i32, _b: i32) -> i32 { @@ -140,7 +140,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_input_constraint(_a: i32, _b: i32) -> i32 { @@ -175,7 +175,7 @@ pub fn change_clobber(_a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_clobber(_a: i32) -> i32 { @@ -210,7 +210,7 @@ pub fn change_options(_a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_options(_a: i32) -> i32 { diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index b6050f059c27b..a2b33fecea865 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -22,7 +22,7 @@ pub fn change_name() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_name() { let _y = 2u64; @@ -38,7 +38,7 @@ pub fn add_type() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn add_type() { let _x: u32 = 2u32; @@ -54,7 +54,7 @@ pub fn change_type() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_type() { let _x: u8 = 2; @@ -70,7 +70,7 @@ pub fn change_mutability_of_reference_type() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_reference_type() { let _x: &mut u64; @@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_slot() { let _x: u64 = 0; @@ -102,7 +102,7 @@ pub fn change_simple_binding_to_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_simple_binding_to_pattern() { let (_a, _b) = (0u8, 'x'); @@ -118,7 +118,7 @@ pub fn change_name_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_name_in_pattern() { let (_a, _c) = (1u8, 'y'); @@ -134,7 +134,7 @@ pub fn add_ref_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn add_ref_in_pattern() { let (ref _a, _b) = (1u8, 'y'); @@ -150,7 +150,7 @@ pub fn add_amp_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn add_amp_in_pattern() { let (&_a, _b) = (&1u8, 'y'); @@ -166,7 +166,7 @@ pub fn change_mutability_of_binding_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); @@ -182,7 +182,7 @@ pub fn add_initializer() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirValidated,MirOptimized")] + except="HirBody,TypeckTables,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn add_initializer() { let _x: i16 = 3i16; @@ -198,7 +198,7 @@ pub fn change_initializer() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_initializer() { let _x = 5u16; diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs index a218b01fc8512..a48d150b8b0f2 100644 --- a/src/test/incremental/hashes/loop_expressions.rs +++ b/src/test/incremental/hashes/loop_expressions.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -47,7 +47,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -118,7 +118,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -168,7 +168,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -193,7 +193,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/match_expressions.rs b/src/test/incremental/hashes/match_expressions.rs index b6b934eb7d508..11fe84d88e9b3 100644 --- a/src/test/incremental/hashes/match_expressions.rs +++ b/src/test/incremental/hashes/match_expressions.rs @@ -26,7 +26,7 @@ pub fn add_arm(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_arm(x: u32) -> u32 { match x { @@ -51,7 +51,7 @@ pub fn change_order_of_arms(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_order_of_arms(x: u32) -> u32 { match x { @@ -75,7 +75,7 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -99,7 +99,7 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -123,7 +123,7 @@ pub fn add_at_binding(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_at_binding(x: u32) -> u32 { match x { @@ -147,7 +147,7 @@ pub fn change_name_of_at_binding(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_name_of_at_binding(x: u32) -> u32 { match x { @@ -170,7 +170,7 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_simple_name_to_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -193,7 +193,7 @@ pub fn change_name_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_name_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -216,7 +216,7 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -238,7 +238,7 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -260,7 +260,7 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", -except="HirBody,MirValidated,MirOptimized,TypeckTables")] +except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { match (&x, x & 1) { @@ -283,7 +283,7 @@ pub fn change_rhs_of_arm(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized")] + except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_rhs_of_arm(x: u32) -> u32 { match x { @@ -307,7 +307,7 @@ pub fn add_alternative_to_arm(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirValidated,MirOptimized,TypeckTables")] + except="HirBody,MirBuilt,MirOptimized,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_alternative_to_arm(x: u32) -> u32 { match x { diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs index 3ae2c396d829c..9a3c93147a098 100644 --- a/src/test/incremental/hashes/panic_exprs.rs +++ b/src/test/incremental/hashes/panic_exprs.rs @@ -18,7 +18,7 @@ // Indexing expression --------------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn indexing(slice: &[u8]) -> u8 { #[cfg(cfail1)] @@ -33,7 +33,7 @@ pub fn indexing(slice: &[u8]) -> u8 { // Arithmetic overflow plus ---------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_plus(val: i32) -> i32 { #[cfg(cfail1)] @@ -48,7 +48,7 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 { // Arithmetic overflow minus ---------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_minus(val: i32) -> i32 { #[cfg(cfail1)] @@ -63,7 +63,7 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 { // Arithmetic overflow mult ---------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_mult(val: i32) -> i32 { #[cfg(cfail1)] @@ -78,7 +78,7 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 { // Arithmetic overflow negation ------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_negation(val: i32) -> i32 { #[cfg(cfail1)] @@ -93,7 +93,7 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 { // Division by zero ------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn division_by_zero(val: i32) -> i32 { #[cfg(cfail1)] @@ -107,7 +107,7 @@ pub fn division_by_zero(val: i32) -> i32 { } // Division by zero ------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn mod_by_zero(val: i32) -> i32 { #[cfg(cfail1)] @@ -122,7 +122,7 @@ pub fn mod_by_zero(val: i32) -> i32 { // shift left ------------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn shift_left(val: i32, shift: usize) -> i32 { #[cfg(cfail1)] @@ -137,7 +137,7 @@ pub fn shift_left(val: i32, shift: usize) -> i32 { // shift right ------------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirValidated,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn shift_right(val: i32, shift: usize) -> i32 { #[cfg(cfail1)] diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs index 5444fe78f0a47..a42fda3188520 100644 --- a/src/test/incremental/hashes/struct_constructors.rs +++ b/src/test/incremental/hashes/struct_constructors.rs @@ -31,7 +31,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_regular_struct() -> RegularStruct { RegularStruct { @@ -82,7 +82,7 @@ pub fn add_field_regular_struct() -> RegularStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_field_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -117,7 +117,7 @@ pub fn change_field_label_regular_struct() -> RegularStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_field_label_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -152,7 +152,7 @@ pub fn change_constructor_path_regular_struct() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_regular_struct() { let _ = RegularStruct2 { @@ -173,7 +173,7 @@ pub mod change_constructor_path_indirectly_regular_struct { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirValidated,TypeckTables" + except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn function() -> Struct { @@ -196,7 +196,7 @@ pub fn change_field_value_tuple_struct() -> TupleStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_tuple_struct() -> TupleStruct { TupleStruct(0, 1, 3) @@ -213,7 +213,7 @@ pub fn change_constructor_path_tuple_struct() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_tuple_struct() { let _ = TupleStruct2(0, 1, 2); @@ -230,7 +230,7 @@ pub mod change_constructor_path_indirectly_tuple_struct { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirValidated,TypeckTables" + except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn function() -> Struct { diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs index 26cc41fd8186c..ef8035a300a43 100644 --- a/src/test/incremental/hashes/unary_and_binary_exprs.rs +++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs @@ -21,7 +21,7 @@ pub fn const_negation() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn const_negation() -> i32 { -1 @@ -36,7 +36,7 @@ pub fn const_bitwise_not() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn const_bitwise_not() -> i32 { !99 @@ -51,7 +51,7 @@ pub fn var_negation(x: i32, y: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn var_negation(x: i32, y: i32) -> i32 { -y @@ -66,7 +66,7 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn var_bitwise_not(x: i32, y: i32) -> i32 { !y @@ -81,7 +81,7 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated,TypeckTables", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt,TypeckTables", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn var_deref(x: &i32, y: &i32) -> i32 { *y @@ -96,7 +96,7 @@ pub fn first_const_add() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn first_const_add() -> i32 { 2 + 3 @@ -111,7 +111,7 @@ pub fn second_const_add() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn second_const_add() -> i32 { 1 + 3 @@ -126,7 +126,7 @@ pub fn first_var_add(a: i32, b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn first_var_add(a: i32, b: i32) -> i32 { b + 2 @@ -141,7 +141,7 @@ pub fn second_var_add(a: i32, b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn second_var_add(a: i32, b: i32) -> i32 { 1 + b @@ -156,7 +156,7 @@ pub fn plus_to_minus(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_minus(a: i32) -> i32 { 1 - a @@ -171,7 +171,7 @@ pub fn plus_to_mult(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_mult(a: i32) -> i32 { 1 * a @@ -186,7 +186,7 @@ pub fn plus_to_div(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_div(a: i32) -> i32 { 1 / a @@ -201,7 +201,7 @@ pub fn plus_to_mod(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_mod(a: i32) -> i32 { 1 % a @@ -216,7 +216,7 @@ pub fn and_to_or(a: bool, b: bool) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn and_to_or(a: bool, b: bool) -> bool { a || b @@ -231,7 +231,7 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 { 1 | a @@ -246,7 +246,7 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 { 1 ^ a @@ -261,7 +261,7 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_lshift(a: i32) -> i32 { a << 1 @@ -276,7 +276,7 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_rshift(a: i32) -> i32 { a >> 1 @@ -291,7 +291,7 @@ pub fn eq_to_uneq(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_uneq(a: i32) -> bool { a != 1 @@ -306,7 +306,7 @@ pub fn eq_to_lt(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_lt(a: i32) -> bool { a < 1 @@ -321,7 +321,7 @@ pub fn eq_to_gt(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_gt(a: i32) -> bool { a > 1 @@ -336,7 +336,7 @@ pub fn eq_to_le(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_le(a: i32) -> bool { a <= 1 @@ -351,7 +351,7 @@ pub fn eq_to_ge(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_ge(a: i32) -> bool { a >= 1 @@ -368,7 +368,7 @@ pub fn type_cast(a: u8) -> u64 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated,TypeckTables", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt,TypeckTables", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn type_cast(a: u8) -> u64 { let b = a as u32; @@ -385,7 +385,7 @@ pub fn value_cast(a: u32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn value_cast(a: u32) -> i32 { 2 as i32 @@ -403,7 +403,7 @@ pub fn place() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn place() -> i32 { let mut x = 10; @@ -423,7 +423,7 @@ pub fn rvalue() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn rvalue() -> i32 { let mut x = 10; @@ -440,7 +440,7 @@ pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")] +#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 { s[j] diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs index edfea05ae9835..c708d5b969df5 100644 --- a/src/test/incremental/hashes/while_let_loops.rs +++ b/src/test/incremental/hashes/while_let_loops.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -48,7 +48,7 @@ pub fn change_loop_condition() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_condition() { let mut _x = 0; @@ -70,7 +70,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -141,7 +141,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -191,7 +191,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -216,7 +216,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs index 85c2c9fa25064..c7b84a120c8df 100644 --- a/src/test/incremental/hashes/while_loops.rs +++ b/src/test/incremental/hashes/while_loops.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -48,7 +48,7 @@ pub fn change_loop_condition() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_condition() { let mut _x = 0; @@ -70,7 +70,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -141,7 +141,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -191,7 +191,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -216,7 +216,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; From aa775a5debb7bb2988467e59defcc54286a9f74d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 15:05:04 +0900 Subject: [PATCH 0739/1064] rustc-std-workspace-core => 2018 --- src/tools/rustc-std-workspace-core/Cargo.toml | 1 + src/tools/rustc-std-workspace-core/lib.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rustc-std-workspace-core/Cargo.toml b/src/tools/rustc-std-workspace-core/Cargo.toml index f000d634e1943..d527ce12bc3a1 100644 --- a/src/tools/rustc-std-workspace-core/Cargo.toml +++ b/src/tools/rustc-std-workspace-core/Cargo.toml @@ -6,6 +6,7 @@ license = 'MIT/Apache-2.0' description = """ Hack for the compiler's own build system """ +edition = "2018" [lib] path = "lib.rs" diff --git a/src/tools/rustc-std-workspace-core/lib.rs b/src/tools/rustc-std-workspace-core/lib.rs index e2946fe2a97f1..99d51bc2d56ac 100644 --- a/src/tools/rustc-std-workspace-core/lib.rs +++ b/src/tools/rustc-std-workspace-core/lib.rs @@ -1,6 +1,5 @@ #![feature(no_core)] #![no_core] - -extern crate core; +#![deny(rust_2018_idioms)] pub use core::*; From 36806b542e8129e76eb191a46babf5b9d4a037c7 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 15:17:51 +0900 Subject: [PATCH 0740/1064] rustc-workspace-hack => 2018 --- src/tools/rustc-workspace-hack/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index f5eeddda036fd..f943ac9815ac6 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -6,6 +6,7 @@ license = 'MIT/Apache-2.0' description = """ Hack for the compiler's own build system """ +edition = "2018" [lib] path = "lib.rs" From b4a6f597934f16f89e27058a32a514c9572f148f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 8 Feb 2019 04:30:27 +0100 Subject: [PATCH 0741/1064] Allow a dirty MirBuilt for make_extern and make_method_extern --- src/test/incremental/hashes/function_interfaces.rs | 2 +- src/test/incremental/hashes/inherent_impls.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 8a0af2b0044a4..4330b0025a251 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -94,7 +94,7 @@ pub unsafe fn make_unsafe() {} pub fn make_extern() {} #[cfg(not(cfail1))] -#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, TypeckTables, FnSignature")] +#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, MirBuilt, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub extern "C" fn make_extern() {} diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 3abc6c4d2e23e..d1574aee9a9c0 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -263,7 +263,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="Hir,HirBody,FnSignature,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="Hir,HirBody,MirBuilt,FnSignature,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub extern fn make_method_extern(&self) { } } From efa8fb006e6e7d0d70f1e65810b69993df44006c Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 16:44:15 +0900 Subject: [PATCH 0742/1064] error_index_generator => 2018 --- src/tools/error_index_generator/Cargo.toml | 1 + src/tools/error_index_generator/main.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index 7f8783c9d89be..116be234f3ceb 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "error_index_generator" version = "0.0.0" +edition = "2018" [dependencies] rustdoc = { path = "../../librustdoc" } diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 72cfd7d5e58e9..ef045495a0864 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -1,8 +1,9 @@ #![feature(rustc_private)] +#![deny(rust_2018_idioms)] + extern crate env_logger; extern crate syntax; -extern crate rustdoc; extern crate serialize as rustc_serialize; use std::collections::BTreeMap; From 5ef71508fec1e2f89b257f6b6b65e5ca3295d658 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sun, 9 Dec 2018 17:40:49 +0100 Subject: [PATCH 0743/1064] unused_imports: update tests --- src/test/ui/bad/bad-lint-cap2.stderr | 2 +- src/test/ui/bad/bad-lint-cap3.stderr | 2 +- src/test/ui/imports/unused.stderr | 2 +- src/test/ui/issues/issue-30730.stderr | 2 +- ...directives-on-use-items-issue-10534.stderr | 4 ++-- src/test/ui/lint/lint-unused-imports.rs | 2 +- src/test/ui/lint/lint-unused-imports.stderr | 20 ++++++++++--------- .../ui/lint/lints-in-foreign-macros.stderr | 6 +++--- .../rfc-2166-underscore-imports/basic.stderr | 4 ++-- .../unused-2018.stderr | 4 ++-- src/test/ui/span/multispan-import-lint.stderr | 4 ++++ .../use/use-nested-groups-unused-imports.rs | 2 +- .../use-nested-groups-unused-imports.stderr | 12 ++++++----- 13 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/test/ui/bad/bad-lint-cap2.stderr b/src/test/ui/bad/bad-lint-cap2.stderr index d7ec41489d156..b9638722778ee 100644 --- a/src/test/ui/bad/bad-lint-cap2.stderr +++ b/src/test/ui/bad/bad-lint-cap2.stderr @@ -2,7 +2,7 @@ error: unused import: `std::option` --> $DIR/bad-lint-cap2.rs:6:5 | LL | use std::option; //~ ERROR - | ^^^^^^^^^^^ + | ----^^^^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/bad-lint-cap2.rs:4:9 diff --git a/src/test/ui/bad/bad-lint-cap3.stderr b/src/test/ui/bad/bad-lint-cap3.stderr index 5bf0b089afa20..21ed50b550afc 100644 --- a/src/test/ui/bad/bad-lint-cap3.stderr +++ b/src/test/ui/bad/bad-lint-cap3.stderr @@ -2,7 +2,7 @@ warning: unused import: `std::option` --> $DIR/bad-lint-cap3.rs:7:5 | LL | use std::option; //~ WARN - | ^^^^^^^^^^^ + | ----^^^^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/bad-lint-cap3.rs:4:9 diff --git a/src/test/ui/imports/unused.stderr b/src/test/ui/imports/unused.stderr index b56e930158cc1..fa82e974e1e29 100644 --- a/src/test/ui/imports/unused.stderr +++ b/src/test/ui/imports/unused.stderr @@ -2,7 +2,7 @@ error: unused import: `super::f` --> $DIR/unused.rs:7:24 | LL | pub(super) use super::f; //~ ERROR unused - | ^^^^^^^^ + | ---------------^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/unused.rs:1:9 diff --git a/src/test/ui/issues/issue-30730.stderr b/src/test/ui/issues/issue-30730.stderr index 0a901076f467a..3cfadd33b8fec 100644 --- a/src/test/ui/issues/issue-30730.stderr +++ b/src/test/ui/issues/issue-30730.stderr @@ -2,7 +2,7 @@ error: unused import: `std::thread` --> $DIR/issue-30730.rs:3:5 | LL | use std::thread; - | ^^^^^^^^^^^ + | ----^^^^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/issue-30730.rs:2:9 diff --git a/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr b/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr index 170b98a12a848..e588d24517c8c 100644 --- a/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr +++ b/src/test/ui/lint/lint-directives-on-use-items-issue-10534.stderr @@ -2,7 +2,7 @@ error: unused import: `a::x` --> $DIR/lint-directives-on-use-items-issue-10534.rs:12:9 | LL | use a::x; //~ ERROR: unused import - | ^^^^ + | ----^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/lint-directives-on-use-items-issue-10534.rs:1:9 @@ -14,7 +14,7 @@ error: unused import: `a::y` --> $DIR/lint-directives-on-use-items-issue-10534.rs:21:9 | LL | use a::y; //~ ERROR: unused import - | ^^^^ + | ----^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/lint-directives-on-use-items-issue-10534.rs:20:12 diff --git a/src/test/ui/lint/lint-unused-imports.rs b/src/test/ui/lint/lint-unused-imports.rs index 489252479fef3..9c5b206203c1d 100644 --- a/src/test/ui/lint/lint-unused-imports.rs +++ b/src/test/ui/lint/lint-unused-imports.rs @@ -6,7 +6,7 @@ use bar::c::cc as cal; use std::mem::*; // shouldn't get errors for not using // everything imported use std::fmt::{}; -//~^ ERROR unused import: `use std::fmt::{};` +//~^ ERROR unused import: `std::fmt::{}` // Should get errors for both 'Some' and 'None' use std::option::Option::{Some, None}; diff --git a/src/test/ui/lint/lint-unused-imports.stderr b/src/test/ui/lint/lint-unused-imports.stderr index 214f4a472dc7e..7970b0201db70 100644 --- a/src/test/ui/lint/lint-unused-imports.stderr +++ b/src/test/ui/lint/lint-unused-imports.stderr @@ -1,8 +1,8 @@ -error: unused import: `use std::fmt::{};` - --> $DIR/lint-unused-imports.rs:8:1 +error: unused import: `std::fmt::{}` + --> $DIR/lint-unused-imports.rs:8:5 | LL | use std::fmt::{}; - | ^^^^^^^^^^^^^^^^^ + | ----^^^^^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/lint-unused-imports.rs:1:9 @@ -14,37 +14,39 @@ error: unused imports: `None`, `Some` --> $DIR/lint-unused-imports.rs:12:27 | LL | use std::option::Option::{Some, None}; - | ^^^^ ^^^^ + | --------------------------^^^^--^^^^-- help: remove the whole `use` item error: unused import: `test::A` --> $DIR/lint-unused-imports.rs:15:5 | LL | use test::A; //~ ERROR unused import: `test::A` - | ^^^^^^^ + | ----^^^^^^^- help: remove the whole `use` item error: unused import: `bar` --> $DIR/lint-unused-imports.rs:24:18 | LL | use test2::{foo, bar}; //~ ERROR unused import: `bar` - | ^^^ + | --^^^ + | | + | help: remove the unused import error: unused import: `foo::Square` --> $DIR/lint-unused-imports.rs:52:13 | LL | use foo::Square; //~ ERROR unused import: `foo::Square` - | ^^^^^^^^^^^ + | ----^^^^^^^^^^^- help: remove the whole `use` item error: unused import: `self::g` --> $DIR/lint-unused-imports.rs:68:9 | LL | use self::g; //~ ERROR unused import: `self::g` - | ^^^^^^^ + | ----^^^^^^^- help: remove the whole `use` item error: unused import: `test2::foo` --> $DIR/lint-unused-imports.rs:77:9 | LL | use test2::foo; //~ ERROR unused import: `test2::foo` - | ^^^^^^^^^^ + | ----^^^^^^^^^^- help: remove the whole `use` item error: unused import: `test::B2` --> $DIR/lint-unused-imports.rs:20:5 diff --git a/src/test/ui/lint/lints-in-foreign-macros.stderr b/src/test/ui/lint/lints-in-foreign-macros.stderr index 8287ca5692bd9..b808ca708a311 100644 --- a/src/test/ui/lint/lints-in-foreign-macros.stderr +++ b/src/test/ui/lint/lints-in-foreign-macros.stderr @@ -2,7 +2,7 @@ warning: unused import: `std::string::ToString` --> $DIR/lints-in-foreign-macros.rs:11:16 | LL | () => {use std::string::ToString;} //~ WARN: unused import - | ^^^^^^^^^^^^^^^^^^^^^ + | ----^^^^^^^^^^^^^^^^^^^^^- help: remove the whole `use` item ... LL | mod a { foo!(); } | ------- in this macro invocation @@ -17,13 +17,13 @@ warning: unused import: `std::string::ToString` --> $DIR/lints-in-foreign-macros.rs:16:18 | LL | mod c { baz!(use std::string::ToString;); } //~ WARN: unused import - | ^^^^^^^^^^^^^^^^^^^^^ + | ----^^^^^^^^^^^^^^^^^^^^^- help: remove the whole `use` item warning: unused import: `std::string::ToString` --> $DIR/lints-in-foreign-macros.rs:17:19 | LL | mod d { baz2!(use std::string::ToString;); } //~ WARN: unused import - | ^^^^^^^^^^^^^^^^^^^^^ + | ----^^^^^^^^^^^^^^^^^^^^^- help: remove the whole `use` item warning: missing documentation for crate --> $DIR/lints-in-foreign-macros.rs:4:1 diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/rfc-2166-underscore-imports/basic.stderr index 3080359192603..c7b36eaf2e76b 100644 --- a/src/test/ui/rfc-2166-underscore-imports/basic.stderr +++ b/src/test/ui/rfc-2166-underscore-imports/basic.stderr @@ -2,7 +2,7 @@ warning: unused import: `m::Tr1 as _` --> $DIR/basic.rs:26:9 | LL | use m::Tr1 as _; //~ WARN unused import - | ^^^^^^^^^^^ + | ----^^^^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/basic.rs:4:9 @@ -14,5 +14,5 @@ warning: unused import: `S as _` --> $DIR/basic.rs:27:9 | LL | use S as _; //~ WARN unused import - | ^^^^^^ + | ----^^^^^^- help: remove the whole `use` item diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr b/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr index 4163c2876074b..0bbc17276d98b 100644 --- a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr +++ b/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr @@ -2,7 +2,7 @@ error: unused import: `core::any` --> $DIR/unused-2018.rs:6:9 | LL | use core::any; //~ ERROR unused import: `core::any` - | ^^^^^^^^^ + | ----^^^^^^^^^- help: remove the whole `use` item | note: lint level defined here --> $DIR/unused-2018.rs:3:9 @@ -14,7 +14,7 @@ error: unused import: `core` --> $DIR/unused-2018.rs:10:9 | LL | use core; //~ ERROR unused import: `core` - | ^^^^ + | ----^^^^- help: remove the whole `use` item error: aborting due to 2 previous errors diff --git a/src/test/ui/span/multispan-import-lint.stderr b/src/test/ui/span/multispan-import-lint.stderr index a730d081b7c03..6bd0e9be81f5e 100644 --- a/src/test/ui/span/multispan-import-lint.stderr +++ b/src/test/ui/span/multispan-import-lint.stderr @@ -10,4 +10,8 @@ note: lint level defined here LL | #![warn(unused)] | ^^^^^^ = note: #[warn(unused_imports)] implied by #[warn(unused)] +help: remove the unused imports + | +LL | use std::cmp::{min}; + | -- -- diff --git a/src/test/ui/use/use-nested-groups-unused-imports.rs b/src/test/ui/use/use-nested-groups-unused-imports.rs index 5bdc7b2c03f0f..5fe85954dc8e9 100644 --- a/src/test/ui/use/use-nested-groups-unused-imports.rs +++ b/src/test/ui/use/use-nested-groups-unused-imports.rs @@ -18,7 +18,7 @@ use foo::{Foo, bar::{baz::{}, foobar::*}, *}; use foo::bar::baz::{*, *}; //~^ ERROR unused import: `*` use foo::{}; - //~^ ERROR unused import: `use foo::{};` + //~^ ERROR unused import: `foo::{}` fn main() { let _: Bar; diff --git a/src/test/ui/use/use-nested-groups-unused-imports.stderr b/src/test/ui/use/use-nested-groups-unused-imports.stderr index f60c7f5023798..6af6f449de5e6 100644 --- a/src/test/ui/use/use-nested-groups-unused-imports.stderr +++ b/src/test/ui/use/use-nested-groups-unused-imports.stderr @@ -2,7 +2,7 @@ error: unused imports: `*`, `Foo`, `baz::{}`, `foobar::*` --> $DIR/use-nested-groups-unused-imports.rs:16:11 | LL | use foo::{Foo, bar::{baz::{}, foobar::*}, *}; - | ^^^ ^^^^^^^ ^^^^^^^^^ ^ + | ----------^^^--------^^^^^^^--^^^^^^^^^---^-- help: remove the whole `use` item | note: lint level defined here --> $DIR/use-nested-groups-unused-imports.rs:3:9 @@ -14,13 +14,15 @@ error: unused import: `*` --> $DIR/use-nested-groups-unused-imports.rs:18:24 | LL | use foo::bar::baz::{*, *}; - | ^ + | --^ + | | + | help: remove the unused import -error: unused import: `use foo::{};` - --> $DIR/use-nested-groups-unused-imports.rs:20:1 +error: unused import: `foo::{}` + --> $DIR/use-nested-groups-unused-imports.rs:20:5 | LL | use foo::{}; - | ^^^^^^^^^^^^ + | ----^^^^^^^- help: remove the whole `use` item error: aborting due to 3 previous errors From 0d28a24c9463891fe2fe51356c8bcb7e1454298a Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 8 Feb 2019 09:43:15 +0100 Subject: [PATCH 0744/1064] Remove code for updating copyright years in generate-deriving-span-tests It's no longer necessary, as there is no license header anymore. --- src/etc/generate-deriving-span-tests.py | 28 ++++++------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index 3d35ae07fbd68..9bd99dc4ceccf 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -8,13 +8,11 @@ sample usage: src/etc/generate-deriving-span-tests.py """ -import os, datetime, stat, re +import os, stat TEST_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '../test/ui/derives/')) -YEAR = datetime.datetime.now().year - TEMPLATE = """ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' @@ -63,19 +61,11 @@ def create_test_case(type, trait, super_traits, error_count): errors = '\n'.join('//~%s ERROR' % ('^' * n) for n in range(error_count)) code = string.format(traits = all_traits, errors = errors) - return TEMPLATE.format(year = YEAR, error_deriving=error_deriving, code = code) + return TEMPLATE.format(error_deriving=error_deriving, code = code) def write_file(name, string): test_file = os.path.join(TEST_DIR, 'derives-span-%s.rs' % name) - with open(test_file) as f: - old_str = f.read() - old_str_ignoring_date = re.sub(r'^// Copyright \d+', - '// Copyright {year}'.format(year = YEAR), old_str) - if old_str_ignoring_date == string: - # if all we're doing is updating the copyright year, ignore it - return 0 - # set write permission if file exists, so it can be changed if os.path.exists(test_file): os.chmod(test_file, stat.S_IWUSR) @@ -86,8 +76,6 @@ def write_file(name, string): # mark file read-only os.chmod(test_file, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) - return 1 - ENUM = 1 STRUCT = 2 @@ -110,15 +98,11 @@ def write_file(name, string): ('Hash', [], 1)]: traits[trait] = (ALL, supers, errs) -files = 0 - for (trait, (types, super_traits, error_count)) in traits.items(): mk = lambda ty: create_test_case(ty, trait, super_traits, error_count) if types & ENUM: - files += write_file(trait + '-enum', mk(ENUM_TUPLE)) - files += write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT)) + write_file(trait + '-enum', mk(ENUM_TUPLE)) + write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT)) if types & STRUCT: - files += write_file(trait + '-struct', mk(STRUCT_FIELDS)) - files += write_file(trait + '-tuple-struct', mk(STRUCT_TUPLE)) - -print('Generated {files} deriving span test{}.'.format('s' if files != 1 else '', files = files)) + write_file(trait + '-struct', mk(STRUCT_FIELDS)) + write_file(trait + '-tuple-struct', mk(STRUCT_TUPLE)) From df420aa783f7f6e89d9004552db4d7625c3beb0f Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 8 Feb 2019 09:48:12 +0100 Subject: [PATCH 0745/1064] Remove initial newline from automatically generated span tests This change was accidentally introduced while removing license headers. --- src/etc/generate-deriving-span-tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index 9bd99dc4ceccf..1c525101c76f6 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -13,7 +13,7 @@ TEST_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '../test/ui/derives/')) -TEMPLATE = """ +TEMPLATE = """\ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' {error_deriving} From c104b5c89767101a40ef173eb84d3aa1122e5e9a Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 7 Feb 2019 15:44:52 +0100 Subject: [PATCH 0746/1064] Also de-duplicate 32- and 64-bit number formatting on wasm32 --- src/libcore/fmt/num.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 31886748fa6c1..b9fa364037108 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -257,12 +257,22 @@ macro_rules! impl_Display { }; } -impl_Display!(i8, u8, i16, u16, i32, u32 as u32 via to_u32 named fmt_u32); -impl_Display!(i64, u64 as u64 via to_u64 named fmt_u64); +// Include wasm32 in here since it doesn't reflect the native pointer size, and +// often cares strongly about getting a smaller code size. +#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] +mod imp { + use super::*; + impl_Display!( + i8, u8, i16, u16, i32, u32, i64, u64, usize, isize + as u64 via to_u64 named fmt_u64 + ); +} + +#[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] +mod imp { + use super::*; + impl_Display!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named fmt_u32); + impl_Display!(i64, u64 as u64 via to_u64 named fmt_u64); +} + impl_Display!(i128, u128 as u128 via to_u128 named fmt_u128); -#[cfg(target_pointer_width = "16")] -impl_Display!(isize, usize as u16 via to_u16 named fmt_usize); -#[cfg(target_pointer_width = "32")] -impl_Display!(isize, usize as u32 via to_u32 named fmt_usize); -#[cfg(target_pointer_width = "64")] -impl_Display!(isize, usize as u64 via to_u64 named fmt_usize); From 05df9ff41537bab6586eea7ad9272eeb611e09e1 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 7 Feb 2019 17:05:23 +0100 Subject: [PATCH 0747/1064] Add a wasm code size test for stringifying numbers --- .../wasm-stringify-ints-small/Makefile | 10 +++++ .../run-make/wasm-stringify-ints-small/foo.rs | 39 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/test/run-make/wasm-stringify-ints-small/Makefile create mode 100755 src/test/run-make/wasm-stringify-ints-small/foo.rs diff --git a/src/test/run-make/wasm-stringify-ints-small/Makefile b/src/test/run-make/wasm-stringify-ints-small/Makefile new file mode 100644 index 0000000000000..18e47242f806b --- /dev/null +++ b/src/test/run-make/wasm-stringify-ints-small/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown + wc -c < $(TMPDIR)/foo.wasm + [ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "21000" ] +else +all: +endif diff --git a/src/test/run-make/wasm-stringify-ints-small/foo.rs b/src/test/run-make/wasm-stringify-ints-small/foo.rs new file mode 100755 index 0000000000000..6aa249aabeb93 --- /dev/null +++ b/src/test/run-make/wasm-stringify-ints-small/foo.rs @@ -0,0 +1,39 @@ +#![crate_type = "cdylib"] + +extern "C" { + fn observe(ptr: *const u8, len: usize); + + fn get_u8() -> u8; + fn get_i8() -> i8; + fn get_u16() -> u16; + fn get_i16() -> i16; + fn get_u32() -> u32; + fn get_i32() -> i32; + fn get_u64() -> u64; + fn get_i64() -> i64; + fn get_usize() -> usize; + fn get_isize() -> isize; +} + +macro_rules! stringify { + ( $($f:ident)* ) => { + $( + let s = $f().to_string(); + observe(s.as_ptr(), s.len()); + )* + }; +} + +#[no_mangle] +pub unsafe extern "C" fn foo() { + stringify!(get_u8); + stringify!(get_i8); + stringify!(get_u16); + stringify!(get_i16); + stringify!(get_u32); + stringify!(get_i32); + stringify!(get_u64); + stringify!(get_i64); + stringify!(get_usize); + stringify!(get_isize); +} From 8fea7054b9c77a7dcf242ce84cfc0a58d81a9c00 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 8 Feb 2019 10:02:24 +0100 Subject: [PATCH 0748/1064] Use write_char for writing padding characters Removes some unsafe *and* saves almost half a kilobyte of code size. --- src/libcore/fmt/mod.rs | 30 +++++-------------- .../wasm-stringify-ints-small/Makefile | 2 +- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 605779046ef51..4c0eb1eeb5530 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1039,24 +1039,19 @@ pub fn write(output: &mut dyn Write, args: Arguments) -> Result { /// Padding after the end of something. Returned by `Formatter::padding`. #[must_use = "don't forget to write the post padding"] struct PostPadding { - fill: [u8; 4], - fill_len: u32, + fill: char, padding: usize, } impl PostPadding { - /// Safety relies on `fill[..fill_len]` being a valid UTF-8 char. - unsafe fn new(fill: [u8; 4], fill_len: u32, padding: usize) -> PostPadding { - PostPadding { fill, fill_len, padding } + fn new(fill: char, padding: usize) -> PostPadding { + PostPadding { fill, padding } } /// Write this post padding. fn write(self, buf: &mut dyn Write) -> Result { - let fill = unsafe { - str::from_utf8_unchecked(&self.fill.get_unchecked(..self.fill_len as usize)) - }; for _ in 0..self.padding { - buf.write_str(fill)?; + buf.write_char(self.fill)?; } Ok(()) } @@ -1326,20 +1321,11 @@ impl<'a> Formatter<'a> { rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2), }; - let mut fill = [0; 4]; - let fill_len = { - let fill = self.fill.encode_utf8(&mut fill); - - for _ in 0..pre_pad { - self.buf.write_str(fill)?; - } - - fill.len() - }; + for _ in 0..pre_pad { + self.buf.write_char(self.fill)?; + } - Ok(unsafe { - PostPadding::new(fill, fill_len as u32, post_pad) - }) + Ok(PostPadding::new(self.fill, post_pad)) } /// Takes the formatted parts and applies the padding. diff --git a/src/test/run-make/wasm-stringify-ints-small/Makefile b/src/test/run-make/wasm-stringify-ints-small/Makefile index 18e47242f806b..26de6a0c68990 100644 --- a/src/test/run-make/wasm-stringify-ints-small/Makefile +++ b/src/test/run-make/wasm-stringify-ints-small/Makefile @@ -4,7 +4,7 @@ ifeq ($(TARGET),wasm32-unknown-unknown) all: $(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown wc -c < $(TMPDIR)/foo.wasm - [ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "21000" ] + [ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "20500" ] else all: endif From f00f0e676887c8970858897836aa1e8a81d8aa60 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 8 Feb 2019 10:04:32 +0100 Subject: [PATCH 0749/1064] Don't shadow the provided `stringify!` macro in a wasm code size test case --- .../run-make/wasm-stringify-ints-small/foo.rs | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) mode change 100755 => 100644 src/test/run-make/wasm-stringify-ints-small/foo.rs diff --git a/src/test/run-make/wasm-stringify-ints-small/foo.rs b/src/test/run-make/wasm-stringify-ints-small/foo.rs old mode 100755 new mode 100644 index 6aa249aabeb93..7a947f013ad48 --- a/src/test/run-make/wasm-stringify-ints-small/foo.rs +++ b/src/test/run-make/wasm-stringify-ints-small/foo.rs @@ -2,22 +2,14 @@ extern "C" { fn observe(ptr: *const u8, len: usize); - - fn get_u8() -> u8; - fn get_i8() -> i8; - fn get_u16() -> u16; - fn get_i16() -> i16; - fn get_u32() -> u32; - fn get_i32() -> i32; - fn get_u64() -> u64; - fn get_i64() -> i64; - fn get_usize() -> usize; - fn get_isize() -> isize; } -macro_rules! stringify { - ( $($f:ident)* ) => { +macro_rules! s { + ( $( $f:ident -> $t:ty );* $(;)* ) => { $( + extern "C" { + fn $f() -> $t; + } let s = $f().to_string(); observe(s.as_ptr(), s.len()); )* @@ -26,14 +18,16 @@ macro_rules! stringify { #[no_mangle] pub unsafe extern "C" fn foo() { - stringify!(get_u8); - stringify!(get_i8); - stringify!(get_u16); - stringify!(get_i16); - stringify!(get_u32); - stringify!(get_i32); - stringify!(get_u64); - stringify!(get_i64); - stringify!(get_usize); - stringify!(get_isize); + s! { + get_u8 -> u8; + get_i8 -> i8; + get_u16 -> u16; + get_i16 -> i16; + get_u32 -> u32; + get_i32 -> i32; + get_u64 -> u64; + get_i64 -> i64; + get_usize -> usize; + get_isize -> isize; + } } From fb3c4fbfc33b77b7beeeaf4a749a2081a8bfbc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 8 Feb 2019 01:16:56 -0800 Subject: [PATCH 0750/1064] Fix nll test output --- src/test/ui/augmented-assignments.nll.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/augmented-assignments.nll.stderr b/src/test/ui/augmented-assignments.nll.stderr index 840b377263db9..33c94d6e3a59e 100644 --- a/src/test/ui/augmented-assignments.nll.stderr +++ b/src/test/ui/augmented-assignments.nll.stderr @@ -9,7 +9,7 @@ LL | x //~ error: use of moved value: `x` LL | | //~^ value used here after move LL | | += LL | | x; //~ value moved here - | | - + | | ^ | | | | |_____move out of `x` occurs here | borrow later used here From 5288f3f9674f876ba7b28c4594301c00cab14984 Mon Sep 17 00:00:00 2001 From: hrls Date: Fri, 8 Feb 2019 12:47:20 +0300 Subject: [PATCH 0751/1064] fix rustdoc JS --- src/librustdoc/html/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index d6c05de0df6f2..877ac9a62bbec 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2026,7 +2026,7 @@ if (!DOMTokenList.prototype.remove) { } else if (action === "hide") { addClass(relatedDoc, "fns-now-collapsed"); addClass(docblock, "hidden-by-usual-hider"); - onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule); + onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule)); onEachLazy(relatedDoc.childNodes, implHider(true, dontApplyBlockRule)); } } From 541503afa13a4ea8596755e0e88e6dd13a95faa5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 8 Feb 2019 11:41:01 +0100 Subject: [PATCH 0752/1064] std::sys::unix::stdio: explain why we do into_raw --- src/libstd/sys/unix/stdio.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs index 8a6b7b5f876ff..715f2eafb2d9b 100644 --- a/src/libstd/sys/unix/stdio.rs +++ b/src/libstd/sys/unix/stdio.rs @@ -12,7 +12,7 @@ impl Stdin { pub fn read(&self, data: &mut [u8]) -> io::Result { let fd = FileDesc::new(libc::STDIN_FILENO); let ret = fd.read(data); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } } @@ -23,7 +23,7 @@ impl Stdout { pub fn write(&self, data: &[u8]) -> io::Result { let fd = FileDesc::new(libc::STDOUT_FILENO); let ret = fd.write(data); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } @@ -38,7 +38,7 @@ impl Stderr { pub fn write(&self, data: &[u8]) -> io::Result { let fd = FileDesc::new(libc::STDERR_FILENO); let ret = fd.write(data); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } From 7815c9b1c80c96d80b2054a5bc182bc628473cfd Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 19:56:52 +0900 Subject: [PATCH 0753/1064] Revert removed #![feature(nll)] --- src/librustc_mir/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 72a13c791cec0..afd33a51a6a3b 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -4,6 +4,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! */ +#![feature(nll)] #![feature(in_band_lifetimes)] #![feature(slice_patterns)] #![feature(slice_sort_by_cached_key)] From d2514523db8d02fedc6f5d88545b96c55dd26a43 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 20:08:08 +0900 Subject: [PATCH 0754/1064] Use real try blocks --- src/librustc_mir/borrow_check/nll/mod.rs | 4 ++-- src/librustc_mir/lib.rs | 9 +-------- src/librustc_mir/util/pretty.rs | 4 ++-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 128d54c9f49d7..1fca104cd3825 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -254,14 +254,14 @@ fn dump_mir_results<'a, 'gcx, 'tcx>( ); // Also dump the inference graph constraints as a graphviz file. - let _: io::Result<()> = try_block! { + let _: io::Result<()> = try { let mut file = pretty::create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, source)?; regioncx.dump_graphviz_raw_constraints(&mut file)?; }; // Also dump the inference graph constraints as a graphviz file. - let _: io::Result<()> = try_block! { + let _: io::Result<()> = try { let mut file = pretty::create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, source)?; regioncx.dump_graphviz_scc_constraints(&mut file)?; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index afd33a51a6a3b..143104a0feec1 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -26,6 +26,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(slice_concat_ext)] #![feature(try_from)] #![feature(reverse_bits)] +#![feature(try_blocks)] #![recursion_limit="256"] @@ -43,14 +44,6 @@ extern crate serialize as rustc_serialize; // used by deriving #[macro_use] extern crate syntax; -// Once we can use edition 2018 in the compiler, -// replace this with real try blocks. -macro_rules! try_block { - ($($inside:tt)*) => ( - (||{ ::std::ops::Try::from_ok({ $($inside)* }) })() - ) -} - mod diagnostics; mod borrow_check; diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 6e1ec31c9372f..2e1fc756833b8 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -131,7 +131,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( ) where F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { - let _: io::Result<()> = try_block! { + let _: io::Result<()> = try { let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?; writeln!(file, "// MIR for `{}`", node_path)?; writeln!(file, "// source = {:?}", source)?; @@ -148,7 +148,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( }; if tcx.sess.opts.debugging_opts.dump_mir_graphviz { - let _: io::Result<()> = try_block! { + let _: io::Result<()> = try { let mut file = create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?; write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?; From c9bc85ecf100da1358ff2c2545fe5fa6caa506c2 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 20:13:12 +0900 Subject: [PATCH 0755/1064] Remove #[macro_use] extern crate bitflags --- src/librustc_mir/lib.rs | 2 -- src/librustc_mir/transform/qualify_consts.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 143104a0feec1..909f96956695d 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -33,8 +33,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] -#[macro_use] -extern crate bitflags; #[macro_use] extern crate log; #[macro_use] extern crate rustc; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index c786e9438af12..ab4e3ad23f69a 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -30,7 +30,7 @@ use std::usize; use crate::transform::{MirPass, MirSource}; use super::promote_consts::{self, Candidate, TempState}; -bitflags! { +bitflags::bitflags! { // Borrows of temporaries can be promoted only if // they have none of these qualifications, with // the exception of `STATIC_REF` (in statics only). From 6140134b6f2004a4d331821278c8b17f47a51f25 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 20:35:41 +0900 Subject: [PATCH 0756/1064] librustc_lint => 2018 --- src/librustc_lint/Cargo.toml | 1 + src/librustc_lint/builtin.rs | 108 +++++++++++++------------ src/librustc_lint/diagnostics.rs | 2 + src/librustc_lint/lib.rs | 10 +-- src/librustc_lint/nonstandard_style.rs | 39 ++++----- src/librustc_lint/types.rs | 19 +++-- src/librustc_lint/unused.rs | 29 ++++--- 7 files changed, 108 insertions(+), 100 deletions(-) diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 7fb7a06ea1ad5..82f7118df2d0b 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_lint" version = "0.0.0" +edition = "2018" [lib] name = "rustc_lint" diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7c25d8d8b793f..cbcc7f3574d03 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -21,6 +21,7 @@ use rustc::hir::def::Def; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::{self, Ty}; +use rustc::{lint, util}; use hir::Node; use util::nodemap::NodeSet; use lint::{LateContext, LintContext, LintArray}; @@ -42,10 +43,13 @@ use syntax::symbol::keywords; use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::expr_to_string; use syntax::visit::FnKind; +use syntax::struct_span_err; use rustc::hir::{self, GenericParamKind, PatKind}; -use nonstandard_style::{MethodLateContext, method_context}; +use crate::nonstandard_style::{MethodLateContext, method_context}; + +use log::debug; // hardwired lints from librustc pub use lint::builtin::*; @@ -70,7 +74,7 @@ impl LintPass for WhileTrue { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue { - fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { if let hir::ExprKind::While(ref cond, ..) = e.node { if let hir::ExprKind::Lit(ref lit) = cond.node { if let ast::LitKind::Bool(true) = lit.node { @@ -102,7 +106,7 @@ declare_lint! { pub struct BoxPointers; impl BoxPointers { - fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext, span: Span, ty: Ty) { + fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext<'_, '_>, span: Span, ty: Ty<'_>) { for leaf_ty in ty.walk() { if leaf_ty.is_box() { let m = format!("type uses owned (Box type) pointers: {}", ty); @@ -123,7 +127,7 @@ impl LintPass for BoxPointers { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) | @@ -150,7 +154,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { } } - fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { let ty = cx.tables.node_id_to_type(e.hir_id); self.check_heap_type(cx, e.span, ty); } @@ -176,7 +180,7 @@ impl LintPass for NonShorthandFieldPatterns { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { - fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) { + fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat) { if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.node { let variant = cx.tables.pat_ty(pat).ty_adt_def() .expect("struct pattern type is not an ADT") @@ -233,7 +237,7 @@ impl LintPass for UnsafeCode { } impl UnsafeCode { - fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) { + fn report_unsafe(&self, cx: &EarlyContext<'_>, span: Span, desc: &'static str) { // This comes from a macro that has #[allow_internal_unsafe]. if span.allows_unsafe() { return; @@ -244,7 +248,7 @@ impl UnsafeCode { } impl EarlyLintPass for UnsafeCode { - fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { if attr.check_name("allow_internal_unsafe") { self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \ macros using unsafe without triggering \ @@ -252,7 +256,7 @@ impl EarlyLintPass for UnsafeCode { } } - fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::Block(ref blk, _) = e.node { // Don't warn about generated blocks, that'll just pollute the output. if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) { @@ -261,7 +265,7 @@ impl EarlyLintPass for UnsafeCode { } } - fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { match it.node { ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => { self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait") @@ -276,8 +280,8 @@ impl EarlyLintPass for UnsafeCode { } fn check_fn(&mut self, - cx: &EarlyContext, - fk: FnKind, + cx: &EarlyContext<'_>, + fk: FnKind<'_>, _: &ast::FnDecl, span: Span, _: ast::NodeId) { @@ -296,7 +300,7 @@ impl EarlyLintPass for UnsafeCode { } } - fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) { + fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &ast::TraitItem) { if let ast::TraitItemKind::Method(ref sig, None) = item.node { if sig.header.unsafety == ast::Unsafety::Unsafe { self.report_unsafe(cx, item.span, "declaration of an `unsafe` method") @@ -354,7 +358,7 @@ impl MissingDoc { } fn check_missing_docs_attrs(&self, - cx: &LateContext, + cx: &LateContext<'_, '_>, id: Option, attrs: &[ast::Attribute], sp: Span, @@ -399,7 +403,7 @@ impl LintPass for MissingDoc { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { - fn enter_lint_attrs(&mut self, _: &LateContext, attrs: &[ast::Attribute]) { + fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { attr.check_name("doc") && @@ -411,11 +415,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { self.doc_hidden_stack.push(doc_hidden); } - fn exit_lint_attrs(&mut self, _: &LateContext, _attrs: &[ast::Attribute]) { + fn exit_lint_attrs(&mut self, _: &LateContext<'_, '_>, _attrs: &[ast::Attribute]) { self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); } - fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) { + fn check_crate(&mut self, cx: &LateContext<'_, '_>, krate: &hir::Crate) { self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate"); for macro_def in &krate.exported_macros { @@ -428,7 +432,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { } } - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { let desc = match it.node { hir::ItemKind::Fn(..) => "a function", hir::ItemKind::Mod(..) => "a module", @@ -473,7 +477,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc); } - fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) { + fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, trait_item: &hir::TraitItem) { if self.private_traits.contains(&trait_item.id) { return; } @@ -491,7 +495,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { desc); } - fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) { + fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem) { // If the method is an impl for a trait, don't doc. if method_context(cx, impl_item.id) == MethodLateContext::TraitImpl { return; @@ -510,7 +514,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { desc); } - fn check_struct_field(&mut self, cx: &LateContext, sf: &hir::StructField) { + fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, sf: &hir::StructField) { if !sf.is_positional() { self.check_missing_docs_attrs(cx, Some(sf.id), @@ -520,7 +524,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { } } - fn check_variant(&mut self, cx: &LateContext, v: &hir::Variant, _: &hir::Generics) { + fn check_variant(&mut self, cx: &LateContext<'_, '_>, v: &hir::Variant, _: &hir::Generics) { self.check_missing_docs_attrs(cx, Some(v.node.data.id()), &v.node.attrs, @@ -549,7 +553,7 @@ impl LintPass for MissingCopyImplementations { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { - fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { if !cx.access_levels.is_reachable(item.id) { return; } @@ -620,7 +624,7 @@ impl LintPass for MissingDebugImplementations { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { - fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { if !cx.access_levels.is_reachable(item.id) { return; } @@ -681,7 +685,7 @@ impl LintPass for AnonymousParameters { } impl EarlyLintPass for AnonymousParameters { - fn check_trait_item(&mut self, cx: &EarlyContext, it: &ast::TraitItem) { + fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::TraitItem) { match it.node { ast::TraitItemKind::Method(ref sig, _) => { for arg in sig.decl.inputs.iter() { @@ -749,7 +753,7 @@ impl LintPass for DeprecatedAttr { } impl EarlyLintPass for DeprecatedAttr { - fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { for &&(n, _, _, ref g) in &self.depr_attrs { if attr.name() == n { if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion), @@ -804,15 +808,15 @@ impl UnusedDocComment { } impl EarlyLintPass for UnusedDocComment { - fn check_local(&mut self, cx: &EarlyContext, decl: &ast::Local) { + fn check_local(&mut self, cx: &EarlyContext<'_>, decl: &ast::Local) { self.warn_if_doc(decl.attrs.iter(), cx); } - fn check_arm(&mut self, cx: &EarlyContext, arm: &ast::Arm) { + fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) { self.warn_if_doc(arm.attrs.iter(), cx); } - fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { self.warn_if_doc(expr.attrs.iter(), cx); } } @@ -837,7 +841,7 @@ impl LintPass for PluginAsLibrary { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { if cx.tcx.plugin_registrar_fn(LOCAL_CRATE).is_some() { // We're compiling a plugin; it's fine to link other plugins. return; @@ -894,7 +898,7 @@ impl LintPass for InvalidNoMangleItems { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { hir::ItemKind::Fn(.., ref generics, _) => { if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") { @@ -968,7 +972,7 @@ impl LintPass for MutableTransmutes { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { - fn check_expr(&mut self, cx: &LateContext, expr: &hir::Expr) { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr) { use rustc_target::spec::abi::Abi::RustIntrinsic; let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \ @@ -1004,7 +1008,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { None } - fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool { + fn def_id_is_transmute(cx: &LateContext<'_, '_>, def_id: DefId) -> bool { cx.tcx.fn_sig(def_id).abi() == RustIntrinsic && cx.tcx.item_name(def_id) == "transmute" } @@ -1032,7 +1036,7 @@ impl LintPass for UnstableFeatures { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures { - fn check_attribute(&mut self, ctx: &LateContext, attr: &ast::Attribute) { + fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) { if attr.check_name("feature") { if let Some(items) = attr.meta_item_list() { for item in items { @@ -1063,7 +1067,7 @@ impl LintPass for UnionsWithDropFields { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields { - fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) { + fn check_item(&mut self, ctx: &LateContext<'_, '_>, item: &hir::Item) { if let hir::ItemKind::Union(ref vdata, _) = item.node { for field in vdata.fields() { let field_ty = ctx.tcx.type_of(ctx.tcx.hir().local_def_id(field.id)); @@ -1099,7 +1103,7 @@ impl LintPass for UnreachablePub { } impl UnreachablePub { - fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId, + fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: ast::NodeId, vis: &hir::Visibility, span: Span, exportable: bool) { let mut applicability = Applicability::MachineApplicable; match vis.node { @@ -1134,20 +1138,20 @@ impl UnreachablePub { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { - fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); } - fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) { + fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, foreign_item: &hir::ForeignItem) { self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis, foreign_item.span, true); } - fn check_struct_field(&mut self, cx: &LateContext, field: &hir::StructField) { + fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, field: &hir::StructField) { self.perform_lint(cx, "field", field.id, &field.vis, field.span, false); } - fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) { + fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem) { self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false); } } @@ -1193,7 +1197,7 @@ impl TypeAliasBounds { } } - fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) { + fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder<'_>) { // Access to associates types should use `::Assoc`, which does not need a // bound. Let's see if this type does that. @@ -1225,7 +1229,7 @@ impl TypeAliasBounds { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { - fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { let (ty, type_alias_generics) = match item.node { hir::ItemKind::Ty(ref ty, ref generics) => (&*ty, generics), _ => return, @@ -1281,7 +1285,7 @@ impl LintPass for UnusedBrokenConst { lint_array!() } } -fn check_const(cx: &LateContext, body_id: hir::BodyId) { +fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) { let def_id = cx.tcx.hir().body_owner_def_id(body_id); let is_static = cx.tcx.is_static(def_id).is_some(); let param_env = if is_static { @@ -1299,7 +1303,7 @@ fn check_const(cx: &LateContext, body_id: hir::BodyId) { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { hir::ItemKind::Const(_, body_id) => { check_const(cx, body_id); @@ -1429,7 +1433,7 @@ impl LintPass for EllipsisInclusiveRangePatterns { } impl EarlyLintPass for EllipsisInclusiveRangePatterns { - fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat, visit_subpats: &mut bool) { + fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &ast::Pat, visit_subpats: &mut bool) { use self::ast::{PatKind, RangeEnd, RangeSyntax::DotDotDot}; /// If `pat` is a `...` pattern, return the start and end of the range, as well as the span @@ -1507,7 +1511,7 @@ impl LintPass for UnnameableTestItems { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { if self.items_nameable { if let hir::ItemKind::Mod(..) = it.node {} else { @@ -1526,7 +1530,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { } } - fn check_item_post(&mut self, _cx: &LateContext, it: &hir::Item) { + fn check_item_post(&mut self, _cx: &LateContext<'_, '_>, it: &hir::Item) { if !self.items_nameable && self.boundary == it.id { self.items_nameable = true; } @@ -1554,7 +1558,7 @@ impl LintPass for KeywordIdents { } impl KeywordIdents { - fn check_tokens(&mut self, cx: &EarlyContext, tokens: TokenStream) { + fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) { for tt in tokens.into_trees() { match tt { TokenTree::Token(span, tok) => match tok.ident() { @@ -1576,13 +1580,13 @@ impl KeywordIdents { } impl EarlyLintPass for KeywordIdents { - fn check_mac_def(&mut self, cx: &EarlyContext, mac_def: &ast::MacroDef, _id: ast::NodeId) { + fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) { self.check_tokens(cx, mac_def.stream()); } - fn check_mac(&mut self, cx: &EarlyContext, mac: &ast::Mac) { + fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) { self.check_tokens(cx, mac.node.tts.clone().into()); } - fn check_ident(&mut self, cx: &EarlyContext, ident: ast::Ident) { + fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { let ident_str = &ident.as_str()[..]; let cur_edition = cx.sess.edition(); let is_raw_ident = |ident: ast::Ident| { @@ -1665,7 +1669,7 @@ impl LintPass for ExplicitOutlivesRequirements { impl ExplicitOutlivesRequirements { fn collect_outlives_bound_spans( &self, - cx: &LateContext, + cx: &LateContext<'_, '_>, item_def_id: DefId, param_name: &str, bounds: &hir::GenericBounds, diff --git a/src/librustc_lint/diagnostics.rs b/src/librustc_lint/diagnostics.rs index 9a608e4fef08b..3165673111cca 100644 --- a/src/librustc_lint/diagnostics.rs +++ b/src/librustc_lint/diagnostics.rs @@ -1,3 +1,5 @@ +use syntax::{register_diagnostic, register_diagnostics}; + register_diagnostics! { E0721, // `await` keyword } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 6607951d2cd14..fa9d8ce6cb7c4 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -21,15 +21,10 @@ #![recursion_limit="256"] -#[macro_use] -extern crate syntax; +#![deny(rust_2018_idioms)] + #[macro_use] extern crate rustc; -#[macro_use] -extern crate log; -extern crate rustc_target; -extern crate syntax_pos; -extern crate rustc_data_structures; mod diagnostics; mod nonstandard_style; @@ -51,7 +46,6 @@ use rustc::lint::builtin::{ parser::ILL_FORMED_ATTRIBUTE_INPUT, }; use rustc::session; -use rustc::util; use rustc::hir; use syntax::ast; diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index ae2ed28104e5b..2dbafc7ede2a2 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,6 +1,7 @@ use rustc::hir::{self, GenericParamKind, PatKind}; use rustc::hir::def::Def; use rustc::hir::intravisit::FnKind; +use rustc::lint; use rustc::ty; use rustc_target::spec::abi::Abi; use lint::{EarlyContext, LateContext, LintContext, LintArray}; @@ -17,7 +18,7 @@ pub enum MethodLateContext { PlainImpl, } -pub fn method_context(cx: &LateContext, id: ast::NodeId) -> MethodLateContext { +pub fn method_context(cx: &LateContext<'_, '_>, id: ast::NodeId) -> MethodLateContext { let def_id = cx.tcx.hir().local_def_id(id); let item = cx.tcx.associated_item(def_id); match item.container { @@ -41,7 +42,7 @@ declare_lint! { pub struct NonCamelCaseTypes; impl NonCamelCaseTypes { - fn check_case(&self, cx: &EarlyContext, sort: &str, ident: &Ident) { + fn check_case(&self, cx: &EarlyContext<'_>, sort: &str, ident: &Ident) { fn char_has_case(c: char) -> bool { c.is_lowercase() || c.is_uppercase() } @@ -115,7 +116,7 @@ impl LintPass for NonCamelCaseTypes { } impl EarlyLintPass for NonCamelCaseTypes { - fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { let has_repr_c = it.attrs .iter() .any(|attr| { @@ -138,11 +139,11 @@ impl EarlyLintPass for NonCamelCaseTypes { } } - fn check_variant(&mut self, cx: &EarlyContext, v: &ast::Variant, _: &ast::Generics) { + fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &ast::Variant, _: &ast::Generics) { self.check_case(cx, "variant", &v.node.ident); } - fn check_generic_param(&mut self, cx: &EarlyContext, param: &ast::GenericParam) { + fn check_generic_param(&mut self, cx: &EarlyContext<'_>, param: &ast::GenericParam) { if let ast::GenericParamKind::Type { .. } = param.kind { self.check_case(cx, "type parameter", ¶m.ident); } @@ -190,7 +191,7 @@ impl NonSnakeCase { } /// Checks if a given identifier is snake case, and reports a diagnostic if not. - fn check_snake_case(&self, cx: &LateContext, sort: &str, ident: &Ident) { + fn check_snake_case(&self, cx: &LateContext<'_, '_>, sort: &str, ident: &Ident) { fn is_snake_case(ident: &str) -> bool { if ident.is_empty() { return true; @@ -249,7 +250,7 @@ impl LintPass for NonSnakeCase { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { - fn check_crate(&mut self, cx: &LateContext, cr: &hir::Crate) { + fn check_crate(&mut self, cx: &LateContext<'_, '_>, cr: &hir::Crate) { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { @@ -286,7 +287,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } } - fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) { + fn check_generic_param(&mut self, cx: &LateContext<'_, '_>, param: &hir::GenericParam) { if let GenericParamKind::Lifetime { .. } = param.kind { self.check_snake_case(cx, "lifetime", ¶m.name.ident()); } @@ -294,8 +295,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { fn check_fn( &mut self, - cx: &LateContext, - fk: FnKind, + cx: &LateContext<'_, '_>, + fk: FnKind<'_>, _: &hir::FnDecl, _: &hir::Body, _: Span, @@ -324,13 +325,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } } - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { if let hir::ItemKind::Mod(_) = it.node { self.check_snake_case(cx, "module", &it.ident); } } - fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) { + fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::TraitItem) { if let hir::TraitItemKind::Method(_, hir::TraitMethod::Required(pnames)) = &item.node { self.check_snake_case(cx, "trait method", &item.ident); for param_name in pnames { @@ -339,7 +340,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } } - fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) { + fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) { if let &PatKind::Binding(_, _, _, ident, _) = &p.node { self.check_snake_case(cx, "variable", &ident); } @@ -347,7 +348,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { fn check_struct_def( &mut self, - cx: &LateContext, + cx: &LateContext<'_, '_>, s: &hir::VariantData, _: ast::Name, _: &hir::Generics, @@ -369,7 +370,7 @@ declare_lint! { pub struct NonUpperCaseGlobals; impl NonUpperCaseGlobals { - fn check_upper_case(cx: &LateContext, sort: &str, ident: &Ident) { + fn check_upper_case(cx: &LateContext<'_, '_>, sort: &str, ident: &Ident) { let name = &ident.name.as_str(); if name.chars().any(|c| c.is_lowercase()) { @@ -399,7 +400,7 @@ impl LintPass for NonUpperCaseGlobals { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => { NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); @@ -411,19 +412,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { } } - fn check_trait_item(&mut self, cx: &LateContext, ti: &hir::TraitItem) { + fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, ti: &hir::TraitItem) { if let hir::TraitItemKind::Const(..) = ti.node { NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ti.ident); } } - fn check_impl_item(&mut self, cx: &LateContext, ii: &hir::ImplItem) { + fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, ii: &hir::ImplItem) { if let hir::ImplItemKind::Const(..) = ii.node { NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident); } } - fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) { + fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) { // Lint for constants that look like binding identifiers (#7526) if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node { if let Def::Const(..) = path.def { diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 4abd55b7e31f7..f6b7ccfe2ecd8 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -4,6 +4,7 @@ use rustc::hir::Node; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx}; +use rustc::{lint, util}; use rustc_data_structures::indexed_vec::Idx; use util::nodemap::FxHashSet; use lint::{LateContext, LintContext, LintArray}; @@ -23,6 +24,8 @@ use rustc::hir; use rustc::mir::interpret::{sign_extend, truncate}; +use log::debug; + declare_lint! { UNUSED_COMPARISONS, Warn, @@ -241,7 +244,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } - fn check_limits(cx: &LateContext, + fn check_limits(cx: &LateContext<'_, '_>, binop: hir::BinOp, l: &hir::Expr, r: &hir::Expr) @@ -298,7 +301,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } - fn get_bin_hex_repr(cx: &LateContext, lit: &ast::Lit) -> Option { + fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &ast::Lit) -> Option { let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?; let firstch = src.chars().next()?; @@ -320,7 +323,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { // // No suggestion for: `isize`, `usize`. fn get_type_suggestion<'a>( - t: &ty::TyKind, + t: &ty::TyKind<'_>, val: u128, negative: bool, ) -> Option { @@ -364,9 +367,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } fn report_bin_hex_error( - cx: &LateContext, + cx: &LateContext<'_, '_>, expr: &hir::Expr, - ty: ty::TyKind, + ty: ty::TyKind<'_>, repr_str: String, val: u128, negative: bool, @@ -481,7 +484,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { fn check_type_for_ffi(&self, cache: &mut FxHashSet>, ty: Ty<'tcx>) -> FfiResult<'tcx> { - use self::FfiResult::*; + use FfiResult::*; let cx = self.cx.tcx; @@ -799,7 +802,7 @@ impl LintPass for ImproperCTypes { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { - fn check_foreign_item(&mut self, cx: &LateContext, it: &hir::ForeignItem) { + fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) { let mut vis = ImproperCTypesVisitor { cx }; let abi = cx.tcx.hir().get_foreign_abi(it.id); if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic { @@ -829,7 +832,7 @@ impl LintPass for VariantSizeDifferences { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { - fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { if let hir::ItemKind::Enum(ref enum_definition, _) = it.node { let item_def_id = cx.tcx.hir().local_def_id(it.id); let t = cx.tcx.type_of(item_def_id); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index acf5da1e1886a..407e684293515 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,5 +1,6 @@ use rustc::hir::def::Def; use rustc::hir::def_id::DefId; +use rustc::lint; use rustc::ty; use rustc::ty::adjustment; use lint::{LateContext, EarlyContext, LintContext, LintArray}; @@ -16,6 +17,8 @@ use syntax_pos::Span; use rustc::hir; +use log::debug; + declare_lint! { pub UNUSED_MUST_USE, Warn, @@ -43,7 +46,7 @@ impl LintPass for UnusedResults { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { - fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { + fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) { let expr = match s.node { hir::StmtKind::Semi(ref expr) => &**expr, _ => return, @@ -168,7 +171,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } fn check_must_use( - cx: &LateContext, + cx: &LateContext<'_, '_>, def_id: DefId, sp: Span, descr_pre_path: &str, @@ -212,7 +215,7 @@ impl LintPass for PathStatements { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements { - fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { + fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) { if let hir::StmtKind::Semi(ref expr) = s.node { if let hir::ExprKind::Path(_) = expr.node { cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect"); @@ -241,7 +244,7 @@ impl LintPass for UnusedAttributes { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { - fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) { debug!("checking attribute: {:?}", attr); // Note that check_name() marks the attribute as used if it matches. for &(name, ty, ..) in BUILTIN_ATTRIBUTES { @@ -303,7 +306,7 @@ pub struct UnusedParens; impl UnusedParens { fn check_unused_parens_expr(&self, - cx: &EarlyContext, + cx: &EarlyContext<'_>, value: &ast::Expr, msg: &str, followed_by_block: bool) { @@ -325,7 +328,7 @@ impl UnusedParens { } fn check_unused_parens_pat(&self, - cx: &EarlyContext, + cx: &EarlyContext<'_>, value: &ast::Pat, msg: &str) { if let ast::PatKind::Paren(_) = value.node { @@ -339,7 +342,7 @@ impl UnusedParens { } } - fn remove_outer_parens(cx: &EarlyContext, span: Span, pattern: &str, msg: &str) { + fn remove_outer_parens(cx: &EarlyContext<'_>, span: Span, pattern: &str, msg: &str) { let span_msg = format!("unnecessary parentheses around {}", msg); let mut err = cx.struct_span_lint(UNUSED_PARENS, span, &span_msg); let mut ate_left_paren = false; @@ -387,7 +390,7 @@ impl LintPass for UnusedParens { } impl EarlyLintPass for UnusedParens { - fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) { + fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { use syntax::ast::ExprKind::*; let (value, msg, followed_by_block) = match e.node { If(ref cond, ..) => (cond, "`if` condition", true), @@ -429,7 +432,7 @@ impl EarlyLintPass for UnusedParens { self.check_unused_parens_expr(cx, &value, msg, followed_by_block); } - fn check_pat(&mut self, cx: &EarlyContext, p: &ast::Pat, _: &mut bool) { + fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat, _: &mut bool) { use ast::PatKind::{Paren, Range}; // The lint visitor will visit each subpattern of `p`. We do not want to lint any range // pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there @@ -443,7 +446,7 @@ impl EarlyLintPass for UnusedParens { } } - fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) { + fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { if let ast::StmtKind::Local(ref local) = s.node { if let Some(ref value) = local.init { self.check_unused_parens_expr(cx, &value, "assigned value", false); @@ -462,7 +465,7 @@ declare_lint! { pub struct UnusedImportBraces; impl UnusedImportBraces { - fn check_use_tree(&self, cx: &EarlyContext, use_tree: &ast::UseTree, item: &ast::Item) { + fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &ast::Item) { if let ast::UseTreeKind::Nested(ref items) = use_tree.kind { // Recursively check nested UseTrees for &(ref tree, _) in items { @@ -509,7 +512,7 @@ impl LintPass for UnusedImportBraces { } impl EarlyLintPass for UnusedImportBraces { - fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { if let ast::ItemKind::Use(ref use_tree) = item.node { self.check_use_tree(cx, use_tree, item); } @@ -536,7 +539,7 @@ impl LintPass for UnusedAllocation { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation { - fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { match e.node { hir::ExprKind::Box(_) => {} _ => return, From b962ecc6f97cbd6258d1a77041a865aecd6fa3fb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 8 Feb 2019 12:38:47 +0100 Subject: [PATCH 0757/1064] Cleanup JS a bit --- src/librustdoc/html/static/main.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index d6c05de0df6f2..3a59d1f259654 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -79,8 +79,6 @@ if (!DOMTokenList.prototype.remove) { // 2 for "In Return Types" var currentTab = 0; - var themesWidth = null; - var titleBeforeSearch = document.title; function getPageId() { @@ -240,7 +238,7 @@ if (!DOMTokenList.prototype.remove) { return String.fromCharCode(c); } - function displayHelp(display, ev) { + function displayHelp(display, ev, help) { if (display === true) { if (hasClass(help, "hidden")) { ev.preventDefault(); @@ -258,7 +256,7 @@ if (!DOMTokenList.prototype.remove) { hideModal(); var search = document.getElementById("search"); if (hasClass(help, "hidden") === false) { - displayHelp(false, ev); + displayHelp(false, ev, help); } else if (hasClass(search, "hidden") === false) { ev.preventDefault(); addClass(search, "hidden"); @@ -289,7 +287,7 @@ if (!DOMTokenList.prototype.remove) { case "s": case "S": - displayHelp(false, ev); + displayHelp(false, ev, help); hideModal(); ev.preventDefault(); focusSearchBar(); @@ -304,7 +302,7 @@ if (!DOMTokenList.prototype.remove) { case "?": if (ev.shiftKey) { hideModal(); - displayHelp(true, ev); + displayHelp(true, ev, help); } break; } @@ -654,7 +652,7 @@ if (!DOMTokenList.prototype.remove) { return MAX_LEV_DISTANCE + 1; } } - return lev_distance;//Math.ceil(total / done); + return Math.ceil(total / done); } } return MAX_LEV_DISTANCE + 1; @@ -2432,7 +2430,7 @@ if (!DOMTokenList.prototype.remove) { // for vertical layout (column-oriented flex layout for divs caused // errors in mobile browsers). if (e.tagName === "H2" || e.tagName === "H3") { - let nextTagName = e.nextElementSibling.tagName; + var nextTagName = e.nextElementSibling.tagName; if (nextTagName == "H2" || nextTagName == "H3") { e.nextElementSibling.style.display = "flex"; } else { From bf531bd4594ad78fe3443554e2b80d7a496faf4a Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 20:40:49 +0900 Subject: [PATCH 0758/1064] librustc_passes => 2018 --- src/librustc_passes/Cargo.toml | 3 ++- src/librustc_passes/ast_validation.rs | 3 ++- src/librustc_passes/diagnostics.rs | 2 ++ src/librustc_passes/hir_stats.rs | 2 +- src/librustc_passes/lib.rs | 14 +++----------- src/librustc_passes/loops.rs | 5 +++-- src/librustc_passes/rvalue_promotion.rs | 16 ++++++++++------ 7 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index f5154a033af8d..00bdcdc0cc021 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_passes" version = "0.0.0" +edition = "2018" [lib] name = "rustc_passes" @@ -16,4 +17,4 @@ rustc_data_structures = { path = "../librustc_data_structures" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } -rustc_errors = { path = "../librustc_errors" } +errors = { path = "../librustc_errors", package = "rustc_errors" } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 3deb2ff8d8a0b..4b1cf6a035ef7 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -15,10 +15,11 @@ use syntax::source_map::Spanned; use syntax::symbol::keywords; use syntax::ptr::P; use syntax::visit::{self, Visitor}; +use syntax::{span_err, struct_span_err, walk_list}; use syntax_ext::proc_macro_decls::is_proc_macro_attr; use syntax_pos::Span; -use errors; use errors::Applicability; +use log::debug; struct AstValidator<'a> { session: &'a Session, diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 037227aeb715d..19d4d3aeb0f65 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; + register_long_diagnostics! { /* E0014: r##" diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 74d6d75a7f528..2427abad07c95 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -61,7 +61,7 @@ impl<'k> StatCollector<'k> { }); entry.count += 1; - entry.size = ::std::mem::size_of_val(node); + entry.size = std::mem::size_of_val(node); } fn print(&self, title: &str) { diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 76605c58a7889..7b0e57846f360 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -13,18 +13,10 @@ #![recursion_limit="256"] -#[macro_use] -extern crate rustc; -extern crate rustc_mir; -extern crate rustc_data_structures; +#![deny(rust_2018_idioms)] #[macro_use] -extern crate log; -#[macro_use] -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc_errors as errors; +extern crate rustc; use rustc::ty::query::Providers; @@ -38,7 +30,7 @@ pub mod loops; __build_diagnostic_array! { librustc_passes, DIAGNOSTICS } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { rvalue_promotion::provide(providers); loops::provide(providers); } diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index f05a7be7d7513..533e043efa9d2 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -1,4 +1,4 @@ -use self::Context::*; +use Context::*; use rustc::session::Session; @@ -9,6 +9,7 @@ use rustc::hir::map::Map; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::{self, Node, Destination}; use syntax::ast; +use syntax::struct_span_err; use syntax_pos::Span; use errors::Applicability; @@ -59,7 +60,7 @@ fn check_mod_loops<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { }.as_deep_visitor()); } -pub(crate) fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers<'_>) { *providers = Providers { check_mod_loops, ..*providers diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index c11b1af97766d..748500ac46b57 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -28,10 +28,11 @@ use rustc::hir; use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -use self::Promotability::*; +use log::debug; +use Promotability::*; use std::ops::{BitAnd, BitAndAssign, BitOr}; -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { rvalue_promotable_map, const_is_rvalue_promotable_to_static, @@ -622,7 +623,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { fn consume(&mut self, _consume_id: ast::NodeId, _consume_span: Span, - _cmt: &mc::cmt_, + _cmt: &mc::cmt_<'_>, _mode: euv::ConsumeMode) {} fn borrow(&mut self, @@ -681,11 +682,14 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { fn mutate(&mut self, _assignment_id: ast::NodeId, _assignment_span: Span, - _assignee_cmt: &mc::cmt_, + _assignee_cmt: &mc::cmt_<'_>, _mode: euv::MutateMode) { } - fn matched_pat(&mut self, _: &hir::Pat, _: &mc::cmt_, _: euv::MatchMode) {} + fn matched_pat(&mut self, _: &hir::Pat, _: &mc::cmt_<'_>, _: euv::MatchMode) {} - fn consume_pat(&mut self, _consume_pat: &hir::Pat, _cmt: &mc::cmt_, _mode: euv::ConsumeMode) {} + fn consume_pat(&mut self, + _consume_pat: &hir::Pat, + _cmt: &mc::cmt_<'_>, + _mode: euv::ConsumeMode) {} } From 7267bc2d4a0ba006d63b58eb927362d620930c68 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 20:50:17 +0900 Subject: [PATCH 0759/1064] librustc_metadata => 2018 --- src/librustc_metadata/Cargo.toml | 3 ++- src/librustc_metadata/creader.rs | 19 +++++++++-------- src/librustc_metadata/cstore.rs | 4 ++-- src/librustc_metadata/cstore_impl.rs | 16 +++++++------- src/librustc_metadata/decoder.rs | 7 +++--- src/librustc_metadata/diagnostics.rs | 2 ++ src/librustc_metadata/dynamic_lib.rs | 2 -- src/librustc_metadata/encoder.rs | 11 +++++----- src/librustc_metadata/index.rs | 7 +++--- src/librustc_metadata/index_builder.rs | 26 +++++++++++------------ src/librustc_metadata/isolated_encoder.rs | 4 ++-- src/librustc_metadata/lib.rs | 14 +++--------- src/librustc_metadata/locator.rs | 13 +++++++----- src/librustc_metadata/native_libs.rs | 1 + src/librustc_metadata/schema.rs | 4 ++-- 15 files changed, 67 insertions(+), 66 deletions(-) diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 337c87c24ba2b..e234f4f880703 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_metadata" version = "0.0.0" +edition = "2018" [lib] name = "rustc_metadata" @@ -14,7 +15,7 @@ log = "0.4" memmap = "0.6" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } +errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } serialize = { path = "../libserialize" } stable_deref_trait = "1.0.0" diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index e9785e7c88d0d..0b4c8a5367c15 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1,9 +1,9 @@ //! Validates all used crates and extern libraries and loads their metadata -use cstore::{self, CStore, CrateSource, MetadataBlob}; -use locator::{self, CratePaths}; -use decoder::proc_macro_def_path_table; -use schema::CrateRoot; +use crate::cstore::{self, CStore, CrateSource, MetadataBlob}; +use crate::locator::{self, CratePaths}; +use crate::decoder::proc_macro_def_path_table; +use crate::schema::CrateRoot; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use rustc::hir::def_id::CrateNum; @@ -29,8 +29,9 @@ use syntax::attr; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; use syntax::visit; +use syntax::{span_err, span_fatal}; use syntax_pos::{Span, DUMMY_SP}; -use log; +use log::{debug, info, log_enabled}; pub struct Library { pub dylib: Option<(PathBuf, PathKind)>, @@ -342,7 +343,7 @@ impl<'a> CrateLoader<'a> { } } - fn load(&mut self, locate_ctxt: &mut locator::Context) -> Option { + fn load(&mut self, locate_ctxt: &mut locator::Context<'_>) -> Option { let library = locate_ctxt.maybe_load_library_crate()?; // In the case that we're loading a crate, but not matching @@ -427,7 +428,7 @@ impl<'a> CrateLoader<'a> { // The map from crate numbers in the crate we're resolving to local crate numbers. // We map 0 and all other holes in the map to our parent crate. The "additional" // self-dependencies should be harmless. - ::std::iter::once(krate).chain(crate_root.crate_deps + std::iter::once(krate).chain(crate_root.crate_deps .decode(metadata) .map(|dep| { info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash, @@ -522,7 +523,7 @@ impl<'a> CrateLoader<'a> { fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option, span: Span) -> Vec<(ast::Name, Lrc)> { use std::{env, mem}; - use dynamic_lib::DynamicLibrary; + use crate::dynamic_lib::DynamicLibrary; use proc_macro::bridge::client::ProcMacro; use syntax_ext::deriving::custom::ProcMacroDerive; use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro}; @@ -996,7 +997,7 @@ impl<'a> CrateLoader<'a> { item.ident, orig_name); let orig_name = match orig_name { Some(orig_name) => { - ::validate_crate_name(Some(self.sess), &orig_name.as_str(), + crate::validate_crate_name(Some(self.sess), &orig_name.as_str(), Some(item.span)); orig_name } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 543fb5d5df5be..a2f69bc45634d 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -1,7 +1,7 @@ // The crate store - a central repo for information collected about external // crates and libraries -use schema; +use crate::schema; use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::map::definitions::DefPathTable; use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; @@ -19,7 +19,7 @@ pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePrefere pub use rustc::middle::cstore::NativeLibraryKind::*; pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule}; -pub use cstore_impl::{provide, provide_extern}; +pub use crate::cstore_impl::{provide, provide_extern}; // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index e61229db86ddb..49a3e335e3417 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -1,9 +1,9 @@ -use cstore::{self, LoadedMacro}; -use encoder; -use link_args; -use native_libs; -use foreign_modules; -use schema; +use crate::cstore::{self, LoadedMacro}; +use crate::encoder; +use crate::link_args; +use crate::native_libs; +use crate::foreign_modules; +use crate::schema; use rustc::ty::query::QueryConfig; use rustc::middle::cstore::{CrateStore, DepKind, @@ -51,7 +51,7 @@ macro_rules! provide { index: CRATE_DEF_INDEX }); let dep_node = def_path_hash - .to_dep_node(::rustc::dep_graph::DepKind::CrateMetadata); + .to_dep_node(rustc::dep_graph::DepKind::CrateMetadata); // The DepNodeIndex of the DepNode::CrateMetadata should be // cached somewhere, so that we can use read_index(). $tcx.dep_graph.read(dep_node); @@ -421,7 +421,7 @@ impl cstore::CStore { use syntax::ext::base::SyntaxExtension; use syntax_ext::proc_macro_impl::BangProcMacro; - let client = ::proc_macro::bridge::client::Client::expand1(::proc_macro::quote); + let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); let ext = SyntaxExtension::ProcMacro { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: true, diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index ad6296e1a3bd8..6d7907b096ac6 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1,7 +1,7 @@ // Decoding metadata from a single crate's metadata -use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; -use schema::*; +use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; +use crate::schema::*; use rustc_data_structures::sync::{Lrc, ReadGuard}; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, Definitions}; @@ -34,6 +34,7 @@ use syntax::symbol::InternedString; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::hygiene::Mark; use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; +use log::debug; pub struct DecodeContext<'a, 'tcx: 'a> { opaque: opaque::Decoder<'a>, @@ -545,7 +546,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_variant(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: &Entry, + item: &Entry<'_>, index: DefIndex, adt_kind: ty::AdtKind) -> ty::VariantDef diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs index 1b1852434740c..c27d13be49358 100644 --- a/src/librustc_metadata/diagnostics.rs +++ b/src/librustc_metadata/diagnostics.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; + register_long_diagnostics! { E0454: r##" A link name was given with an empty name. Erroneous code example: diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index 7d1c3c09d33e9..b9dc4195cb228 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -76,7 +76,6 @@ impl DynamicLibrary { #[cfg(test)] mod tests { use super::*; - use libc; use std::mem; #[test] @@ -127,7 +126,6 @@ mod tests { #[cfg(unix)] mod dl { - use libc; use std::ffi::{CStr, OsStr, CString}; use std::os::unix::prelude::*; use std::ptr; diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 3b212f3b7472d..d68ab9750b970 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1,7 +1,7 @@ -use index::Index; -use index_builder::{FromId, IndexBuilder, Untracked}; -use isolated_encoder::IsolatedEncoder; -use schema::*; +use crate::index::Index; +use crate::index_builder::{FromId, IndexBuilder, Untracked}; +use crate::isolated_encoder::IsolatedEncoder; +use crate::schema::*; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, EncodedMetadata, ForeignModule}; @@ -34,6 +34,7 @@ use syntax::attr; use syntax::source_map::Spanned; use syntax::symbol::keywords; use syntax_pos::{self, hygiene, FileName, SourceFile, Span}; +use log::{debug, trace}; use rustc::hir::{self, PatKind}; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -1521,7 +1522,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { // symbol associated with them (they weren't translated) or if they're an FFI // definition (as that's not defined in this crate). fn encode_exported_symbols(&mut self, - exported_symbols: &[(ExportedSymbol, SymbolExportLevel)]) + exported_symbols: &[(ExportedSymbol<'_>, SymbolExportLevel)]) -> EncodedExportedSymbols { // The metadata symbol name is special. It should not show up in // downstream crates. diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index ccf398241b191..18f30383090cd 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -1,9 +1,10 @@ -use schema::*; +use crate::schema::*; use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace}; use rustc_serialize::opaque::Encoder; use std::slice; use std::u32; +use log::debug; /// While we are generating the metadata, we also track the position /// of each DefIndex. It is not required that all definitions appear @@ -24,12 +25,12 @@ impl Index { } } - pub fn record(&mut self, def_id: DefId, entry: Lazy) { + pub fn record(&mut self, def_id: DefId, entry: Lazy>) { assert!(def_id.is_local()); self.record_index(def_id.index, entry); } - pub fn record_index(&mut self, item: DefIndex, entry: Lazy) { + pub fn record_index(&mut self, item: DefIndex, entry: Lazy>) { assert!(entry.position < (u32::MAX as usize)); let position = entry.position as u32; let space_index = item.address_space().index(); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 3608b12aea934..4175f7acd0688 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -45,10 +45,10 @@ //! give a callback fn, rather than taking a closure: it allows us to //! easily control precisely what data is given to that fn. -use encoder::EncodeContext; -use index::Index; -use schema::*; -use isolated_encoder::IsolatedEncoder; +use crate::encoder::EncodeContext; +use crate::index::Index; +use crate::schema::*; +use crate::isolated_encoder::IsolatedEncoder; use rustc::hir; use rustc::hir::def_id::DefId; @@ -133,21 +133,21 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { /// `DefId` index, or implement the `read` method so that it can add /// a read of whatever dep-graph nodes are appropriate. pub trait DepGraphRead { - fn read(&self, tcx: TyCtxt); + fn read(&self, tcx: TyCtxt<'_, '_, '_>); } impl DepGraphRead for DefId { - fn read(&self, _tcx: TyCtxt) {} + fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {} } impl DepGraphRead for ast::NodeId { - fn read(&self, _tcx: TyCtxt) {} + fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {} } impl DepGraphRead for Option where T: DepGraphRead { - fn read(&self, tcx: TyCtxt) { + fn read(&self, tcx: TyCtxt<'_, '_, '_>) { match *self { Some(ref v) => v.read(tcx), None => (), @@ -158,7 +158,7 @@ impl DepGraphRead for Option impl DepGraphRead for [T] where T: DepGraphRead { - fn read(&self, tcx: TyCtxt) { + fn read(&self, tcx: TyCtxt<'_, '_, '_>) { for i in self { i.read(tcx); } @@ -171,7 +171,7 @@ macro_rules! read_tuple { where $($name: DepGraphRead),* { #[allow(non_snake_case)] - fn read(&self, tcx: TyCtxt) { + fn read(&self, tcx: TyCtxt<'_, '_, '_>) { let &($(ref $name),*) = self; $($name.read(tcx);)* } @@ -184,7 +184,7 @@ read_tuple!(A, B, C); macro_rules! read_hir { ($t:ty) => { impl<'tcx> DepGraphRead for &'tcx $t { - fn read(&self, tcx: TyCtxt) { + fn read(&self, tcx: TyCtxt<'_, '_, '_>) { tcx.hir().read(self.id); } } @@ -208,7 +208,7 @@ read_hir!(hir::MacroDef); pub struct Untracked(pub T); impl DepGraphRead for Untracked { - fn read(&self, _tcx: TyCtxt) {} + fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {} } /// Newtype that can be used to package up misc data extracted from a @@ -218,7 +218,7 @@ impl DepGraphRead for Untracked { pub struct FromId(pub ast::NodeId, pub T); impl DepGraphRead for FromId { - fn read(&self, tcx: TyCtxt) { + fn read(&self, tcx: TyCtxt<'_, '_, '_>) { tcx.hir().read(self.0); } } diff --git a/src/librustc_metadata/isolated_encoder.rs b/src/librustc_metadata/isolated_encoder.rs index c09d35d150a12..e879a73e650bb 100644 --- a/src/librustc_metadata/isolated_encoder.rs +++ b/src/librustc_metadata/isolated_encoder.rs @@ -1,5 +1,5 @@ -use encoder::EncodeContext; -use schema::{Lazy, LazySeq}; +use crate::encoder::EncodeContext; +use crate::schema::{Lazy, LazySeq}; use rustc::ty::TyCtxt; use rustc_serialize::Encodable; diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 1a6614212407d..c8891296417d8 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -15,23 +15,15 @@ #![recursion_limit="256"] +#![deny(rust_2018_idioms)] + extern crate libc; -#[macro_use] -extern crate log; -extern crate memmap; -extern crate stable_deref_trait; -#[macro_use] -extern crate syntax; -extern crate syntax_pos; -extern crate flate2; +#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; // used by deriving -extern crate rustc_errors as errors; -extern crate syntax_ext; extern crate proc_macro; #[macro_use] extern crate rustc; -extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 6b49d6b9e52cb..f120072b37c05 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -212,9 +212,9 @@ //! no means all of the necessary details. Take a look at the rest of //! metadata::locator or metadata::creader for all the juicy details! -use cstore::{MetadataRef, MetadataBlob}; -use creader::Library; -use schema::{METADATA_HEADER, rustc_version}; +use crate::cstore::{MetadataRef, MetadataBlob}; +use crate::creader::Library; +use crate::schema::{METADATA_HEADER, rustc_version}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; @@ -226,6 +226,7 @@ use rustc::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; use syntax::symbol::Symbol; +use syntax::struct_span_err; use syntax_pos::Span; use rustc_target::spec::{Target, TargetTriple}; @@ -241,6 +242,8 @@ use flate2::read::DeflateDecoder; use rustc_data_structures::owning_ref::OwningRef; +use log::{debug, info, warn}; + pub struct CrateMismatch { path: PathBuf, got: String, @@ -283,7 +286,7 @@ enum CrateFlavor { } impl fmt::Display for CrateFlavor { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match *self { CrateFlavor::Rlib => "rlib", CrateFlavor::Rmeta => "rmeta", @@ -600,7 +603,7 @@ impl<'a> Context<'a> { } } - let mut err: Option = None; + let mut err: Option> = None; for (lib, kind) in m { info!("{} reading metadata from: {}", flavor, lib.display()); let (hash, metadata) = diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 1f00086e32fe1..118fb203c69a1 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -9,6 +9,7 @@ use syntax::attr; use syntax::source_map::Span; use syntax::feature_gate::{self, GateIssue}; use syntax::symbol::Symbol; +use syntax::{span_err, struct_span_err}; pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { let mut collector = Collector { diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index f3ff9747625f5..af79ea37dff55 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -1,4 +1,4 @@ -use index; +use crate::index; use rustc::hir; use rustc::hir::def::{self, CtorKind}; @@ -518,7 +518,7 @@ pub enum AssociatedContainer { ImplFinal, } -impl_stable_hash_for!(enum ::schema::AssociatedContainer { +impl_stable_hash_for!(enum crate::schema::AssociatedContainer { TraitRequired, TraitWithDefault, ImplDefault, From fed677e56fadde3cbdc2a7161765165407be47b6 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 20:55:12 +0900 Subject: [PATCH 0760/1064] librustc_cratesio_shim => 2018 --- src/librustc_cratesio_shim/Cargo.toml | 1 + src/librustc_cratesio_shim/src/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/librustc_cratesio_shim/Cargo.toml b/src/librustc_cratesio_shim/Cargo.toml index b8e494e4040ec..6bdfbe09354b4 100644 --- a/src/librustc_cratesio_shim/Cargo.toml +++ b/src/librustc_cratesio_shim/Cargo.toml @@ -15,6 +15,7 @@ authors = ["The Rust Project Developers"] name = "rustc_cratesio_shim" version = "0.0.0" +edition = "2018" [lib] crate-type = ["dylib"] diff --git a/src/librustc_cratesio_shim/src/lib.rs b/src/librustc_cratesio_shim/src/lib.rs index 4024087f4d3ef..4c170f4f5f6f9 100644 --- a/src/librustc_cratesio_shim/src/lib.rs +++ b/src/librustc_cratesio_shim/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(rust_2018_idioms)] + // See Cargo.toml for a comment explaining this crate. #![allow(unused_extern_crates)] From a7241c8ca6e37d4861c0ddc5639aee9d66fdbe8f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 21:00:07 +0900 Subject: [PATCH 0761/1064] librustc_target => 2018 --- src/librustc_target/Cargo.toml | 1 + src/librustc_target/abi/call/aarch64.rs | 4 ++-- src/librustc_target/abi/call/amdgpu.rs | 4 ++-- src/librustc_target/abi/call/arm.rs | 6 +++--- src/librustc_target/abi/call/asmjs.rs | 6 +++--- src/librustc_target/abi/call/hexagon.rs | 8 ++++---- src/librustc_target/abi/call/mips.rs | 10 +++++----- src/librustc_target/abi/call/mips64.rs | 6 +++--- src/librustc_target/abi/call/mod.rs | 18 +++++++++--------- src/librustc_target/abi/call/msp430.rs | 8 ++++---- src/librustc_target/abi/call/nvptx.rs | 8 ++++---- src/librustc_target/abi/call/nvptx64.rs | 8 ++++---- src/librustc_target/abi/call/powerpc.rs | 10 +++++----- src/librustc_target/abi/call/powerpc64.rs | 8 ++++---- src/librustc_target/abi/call/riscv.rs | 8 ++++---- src/librustc_target/abi/call/s390x.rs | 6 +++--- src/librustc_target/abi/call/sparc.rs | 10 +++++----- src/librustc_target/abi/call/sparc64.rs | 4 ++-- src/librustc_target/abi/call/wasm32.rs | 8 ++++---- src/librustc_target/abi/call/x86.rs | 6 +++--- src/librustc_target/abi/call/x86_64.rs | 4 ++-- src/librustc_target/abi/call/x86_win64.rs | 8 ++++---- src/librustc_target/abi/mod.rs | 10 +++++----- src/librustc_target/lib.rs | 6 +++--- src/librustc_target/spec/aarch64_apple_ios.rs | 2 +- src/librustc_target/spec/aarch64_fuchsia.rs | 2 +- .../spec/aarch64_linux_android.rs | 2 +- .../spec/aarch64_pc_windows_msvc.rs | 2 +- .../spec/aarch64_unknown_cloudabi.rs | 2 +- .../spec/aarch64_unknown_freebsd.rs | 2 +- .../spec/aarch64_unknown_hermit.rs | 2 +- .../spec/aarch64_unknown_linux_gnu.rs | 2 +- .../spec/aarch64_unknown_linux_musl.rs | 2 +- .../spec/aarch64_unknown_netbsd.rs | 2 +- .../spec/aarch64_unknown_openbsd.rs | 2 +- src/librustc_target/spec/abi.rs | 2 +- src/librustc_target/spec/android_base.rs | 2 +- src/librustc_target/spec/apple_base.rs | 2 +- src/librustc_target/spec/apple_ios_base.rs | 4 ++-- src/librustc_target/spec/arm_base.rs | 2 +- .../spec/arm_linux_androideabi.rs | 2 +- .../spec/arm_unknown_linux_gnueabi.rs | 2 +- .../spec/arm_unknown_linux_gnueabihf.rs | 2 +- .../spec/arm_unknown_linux_musleabi.rs | 2 +- .../spec/arm_unknown_linux_musleabihf.rs | 2 +- src/librustc_target/spec/armebv7r_none_eabi.rs | 2 +- .../spec/armebv7r_none_eabihf.rs | 2 +- .../spec/armv4t_unknown_linux_gnueabi.rs | 2 +- .../spec/armv5te_unknown_linux_gnueabi.rs | 2 +- .../spec/armv5te_unknown_linux_musleabi.rs | 2 +- .../spec/armv6_unknown_netbsd_eabihf.rs | 2 +- src/librustc_target/spec/armv7_apple_ios.rs | 2 +- .../spec/armv7_linux_androideabi.rs | 2 +- .../spec/armv7_unknown_cloudabi_eabihf.rs | 2 +- .../spec/armv7_unknown_linux_gnueabihf.rs | 2 +- .../spec/armv7_unknown_linux_musleabihf.rs | 2 +- .../spec/armv7_unknown_netbsd_eabihf.rs | 2 +- src/librustc_target/spec/armv7r_none_eabi.rs | 2 +- src/librustc_target/spec/armv7r_none_eabihf.rs | 2 +- src/librustc_target/spec/armv7s_apple_ios.rs | 2 +- src/librustc_target/spec/bitrig_base.rs | 2 +- src/librustc_target/spec/cloudabi_base.rs | 2 +- src/librustc_target/spec/dragonfly_base.rs | 2 +- src/librustc_target/spec/freebsd_base.rs | 2 +- src/librustc_target/spec/fuchsia_base.rs | 2 +- src/librustc_target/spec/haiku_base.rs | 2 +- src/librustc_target/spec/hermit_base.rs | 2 +- src/librustc_target/spec/i386_apple_ios.rs | 2 +- .../spec/i586_pc_windows_msvc.rs | 2 +- .../spec/i586_unknown_linux_gnu.rs | 2 +- .../spec/i586_unknown_linux_musl.rs | 2 +- src/librustc_target/spec/i686_apple_darwin.rs | 2 +- src/librustc_target/spec/i686_linux_android.rs | 2 +- .../spec/i686_pc_windows_gnu.rs | 2 +- .../spec/i686_pc_windows_msvc.rs | 2 +- .../spec/i686_unknown_cloudabi.rs | 2 +- .../spec/i686_unknown_dragonfly.rs | 2 +- .../spec/i686_unknown_freebsd.rs | 2 +- src/librustc_target/spec/i686_unknown_haiku.rs | 2 +- .../spec/i686_unknown_linux_gnu.rs | 2 +- .../spec/i686_unknown_linux_musl.rs | 2 +- .../spec/i686_unknown_netbsd.rs | 2 +- .../spec/i686_unknown_openbsd.rs | 2 +- src/librustc_target/spec/l4re_base.rs | 2 +- src/librustc_target/spec/linux_base.rs | 2 +- src/librustc_target/spec/linux_musl_base.rs | 2 +- .../spec/mips64_unknown_linux_gnuabi64.rs | 2 +- .../spec/mips64el_unknown_linux_gnuabi64.rs | 2 +- .../spec/mips_unknown_linux_gnu.rs | 2 +- .../spec/mips_unknown_linux_musl.rs | 2 +- .../spec/mips_unknown_linux_uclibc.rs | 2 +- .../spec/mipsel_unknown_linux_gnu.rs | 2 +- .../spec/mipsel_unknown_linux_musl.rs | 2 +- .../spec/mipsel_unknown_linux_uclibc.rs | 2 +- src/librustc_target/spec/mod.rs | 4 ++-- src/librustc_target/spec/msp430_none_elf.rs | 2 +- src/librustc_target/spec/netbsd_base.rs | 2 +- .../spec/nvptx64_nvidia_cuda.rs | 4 ++-- src/librustc_target/spec/openbsd_base.rs | 2 +- .../spec/powerpc64_unknown_freebsd.rs | 2 +- .../spec/powerpc64_unknown_linux_gnu.rs | 2 +- .../spec/powerpc64_unknown_linux_musl.rs | 2 +- .../spec/powerpc64le_unknown_linux_gnu.rs | 2 +- .../spec/powerpc64le_unknown_linux_musl.rs | 2 +- .../spec/powerpc_unknown_linux_gnu.rs | 2 +- .../spec/powerpc_unknown_linux_gnuspe.rs | 2 +- .../spec/powerpc_unknown_linux_musl.rs | 2 +- .../spec/powerpc_unknown_netbsd.rs | 2 +- src/librustc_target/spec/redox_base.rs | 2 +- .../spec/riscv32imac_unknown_none_elf.rs | 2 +- .../spec/riscv32imc_unknown_none_elf.rs | 2 +- src/librustc_target/spec/riscv_base.rs | 2 +- .../spec/s390x_unknown_linux_gnu.rs | 2 +- src/librustc_target/spec/solaris_base.rs | 2 +- .../spec/sparc64_unknown_linux_gnu.rs | 2 +- .../spec/sparc64_unknown_netbsd.rs | 2 +- .../spec/sparc_unknown_linux_gnu.rs | 2 +- .../spec/sparcv9_sun_solaris.rs | 2 +- src/librustc_target/spec/thumb_base.rs | 2 +- src/librustc_target/spec/thumbv6m_none_eabi.rs | 2 +- .../spec/thumbv7a_pc_windows_msvc.rs | 2 +- .../spec/thumbv7em_none_eabi.rs | 2 +- .../spec/thumbv7em_none_eabihf.rs | 2 +- src/librustc_target/spec/thumbv7m_none_eabi.rs | 2 +- .../spec/thumbv7neon_linux_androideabi.rs | 2 +- .../thumbv7neon_unknown_linux_gnueabihf.rs | 2 +- .../spec/thumbv8m_base_none_eabi.rs | 2 +- .../spec/thumbv8m_main_none_eabi.rs | 2 +- .../spec/thumbv8m_main_none_eabihf.rs | 2 +- src/librustc_target/spec/uefi_base.rs | 2 +- src/librustc_target/spec/windows_base.rs | 2 +- src/librustc_target/spec/windows_msvc_base.rs | 2 +- .../spec/x86_64_apple_darwin.rs | 2 +- src/librustc_target/spec/x86_64_apple_ios.rs | 2 +- src/librustc_target/spec/x86_64_fuchsia.rs | 2 +- .../spec/x86_64_linux_android.rs | 2 +- .../spec/x86_64_pc_windows_gnu.rs | 2 +- .../spec/x86_64_pc_windows_msvc.rs | 2 +- .../spec/x86_64_rumprun_netbsd.rs | 2 +- src/librustc_target/spec/x86_64_sun_solaris.rs | 2 +- .../spec/x86_64_unknown_bitrig.rs | 2 +- .../spec/x86_64_unknown_cloudabi.rs | 2 +- .../spec/x86_64_unknown_dragonfly.rs | 2 +- .../spec/x86_64_unknown_freebsd.rs | 2 +- .../spec/x86_64_unknown_haiku.rs | 2 +- .../spec/x86_64_unknown_hermit.rs | 2 +- .../spec/x86_64_unknown_l4re_uclibc.rs | 2 +- .../spec/x86_64_unknown_linux_gnu.rs | 2 +- .../spec/x86_64_unknown_linux_gnux32.rs | 2 +- .../spec/x86_64_unknown_linux_musl.rs | 2 +- .../spec/x86_64_unknown_netbsd.rs | 2 +- .../spec/x86_64_unknown_openbsd.rs | 2 +- .../spec/x86_64_unknown_redox.rs | 2 +- .../spec/x86_64_unknown_uefi.rs | 2 +- 154 files changed, 221 insertions(+), 220 deletions(-) diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml index dfdd7f0ae58e5..ecea15a992250 100644 --- a/src/librustc_target/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_target" version = "0.0.0" +edition = "2018" [lib] name = "rustc_target" diff --git a/src/librustc_target/abi/call/aarch64.rs b/src/librustc_target/abi/call/aarch64.rs index 9f9bba14b963e..f50ec6c2e7e3a 100644 --- a/src/librustc_target/abi/call/aarch64.rs +++ b/src/librustc_target/abi/call/aarch64.rs @@ -1,5 +1,5 @@ -use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) -> Option diff --git a/src/librustc_target/abi/call/amdgpu.rs b/src/librustc_target/abi/call/amdgpu.rs index ea9d4172cbc23..6bfd1f4387385 100644 --- a/src/librustc_target/abi/call/amdgpu.rs +++ b/src/librustc_target/abi/call/amdgpu.rs @@ -1,5 +1,5 @@ -use abi::call::{ArgType, FnType, }; -use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::abi::call::{ArgType, FnType, }; +use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; fn classify_ret_ty<'a, Ty, C>(_cx: &C, ret: &mut ArgType<'a, Ty>) where Ty: TyLayoutMethods<'a, C> + Copy, diff --git a/src/librustc_target/abi/call/arm.rs b/src/librustc_target/abi/call/arm.rs index 228dd36216158..52d7f3ac3dcbf 100644 --- a/src/librustc_target/abi/call/arm.rs +++ b/src/librustc_target/abi/call/arm.rs @@ -1,6 +1,6 @@ -use abi::call::{Conv, FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -use spec::HasTargetSpec; +use crate::abi::call::{Conv, FnType, ArgType, Reg, RegKind, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::spec::HasTargetSpec; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) -> Option diff --git a/src/librustc_target/abi/call/asmjs.rs b/src/librustc_target/abi/call/asmjs.rs index 85444500c5e11..92c86372a86f3 100644 --- a/src/librustc_target/abi/call/asmjs.rs +++ b/src/librustc_target/abi/call/asmjs.rs @@ -1,5 +1,5 @@ -use abi::call::{FnType, ArgType, Uniform}; -use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::abi::call::{FnType, ArgType, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; // Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128 @@ -26,7 +26,7 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>) } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { if arg.layout.is_aggregate() { arg.make_indirect_byval(); } diff --git a/src/librustc_target/abi/call/hexagon.rs b/src/librustc_target/abi/call/hexagon.rs index d538a8068ac4a..db8c915cdb4bd 100644 --- a/src/librustc_target/abi/call/hexagon.rs +++ b/src/librustc_target/abi/call/hexagon.rs @@ -1,8 +1,8 @@ #![allow(non_upper_case_globals)] -use abi::call::{FnType, ArgType}; +use crate::abi::call::{FnType, ArgType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { ret.make_indirect(); } else { @@ -10,7 +10,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); } else { @@ -18,7 +18,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType<'_,Ty>) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_target/abi/call/mips.rs b/src/librustc_target/abi/call/mips.rs index 2335bfbb5b87b..d496abf8e8b28 100644 --- a/src/librustc_target/abi/call/mips.rs +++ b/src/librustc_target/abi/call/mips.rs @@ -1,7 +1,7 @@ -use abi::call::{ArgType, FnType, Reg, Uniform}; -use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; +use crate::abi::call::{ArgType, FnType, Reg, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; -fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType, offset: &mut Size) +fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { if !ret.layout.is_aggregate() { @@ -12,7 +12,7 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType, offset: &mut Size) } } -fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) +fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { let dl = cx.data_layout(); @@ -34,7 +34,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) *offset = offset.align_to(align) + size.align_to(align); } -pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) +pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { let mut offset = Size::ZERO; diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs index 6f3e6494a4ae8..5ba05c6bcde37 100644 --- a/src/librustc_target/abi/call/mips64.rs +++ b/src/librustc_target/abi/call/mips64.rs @@ -1,7 +1,7 @@ -use abi::call::{ArgAttribute, ArgType, CastTarget, FnType, PassMode, Reg, RegKind, Uniform}; -use abi::{self, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods}; +use crate::abi::call::{ArgAttribute, ArgType, CastTarget, FnType, PassMode, Reg, RegKind, Uniform}; +use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods}; -fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) { +fn extend_integer_width_mips(arg: &mut ArgType<'_, Ty>, bits: u64) { // Always sign extend u32 values on 64-bit mips if let abi::Abi::Scalar(ref scalar) = arg.layout.abi { if let abi::Int(i, signed) = scalar.value { diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 0d50439c67ec0..839c9a857e64a 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -1,6 +1,6 @@ -use abi::{self, Abi, Align, FieldPlacement, Size}; -use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -use spec::HasTargetSpec; +use crate::abi::{self, Abi, Align, FieldPlacement, Size}; +use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::spec::{self, HasTargetSpec}; mod aarch64; mod amdgpu; @@ -42,13 +42,13 @@ pub enum PassMode { // Hack to disable non_upper_case_globals only for the bitflags! and not for the rest // of this module -pub use self::attr_impl::ArgAttribute; +pub use attr_impl::ArgAttribute; #[allow(non_upper_case_globals)] #[allow(unused)] mod attr_impl { // The subset of llvm::Attribute needed for arguments, packed into a bitfield. - bitflags! { + bitflags::bitflags! { #[derive(Default)] pub struct ArgAttribute: u16 { const ByVal = 1 << 0; @@ -526,22 +526,22 @@ pub struct FnType<'a, Ty> { } impl<'a, Ty> FnType<'a, Ty> { - pub fn adjust_for_cabi(&mut self, cx: &C, abi: ::spec::abi::Abi) -> Result<(), String> + pub fn adjust_for_cabi(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String> where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout + HasTargetSpec { match &cx.target_spec().arch[..] { "x86" => { - let flavor = if abi == ::spec::abi::Abi::Fastcall { + let flavor = if abi == spec::abi::Abi::Fastcall { x86::Flavor::Fastcall } else { x86::Flavor::General }; x86::compute_abi_info(cx, self, flavor); }, - "x86_64" => if abi == ::spec::abi::Abi::SysV64 { + "x86_64" => if abi == spec::abi::Abi::SysV64 { x86_64::compute_abi_info(cx, self); - } else if abi == ::spec::abi::Abi::Win64 || cx.target_spec().options.is_like_windows { + } else if abi == spec::abi::Abi::Win64 || cx.target_spec().options.is_like_windows { x86_win64::compute_abi_info(self); } else { x86_64::compute_abi_info(cx, self); diff --git a/src/librustc_target/abi/call/msp430.rs b/src/librustc_target/abi/call/msp430.rs index d8ba37db53d4d..7ae1116cba847 100644 --- a/src/librustc_target/abi/call/msp430.rs +++ b/src/librustc_target/abi/call/msp430.rs @@ -1,7 +1,7 @@ // Reference: MSP430 Embedded Application Binary Interface // http://www.ti.com/lit/an/slaa534/slaa534.pdf -use abi::call::{ArgType, FnType}; +use crate::abi::call::{ArgType, FnType}; // 3.5 Structures or Unions Passed and Returned by Reference // @@ -9,7 +9,7 @@ use abi::call::{ArgType, FnType}; // returned by reference. To pass a structure or union by reference, the caller // places its address in the appropriate location: either in a register or on // the stack, according to its position in the argument list. (..)" -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 { ret.make_indirect(); } else { @@ -17,7 +17,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 { arg.make_indirect(); } else { @@ -25,7 +25,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_target/abi/call/nvptx.rs b/src/librustc_target/abi/call/nvptx.rs index 4cf0f11eb1e4a..4722249f73007 100644 --- a/src/librustc_target/abi/call/nvptx.rs +++ b/src/librustc_target/abi/call/nvptx.rs @@ -1,9 +1,9 @@ // Reference: PTX Writer's Guide to Interoperability // http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability -use abi::call::{ArgType, FnType}; +use crate::abi::call::{ArgType, FnType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 { ret.make_indirect(); } else { @@ -11,7 +11,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 { arg.make_indirect(); } else { @@ -19,7 +19,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_target/abi/call/nvptx64.rs b/src/librustc_target/abi/call/nvptx64.rs index 8ccc77598c90a..51c00ae007c3c 100644 --- a/src/librustc_target/abi/call/nvptx64.rs +++ b/src/librustc_target/abi/call/nvptx64.rs @@ -1,9 +1,9 @@ // Reference: PTX Writer's Guide to Interoperability // http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability -use abi::call::{ArgType, FnType}; +use crate::abi::call::{ArgType, FnType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { ret.make_indirect(); } else { @@ -11,7 +11,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); } else { @@ -19,7 +19,7 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_target/abi/call/powerpc.rs b/src/librustc_target/abi/call/powerpc.rs index 2335bfbb5b87b..d496abf8e8b28 100644 --- a/src/librustc_target/abi/call/powerpc.rs +++ b/src/librustc_target/abi/call/powerpc.rs @@ -1,7 +1,7 @@ -use abi::call::{ArgType, FnType, Reg, Uniform}; -use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; +use crate::abi::call::{ArgType, FnType, Reg, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; -fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType, offset: &mut Size) +fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { if !ret.layout.is_aggregate() { @@ -12,7 +12,7 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType, offset: &mut Size) } } -fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) +fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { let dl = cx.data_layout(); @@ -34,7 +34,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) *offset = offset.align_to(align) + size.align_to(align); } -pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) +pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { let mut offset = Size::ZERO; diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 305a2d4225056..a9683104d164e 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -2,16 +2,16 @@ // Alignment of 128 bit types is not currently handled, this will // need to be fixed when PowerPC vector support is added. -use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -use spec::HasTargetSpec; +use crate::abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; +use crate::abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::spec::HasTargetSpec; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { ELFv1, // original ABI used for powerpc64 (big-endian) ELFv2, // newer ABI used for powerpc64le and musl (both endians) } -use self::ABI::*; +use ABI::*; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) -> Option diff --git a/src/librustc_target/abi/call/riscv.rs b/src/librustc_target/abi/call/riscv.rs index 4950bcd3330aa..ba82e49ddb03e 100644 --- a/src/librustc_target/abi/call/riscv.rs +++ b/src/librustc_target/abi/call/riscv.rs @@ -1,9 +1,9 @@ // Reference: RISC-V ELF psABI specification // https://github.com/riscv/riscv-elf-psabi-doc -use abi::call::{ArgType, FnType}; +use crate::abi::call::{ArgType, FnType}; -fn classify_ret_ty(arg: &mut ArgType, xlen: u64) { +fn classify_ret_ty(arg: &mut ArgType<'_, Ty>, xlen: u64) { // "Scalars wider than 2✕XLEN are passed by reference and are replaced in // the argument list with the address." // "Aggregates larger than 2✕XLEN bits are passed by reference and are @@ -19,7 +19,7 @@ fn classify_ret_ty(arg: &mut ArgType, xlen: u64) { arg.extend_integer_width_to(xlen); // this method only affects integer scalars } -fn classify_arg_ty(arg: &mut ArgType, xlen: u64) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>, xlen: u64) { // "Scalars wider than 2✕XLEN are passed by reference and are replaced in // the argument list with the address." // "Aggregates larger than 2✕XLEN bits are passed by reference and are @@ -35,7 +35,7 @@ fn classify_arg_ty(arg: &mut ArgType, xlen: u64) { arg.extend_integer_width_to(xlen); // this method only affects integer scalars } -pub fn compute_abi_info(fty: &mut FnType, xlen: u64) { +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>, xlen: u64) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret, xlen); } diff --git a/src/librustc_target/abi/call/s390x.rs b/src/librustc_target/abi/call/s390x.rs index 954c37fee42dd..c2717b1bcb815 100644 --- a/src/librustc_target/abi/call/s390x.rs +++ b/src/librustc_target/abi/call/s390x.rs @@ -1,10 +1,10 @@ // FIXME: The assumes we're using the non-vector ABI, i.e., compiling // for a pre-z13 machine or using -mno-vx. -use abi::call::{FnType, ArgType, Reg}; -use abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::abi::call::{FnType, ArgType, Reg}; +use crate::abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -fn classify_ret_ty<'a, Ty, C>(ret: &mut ArgType) +fn classify_ret_ty<'a, Ty, C>(ret: &mut ArgType<'_, Ty>) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 { diff --git a/src/librustc_target/abi/call/sparc.rs b/src/librustc_target/abi/call/sparc.rs index 2335bfbb5b87b..d496abf8e8b28 100644 --- a/src/librustc_target/abi/call/sparc.rs +++ b/src/librustc_target/abi/call/sparc.rs @@ -1,7 +1,7 @@ -use abi::call::{ArgType, FnType, Reg, Uniform}; -use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; +use crate::abi::call::{ArgType, FnType, Reg, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods}; -fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType, offset: &mut Size) +fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { if !ret.layout.is_aggregate() { @@ -12,7 +12,7 @@ fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType, offset: &mut Size) } } -fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) +fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { let dl = cx.data_layout(); @@ -34,7 +34,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) *offset = offset.align_to(align) + size.align_to(align); } -pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) +pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>) where Ty: TyLayoutMethods<'a, C>, C: LayoutOf + HasDataLayout { let mut offset = Size::ZERO; diff --git a/src/librustc_target/abi/call/sparc64.rs b/src/librustc_target/abi/call/sparc64.rs index 150b48a8d0255..d8930a875efbc 100644 --- a/src/librustc_target/abi/call/sparc64.rs +++ b/src/librustc_target/abi/call/sparc64.rs @@ -1,7 +1,7 @@ // FIXME: This needs an audit for correctness and completeness. -use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) -> Option diff --git a/src/librustc_target/abi/call/wasm32.rs b/src/librustc_target/abi/call/wasm32.rs index 78f43f8b508b3..1fdcbb8e39bdf 100644 --- a/src/librustc_target/abi/call/wasm32.rs +++ b/src/librustc_target/abi/call/wasm32.rs @@ -1,14 +1,14 @@ -use abi::call::{FnType, ArgType}; +use crate::abi::call::{FnType, ArgType}; -fn classify_ret_ty(ret: &mut ArgType) { +fn classify_ret_ty(ret: &mut ArgType<'_, Ty>) { ret.extend_integer_width_to(32); } -fn classify_arg_ty(arg: &mut ArgType) { +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>) { arg.extend_integer_width_to(32); } -pub fn compute_abi_info(fty: &mut FnType) { +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } diff --git a/src/librustc_target/abi/call/x86.rs b/src/librustc_target/abi/call/x86.rs index 648a4b5bb9d79..2e809571ab18b 100644 --- a/src/librustc_target/abi/call/x86.rs +++ b/src/librustc_target/abi/call/x86.rs @@ -1,6 +1,6 @@ -use abi::call::{ArgAttribute, FnType, PassMode, Reg, RegKind}; -use abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; -use spec::HasTargetSpec; +use crate::abi::call::{ArgAttribute, FnType, PassMode, Reg, RegKind}; +use crate::abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use crate::spec::HasTargetSpec; #[derive(PartialEq)] pub enum Flavor { diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs index 9d8cc19aac524..680e529b108e0 100644 --- a/src/librustc_target/abi/call/x86_64.rs +++ b/src/librustc_target/abi/call/x86_64.rs @@ -1,8 +1,8 @@ // The classification code for the x86_64 ABI is taken from the clay language // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp -use abi::call::{ArgType, CastTarget, FnType, Reg, RegKind}; -use abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods}; +use crate::abi::call::{ArgType, CastTarget, FnType, Reg, RegKind}; +use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods}; /// Classification of "eightbyte" components. // N.B., the order of the variants is from general to specific, diff --git a/src/librustc_target/abi/call/x86_win64.rs b/src/librustc_target/abi/call/x86_win64.rs index c583f7a0a2a24..ebdeb63150a46 100644 --- a/src/librustc_target/abi/call/x86_win64.rs +++ b/src/librustc_target/abi/call/x86_win64.rs @@ -1,10 +1,10 @@ -use abi::call::{ArgType, FnType, Reg}; -use abi::Abi; +use crate::abi::call::{ArgType, FnType, Reg}; +use crate::abi::Abi; // Win64 ABI: http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx -pub fn compute_abi_info(fty: &mut FnType) { - let fixup = |a: &mut ArgType| { +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>) { + let fixup = |a: &mut ArgType<'_, Ty>| { match a.layout.abi { Abi::Uninhabited => {} Abi::ScalarPair(..) | diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 3f95e666535be..bb194d5bb1285 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -1,7 +1,7 @@ -pub use self::Integer::*; -pub use self::Primitive::*; +pub use Integer::*; +pub use Primitive::*; -use spec::Target; +use crate::spec::Target; use std::fmt; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; @@ -533,13 +533,13 @@ pub enum FloatTy { } impl fmt::Debug for FloatTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self, f) } } impl fmt::Display for FloatTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.ty_to_string()) } } diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 0df0027c171aa..aab286a4a7d1b 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -17,11 +17,11 @@ #![feature(slice_patterns)] #![feature(step_trait)] -#[macro_use] -extern crate bitflags; -extern crate serialize; +#![deny(rust_2018_idioms)] + #[macro_use] extern crate log; +#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; // used by deriving // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/src/librustc_target/spec/aarch64_apple_ios.rs index 2210fd1e9e7c9..8bdc08c788d01 100644 --- a/src/librustc_target/spec/aarch64_apple_ios.rs +++ b/src/librustc_target/spec/aarch64_apple_ios.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/aarch64_fuchsia.rs b/src/librustc_target/spec/aarch64_fuchsia.rs index e39a1c2e1068c..308954d56f8bf 100644 --- a/src/librustc_target/spec/aarch64_fuchsia.rs +++ b/src/librustc_target/spec/aarch64_fuchsia.rs @@ -1,4 +1,4 @@ -use spec::{LldFlavor, LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LldFlavor, LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::fuchsia_base::opts(); diff --git a/src/librustc_target/spec/aarch64_linux_android.rs b/src/librustc_target/spec/aarch64_linux_android.rs index c05964295d37a..65160f6231e8c 100644 --- a/src/librustc_target/spec/aarch64_linux_android.rs +++ b/src/librustc_target/spec/aarch64_linux_android.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a // for target ABI requirements. diff --git a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs b/src/librustc_target/spec/aarch64_pc_windows_msvc.rs index b33430b59e8f9..1aee381d604c3 100644 --- a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs +++ b/src/librustc_target/spec/aarch64_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult, PanicStrategy}; +use crate::spec::{LinkerFlavor, Target, TargetResult, PanicStrategy}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs b/src/librustc_target/spec/aarch64_unknown_cloudabi.rs index ac3345ce3f214..7141954306769 100644 --- a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs +++ b/src/librustc_target/spec/aarch64_unknown_cloudabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_freebsd.rs b/src/librustc_target/spec/aarch64_unknown_freebsd.rs index 1fb0a2bcf7c22..36860649c53ad 100644 --- a/src/librustc_target/spec/aarch64_unknown_freebsd.rs +++ b/src/librustc_target/spec/aarch64_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_hermit.rs b/src/librustc_target/spec/aarch64_unknown_hermit.rs index 26006d0060d49..7b020605102b1 100644 --- a/src/librustc_target/spec/aarch64_unknown_hermit.rs +++ b/src/librustc_target/spec/aarch64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::hermit_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs index d30d927b6dd3d..e772d8b532cb0 100644 --- a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs index 258725fed15be..8123ee82ed524 100644 --- a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_netbsd.rs b/src/librustc_target/spec/aarch64_unknown_netbsd.rs index 10aef8f923d4c..47ae08ade9a6b 100644 --- a/src/librustc_target/spec/aarch64_unknown_netbsd.rs +++ b/src/librustc_target/spec/aarch64_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/aarch64_unknown_openbsd.rs b/src/librustc_target/spec/aarch64_unknown_openbsd.rs index 815e11a919c0f..c9cd64c3a84af 100644 --- a/src/librustc_target/spec/aarch64_unknown_openbsd.rs +++ b/src/librustc_target/spec/aarch64_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs index 46606e707d757..c9c41f1092240 100644 --- a/src/librustc_target/spec/abi.rs +++ b/src/librustc_target/spec/abi.rs @@ -96,7 +96,7 @@ impl Abi { } impl fmt::Display for Abi { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "\"{}\"", self.name()) } } diff --git a/src/librustc_target/spec/android_base.rs b/src/librustc_target/spec/android_base.rs index a8f8ad3185f0d..684c059b41482 100644 --- a/src/librustc_target/spec/android_base.rs +++ b/src/librustc_target/spec/android_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, TargetOptions}; +use crate::spec::{LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs index a80d1904a7471..c21f7f38ca5a3 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -1,6 +1,6 @@ use std::env; -use spec::{LinkArgs, TargetOptions}; +use crate::spec::{LinkArgs, TargetOptions}; pub fn opts() -> TargetOptions { // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs index 72346ab1f34b6..3068ed8d206cd 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_ios_base.rs @@ -1,8 +1,8 @@ use std::io; use std::process::Command; -use spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use self::Arch::*; +use Arch::*; #[allow(non_camel_case_types)] #[derive(Copy, Clone)] diff --git a/src/librustc_target/spec/arm_base.rs b/src/librustc_target/spec/arm_base.rs index 1d51d60c8f258..77e7bfac62d58 100644 --- a/src/librustc_target/spec/arm_base.rs +++ b/src/librustc_target/spec/arm_base.rs @@ -1,4 +1,4 @@ -use spec::abi::Abi; +use crate::spec::abi::Abi; // All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm pub fn abi_blacklist() -> Vec { diff --git a/src/librustc_target/spec/arm_linux_androideabi.rs b/src/librustc_target/spec/arm_linux_androideabi.rs index 5e4bebfa1c1a4..bb066dc9ad833 100644 --- a/src/librustc_target/spec/arm_linux_androideabi.rs +++ b/src/librustc_target/spec/arm_linux_androideabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::android_base::opts(); diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs index 0f891dacc6dbf..f291818ba80f5 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs index 5503bf326cd7b..32b509d9721ef 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs index c2162beba26e8..7637577e7e848 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs index b3f00331b3c9e..9def151b3ef29 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/src/librustc_target/spec/armebv7r_none_eabi.rs index cd41ffbab4d9c..86c62daa6180a 100644 --- a/src/librustc_target/spec/armebv7r_none_eabi.rs +++ b/src/librustc_target/spec/armebv7r_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R) use std::default::Default; -use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs index 05b12dd28bacd..50ee76414ef9a 100644 --- a/src/librustc_target/spec/armebv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Cortex-R4F/R5F processor (ARMv7-R) use std::default::Default; -use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs index 7fe021e5327b9..7cd4b14cdebc8 100644 --- a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs index c85a80f6e8a4c..15f614827718b 100644 --- a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs index dce767898c06b..74915b942ea4f 100644 --- a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs +++ b/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs index 95cc41e6c98fb..e460b6c574a26 100644 --- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/armv7_apple_ios.rs b/src/librustc_target/spec/armv7_apple_ios.rs index 98018215c805a..2052d17403dfd 100644 --- a/src/librustc_target/spec/armv7_apple_ios.rs +++ b/src/librustc_target/spec/armv7_apple_ios.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/armv7_linux_androideabi.rs b/src/librustc_target/spec/armv7_linux_androideabi.rs index 65c3c7f7057ab..92f1a55e024d7 100644 --- a/src/librustc_target/spec/armv7_linux_androideabi.rs +++ b/src/librustc_target/spec/armv7_linux_androideabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // This target if is for the baseline of the Android v7a ABI // in thumb mode. It's named armv7-* instead of thumbv7-* diff --git a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs index fa43879dccab8..a6c7fb537c785 100644 --- a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs index 864c59b81844e..f16215433c766 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // This target is for glibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs index ae0cb2c08b430..45a26966b716b 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // This target is for musl Linux on ARMv7 without thumb-mode or NEON. diff --git a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs index f9e416fd06e92..44e2636e9188e 100644 --- a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs index 38d115bc85e7f..19d332467dec5 100644 --- a/src/librustc_target/spec/armv7r_none_eabi.rs +++ b/src/librustc_target/spec/armv7r_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) use std::default::Default; -use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs index cb707f7183a49..06ef9f3ec4e37 100644 --- a/src/librustc_target/spec/armv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armv7r_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) use std::default::Default; -use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv7s_apple_ios.rs b/src/librustc_target/spec/armv7s_apple_ios.rs index 6d9635b308e90..29e290285e4a9 100644 --- a/src/librustc_target/spec/armv7s_apple_ios.rs +++ b/src/librustc_target/spec/armv7s_apple_ios.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/bitrig_base.rs b/src/librustc_target/spec/bitrig_base.rs index 3b6985fa4c826..9b34119fc00c9 100644 --- a/src/librustc_target/spec/bitrig_base.rs +++ b/src/librustc_target/spec/bitrig_base.rs @@ -1,4 +1,4 @@ -use spec::{TargetOptions, RelroLevel}; +use crate::spec::{TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/cloudabi_base.rs b/src/librustc_target/spec/cloudabi_base.rs index 145de0ebe6995..a34122d3e0fe2 100644 --- a/src/librustc_target/spec/cloudabi_base.rs +++ b/src/librustc_target/spec/cloudabi_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/dragonfly_base.rs b/src/librustc_target/spec/dragonfly_base.rs index 6ce2912da75cf..766030e8015d0 100644 --- a/src/librustc_target/spec/dragonfly_base.rs +++ b/src/librustc_target/spec/dragonfly_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/freebsd_base.rs b/src/librustc_target/spec/freebsd_base.rs index 47316f77e634e..51f030f59084d 100644 --- a/src/librustc_target/spec/freebsd_base.rs +++ b/src/librustc_target/spec/freebsd_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs index 5d94f308410a6..4e4f2fa0cf34c 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -1,4 +1,4 @@ -use spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/haiku_base.rs b/src/librustc_target/spec/haiku_base.rs index 00c6bd40dc584..d071062705306 100644 --- a/src/librustc_target/spec/haiku_base.rs +++ b/src/librustc_target/spec/haiku_base.rs @@ -1,4 +1,4 @@ -use spec::{TargetOptions, RelroLevel}; +use crate::spec::{TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs index d7d8562e055d8..ee753393ddb3d 100644 --- a/src/librustc_target/spec/hermit_base.rs +++ b/src/librustc_target/spec/hermit_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/i386_apple_ios.rs b/src/librustc_target/spec/i386_apple_ios.rs index d0e317630013b..78e9cbb61ef58 100644 --- a/src/librustc_target/spec/i386_apple_ios.rs +++ b/src/librustc_target/spec/i386_apple_ios.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/i586_pc_windows_msvc.rs b/src/librustc_target/spec/i586_pc_windows_msvc.rs index 12a7f98beff95..ba712aced8474 100644 --- a/src/librustc_target/spec/i586_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i586_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use spec::TargetResult; +use crate::spec::TargetResult; pub fn target() -> TargetResult { let mut base = super::i686_pc_windows_msvc::target()?; diff --git a/src/librustc_target/spec/i586_unknown_linux_gnu.rs b/src/librustc_target/spec/i586_unknown_linux_gnu.rs index 76f6a4eba389f..49f4f2cb6b999 100644 --- a/src/librustc_target/spec/i586_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/i586_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::TargetResult; +use crate::spec::TargetResult; pub fn target() -> TargetResult { let mut base = super::i686_unknown_linux_gnu::target()?; diff --git a/src/librustc_target/spec/i586_unknown_linux_musl.rs b/src/librustc_target/spec/i586_unknown_linux_musl.rs index 2b56fd7a7e370..0f2ccebd6dace 100644 --- a/src/librustc_target/spec/i586_unknown_linux_musl.rs +++ b/src/librustc_target/spec/i586_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::TargetResult; +use crate::spec::TargetResult; pub fn target() -> TargetResult { let mut base = super::i686_unknown_linux_musl::target()?; diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs index 40d9588e463a6..c8a61296d33d2 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::apple_base::opts(); diff --git a/src/librustc_target/spec/i686_linux_android.rs b/src/librustc_target/spec/i686_linux_android.rs index 5b8cb7ac55d58..3f73d24ee848b 100644 --- a/src/librustc_target/spec/i686_linux_android.rs +++ b/src/librustc_target/spec/i686_linux_android.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#x86 // for target ABI requirements. diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs index d7bc38ca172d5..12214a7d53119 100644 --- a/src/librustc_target/spec/i686_pc_windows_gnu.rs +++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_base::opts(); diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/src/librustc_target/spec/i686_pc_windows_msvc.rs index f0d75ae4e9bdd..1967834819ab2 100644 --- a/src/librustc_target/spec/i686_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i686_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_cloudabi.rs b/src/librustc_target/spec/i686_unknown_cloudabi.rs index 3a9e424698127..f3b40633b4007 100644 --- a/src/librustc_target/spec/i686_unknown_cloudabi.rs +++ b/src/librustc_target/spec/i686_unknown_cloudabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_dragonfly.rs b/src/librustc_target/spec/i686_unknown_dragonfly.rs index 9d71c5a823361..20315e7145c73 100644 --- a/src/librustc_target/spec/i686_unknown_dragonfly.rs +++ b/src/librustc_target/spec/i686_unknown_dragonfly.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::dragonfly_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_freebsd.rs b/src/librustc_target/spec/i686_unknown_freebsd.rs index 627dffa89d247..71f05a140f3df 100644 --- a/src/librustc_target/spec/i686_unknown_freebsd.rs +++ b/src/librustc_target/spec/i686_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_haiku.rs b/src/librustc_target/spec/i686_unknown_haiku.rs index 86c64ce684bb8..b807e4eee39a5 100644 --- a/src/librustc_target/spec/i686_unknown_haiku.rs +++ b/src/librustc_target/spec/i686_unknown_haiku.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::haiku_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_linux_gnu.rs b/src/librustc_target/spec/i686_unknown_linux_gnu.rs index ab38832831157..5875cbf78bfe6 100644 --- a/src/librustc_target/spec/i686_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/i686_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_linux_musl.rs b/src/librustc_target/spec/i686_unknown_linux_musl.rs index 81cbf57e577a6..732949034e824 100644 --- a/src/librustc_target/spec/i686_unknown_linux_musl.rs +++ b/src/librustc_target/spec/i686_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_netbsd.rs b/src/librustc_target/spec/i686_unknown_netbsd.rs index 1027e240224c9..e8a9f29ea5f4c 100644 --- a/src/librustc_target/spec/i686_unknown_netbsd.rs +++ b/src/librustc_target/spec/i686_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/i686_unknown_openbsd.rs b/src/librustc_target/spec/i686_unknown_openbsd.rs index d2bbc6bb2dbaf..d7c323e0d8a8a 100644 --- a/src/librustc_target/spec/i686_unknown_openbsd.rs +++ b/src/librustc_target/spec/i686_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); diff --git a/src/librustc_target/spec/l4re_base.rs b/src/librustc_target/spec/l4re_base.rs index 951005998be07..9317f053efe70 100644 --- a/src/librustc_target/spec/l4re_base.rs +++ b/src/librustc_target/spec/l4re_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; use std::default::Default; //use std::process::Command; diff --git a/src/librustc_target/spec/linux_base.rs b/src/librustc_target/spec/linux_base.rs index b036bf81a7542..195fba3915f94 100644 --- a/src/librustc_target/spec/linux_base.rs +++ b/src/librustc_target/spec/linux_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/linux_musl_base.rs b/src/librustc_target/spec/linux_musl_base.rs index 1bc90d1a73287..e294e63982de4 100644 --- a/src/librustc_target/spec/linux_musl_base.rs +++ b/src/librustc_target/spec/linux_musl_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, TargetOptions}; +use crate::spec::{LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs index 650f38702b67b..3b38e64050f3b 100644 --- a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs +++ b/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs index cb348d49479b9..0f6cd86d616d8 100644 --- a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs +++ b/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/mips_unknown_linux_gnu.rs b/src/librustc_target/spec/mips_unknown_linux_gnu.rs index 6cc3d30be1fb0..b4d29c5fbeaf4 100644 --- a/src/librustc_target/spec/mips_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/mips_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/mips_unknown_linux_musl.rs b/src/librustc_target/spec/mips_unknown_linux_musl.rs index 152b11b4aeeb5..c56c6e3822959 100644 --- a/src/librustc_target/spec/mips_unknown_linux_musl.rs +++ b/src/librustc_target/spec/mips_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs b/src/librustc_target/spec/mips_unknown_linux_uclibc.rs index 99cd20e9a52e8..cb02769c7dfe4 100644 --- a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs +++ b/src/librustc_target/spec/mips_unknown_linux_uclibc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs index 476cf15270649..ed49ddd49937f 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs b/src/librustc_target/spec/mipsel_unknown_linux_musl.rs index 9df131dbe2510..bcc49cf5ffe4f 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs b/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs index 37c55d11f25c9..205f328a24cec 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index aeecce49b0c67..107583e4fc0a0 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -40,7 +40,7 @@ use std::default::Default; use std::{fmt, io}; use std::path::{Path, PathBuf}; use std::str::FromStr; -use spec::abi::{Abi, lookup as lookup_abi}; +use crate::spec::abi::{Abi, lookup as lookup_abi}; pub mod abi; mod android_base; @@ -1408,7 +1408,7 @@ impl TargetTriple { } impl fmt::Display for TargetTriple { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.debug_triple()) } } diff --git a/src/librustc_target/spec/msp430_none_elf.rs b/src/librustc_target/spec/msp430_none_elf.rs index df564bc924baf..90af5898089b8 100644 --- a/src/librustc_target/spec/msp430_none_elf.rs +++ b/src/librustc_target/spec/msp430_none_elf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs index b88d360dd3785..e9cd98c0e7151 100644 --- a/src/librustc_target/spec/netbsd_base.rs +++ b/src/librustc_target/spec/netbsd_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs index e8512415e66a3..db9d6a7409ee5 100644 --- a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs +++ b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs @@ -1,5 +1,5 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy, MergeFunctions}; -use spec::abi::Abi; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy, MergeFunctions}; +use crate::spec::abi::Abi; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/openbsd_base.rs b/src/librustc_target/spec/openbsd_base.rs index 4bdf73fc92213..5bcfd62d75bd4 100644 --- a/src/librustc_target/spec/openbsd_base.rs +++ b/src/librustc_target/spec/openbsd_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs b/src/librustc_target/spec/powerpc64_unknown_freebsd.rs index cc7b87bfdebc3..360876b9ff557 100644 --- a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs +++ b/src/librustc_target/spec/powerpc64_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs index 1f7ae933cedd1..c16db7583f32b 100644 --- a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult, RelroLevel}; +use crate::spec::{LinkerFlavor, Target, TargetResult, RelroLevel}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs index 6fc8be8a5c4d8..ac0b7431f91a4 100644 --- a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs index 21791a75d2a29..038b925a28692 100644 --- a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs index 38f7fe887f5a9..57103345f0a0c 100644 --- a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs +++ b/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs index 286d177c864e4..38a801d5ab507 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs b/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs index ae144af047232..675b2c749d648 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc_unknown_linux_musl.rs index 3b61889163b4c..240443aa98db4 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/powerpc_unknown_netbsd.rs b/src/librustc_target/spec/powerpc_unknown_netbsd.rs index e8662a7851907..10e7089cf1c4c 100644 --- a/src/librustc_target/spec/powerpc_unknown_netbsd.rs +++ b/src/librustc_target/spec/powerpc_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/redox_base.rs b/src/librustc_target/spec/redox_base.rs index dd32f02e34049..dc51aeb58391f 100644 --- a/src/librustc_target/spec/redox_base.rs +++ b/src/librustc_target/spec/redox_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs index 8adf562ca7e52..5064393d31135 100644 --- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, LldFlavor, PanicStrategy, +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs index 5d8157ee59a0a..31e74c5920cf9 100644 --- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, LldFlavor, PanicStrategy, +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/riscv_base.rs b/src/librustc_target/spec/riscv_base.rs index ea7fdc39a9a96..ec1dc9b4918bd 100644 --- a/src/librustc_target/spec/riscv_base.rs +++ b/src/librustc_target/spec/riscv_base.rs @@ -1,4 +1,4 @@ -use spec::abi::Abi; +use crate::spec::abi::Abi; // All the calling conventions trigger an assertion(Unsupported calling // convention) in llvm on RISCV diff --git a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs b/src/librustc_target/spec/s390x_unknown_linux_gnu.rs index c18c94511f8d7..f259787e1d54d 100644 --- a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/s390x_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs index f5f8509210570..0dfbb13b77317 100644 --- a/src/librustc_target/spec/solaris_base.rs +++ b/src/librustc_target/spec/solaris_base.rs @@ -1,4 +1,4 @@ -use spec::TargetOptions; +use crate::spec::TargetOptions; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs b/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs index e5e3752be7f82..c842b22d4e16e 100644 --- a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/sparc64_unknown_netbsd.rs b/src/librustc_target/spec/sparc64_unknown_netbsd.rs index 62efd41dbb8ee..78d53e69e8b52 100644 --- a/src/librustc_target/spec/sparc64_unknown_netbsd.rs +++ b/src/librustc_target/spec/sparc64_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs b/src/librustc_target/spec/sparc_unknown_linux_gnu.rs index b6468993790d8..162cd311a3826 100644 --- a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/sparc_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/sparcv9_sun_solaris.rs b/src/librustc_target/spec/sparcv9_sun_solaris.rs index f1c5c5ac44f1a..acc03fd0d79ee 100644 --- a/src/librustc_target/spec/sparcv9_sun_solaris.rs +++ b/src/librustc_target/spec/sparcv9_sun_solaris.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::solaris_base::opts(); diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs index 06cb6a8d823ef..ed0dbb766a835 100644 --- a/src/librustc_target/spec/thumb_base.rs +++ b/src/librustc_target/spec/thumb_base.rs @@ -28,7 +28,7 @@ // build scripts / gcc flags. use std::default::Default; -use spec::{PanicStrategy, TargetOptions}; +use crate::spec::{PanicStrategy, TargetOptions}; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/src/librustc_target/spec/thumbv6m_none_eabi.rs index 98c46e9c600a3..2ab61b57f6bb6 100644 --- a/src/librustc_target/spec/thumbv6m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv6m_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs index eaa08fadbc0f3..310fac31c0c5b 100644 --- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs +++ b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); diff --git a/src/librustc_target/spec/thumbv7em_none_eabi.rs b/src/librustc_target/spec/thumbv7em_none_eabi.rs index 8a1fe09cdb07a..97114c342cdc7 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabi.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabi.rs @@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/thumbv7em_none_eabihf.rs b/src/librustc_target/spec/thumbv7em_none_eabihf.rs index 0c9aa1c5149ff..e4358bdd7991e 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabihf.rs @@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag. -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/thumbv7m_none_eabi.rs b/src/librustc_target/spec/thumbv7m_none_eabi.rs index 9bff3473c58af..daf25b16d58d6 100644 --- a/src/librustc_target/spec/thumbv7m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv7m_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs b/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs index 2d92e29c09d96..e248b930e6e4c 100644 --- a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs +++ b/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // This target if is for the Android v7a ABI in thumb mode with // NEON unconditionally enabled and, therefore, with 32 FPU registers diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs index bdf57969154c0..bef62b0a2ebe6 100644 --- a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; // This target is for glibc Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) diff --git a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs b/src/librustc_target/spec/thumbv8m_base_none_eabi.rs index 0e0e73efd45cc..be8a476db4dbc 100644 --- a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs +++ b/src/librustc_target/spec/thumbv8m_base_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs index dc2454d749780..49ab643d484bc 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs +++ b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs index 5fa1f42288d1a..6a3d8e61d7fe8 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs index 4628089ffe1f4..5078d500679d1 100644 --- a/src/librustc_target/spec/uefi_base.rs +++ b/src/librustc_target/spec/uefi_base.rs @@ -9,7 +9,7 @@ // the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all // code runs in the same environment, no process separation is supported. -use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs index 65d618232a249..38db9cd356cd8 100644 --- a/src/librustc_target/spec/windows_base.rs +++ b/src/librustc_target/spec/windows_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index 89f6b1bcc71c5..fdd747cdb865a 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -1,4 +1,4 @@ -use spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs index 7de33fe8ac52a..0911ce06c13d7 100644 --- a/src/librustc_target/spec/x86_64_apple_darwin.rs +++ b/src/librustc_target/spec/x86_64_apple_darwin.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::apple_base::opts(); diff --git a/src/librustc_target/spec/x86_64_apple_ios.rs b/src/librustc_target/spec/x86_64_apple_ios.rs index 286a73d48048c..1f9594b906282 100644 --- a/src/librustc_target/spec/x86_64_apple_ios.rs +++ b/src/librustc_target/spec/x86_64_apple_ios.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; pub fn target() -> TargetResult { diff --git a/src/librustc_target/spec/x86_64_fuchsia.rs b/src/librustc_target/spec/x86_64_fuchsia.rs index 00fb7066ca28f..a24d432c591d2 100644 --- a/src/librustc_target/spec/x86_64_fuchsia.rs +++ b/src/librustc_target/spec/x86_64_fuchsia.rs @@ -1,4 +1,4 @@ -use spec::{LldFlavor, LinkerFlavor, Target, TargetResult}; +use crate::spec::{LldFlavor, LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::fuchsia_base::opts(); diff --git a/src/librustc_target/spec/x86_64_linux_android.rs b/src/librustc_target/spec/x86_64_linux_android.rs index 29d5dfa5790a1..c3c6c7bf56fef 100644 --- a/src/librustc_target/spec/x86_64_linux_android.rs +++ b/src/librustc_target/spec/x86_64_linux_android.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::android_base::opts(); diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs index c3c36d22cef5e..35e0d55cd045e 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_base::opts(); diff --git a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs b/src/librustc_target/spec/x86_64_pc_windows_msvc.rs index 178d67784e653..073d49be5a9ab 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); diff --git a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs index 37c7925c6985e..a2c706c4c7232 100644 --- a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs +++ b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/x86_64_sun_solaris.rs b/src/librustc_target/spec/x86_64_sun_solaris.rs index 3534f9e6436b4..3bf3f51ae2512 100644 --- a/src/librustc_target/spec/x86_64_sun_solaris.rs +++ b/src/librustc_target/spec/x86_64_sun_solaris.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::solaris_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_bitrig.rs b/src/librustc_target/spec/x86_64_unknown_bitrig.rs index fa5392175606a..999d93a7e6090 100644 --- a/src/librustc_target/spec/x86_64_unknown_bitrig.rs +++ b/src/librustc_target/spec/x86_64_unknown_bitrig.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::bitrig_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs b/src/librustc_target/spec/x86_64_unknown_cloudabi.rs index c1253a3b2727b..d48120c5401c2 100644 --- a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs +++ b/src/librustc_target/spec/x86_64_unknown_cloudabi.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs b/src/librustc_target/spec/x86_64_unknown_dragonfly.rs index 815aa57252561..f55ee6969092b 100644 --- a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs +++ b/src/librustc_target/spec/x86_64_unknown_dragonfly.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::dragonfly_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_freebsd.rs b/src/librustc_target/spec/x86_64_unknown_freebsd.rs index 8d43883f33bf3..1d9c5cce3f729 100644 --- a/src/librustc_target/spec/x86_64_unknown_freebsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_haiku.rs b/src/librustc_target/spec/x86_64_unknown_haiku.rs index 608354732d9d1..4ab15fa4e90f5 100644 --- a/src/librustc_target/spec/x86_64_unknown_haiku.rs +++ b/src/librustc_target/spec/x86_64_unknown_haiku.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::haiku_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_hermit.rs b/src/librustc_target/spec/x86_64_unknown_hermit.rs index de5992cbf5ef2..a696ee16d7c9e 100644 --- a/src/librustc_target/spec/x86_64_unknown_hermit.rs +++ b/src/librustc_target/spec/x86_64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::hermit_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs b/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs index cf04cc1bdc2f5..e5fdb386ef301 100644 --- a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs +++ b/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::l4re_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs b/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs index c6ec8de5b7312..cb279e86f1498 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs b/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs index e4dfb8d05cdfa..0b2d7aacc4ddf 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs b/src/librustc_target/spec/x86_64_unknown_linux_musl.rs index 95321fe2f783e..2e1bc839873c7 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/x86_64_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_netbsd.rs b/src/librustc_target/spec/x86_64_unknown_netbsd.rs index fbd07ecce1afb..ffc4f1d5c49b7 100644 --- a/src/librustc_target/spec/x86_64_unknown_netbsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_openbsd.rs b/src/librustc_target/spec/x86_64_unknown_openbsd.rs index 68496247b1596..f2abd1071227e 100644 --- a/src/librustc_target/spec/x86_64_unknown_openbsd.rs +++ b/src/librustc_target/spec/x86_64_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_redox.rs b/src/librustc_target/spec/x86_64_unknown_redox.rs index d04bc5cc6ec21..f0a4519f59548 100644 --- a/src/librustc_target/spec/x86_64_unknown_redox.rs +++ b/src/librustc_target/spec/x86_64_unknown_redox.rs @@ -1,4 +1,4 @@ -use spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::redox_base::opts(); diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs index 0d7b4fc060bd9..9ac17a1693fb5 100644 --- a/src/librustc_target/spec/x86_64_unknown_uefi.rs +++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs @@ -5,7 +5,7 @@ // The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features. -use spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::uefi_base::opts(); From 0e622a8ba1d43904ff16231e4fe8a1907e66d563 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 21:06:07 +0900 Subject: [PATCH 0762/1064] librustc_codegen_utils => 2018 --- src/librustc_codegen_utils/Cargo.toml | 1 + src/librustc_codegen_utils/codegen_backend.rs | 22 +++++++++---------- src/librustc_codegen_utils/lib.rs | 12 ++-------- src/librustc_codegen_utils/link.rs | 2 +- src/librustc_codegen_utils/symbol_names.rs | 4 +++- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml index 34a09f30b6411..5f241eb20fb55 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_codegen_utils/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_codegen_utils" version = "0.0.0" +edition = "2018" [lib] name = "rustc_codegen_utils" diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 8981c542961e2..8270d2a4077cf 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -31,7 +31,7 @@ use rustc::middle::cstore::EncodedMetadata; use rustc::middle::cstore::MetadataLoader; use rustc::dep_graph::DepGraph; use rustc_target::spec::Target; -use link::out_filename; +use crate::link::out_filename; pub use rustc_data_structures::sync::MetadataRef; @@ -44,8 +44,8 @@ pub trait CodegenBackend { fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] } fn metadata_loader(&self) -> Box; - fn provide(&self, _providers: &mut Providers); - fn provide_extern(&self, _providers: &mut Providers); + fn provide(&self, _providers: &mut Providers<'_>); + fn provide_extern(&self, _providers: &mut Providers<'_>); fn codegen_crate<'a, 'tcx>( &self, tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -111,8 +111,8 @@ impl CodegenBackend for MetadataOnlyCodegenBackend { box NoLlvmMetadataLoader } - fn provide(&self, providers: &mut Providers) { - ::symbol_names::provide(providers); + fn provide(&self, providers: &mut Providers<'_>) { + crate::symbol_names::provide(providers); providers.target_features_whitelist = |_tcx, _cnum| { Default::default() // Just a dummy @@ -120,7 +120,7 @@ impl CodegenBackend for MetadataOnlyCodegenBackend { providers.is_reachable_non_generic = |_tcx, _defid| true; providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new()); } - fn provide_extern(&self, providers: &mut Providers) { + fn provide_extern(&self, providers: &mut Providers<'_>) { providers.is_reachable_non_generic = |_tcx, _defid| true; } @@ -131,12 +131,12 @@ impl CodegenBackend for MetadataOnlyCodegenBackend { ) -> Box { use rustc_mir::monomorphize::item::MonoItem; - ::check_for_rustc_errors_attr(tcx); - ::symbol_names_test::report_symbol_names(tcx); - ::rustc_incremental::assert_dep_graph(tcx); - ::rustc_incremental::assert_module_sources::assert_module_sources(tcx); + crate::check_for_rustc_errors_attr(tcx); + crate::symbol_names_test::report_symbol_names(tcx); + rustc_incremental::assert_dep_graph(tcx); + rustc_incremental::assert_module_sources::assert_module_sources(tcx); // FIXME: Fix this - // ::rustc::middle::dependency_format::calculate(tcx); + // rustc::middle::dependency_format::calculate(tcx); let _ = tcx.link_args(LOCAL_CRATE); let _ = tcx.native_libraries(LOCAL_CRATE); let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 8e96f98540117..4c01681320f2b 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -16,18 +16,10 @@ #![recursion_limit="256"] -extern crate flate2; -#[macro_use] -extern crate log; +#![deny(rust_2018_idioms)] #[macro_use] extern crate rustc; -extern crate rustc_target; -extern crate rustc_metadata; -extern crate rustc_mir; -extern crate rustc_incremental; -extern crate syntax; -extern crate syntax_pos; #[macro_use] extern crate rustc_data_structures; use rustc::ty::TyCtxt; @@ -42,7 +34,7 @@ pub mod symbol_names_test; /// error in codegen. This is used to write compile-fail tests /// that actually test that compilation succeeds without /// reporting an error. -pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { +pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_, '_, '_>) { if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { if tcx.has_attr(def_id, "rustc_error") { tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful"); diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index 09e22bd2c91a9..f3a1b219f8a84 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -41,7 +41,7 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { let validate = |s: String, span: Option| { - ::rustc_metadata::validate_crate_name(sess, &s, span); + rustc_metadata::validate_crate_name(sess, &s, span); s }; diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 3238a0b10bfd6..8d105853d92f1 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -103,10 +103,12 @@ use rustc_mir::monomorphize::Instance; use syntax_pos::symbol::Symbol; +use log::debug; + use std::fmt::Write; use std::mem::discriminant; -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { def_symbol_name, symbol_name, From a2c4a36c6132ad6e462992e1c8ab9c2c22eb5e0f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 21:11:10 +0900 Subject: [PATCH 0763/1064] librustc_borrowck => 2018 --- src/librustc_borrowck/Cargo.toml | 9 +++-- src/librustc_borrowck/borrowck/check_loans.rs | 11 +++--- .../borrowck/gather_loans/gather_moves.rs | 9 ++--- .../borrowck/gather_loans/lifetime.rs | 3 +- .../borrowck/gather_loans/mod.rs | 9 ++--- .../borrowck/gather_loans/move_error.rs | 9 ++--- .../borrowck/gather_loans/restrictions.rs | 5 +-- src/librustc_borrowck/borrowck/mod.rs | 35 ++++++++++--------- src/librustc_borrowck/borrowck/move_data.rs | 15 ++++---- src/librustc_borrowck/borrowck/unused.rs | 2 +- src/librustc_borrowck/dataflow.rs | 9 ++--- src/librustc_borrowck/graphviz.rs | 13 ++++--- src/librustc_borrowck/lib.rs | 11 +----- 13 files changed, 71 insertions(+), 69 deletions(-) diff --git a/src/librustc_borrowck/Cargo.toml b/src/librustc_borrowck/Cargo.toml index 3368bbf3855a5..f293739dec727 100644 --- a/src/librustc_borrowck/Cargo.toml +++ b/src/librustc_borrowck/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_borrowck" version = "0.0.0" +edition = "2018" [lib] name = "rustc_borrowck" @@ -13,8 +14,10 @@ test = false log = "0.4" syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -graphviz = { path = "../libgraphviz" } +# for "clarity", rename the graphviz crate to dot; graphviz within `borrowck` +# refers to the borrowck-specific graphviz adapter traits. +dot = { path = "../libgraphviz", package = "graphviz" } rustc = { path = "../librustc" } rustc_mir = { path = "../librustc_mir" } -rustc_errors = { path = "../librustc_errors" } -rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file +errors = { path = "../librustc_errors", package = "rustc_errors" } +rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index cafb29ed99a41..f675c8d38a676 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -7,10 +7,10 @@ // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -use self::UseError::*; +use UseError::*; -use borrowck::*; -use borrowck::InteriorKind::{InteriorElement, InteriorField}; +use crate::borrowck::*; +use crate::borrowck::InteriorKind::{InteriorElement, InteriorField}; use rustc::middle::expr_use_visitor as euv; use rustc::middle::expr_use_visitor::MutateMode; use rustc::middle::mem_categorization as mc; @@ -22,6 +22,7 @@ use syntax_pos::Span; use rustc::hir; use rustc::hir::Node; use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; +use log::debug; use std::rc::Rc; @@ -101,7 +102,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn matched_pat(&mut self, _matched_pat: &hir::Pat, - _cmt: &mc::cmt_, + _cmt: &mc::cmt_<'_>, _mode: euv::MatchMode) { } fn consume_pat(&mut self, @@ -910,7 +911,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { pub fn report_illegal_mutation(&self, span: Span, loan_path: &LoanPath<'tcx>, - loan: &Loan) { + loan: &Loan<'_>) { self.bccx.cannot_assign_to_borrowed( span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast) .emit(); diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index f5e27a953c27d..6b050fd9ba230 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -1,9 +1,9 @@ //! Computes moves. -use borrowck::*; -use borrowck::gather_loans::move_error::MovePlace; -use borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector}; -use borrowck::move_data::*; +use crate::borrowck::*; +use crate::borrowck::gather_loans::move_error::MovePlace; +use crate::borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector}; +use crate::borrowck::move_data::*; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; @@ -15,6 +15,7 @@ use syntax::ast; use syntax_pos::Span; use rustc::hir::*; use rustc::hir::Node; +use log::debug; struct GatherMoveInfo<'c, 'tcx: 'c> { id: hir::ItemLocalId, diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 8fc0a3d63384a..11597455bca8f 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -1,7 +1,7 @@ //! This module implements the check that the lifetime of a borrow //! does not exceed the lifetime of the value being borrowed. -use borrowck::*; +use crate::borrowck::*; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; @@ -10,6 +10,7 @@ use rustc::ty; use syntax::ast; use syntax_pos::Span; +use log::debug; type R = Result<(),()>; diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index d681c771d2fa9..c21a43bc68333 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -6,8 +6,8 @@ // their associated scopes. In phase two, checking loans, we will then make // sure that all of these loans are honored. -use borrowck::*; -use borrowck::move_data::MoveData; +use crate::borrowck::*; +use crate::borrowck::move_data::MoveData; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; @@ -17,8 +17,9 @@ use rustc::ty::{self, TyCtxt}; use syntax::ast; use syntax_pos::Span; use rustc::hir; +use log::debug; -use self::restrictions::RestrictionResult; +use restrictions::RestrictionResult; mod lifetime; mod restrictions; @@ -427,7 +428,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // } } - pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath) { + pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath<'_>) { //! For mutable loans of content whose mutability derives //! from a local variable, mark the mutability decl as necessary. diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index 00cbc250bd686..622dd8e891ac7 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -1,4 +1,4 @@ -use borrowck::BorrowckCtxt; +use crate::borrowck::BorrowckCtxt; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::middle::mem_categorization::NoteClosureEnv; @@ -8,7 +8,8 @@ use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; use syntax::ast; use syntax_pos; use errors::{DiagnosticBuilder, Applicability}; -use borrowck::gather_loans::gather_moves::PatternSource; +use crate::borrowck::gather_loans::gather_moves::PatternSource; +use log::debug; pub struct MoveErrorCollector<'tcx> { errors: Vec> @@ -167,10 +168,10 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>, } } -fn note_move_destination(mut err: DiagnosticBuilder, +fn note_move_destination(mut err: DiagnosticBuilder<'_>, move_to_span: syntax_pos::Span, pat_name: ast::Name, - is_first_note: bool) -> DiagnosticBuilder { + is_first_note: bool) -> DiagnosticBuilder<'_> { if is_first_note { err.span_label( move_to_span, diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index a43a7f1e09ae1..9f4c05a6b255f 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -1,13 +1,14 @@ //! Computes the restrictions that result from a borrow. -use borrowck::*; +use crate::borrowck::*; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::ty; use syntax_pos::Span; +use log::debug; -use borrowck::ToInteriorKind; +use crate::borrowck::ToInteriorKind; use std::rc::Rc; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index e40c2b4508922..4ced72cd279b2 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -2,13 +2,13 @@ #![allow(non_camel_case_types)] -pub use self::LoanPathKind::*; -pub use self::LoanPathElem::*; -pub use self::bckerr_code::*; -pub use self::AliasableViolationKind::*; -pub use self::MovedValueUseKind::*; +pub use LoanPathKind::*; +pub use LoanPathElem::*; +pub use bckerr_code::*; +pub use AliasableViolationKind::*; +pub use MovedValueUseKind::*; -use self::InteriorKind::*; +use InteriorKind::*; use rustc::hir::HirId; use rustc::hir::Node; @@ -37,10 +37,11 @@ use std::hash::{Hash, Hasher}; use syntax::ast; use syntax_pos::{MultiSpan, Span}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use log::debug; use rustc::hir; -use dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; +use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; pub mod check_loans; @@ -61,7 +62,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { }); } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { borrowck, ..*providers @@ -398,7 +399,7 @@ pub enum LoanPathElem<'tcx> { } fn closure_to_block(closure_id: LocalDefId, - tcx: TyCtxt) -> ast::NodeId { + tcx: TyCtxt<'_, '_, '_>) -> ast::NodeId { let closure_id = tcx.hir().local_def_id_to_node_id(closure_id); match tcx.hir().get(closure_id) { Node::Expr(expr) => match expr.node { @@ -1214,8 +1215,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } fn note_immutability_blame(&self, - db: &mut DiagnosticBuilder, - blame: Option, + db: &mut DiagnosticBuilder<'_>, + blame: Option>, error_node_id: ast::NodeId) { match blame { None => {} @@ -1271,7 +1272,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { // binding: either to make the binding mutable (if its type is // not a mutable reference) or to avoid borrowing altogether fn note_immutable_local(&self, - db: &mut DiagnosticBuilder, + db: &mut DiagnosticBuilder<'_>, borrowed_node_id: ast::NodeId, binding_node_id: ast::NodeId) { let let_span = self.tcx.hir().span(binding_node_id); @@ -1349,7 +1350,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder, err: &BckError<'a, 'tcx>, + fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder<'_>, err: &BckError<'a, 'tcx>, error_span: &Span) { match err.cmt.note { mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => { @@ -1487,7 +1488,7 @@ impl DataFlowOperator for LoanDataFlowOperator { } impl<'tcx> fmt::Debug for InteriorKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { InteriorField(mc::FieldIndex(_, info)) => write!(f, "{}", info), InteriorElement => write!(f, "[]"), @@ -1496,7 +1497,7 @@ impl<'tcx> fmt::Debug for InteriorKind { } impl<'tcx> fmt::Debug for Loan<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Loan_{}({:?}, {:?}, {:?}-{:?}, {:?})", self.index, self.loan_path, @@ -1508,7 +1509,7 @@ impl<'tcx> fmt::Debug for Loan<'tcx> { } impl<'tcx> fmt::Debug for LoanPath<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { LpVar(id) => { write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_string(id))) @@ -1543,7 +1544,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { } impl<'tcx> fmt::Display for LoanPath<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { LpVar(id) => { write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_user_string(id))) diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 56c9f928eb03a..a206c37e97b09 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -1,11 +1,11 @@ //! Data structures used for tracking moves. Please see the extensive //! comments in the section "Moves and initialization" in `README.md`. -pub use self::MoveKind::*; +pub use MoveKind::*; -use dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; +use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; -use borrowck::*; +use crate::borrowck::*; use rustc::cfg; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::FxHashMap; @@ -15,6 +15,7 @@ use std::rc::Rc; use std::usize; use syntax_pos::Span; use rustc::hir; +use log::debug; #[derive(Default)] pub struct MoveData<'tcx> { @@ -145,7 +146,7 @@ pub struct AssignDataFlowOperator; pub type AssignDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, AssignDataFlowOperator>; -fn loan_path_is_precise(loan_path: &LoanPath) -> bool { +fn loan_path_is_precise(loan_path: &LoanPath<'_>) -> bool { match loan_path.kind { LpVar(_) | LpUpvar(_) => { true @@ -428,8 +429,8 @@ impl<'a, 'tcx> MoveData<'tcx> { /// killed by scoping. See `README.md` for more details. fn add_gen_kills(&self, bccx: &BorrowckCtxt<'a, 'tcx>, - dfcx_moves: &mut MoveDataFlow, - dfcx_assign: &mut AssignDataFlow) { + dfcx_moves: &mut MoveDataFlow<'_, '_>, + dfcx_assign: &mut AssignDataFlow<'_, '_>) { for (i, the_move) in self.moves.borrow().iter().enumerate() { dfcx_moves.add_gen(the_move.id, i); } @@ -537,7 +538,7 @@ impl<'a, 'tcx> MoveData<'tcx> { path: MovePathIndex, kill_id: hir::ItemLocalId, kill_kind: KillFrom, - dfcx_moves: &mut MoveDataFlow) { + dfcx_moves: &mut MoveDataFlow<'_, '_>) { // We can only perform kills for paths that refer to a unique location, // since otherwise we may kill a move from one location with an // assignment referring to another location. diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs index 5db98f0e223e4..60a9c18e95ee9 100644 --- a/src/librustc_borrowck/borrowck/unused.rs +++ b/src/librustc_borrowck/borrowck/unused.rs @@ -7,7 +7,7 @@ use errors::Applicability; use std::slice; use syntax::ptr::P; -use borrowck::BorrowckCtxt; +use crate::borrowck::BorrowckCtxt; pub fn check<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, body: &'tcx hir::Body) { let mut used_mut = bccx.used_mut_nodes.borrow().clone(); diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs index 8cf620567405c..90f33ede62c21 100644 --- a/src/librustc_borrowck/dataflow.rs +++ b/src/librustc_borrowck/dataflow.rs @@ -10,6 +10,7 @@ use std::io; use std::mem; use std::usize; use syntax::print::pprust::PrintState; +use log::debug; use rustc_data_structures::graph::implementation::OUTGOING; @@ -80,7 +81,7 @@ pub trait DataFlowOperator : BitwiseOperator { fn initial_value(&self) -> bool; } -struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> { +struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O> { dfcx: &'a mut DataFlowContext<'b, 'tcx, O>, changed: bool } @@ -99,12 +100,12 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> { - fn nested(&self, state: &mut pprust::State, nested: pprust::Nested) -> io::Result<()> { + fn nested(&self, state: &mut pprust::State<'_>, nested: pprust::Nested) -> io::Result<()> { pprust::PpAnn::nested(self.tcx.hir(), state, nested) } fn pre(&self, - ps: &mut pprust::State, - node: pprust::AnnNode) -> io::Result<()> { + ps: &mut pprust::State<'_>, + node: pprust::AnnNode<'_>) -> io::Result<()> { let id = match node { pprust::AnnNode::Name(_) => return Ok(()), pprust::AnnNode::Expr(expr) => expr.hir_id.local_id, diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index adad8c55f2159..77056d4d3eb15 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -2,16 +2,15 @@ //! libgraphviz traits, specialized to attaching borrowck analysis //! data to rendered labels. -pub use self::Variant::*; +pub use Variant::*; pub use rustc::cfg::graphviz::{Node, Edge}; use rustc::cfg::graphviz as cfg_dot; -use borrowck; -use borrowck::{BorrowckCtxt, LoanPath}; -use dot; +use crate::borrowck::{self, BorrowckCtxt, LoanPath}; +use crate::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit}; +use log::debug; use rustc::cfg::CFGIndex; -use dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit}; use std::rc::Rc; #[derive(Debug, Copy, Clone)] @@ -53,7 +52,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { sets } - fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node, v: Variant) -> String { + fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node<'_>, v: Variant) -> String { let cfgidx = n.0; match v { Loans => self.dataflow_loans_for(e, cfgidx), @@ -89,7 +88,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { let dfcx = &self.analysis_data.loans; let loan_index_to_path = |loan_index| { let all_loans = &self.analysis_data.all_loans; - let l: &borrowck::Loan = &all_loans[loan_index]; + let l: &borrowck::Loan<'_> = &all_loans[loan_index]; l.loan_path() }; self.build_set(e, cfgidx, dfcx, loan_index_to_path) diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 8bdc4e1d5c1ea..75ac38209371a 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -3,23 +3,14 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] +#![deny(rust_2018_idioms)] #![feature(nll)] #![recursion_limit="256"] -#[macro_use] extern crate log; -extern crate syntax; -extern crate syntax_pos; -extern crate rustc_errors as errors; -extern crate rustc_data_structures; - -// for "clarity", rename the graphviz crate to dot; graphviz within `borrowck` -// refers to the borrowck-specific graphviz adapter traits. -extern crate graphviz as dot; #[macro_use] extern crate rustc; -extern crate rustc_mir; pub use borrowck::check_crate; pub use borrowck::build_borrowck_dataflow_data_for_fn; From 4f2e97e0ed4a988a037a132f1efdd9456f1c1315 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 21:16:35 +0900 Subject: [PATCH 0764/1064] librustc_incremental => 2018 --- src/librustc_incremental/Cargo.toml | 1 + src/librustc_incremental/assert_dep_graph.rs | 12 ++++----- src/librustc_incremental/lib.rs | 11 +++----- .../persist/dirty_clean.rs | 4 +-- src/librustc_incremental/persist/load.rs | 1 - src/librustc_incremental/persist/mod.rs | 26 +++++++++---------- src/librustc_incremental/persist/save.rs | 4 +-- .../persist/work_product.rs | 2 +- 8 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml index b8519ee1ab1a5..10b448b7fec3f 100644 --- a/src/librustc_incremental/Cargo.toml +++ b/src/librustc_incremental/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_incremental" version = "0.0.0" +edition = "2018" [lib] name = "rustc_incremental" diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 57ab48493fa93..b715a32cb0573 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -217,7 +217,7 @@ fn check_paths<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn dump_graph(tcx: TyCtxt) { +fn dump_graph(tcx: TyCtxt<'_, '_, '_>) { let path: String = env::var("RUST_DEP_GRAPH").unwrap_or_else(|_| "dep_graph".to_string()); let query = tcx.dep_graph.query(); @@ -261,11 +261,11 @@ pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>, impl<'a, 'tcx, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> { type Node = &'q DepNode; type Edge = (&'q DepNode, &'q DepNode); - fn nodes(&self) -> dot::Nodes<&'q DepNode> { + fn nodes(&self) -> dot::Nodes<'_, &'q DepNode> { let nodes: Vec<_> = self.0.iter().cloned().collect(); nodes.into() } - fn edges(&self) -> dot::Edges<(&'q DepNode, &'q DepNode)> { + fn edges(&self) -> dot::Edges<'_, (&'q DepNode, &'q DepNode)> { self.1[..].into() } fn source(&self, edge: &(&'q DepNode, &'q DepNode)) -> &'q DepNode { @@ -279,10 +279,10 @@ impl<'a, 'tcx, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> { impl<'a, 'tcx, 'q> dot::Labeller<'a> for GraphvizDepGraph<'q> { type Node = &'q DepNode; type Edge = (&'q DepNode, &'q DepNode); - fn graph_id(&self) -> dot::Id { + fn graph_id(&self) -> dot::Id<'_> { dot::Id::new("DependencyGraph").unwrap() } - fn node_id(&self, n: &&'q DepNode) -> dot::Id { + fn node_id(&self, n: &&'q DepNode) -> dot::Id<'_> { let s: String = format!("{:?}", n).chars() .map(|c| if c == '_' || c.is_alphanumeric() { c } else { '_' }) @@ -290,7 +290,7 @@ impl<'a, 'tcx, 'q> dot::Labeller<'a> for GraphvizDepGraph<'q> { debug!("n={:?} s={:?}", n, s); dot::Id::new(s).unwrap() } - fn node_label(&self, n: &&'q DepNode) -> dot::LabelText { + fn node_label(&self, n: &&'q DepNode) -> dot::LabelText<'_> { dot::LabelText::label(format!("{:?}", n)) } } diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index ae2e6e0b94cfc..1fc51c2731140 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -9,16 +9,13 @@ #![recursion_limit="256"] -extern crate graphviz; +#![deny(rust_2018_idioms)] + #[macro_use] extern crate rustc; -extern crate rustc_data_structures; -extern crate serialize as rustc_serialize; -extern crate rand; -extern crate rustc_fs_util; +#[allow(unused_extern_crates)] +extern crate serialize as rustc_serialize; // used by deriving #[macro_use] extern crate log; -extern crate syntax; -extern crate syntax_pos; mod assert_dep_graph; pub mod assert_module_sources; diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 3ff4d2ec38dff..9b52199465b5c 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -538,7 +538,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'a, 'tcx> { /// /// Also make sure that the `label` and `except` fields do not /// both exist. -fn check_config(tcx: TyCtxt, attr: &Attribute) -> bool { +fn check_config(tcx: TyCtxt<'_, '_, '_>, attr: &Attribute) -> bool { debug!("check_config(attr={:?})", attr); let config = &tcx.sess.parse_sess.config; debug!("check_config: config={:?}", config); @@ -573,7 +573,7 @@ fn check_config(tcx: TyCtxt, attr: &Attribute) -> bool { } } -fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> ast::Name { +fn expect_associated_value(tcx: TyCtxt<'_, '_, '_>, item: &NestedMetaItem) -> ast::Name { if let Some(value) = item.value_str() { value } else { diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index f330de7191865..ecf8bc4a88084 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -9,7 +9,6 @@ use rustc::util::common::time_ext; use rustc_serialize::Decodable as RustcDecodable; use rustc_serialize::opaque::Decoder; use std::path::Path; -use std; use super::data::*; use super::fs::*; diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs index bd59f24d04e79..3aad4f5abb884 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/src/librustc_incremental/persist/mod.rs @@ -10,16 +10,16 @@ mod save; mod work_product; mod file_format; -pub use self::fs::finalize_session_directory; -pub use self::fs::garbage_collect_session_directories; -pub use self::fs::in_incr_comp_dir; -pub use self::fs::in_incr_comp_dir_sess; -pub use self::fs::prepare_session_directory; -pub use self::load::dep_graph_tcx_init; -pub use self::load::load_dep_graph; -pub use self::load::load_query_result_cache; -pub use self::load::LoadResult; -pub use self::save::save_dep_graph; -pub use self::save::save_work_product_index; -pub use self::work_product::copy_cgu_workproducts_to_incr_comp_cache_dir; -pub use self::work_product::delete_workproduct_files; +pub use fs::finalize_session_directory; +pub use fs::garbage_collect_session_directories; +pub use fs::in_incr_comp_dir; +pub use fs::in_incr_comp_dir_sess; +pub use fs::prepare_session_directory; +pub use load::dep_graph_tcx_init; +pub use load::load_dep_graph; +pub use load::load_query_result_cache; +pub use load::LoadResult; +pub use save::save_dep_graph; +pub use save::save_work_product_index; +pub use work_product::copy_cgu_workproducts_to_incr_comp_cache_dir; +pub use work_product::delete_workproduct_files; diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 6a7553b388297..34fe2f1c25d04 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -129,7 +129,7 @@ fn save_in(sess: &Session, path_buf: PathBuf, encode: F) } } -fn encode_dep_graph(tcx: TyCtxt, +fn encode_dep_graph(tcx: TyCtxt<'_, '_, '_>, encoder: &mut Encoder) { // First encode the commandline arguments hash tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap(); @@ -234,7 +234,7 @@ fn encode_work_product_index(work_products: &FxHashMap, encoder: &mut Encoder) { time(tcx.sess, "serialize query result cache", || { tcx.serialize_query_result_cache(encoder).unwrap(); diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index 535f6930aa39a..3495b27c5ebca 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -1,6 +1,6 @@ //! This module contains files for saving intermediate work-products. -use persist::fs::*; +use crate::persist::fs::*; use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; use rustc::session::Session; use rustc_fs_util::link_or_copy; From 03d4fd973aaa6dca0d1e756ecab5d4f17947337b Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 8 Feb 2019 14:30:13 +0100 Subject: [PATCH 0765/1064] Use descriptive variant name --- src/librustc/middle/stability.rs | 4 ++-- src/test/ui/missing/missing-stability.rs | 4 ++-- src/test/ui/missing/missing-stability.stderr | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 1f7345dde8e8e..45f53dee98582 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -352,7 +352,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { hir::ItemKind::Mod(..) => self.check_missing_stability(i.id, i.span, "module"), - _ => self.check_missing_stability(i.id, i.span, "node") + _ => self.check_missing_stability(i.id, i.span, i.node.descriptive_variant()) } intravisit::walk_item(self, i) @@ -382,7 +382,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { } fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) { - self.check_missing_stability(i.id, i.span, "node"); + self.check_missing_stability(i.id, i.span, i.node.descriptive_variant()); intravisit::walk_foreign_item(self, i); } diff --git a/src/test/ui/missing/missing-stability.rs b/src/test/ui/missing/missing-stability.rs index c7d721e836d1f..469c22fdb17d7 100644 --- a/src/test/ui/missing/missing-stability.rs +++ b/src/test/ui/missing/missing-stability.rs @@ -6,7 +6,7 @@ #![stable(feature = "stable_test_feature", since = "1.0.0")] pub fn unmarked() { - //~^ ERROR node has missing stability attribute + //~^ ERROR function has missing stability attribute () } @@ -20,5 +20,5 @@ pub mod foo { pub mod bar { // #[stable] is not inherited pub fn unmarked() {} - //~^ ERROR node has missing stability attribute + //~^ ERROR function has missing stability attribute } diff --git a/src/test/ui/missing/missing-stability.stderr b/src/test/ui/missing/missing-stability.stderr index bced3efd83da3..6c81f2bac5788 100644 --- a/src/test/ui/missing/missing-stability.stderr +++ b/src/test/ui/missing/missing-stability.stderr @@ -1,13 +1,13 @@ -error: node has missing stability attribute +error: function has missing stability attribute --> $DIR/missing-stability.rs:8:1 | LL | / pub fn unmarked() { -LL | | //~^ ERROR node has missing stability attribute +LL | | //~^ ERROR function has missing stability attribute LL | | () LL | | } | |_^ -error: node has missing stability attribute +error: function has missing stability attribute --> $DIR/missing-stability.rs:22:5 | LL | pub fn unmarked() {} From fe276239b3e01129fe1c2ecf5d729a430a6e184e Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 8 Feb 2019 22:30:58 +0900 Subject: [PATCH 0766/1064] librustc_typeck => 2018 --- src/librustc_typeck/Cargo.toml | 3 +- src/librustc_typeck/astconv.rs | 20 ++++++------ src/librustc_typeck/check/_match.rs | 6 ++-- src/librustc_typeck/check/cast.rs | 8 ++--- src/librustc_typeck/check/closure.rs | 4 +-- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/check/dropck.rs | 6 ++-- .../check/generator_interior.rs | 2 +- src/librustc_typeck/check/intrinsic.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 8 ++--- src/librustc_typeck/check/method/mod.rs | 6 ++-- src/librustc_typeck/check/method/probe.rs | 10 +++--- src/librustc_typeck/check/method/suggest.rs | 8 ++--- src/librustc_typeck/check/mod.rs | 32 +++++++++---------- src/librustc_typeck/check/regionck.rs | 10 +++--- src/librustc_typeck/check/upvar.rs | 6 ++-- src/librustc_typeck/check/wfcheck.rs | 6 ++-- src/librustc_typeck/check/writeback.rs | 2 +- src/librustc_typeck/check_unused.rs | 2 +- .../coherence/inherent_impls_overlap.rs | 4 +-- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/collect.rs | 16 +++++----- .../constrained_type_params.rs | 2 +- src/librustc_typeck/impl_wf_check.rs | 4 +-- src/librustc_typeck/lib.rs | 16 ++++------ src/librustc_typeck/outlives/explicit.rs | 2 +- .../outlives/implicit_infer.rs | 3 +- src/librustc_typeck/outlives/mod.rs | 2 +- src/librustc_typeck/variance/terms.rs | 2 +- 30 files changed, 98 insertions(+), 100 deletions(-) diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 68b28a60fdff7..dcfcd74257e6f 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_typeck" version = "0.0.0" +edition = "2018" [lib] name = "rustc_typeck" @@ -14,7 +15,7 @@ arena = { path = "../libarena" } log = "0.4" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } +errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8da0b6dcbeac3..d6e9b5a4251e2 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -3,13 +3,13 @@ //! instance of `AstConv`. use errors::{Applicability, DiagnosticId}; -use hir::{self, GenericArg, GenericArgs}; -use hir::def::Def; -use hir::def_id::DefId; -use hir::HirVec; -use lint; -use middle::resolve_lifetime as rl; -use namespace::Namespace; +use crate::hir::{self, GenericArg, GenericArgs}; +use crate::hir::def::Def; +use crate::hir::def_id::DefId; +use crate::hir::HirVec; +use crate::lint; +use crate::middle::resolve_lifetime as rl; +use crate::namespace::Namespace; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; @@ -18,15 +18,15 @@ use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::ty::wf::object_region_bounds; use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi; -use require_c_abi_if_variadic; +use crate::require_c_abi_if_variadic; use smallvec::SmallVec; use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{DUMMY_SP, Span, MultiSpan}; -use util::common::ErrorReported; -use util::nodemap::FxHashMap; +use crate::util::common::ErrorReported; +use crate::util::nodemap::FxHashMap; use std::collections::BTreeSet; use std::iter; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index a90d83f3f8be0..3a670c8e2f15e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -1,5 +1,6 @@ -use check::{FnCtxt, Expectation, Diverges, Needs}; -use check::coercion::CoerceMany; +use crate::check::{FnCtxt, Expectation, Diverges, Needs}; +use crate::check::coercion::CoerceMany; +use crate::util::nodemap::FxHashMap; use errors::Applicability; use rustc::hir::{self, PatKind}; use rustc::hir::def::{Def, CtorKind}; @@ -13,7 +14,6 @@ use syntax::source_map::Spanned; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::Span; -use util::nodemap::FxHashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 85cae17fd8524..be6d432a67f9e 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -31,8 +31,8 @@ use super::FnCtxt; use errors::{DiagnosticBuilder,Applicability}; -use hir::def_id::DefId; -use lint; +use crate::hir::def_id::DefId; +use crate::lint; use rustc::hir; use rustc::session::Session; use rustc::traits; @@ -43,7 +43,7 @@ use rustc::ty::subst::Substs; use rustc::middle::lang_items; use syntax::ast; use syntax_pos::Span; -use util::common::ErrorReported; +use crate::util::common::ErrorReported; /// Reifies a cast check to be checked once we have full type information for /// a function context. @@ -294,7 +294,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { .emit(); } CastError::SizedUnsizedCast => { - use structured_errors::{SizedUnsizedCastError, StructuredDiagnostic}; + use crate::structured_errors::{SizedUnsizedCastError, StructuredDiagnostic}; SizedUnsizedCastError::new(&fcx.tcx.sess, self.span, self.expr_ty, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index df83c92fde5b4..24c300911b384 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -2,8 +2,8 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; -use astconv::AstConv; -use middle::region; +use crate::astconv::AstConv; +use crate::middle::region; use rustc::hir::def_id::DefId; use rustc::infer::{InferOk, InferResult}; use rustc::infer::LateBoundRegionConversionTime; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d1dfe9469fb77..8a91e425db7bf 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -50,7 +50,7 @@ //! sort of a minor point so I've opted to leave it for later---after all //! we may want to adjust precisely when coercions occur. -use check::{FnCtxt, Needs}; +use crate::check::{FnCtxt, Needs}; use errors::DiagnosticBuilder; use rustc::hir; use rustc::hir::def_id::DefId; diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 0d4690c83170a..82f00374521bd 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -1,4 +1,4 @@ -use check::FnCtxt; +use crate::check::FnCtxt; use rustc::infer::InferOk; use rustc::traits::{ObligationCause, ObligationCauseCode}; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 60b5db0d12cc4..d7ed949006a6b 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -1,13 +1,13 @@ -use check::regionck::RegionCtxt; +use crate::check::regionck::RegionCtxt; -use hir::def_id::DefId; +use crate::hir::def_id::DefId; use rustc::infer::outlives::env::OutlivesEnvironment; use rustc::infer::{self, InferOk, SuppressRegionErrors}; use rustc::middle::region; use rustc::traits::{ObligationCause, TraitEngine, TraitEngineExt}; use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt}; -use util::common::ErrorReported; +use crate::util::common::ErrorReported; use syntax::ast; use syntax_pos::Span; diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 225fa1dc4f45c..7f4b0a96a15ab 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -11,7 +11,7 @@ use rustc::ty::{self, Ty}; use rustc_data_structures::sync::Lrc; use syntax_pos::Span; use super::FnCtxt; -use util::nodemap::FxHashMap; +use crate::util::nodemap::FxHashMap; struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 82d4300d99687..912ea39dce3ce 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -4,7 +4,7 @@ use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::ty::{self, TyCtxt, Ty}; use rustc::ty::subst::Subst; -use require_same_types; +use crate::require_same_types; use rustc_target::spec::abi::Abi; use syntax::symbol::Symbol; diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 2cf2974a45a1c..34b248a106cb0 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -1,9 +1,9 @@ use super::{probe, MethodCallee}; -use astconv::AstConv; -use check::{FnCtxt, PlaceOp, callee, Needs}; -use hir::GenericArg; -use hir::def_id::DefId; +use crate::astconv::AstConv; +use crate::check::{FnCtxt, PlaceOp, callee, Needs}; +use crate::hir::GenericArg; +use crate::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, Ty, GenericParamDefKind}; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index b7d015729b42d..02cd5b7985594 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -10,9 +10,9 @@ pub use self::MethodError::*; pub use self::CandidateSource::*; pub use self::suggest::{SelfSource, TraitInfo}; -use check::FnCtxt; +use crate::check::FnCtxt; +use crate::namespace::Namespace; use errors::{Applicability, DiagnosticBuilder}; -use namespace::Namespace; use rustc_data_structures::sync::Lrc; use rustc::hir; use rustc::hir::def::Def; @@ -29,7 +29,7 @@ use syntax_pos::Span; use crate::{check_type_alias_enum_variants_enabled}; use self::probe::{IsSuggestion, ProbeScope}; -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut ty::query::Providers<'_>) { suggest::provide(providers); probe::provide(providers); } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 623677482db34..3636c1fa2ffb5 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -3,11 +3,11 @@ use super::NoMatchData; use super::{CandidateSource, ImplSource, TraitSource}; use super::suggest; -use check::autoderef::{self, Autoderef}; -use check::FnCtxt; -use hir::def_id::DefId; -use hir::def::Def; -use namespace::Namespace; +use crate::check::autoderef::{self, Autoderef}; +use crate::check::FnCtxt; +use crate::hir::def_id::DefId; +use crate::hir::def::Def; +use crate::namespace::Namespace; use rustc_data_structures::sync::Lrc; use rustc::hir; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 55b6e8f099ea9..8f98b347b4cc6 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -1,10 +1,11 @@ //! Give useful errors and suggestions to users when an item can't be //! found or is otherwise invalid. -use check::FnCtxt; +use crate::check::FnCtxt; +use crate::middle::lang_items::FnOnceTraitLangItem; +use crate::namespace::Namespace; +use crate::util::nodemap::FxHashSet; use errors::{Applicability, DiagnosticBuilder}; -use middle::lang_items::FnOnceTraitLangItem; -use namespace::Namespace; use rustc_data_structures::sync::Lrc; use rustc::hir::{self, ExprKind, Node, QPath}; use rustc::hir::def::Def; @@ -15,7 +16,6 @@ use rustc::infer::type_variable::TypeVariableOrigin; use rustc::traits::Obligation; use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable}; use rustc::ty::item_path::with_crate_prefix; -use util::nodemap::FxHashSet; use syntax_pos::{Span, FileName}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3e2a9d720f1c1..01da7179c5763 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,15 +83,15 @@ mod generator_interior; pub mod intrinsic; mod op; -use astconv::{AstConv, PathSeg}; +use crate::astconv::{AstConv, PathSeg}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath}; use rustc::hir::def::{CtorKind, Def}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::itemlikevisit::ItemLikeVisitor; -use middle::lang_items; -use namespace::Namespace; +use crate::middle::lang_items; +use crate::namespace::Namespace; use rustc::infer::{self, InferCtxt, InferOk, InferResult, RegionVariableOrigin}; use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_data_structures::indexed_vec::Idx; @@ -130,14 +130,14 @@ use std::mem::replace; use std::ops::{self, Deref}; use std::slice; -use require_c_abi_if_variadic; -use session::{CompileIncomplete, Session}; -use session::config::EntryFnType; -use TypeAndSubsts; -use lint; -use util::captures::Captures; -use util::common::{ErrorReported, indenter}; -use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, NodeMap}; +use crate::require_c_abi_if_variadic; +use crate::session::{CompileIncomplete, Session}; +use crate::session::config::EntryFnType; +use crate::TypeAndSubsts; +use crate::lint; +use crate::util::captures::Captures; +use crate::util::common::{ErrorReported, indenter}; +use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, NodeMap}; pub use self::Expectation::*; use self::autoderef::Autoderef; @@ -3044,7 +3044,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // arguments which we skipped above. if variadic { fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) { - use structured_errors::{VariadicError, StructuredDiagnostic}; + use crate::structured_errors::{VariadicError, StructuredDiagnostic}; VariadicError::new(s, span, t, cast_ty).diagnostic().emit(); } @@ -3685,8 +3685,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { display } - fn no_such_field_err(&self, span: Span, field: T, expr_t: &ty::TyS) - -> DiagnosticBuilder { + fn no_such_field_err(&self, span: Span, field: T, expr_t: &ty::TyS<'_>) + -> DiagnosticBuilder<'_> { type_error_struct!(self.tcx().sess, span, expr_t, E0609, "no field `{}` on type `{}`", field, expr_t) @@ -5257,7 +5257,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &self, blk: &'gcx hir::Block, expected_ty: Ty<'tcx>, - err: &mut DiagnosticBuilder, + err: &mut DiagnosticBuilder<'_>, ) { if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) { err.span_suggestion( @@ -5725,7 +5725,7 @@ fn fatally_break_rust(sess: &Session) { ); handler.note_without_error(&format!("rustc {} running on {}", option_env!("CFG_VERSION").unwrap_or("unknown_version"), - ::session::config::host_triple(), + crate::session::config::host_triple(), )); } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index b90c18eb41cb5..c058977181c9b 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -72,11 +72,11 @@ //! relation, except that a borrowed pointer never owns its //! contents. -use check::dropck; -use check::FnCtxt; -use middle::mem_categorization as mc; -use middle::mem_categorization::Categorization; -use middle::region; +use crate::check::dropck; +use crate::check::FnCtxt; +use crate::middle::mem_categorization as mc; +use crate::middle::mem_categorization::Categorization; +use crate::middle::region; use rustc::hir::def_id::DefId; use rustc::infer::outlives::env::OutlivesEnvironment; use rustc::infer::{self, RegionObligation, SuppressRegionErrors}; diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index ffd7c2114e5ab..f28de9bc5876d 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -32,9 +32,9 @@ use super::FnCtxt; -use middle::expr_use_visitor as euv; -use middle::mem_categorization as mc; -use middle::mem_categorization::Categorization; +use crate::middle::expr_use_visitor as euv; +use crate::middle::mem_categorization as mc; +use crate::middle::mem_categorization::Categorization; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::hir::def_id::LocalDefId; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 97881708b0a07..3b80429532da0 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1,7 +1,7 @@ -use check::{Inherited, FnCtxt}; -use constrained_type_params::{identify_constrained_type_params, Parameter}; +use crate::check::{Inherited, FnCtxt}; +use crate::constrained_type_params::{identify_constrained_type_params, Parameter}; -use hir::def_id::DefId; +use crate::hir::def_id::DefId; use rustc::traits::{self, ObligationCauseCode}; use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable, ToPredicate}; use rustc::ty::subst::{Subst, Substs}; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 238b087fe32f8..46ca538546460 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -2,7 +2,7 @@ // unresolved type variables and replaces "ty_var" types with their // substitutions. -use check::FnCtxt; +use crate::check::FnCtxt; use errors::DiagnosticBuilder; use rustc::hir; use rustc::hir::def_id::{DefId, DefIndex}; diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index a7e19fc4237cc..18194eeba80a2 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -1,4 +1,4 @@ -use lint; +use crate::lint; use rustc::ty::TyCtxt; use errors::Applicability; diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index 52dee29294cb7..138c598a7bbf0 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -1,11 +1,11 @@ -use namespace::Namespace; +use crate::namespace::Namespace; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::traits::{self, IntercrateMode}; use rustc::ty::TyCtxt; -use lint; +use crate::lint; pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 853c4c85d3f3b..4eee68b99d968 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -5,7 +5,7 @@ // done by the orphan and overlap modules. Then we build up various // mappings. That mapping code resides here. -use hir::def_id::{DefId, LOCAL_CRATE}; +use crate::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::traits; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::ty::query::Providers; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 9dc74c5d63a4e..94d20b9db2507 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -14,13 +14,13 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. -use astconv::{AstConv, Bounds}; -use constrained_type_params as ctp; -use check::intrinsic::intrisic_operation_unsafety; -use lint; -use middle::lang_items::SizedTraitLangItem; -use middle::resolve_lifetime as rl; -use middle::weak_lang_items; +use crate::astconv::{AstConv, Bounds}; +use crate::constrained_type_params as ctp; +use crate::check::intrinsic::intrisic_operation_unsafety; +use crate::lint; +use crate::middle::lang_items::SizedTraitLangItem; +use crate::middle::resolve_lifetime as rl; +use crate::middle::weak_lang_items; use rustc::mir::mono::Linkage; use rustc::ty::query::Providers; use rustc::ty::subst::Substs; @@ -68,7 +68,7 @@ fn collect_mod_item_types<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefI ); } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { type_of, generics_of, diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 199ea315896df..d1f33b65fc07a 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -124,7 +124,7 @@ pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, /// which is determined by 1, which requires `U`, that is determined /// by 0. I should probably pick a less tangled example, but I can't /// think of any. -pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt, +pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt<'_, '_, '_>, predicates: &mut [(ty::Predicate<'tcx>, Span)], impl_trait_ref: Option>, input_parameters: &mut FxHashSet) diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 07f5fca6fe68e..6de06b6481695 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -8,7 +8,7 @@ //! specialization errors. These things can (and probably should) be //! fixed, but for the moment it's easier to do these checks early. -use constrained_type_params as ctp; +use crate::constrained_type_params as ctp; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::def_id::DefId; @@ -162,7 +162,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // used elsewhere are not projected back out. } -fn report_unused_parameter(tcx: TyCtxt, +fn report_unused_parameter(tcx: TyCtxt<'_, '_, '_>, span: Span, kind: &str, name: &str) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 8d77310f3d427..e99ec539c7721 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -72,17 +72,15 @@ This API is completely unstable and subject to change. #![recursion_limit="256"] +#![deny(rust_2018_idioms)] +#![allow(explicit_outlives_requirements)] + +#![allow(elided_lifetimes_in_paths)] // WIP + #[macro_use] extern crate log; #[macro_use] extern crate syntax; -extern crate syntax_pos; - -extern crate arena; #[macro_use] extern crate rustc; -extern crate rustc_data_structures; -extern crate rustc_errors as errors; -extern crate rustc_target; -extern crate smallvec; // N.B., this module needs to be declared first so diagnostics are // registered before they are used. @@ -141,7 +139,7 @@ fn check_type_alias_enum_variants_enabled<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, } } -fn require_c_abi_if_variadic(tcx: TyCtxt, +fn require_c_abi_if_variadic(tcx: TyCtxt<'_, '_, '_>, decl: &hir::FnDecl, abi: Abi, span: Span) { @@ -310,7 +308,7 @@ fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { } } -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { collect::provide(providers); coherence::provide(providers); check::provide(providers); diff --git a/src/librustc_typeck/outlives/explicit.rs b/src/librustc_typeck/outlives/explicit.rs index 38f4b37b29289..574086f780a9d 100644 --- a/src/librustc_typeck/outlives/explicit.rs +++ b/src/librustc_typeck/outlives/explicit.rs @@ -1,6 +1,6 @@ use rustc::hir::def_id::DefId; use rustc::ty::{self, OutlivesPredicate, TyCtxt}; -use util::nodemap::FxHashMap; +use crate::util::nodemap::FxHashMap; use super::utils::*; diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index e388a3e0d0c2f..0ff884d72b19f 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -1,5 +1,4 @@ -use rustc::hir; -use hir::Node; +use rustc::hir::{self, Node}; use rustc::hir::def_id::DefId; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::subst::{Kind, Subst, UnpackedKind}; diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index f0310f250a9bd..b3634d37cc2b8 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -12,7 +12,7 @@ mod implicit_infer; pub mod test; mod utils; -pub fn provide(providers: &mut Providers) { +pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { inferred_outlives_of, inferred_outlives_crate, diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index d53e2d2ad7883..ec0acfb63a89a 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -15,7 +15,7 @@ use std::fmt; use syntax::ast; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; -use util::nodemap::NodeMap; +use crate::util::nodemap::NodeMap; use self::VarianceTerm::*; From bb1eed0ec8537a09666978ad92d71ee1b5aba13b Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 8 Feb 2019 15:07:26 +0100 Subject: [PATCH 0767/1064] Correct descriptive item name for impl --- src/librustc/hir/mod.rs | 2 +- src/librustc/middle/stability.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 3e7dd1432e1e3..d520acf950a23 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2288,7 +2288,7 @@ impl ItemKind { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "item", + ItemKind::Impl(..) => "impl", } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 45f53dee98582..04046fa3b00ab 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -350,8 +350,6 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // optional. They inherit stability from their parents when unannotated. hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {} - hir::ItemKind::Mod(..) => self.check_missing_stability(i.id, i.span, "module"), - _ => self.check_missing_stability(i.id, i.span, i.node.descriptive_variant()) } @@ -359,14 +357,14 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { } fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { - self.check_missing_stability(ti.id, ti.span, "node"); + self.check_missing_stability(ti.id, ti.span, "item"); intravisit::walk_trait_item(self, ti); } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { let impl_def_id = self.tcx.hir().local_def_id(self.tcx.hir().get_parent(ii.id)); if self.tcx.impl_trait_ref(impl_def_id).is_none() { - self.check_missing_stability(ii.id, ii.span, "node"); + self.check_missing_stability(ii.id, ii.span, "item"); } intravisit::walk_impl_item(self, ii); } From 9fa01da50eef19ca156de81361c800356fdd4c3b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 8 Feb 2019 15:09:05 +0100 Subject: [PATCH 0768/1064] Improve stability tags display --- src/librustdoc/html/render.rs | 3 +-- src/librustdoc/html/static/themes/dark.css | 10 +++++----- src/librustdoc/html/static/themes/light.css | 8 ++++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a85ac19286af5..7951d056666ee 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2775,8 +2775,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, \ {name}{unsafety_flag}\ - {stab_tags}{docs}\ - \ + {stab_tags}{docs}\ ", name = *myitem.name.as_ref().unwrap(), stab_tags = stability_tags(myitem), diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 6935ecde791f8..7e930ce578c1f 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -188,15 +188,15 @@ a.test-arrow { box-shadow: 1px 0 0 1px #000, 0 0 0 2px transparent; } -.stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #404040; } -.stab.internal { background: #FFB9B3; border-color: #B71C1C; color: #404040; } -.stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #404040; } -.stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #404040; } - .module-item .stab { color: #ddd; } +.stab.unstable {background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } +.stab.internal { background: #FFB9B3; border-color: #B71C1C; color: #2f2f2f; } +.stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #2f2f2f; } +.stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #2f2f2f; } + #help > div { background: #4d4d4d; border-color: #bfbfbf; diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 306e8dc15d893..8a798ae8f9833 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -189,15 +189,15 @@ a.test-arrow { box-shadow: 1px 0 0 1px #e0e0e0, 0 0 0 2px transparent; } +.module-item .stab { + color: #000; +} + .stab.unstable { background: #FFF5D6; border-color: #FFC600; } .stab.internal { background: #FFB9B3; border-color: #B71C1C; } .stab.deprecated { background: #F3DFFF; border-color: #7F0087; } .stab.portability { background: #C4ECFF; border-color: #7BA5DB; } -.module-item .stab { - color: #000; -} - #help > div { background: #e9e9e9; border-color: #bfbfbf; From 802c897eb3c95e6643bd4e2cd85052786458e3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 8 Feb 2019 05:44:15 -0800 Subject: [PATCH 0769/1064] review comments: (marginally) reduce memory consumtion --- src/librustc/infer/error_reporting/mod.rs | 14 +++++++---- src/librustc/traits/mod.rs | 3 ++- src/librustc/traits/structural_impls.rs | 13 ++++++---- src/librustc_typeck/check/_match.rs | 8 ++++++- src/test/ui/match/match-type-err-first-arm.rs | 18 ++++++++++++++ .../ui/match/match-type-err-first-arm.stderr | 24 ++++++++++++++++++- 6 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 361aee4405b40..82e9a1e3c895b 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -512,6 +512,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ObligationCauseCode::MatchExpressionArm { source, ref prior_arms, + last_ty, .. } => match source { hir::MatchSource::IfLetDesugar { .. } => { @@ -522,13 +523,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _ => { let msg = "`match` arms have incompatible types"; err.span_label(cause.span, msg); - if prior_arms.len() < 4 { - for (sp, ty) in prior_arms { - err.span_label(*sp, format!("this is found to be of type `{}`", ty)); + if prior_arms.len() <= 4 { + for sp in prior_arms { + err.span_label(*sp, format!( + "this is found to be of type `{}`", + last_ty, + )); } - } else if let Some((sp, ty)) = prior_arms.last() { + } else if let Some(sp) = prior_arms.last() { err.span_label(*sp, format!( - "this and all prior arms are found to be of type `{}`", ty, + "this and all prior arms are found to be of type `{}`", last_ty, )); } } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 9824ff8f397e1..7fc27ba735e47 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -224,7 +224,8 @@ pub enum ObligationCauseCode<'tcx> { MatchExpressionArm { arm_span: Span, source: hir::MatchSource, - prior_arms: Vec<(Span, Ty<'tcx>)>, + prior_arms: Vec, + last_ty: Ty<'tcx>, }, /// Computing common supertype in the pattern guard for the arms of a match expression diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index c0e00cf291bac..8bbeec0b8ac2b 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -517,11 +517,16 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { arm_span, source, ref prior_arms, + last_ty, } => { - let prior_arms = prior_arms.iter().filter_map(|(sp, ty)| { - tcx.lift(ty).map(|ty| (*sp, ty)) - }).collect(); - Some(super::MatchExpressionArm { arm_span, source, prior_arms }) + tcx.lift(&last_ty).map(|last_ty| { + super::MatchExpressionArm { + arm_span, + source, + prior_arms: prior_arms.clone(), + last_ty, + } + }) } super::MatchExpressionArmPattern { span, ty } => { tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty }) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index c662a49abf9ea..cfc7cedc5e3e5 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -690,6 +690,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); }; let mut other_arms = vec![]; // used only for diagnostics + let mut prior_arm_ty = None; for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() { if let Some(ref g) = arm.guard { self.diverges.set(pats_diverge); @@ -730,11 +731,16 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); arm_span, source: match_src, prior_arms: other_arms.clone(), + last_ty: prior_arm_ty.unwrap(), }) }; coercion.coerce(self, &cause, &arm.body, arm_ty); } - other_arms.push((arm_span, arm_ty)); + other_arms.push(arm_span); + if other_arms.len() > 5 { + other_arms.remove(0); + } + prior_arm_ty = Some(arm_ty); } // We won't diverge unless the discriminant or all arms diverge. diff --git a/src/test/ui/match/match-type-err-first-arm.rs b/src/test/ui/match/match-type-err-first-arm.rs index 31fa50d2b452b..b4b84ef8f1cec 100644 --- a/src/test/ui/match/match-type-err-first-arm.rs +++ b/src/test/ui/match/match-type-err-first-arm.rs @@ -25,3 +25,21 @@ fn test_func2(n: i32) -> i32 { }; x } + +fn test_func3(n: i32) -> i32 { + let x = match n { + //~^ NOTE `match` arms have incompatible types + 1 => 'b', + 2 => 'b', + 3 => 'b', + 4 => 'b', + 5 => 'b', + 6 => 'b', + //~^ NOTE this and all prior arms are found to be of type `char` + _ => 42, + //~^ ERROR match arms have incompatible types + //~| NOTE expected char, found integer + //~| NOTE expected type `char` + }; + x +} diff --git a/src/test/ui/match/match-type-err-first-arm.stderr b/src/test/ui/match/match-type-err-first-arm.stderr index 8f722343a5875..db8bef8dc7755 100644 --- a/src/test/ui/match/match-type-err-first-arm.stderr +++ b/src/test/ui/match/match-type-err-first-arm.stderr @@ -26,6 +26,28 @@ LL | | }; = note: expected type `char` found type `{integer}` -error: aborting due to 2 previous errors +error[E0308]: match arms have incompatible types + --> $DIR/match-type-err-first-arm.rs:39:14 + | +LL | let x = match n { + | _____________- +LL | | //~^ NOTE `match` arms have incompatible types +LL | | 1 => 'b', +LL | | 2 => 'b', +... | +LL | | 6 => 'b', + | | --- this and all prior arms are found to be of type `char` +LL | | //~^ NOTE this and all prior arms are found to be of type `char` +LL | | _ => 42, + | | ^^ expected char, found integer +... | +LL | | //~| NOTE expected type `char` +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected type `char` + found type `{integer}` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. From 8f6d05b819bfadfad8f3fea9ba83deb7522dac78 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 8 Feb 2019 16:05:33 +0100 Subject: [PATCH 0770/1064] Don't default on std crate when manipulating browser history --- src/librustdoc/html/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index d6c05de0df6f2..41af44040f4cf 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1598,7 +1598,7 @@ if (!DOMTokenList.prototype.remove) { clearTimeout(searchTimeout); if (search_input.value.length === 0) { if (browserSupportsHistoryApi()) { - history.replaceState("", "std - Rust", "?search="); + history.replaceState("", window.currentCrate + " - Rust", "?search="); } if (hasClass(main, "content")) { removeClass(main, "hidden"); From 7d6bfc53c85d3eb9470fd30621a1b54a61bbbdb6 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Fri, 8 Feb 2019 16:41:37 +0100 Subject: [PATCH 0771/1064] Extract block to insert an intrinsic into its own function --- src/librustc_codegen_llvm/context.rs | 29 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index f679558844198..03de20861a9e5 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -465,6 +465,20 @@ impl CodegenCx<'b, 'tcx> { self.declare_intrinsic(key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key)) } + fn insert_intrinsic( + &self, name: &'static str, args: Option<&[&'b llvm::Type]>, ret: &'b llvm::Type + ) -> &'b llvm::Value { + let fn_ty = if let Some(args) = args { + self.type_func(args, ret) + } else { + self.type_variadic_func(&[], ret) + }; + let f = self.declare_cfn(name, fn_ty); + llvm::SetUnnamedAddr(f, false); + self.intrinsics.borrow_mut().insert(name, f.clone()); + f + } + fn declare_intrinsic( &self, key: &str @@ -472,26 +486,17 @@ impl CodegenCx<'b, 'tcx> { macro_rules! ifn { ($name:expr, fn() -> $ret:expr) => ( if key == $name { - let f = self.declare_cfn($name, self.type_func(&[], $ret)); - llvm::SetUnnamedAddr(f, false); - self.intrinsics.borrow_mut().insert($name, f.clone()); - return Some(f); + return Some(self.insert_intrinsic($name, Some(&[]), $ret)); } ); ($name:expr, fn(...) -> $ret:expr) => ( if key == $name { - let f = self.declare_cfn($name, self.type_variadic_func(&[], $ret)); - llvm::SetUnnamedAddr(f, false); - self.intrinsics.borrow_mut().insert($name, f.clone()); - return Some(f); + return Some(self.insert_intrinsic($name, None, $ret)); } ); ($name:expr, fn($($arg:expr),*) -> $ret:expr) => ( if key == $name { - let f = self.declare_cfn($name, self.type_func(&[$($arg),*], $ret)); - llvm::SetUnnamedAddr(f, false); - self.intrinsics.borrow_mut().insert($name, f.clone()); - return Some(f); + return Some(self.insert_intrinsic($name, Some(&[$($arg),*]), $ret)); } ); } From 5f41f8be30ea93e4fc86be2faea5e981ff3f8c2f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 8 Feb 2019 16:44:50 +0100 Subject: [PATCH 0772/1064] Deny warnings in std stage 0 --- src/bootstrap/builder.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b0d15e6a5df5f..8540d92f74917 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1018,8 +1018,7 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_VERBOSE", self.verbosity.to_string()); - // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful. - if self.config.deny_warnings && !(mode == Mode::Std && stage == 0) { + if self.config.deny_warnings { cargo.env("RUSTC_DENY_WARNINGS", "1"); } From 3e2b5a4b08d9647f7438f4e945d4c8b37c36a58c Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 9 Feb 2019 01:36:22 +0900 Subject: [PATCH 0773/1064] librustc_data_structures => 2018 --- src/librustc_data_structures/Cargo.toml | 5 +-- src/librustc_data_structures/bit_set.rs | 8 ++--- src/librustc_data_structures/fingerprint.rs | 4 +-- src/librustc_data_structures/flock.rs | 13 ------- .../graph/dominators/mod.rs | 8 ++--- .../graph/implementation/mod.rs | 26 ++++++-------- .../graph/implementation/tests.rs | 2 +- src/librustc_data_structures/graph/scc/mod.rs | 8 ++--- .../graph/scc/test.rs | 2 +- src/librustc_data_structures/graph/test.rs | 2 +- src/librustc_data_structures/indexed_vec.rs | 8 ++--- src/librustc_data_structures/lib.rs | 13 ++----- .../obligation_forest/graphviz.rs | 14 ++++---- .../obligation_forest/mod.rs | 4 +-- .../owning_ref/mod.rs | 6 ++-- src/librustc_data_structures/ptr_key.rs | 2 +- .../snapshot_map/mod.rs | 2 +- src/librustc_data_structures/sorted_map.rs | 2 +- src/librustc_data_structures/stable_hasher.rs | 10 +++--- src/librustc_data_structures/svh.rs | 4 +-- src/librustc_data_structures/sync.rs | 34 +++++++++---------- src/librustc_data_structures/tiny_list.rs | 2 +- .../transitive_relation.rs | 8 ++--- .../vec_linked_list.rs | 2 +- src/librustc_data_structures/work_queue.rs | 4 +-- 25 files changed, 86 insertions(+), 107 deletions(-) diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 1754376a5d7f9..f781952d4172c 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_data_structures" version = "0.0.0" +edition = "2018" [lib] name = "rustc_data_structures" @@ -16,8 +17,8 @@ serialize = { path = "../libserialize" } graphviz = { path = "../libgraphviz" } cfg-if = "0.1.2" stable_deref_trait = "1.0.0" -rustc-rayon = "0.1.1" -rustc-rayon-core = "0.1.1" +rayon = { version = "0.1.1", package = "rustc-rayon" } +rayon-core = { version = "0.1.1", package = "rustc-rayon-core" } rustc-hash = "1.0.1" smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index 8adfe3749af8e..05d2185ae69b4 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -1,4 +1,4 @@ -use indexed_vec::{Idx, IndexVec}; +use crate::indexed_vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; use std::iter; @@ -208,7 +208,7 @@ impl SubtractFromBitSet for BitSet { } impl fmt::Debug for BitSet { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { w.debug_list() .entries(self.iter()) .finish() @@ -366,7 +366,7 @@ impl SparseBitSet { dense } - fn iter(&self) -> slice::Iter { + fn iter(&self) -> slice::Iter<'_, T> { self.elems.iter() } } @@ -536,7 +536,7 @@ impl HybridBitSet { } } - pub fn iter(&self) -> HybridIter { + pub fn iter(&self) -> HybridIter<'_, T> { match self { HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()), HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()), diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index 2e596ca3e44f1..c4c0db5801209 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -1,5 +1,5 @@ +use crate::stable_hasher; use std::mem; -use stable_hasher; use serialize; use serialize::opaque::{EncodeResult, Encoder, Decoder}; @@ -70,7 +70,7 @@ impl Fingerprint { } impl ::std::fmt::Display for Fingerprint { - fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { write!(formatter, "{:x}-{:x}", self.0, self.1) } } diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs index 2dea249f1c07c..255c5fd7fe7ec 100644 --- a/src/librustc_data_structures/flock.rs +++ b/src/librustc_data_structures/flock.rs @@ -14,12 +14,9 @@ cfg_if! { if #[cfg(unix)] { use std::ffi::{CString, OsStr}; use std::os::unix::prelude::*; - use libc; #[cfg(any(target_os = "linux", target_os = "android"))] mod os { - use libc; - #[repr(C)] pub struct flock { pub l_type: libc::c_short, @@ -35,8 +32,6 @@ cfg_if! { #[cfg(target_os = "freebsd")] mod os { - use libc; - #[repr(C)] pub struct flock { pub l_start: libc::off_t, @@ -53,8 +48,6 @@ cfg_if! { target_os = "netbsd", target_os = "openbsd"))] mod os { - use libc; - #[repr(C)] pub struct flock { pub l_start: libc::off_t, @@ -70,8 +63,6 @@ cfg_if! { #[cfg(target_os = "haiku")] mod os { - use libc; - #[repr(C)] pub struct flock { pub l_type: libc::c_short, @@ -87,8 +78,6 @@ cfg_if! { #[cfg(any(target_os = "macos", target_os = "ios"))] mod os { - use libc; - #[repr(C)] pub struct flock { pub l_start: libc::off_t, @@ -104,8 +93,6 @@ cfg_if! { #[cfg(target_os = "solaris")] mod os { - use libc; - #[repr(C)] pub struct flock { pub l_type: libc::c_short, diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 536efffbb22f4..aaed41d9fa362 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -117,7 +117,7 @@ impl Dominators { self.immediate_dominators[node].unwrap() } - pub fn dominators(&self, node: Node) -> Iter { + pub fn dominators(&self, node: Node) -> Iter<'_, Node> { assert!(self.is_reachable(node), "node {:?} is not reachable", node); Iter { dominators: self, @@ -136,7 +136,7 @@ impl Dominators { } } -pub struct Iter<'dom, Node: Idx + 'dom> { +pub struct Iter<'dom, Node: Idx> { dominators: &'dom Dominators, node: Option, } @@ -171,7 +171,7 @@ impl DominatorTree { } impl fmt::Debug for DominatorTree { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt( &DominatorTreeNode { tree: self, @@ -188,7 +188,7 @@ struct DominatorTreeNode<'tree, Node: Idx> { } impl<'tree, Node: Idx> fmt::Debug for DominatorTreeNode<'tree, Node> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let subtrees: Vec<_> = self.tree .children(self.node) .iter() diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/src/librustc_data_structures/graph/implementation/mod.rs index 0768873f83626..a8b734094064a 100644 --- a/src/librustc_data_structures/graph/implementation/mod.rs +++ b/src/librustc_data_structures/graph/implementation/mod.rs @@ -20,10 +20,10 @@ //! the field `next_edge`). Each of those fields is an array that should //! be indexed by the direction (see the type `Direction`). -use bit_set::BitSet; +use crate::bit_set::BitSet; +use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate}; use std::fmt::Debug; use std::usize; -use snapshot_vec::{SnapshotVec, SnapshotVecDelegate}; #[cfg(test)] mod tests; @@ -212,15 +212,19 @@ impl Graph { .all(|(edge_idx, edge)| f(edge_idx, edge)) } - pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges { + pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> { self.adjacent_edges(source, OUTGOING) } - pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges { + pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> { self.adjacent_edges(source, INCOMING) } - pub fn adjacent_edges(&self, source: NodeIndex, direction: Direction) -> AdjacentEdges { + pub fn adjacent_edges( + &self, + source: NodeIndex, + direction: Direction + ) -> AdjacentEdges<'_, N, E> { let first_edge = self.node(source).first_edge[direction.repr]; AdjacentEdges { graph: self, @@ -291,11 +295,7 @@ impl Graph { // # Iterators -pub struct AdjacentEdges<'g, N, E> -where - N: 'g, - E: 'g, -{ +pub struct AdjacentEdges<'g, N, E> { graph: &'g Graph, direction: Direction, next: EdgeIndex, @@ -331,11 +331,7 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { } } -pub struct DepthFirstTraversal<'g, N, E> -where - N: 'g, - E: 'g, -{ +pub struct DepthFirstTraversal<'g, N, E> { graph: &'g Graph, stack: Vec, visited: BitSet, diff --git a/src/librustc_data_structures/graph/implementation/tests.rs b/src/librustc_data_structures/graph/implementation/tests.rs index a7a2504239610..82c6da3f42711 100644 --- a/src/librustc_data_structures/graph/implementation/tests.rs +++ b/src/librustc_data_structures/graph/implementation/tests.rs @@ -1,4 +1,4 @@ -use graph::implementation::*; +use crate::graph::implementation::*; use std::fmt::Debug; type TestGraph = Graph<&'static str, &'static str>; diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs index baab377ef1276..e3264fda2629c 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/src/librustc_data_structures/graph/scc/mod.rs @@ -3,9 +3,9 @@ //! node in the graph. This uses Tarjan's algorithm that completes in //! O(n) time. -use fx::FxHashSet; -use graph::{DirectedGraph, WithNumNodes, WithSuccessors}; -use indexed_vec::{Idx, IndexVec}; +use crate::fx::FxHashSet; +use crate::graph::{DirectedGraph, WithNumNodes, WithSuccessors}; +use crate::indexed_vec::{Idx, IndexVec}; use std::ops::Range; mod test; @@ -93,7 +93,7 @@ impl SccData { } } -struct SccsConstruction<'c, G: DirectedGraph + WithNumNodes + WithSuccessors + 'c, S: Idx> { +struct SccsConstruction<'c, G: DirectedGraph + WithNumNodes + WithSuccessors, S: Idx> { graph: &'c G, /// The state of each node; used during walk to record the stack diff --git a/src/librustc_data_structures/graph/scc/test.rs b/src/librustc_data_structures/graph/scc/test.rs index e23cb1348b015..da3a1ceefe94b 100644 --- a/src/librustc_data_structures/graph/scc/test.rs +++ b/src/librustc_data_structures/graph/scc/test.rs @@ -1,6 +1,6 @@ #![cfg(test)] -use graph::test::TestGraph; +use crate::graph::test::TestGraph; use super::*; #[test] diff --git a/src/librustc_data_structures/graph/test.rs b/src/librustc_data_structures/graph/test.rs index 3d482e448bdb7..b390c41957294 100644 --- a/src/librustc_data_structures/graph/test.rs +++ b/src/librustc_data_structures/graph/test.rs @@ -1,4 +1,4 @@ -use fx::FxHashMap; +use crate::fx::FxHashMap; use std::cmp::max; use std::slice; use std::iter; diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 8d8fbe588a021..516ea7fb7d946 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -257,7 +257,7 @@ macro_rules! newtype_index { @type [$type:ident] @debug_format [$debug_format:tt]) => ( impl ::std::fmt::Debug for $type { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { write!(fmt, $debug_format, self.as_u32()) } } @@ -495,7 +495,7 @@ impl serialize::Decodable for IndexVec { } impl fmt::Debug for IndexVec { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.raw, fmt) } } @@ -573,7 +573,7 @@ impl IndexVec { } #[inline] - pub fn iter(&self) -> slice::Iter { + pub fn iter(&self) -> slice::Iter<'_, T> { self.raw.iter() } @@ -589,7 +589,7 @@ impl IndexVec { } #[inline] - pub fn iter_mut(&mut self) -> slice::IterMut { + pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { self.raw.iter_mut() } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index a46f8aed32499..08b453cf493f8 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -24,23 +24,16 @@ #![cfg_attr(unix, feature(libc))] #![cfg_attr(test, feature(test))] -extern crate core; -extern crate ena; +#![deny(rust_2018_idioms)] + #[macro_use] extern crate log; +#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; // used by deriving #[cfg(unix)] extern crate libc; -extern crate parking_lot; #[macro_use] extern crate cfg_if; -extern crate stable_deref_trait; -extern crate rustc_rayon as rayon; -extern crate rustc_rayon_core as rayon_core; -extern crate rustc_hash; -extern crate serialize; -extern crate graphviz; -extern crate smallvec; // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. #[allow(unused_extern_crates)] diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/src/librustc_data_structures/obligation_forest/graphviz.rs index c2e3938b305d2..72551b42324d0 100644 --- a/src/librustc_data_structures/obligation_forest/graphviz.rs +++ b/src/librustc_data_structures/obligation_forest/graphviz.rs @@ -1,5 +1,5 @@ +use crate::obligation_forest::{ForestObligation, ObligationForest}; use graphviz as dot; -use obligation_forest::{ForestObligation, ObligationForest}; use std::env::var_os; use std::fs::File; use std::path::Path; @@ -41,22 +41,22 @@ impl<'a, O: ForestObligation + 'a> dot::Labeller<'a> for &'a ObligationForest type Node = usize; type Edge = (usize, usize); - fn graph_id(&self) -> dot::Id { + fn graph_id(&self) -> dot::Id<'_> { dot::Id::new("trait_obligation_forest").unwrap() } - fn node_id(&self, index: &Self::Node) -> dot::Id { + fn node_id(&self, index: &Self::Node) -> dot::Id<'_> { dot::Id::new(format!("obligation_{}", index)).unwrap() } - fn node_label(&self, index: &Self::Node) -> dot::LabelText { + fn node_label(&self, index: &Self::Node) -> dot::LabelText<'_> { let node = &self.nodes[*index]; let label = format!("{:?} ({:?})", node.obligation.as_predicate(), node.state.get()); dot::LabelText::LabelStr(label.into()) } - fn edge_label(&self, (_index_source, _index_target): &Self::Edge) -> dot::LabelText { + fn edge_label(&self, (_index_source, _index_target): &Self::Edge) -> dot::LabelText<'_> { dot::LabelText::LabelStr("".into()) } } @@ -65,11 +65,11 @@ impl<'a, O: ForestObligation + 'a> dot::GraphWalk<'a> for &'a ObligationForest dot::Nodes { + fn nodes(&self) -> dot::Nodes<'_, Self::Node> { (0..self.nodes.len()).collect() } - fn edges(&self) -> dot::Edges { + fn edges(&self) -> dot::Edges<'_, Self::Edge> { (0..self.nodes.len()) .flat_map(|i| { let node = &self.nodes[i]; diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 9dd7d204f0373..546bb64168e14 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -80,7 +80,7 @@ //! processing step, we compress the vector to remove completed and error //! nodes, which aren't needed anymore. -use fx::{FxHashMap, FxHashSet}; +use crate::fx::{FxHashMap, FxHashSet}; use std::cell::Cell; use std::collections::hash_map::Entry; @@ -733,7 +733,7 @@ impl Node { // I need a Clone closure #[derive(Clone)] -struct GetObligation<'a, O: 'a>(&'a [Node]); +struct GetObligation<'a, O>(&'a [Node]); impl<'a, 'b, O> FnOnce<(&'b usize,)> for GetObligation<'a, O> { type Output = &'a O; diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index 0b126e5c572ed..30e510cc5b055 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -1002,7 +1002,7 @@ impl Debug for OwningRef where O: Debug, T: Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "OwningRef {{ owner: {:?}, reference: {:?} }}", self.owner(), @@ -1014,7 +1014,7 @@ impl Debug for OwningRefMut where O: Debug, T: Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "OwningRefMut {{ owner: {:?}, reference: {:?} }}", self.owner(), @@ -1047,7 +1047,7 @@ unsafe impl Sync for OwningRefMut where O: Sync, for<'a> (&'a mut T): Sync {} impl Debug for dyn Erased { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "",) } } diff --git a/src/librustc_data_structures/ptr_key.rs b/src/librustc_data_structures/ptr_key.rs index 322dcbe8f08fb..bf3ae2d7af58f 100644 --- a/src/librustc_data_structures/ptr_key.rs +++ b/src/librustc_data_structures/ptr_key.rs @@ -4,7 +4,7 @@ use std::ops::Deref; /// A wrapper around reference that compares and hashes like a pointer. /// Can be used as a key in sets/maps indexed by pointers to avoid `unsafe`. #[derive(Debug)] -pub struct PtrKey<'a, T: 'a>(pub &'a T); +pub struct PtrKey<'a, T>(pub &'a T); impl<'a, T> Clone for PtrKey<'a, T> { fn clone(&self) -> Self { *self } diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index d408727aea504..91d6e29237002 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -1,4 +1,4 @@ -use fx::FxHashMap; +use crate::fx::FxHashMap; use std::hash::Hash; use std::ops; use std::mem; diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs index 64bbb8d7c08d1..1f674c1c664e4 100644 --- a/src/librustc_data_structures/sorted_map.rs +++ b/src/librustc_data_structures/sorted_map.rs @@ -111,7 +111,7 @@ impl SortedMap { /// Iterate over elements, sorted by key #[inline] - pub fn iter(&self) -> ::std::slice::Iter<(K, V)> { + pub fn iter(&self) -> ::std::slice::Iter<'_, (K, V)> { self.data.iter() } diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 4583f12ec8cbc..19343a9250df3 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -1,7 +1,9 @@ use std::hash::{Hash, Hasher, BuildHasher}; use std::marker::PhantomData; use std::mem; -use sip128::SipHasher128; +use crate::sip128::SipHasher128; +use crate::indexed_vec; +use crate::bit_set; /// When hashing something that ends up affecting properties like symbol names, /// we want these symbol names to be calculated independently of other factors @@ -17,7 +19,7 @@ pub struct StableHasher { } impl ::std::fmt::Debug for StableHasher { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { write!(f, "{:?}", self.state) } } @@ -433,7 +435,7 @@ impl HashStable for ::std::mem::Discriminant { } } -impl HashStable for ::indexed_vec::IndexVec +impl HashStable for indexed_vec::IndexVec where T: HashStable, { fn hash_stable(&self, @@ -447,7 +449,7 @@ impl HashStable for ::indexed_vec::IndexVec< } -impl HashStable for ::bit_set::BitSet +impl HashStable for bit_set::BitSet { fn hash_stable(&self, ctx: &mut CTX, diff --git a/src/librustc_data_structures/svh.rs b/src/librustc_data_structures/svh.rs index 749479534979c..3757f921098f2 100644 --- a/src/librustc_data_structures/svh.rs +++ b/src/librustc_data_structures/svh.rs @@ -9,7 +9,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use serialize::{Encodable, Decodable, Encoder, Decoder}; -use stable_hasher; +use crate::stable_hasher; #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Svh { @@ -40,7 +40,7 @@ impl Hash for Svh { } impl fmt::Display for Svh { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad(&self.to_string()) } } diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 7fef1f374d6fd..ba1f6eb56fe88 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -21,7 +21,7 @@ use std::collections::HashMap; use std::hash::{Hash, BuildHasher}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; -use owning_ref::{Erased, OwningRef}; +use crate::owning_ref::{Erased, OwningRef}; pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) where A: FnOnce() -> RA, @@ -261,12 +261,12 @@ cfg_if! { } #[inline(always)] - pub fn lock(&self) -> LockGuard { + pub fn lock(&self) -> LockGuard<'_, T> { self.0.lock() } #[inline(always)] - pub fn lock_mut(&self) -> LockGuard { + pub fn lock_mut(&self) -> LockGuard<'_, T> { self.lock() } } @@ -490,19 +490,19 @@ impl Lock { #[cfg(parallel_compiler)] #[inline(always)] - pub fn try_lock(&self) -> Option> { + pub fn try_lock(&self) -> Option> { self.0.try_lock() } #[cfg(not(parallel_compiler))] #[inline(always)] - pub fn try_lock(&self) -> Option> { + pub fn try_lock(&self) -> Option> { self.0.try_borrow_mut().ok() } #[cfg(parallel_compiler)] #[inline(always)] - pub fn lock(&self) -> LockGuard { + pub fn lock(&self) -> LockGuard<'_, T> { if ERROR_CHECKING { self.0.try_lock().expect("lock was already held") } else { @@ -512,7 +512,7 @@ impl Lock { #[cfg(not(parallel_compiler))] #[inline(always)] - pub fn lock(&self) -> LockGuard { + pub fn lock(&self) -> LockGuard<'_, T> { self.0.borrow_mut() } @@ -522,12 +522,12 @@ impl Lock { } #[inline(always)] - pub fn borrow(&self) -> LockGuard { + pub fn borrow(&self) -> LockGuard<'_, T> { self.lock() } #[inline(always)] - pub fn borrow_mut(&self) -> LockGuard { + pub fn borrow_mut(&self) -> LockGuard<'_, T> { self.lock() } } @@ -568,13 +568,13 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] - pub fn read(&self) -> ReadGuard { + pub fn read(&self) -> ReadGuard<'_, T> { self.0.borrow() } #[cfg(parallel_compiler)] #[inline(always)] - pub fn read(&self) -> ReadGuard { + pub fn read(&self) -> ReadGuard<'_, T> { if ERROR_CHECKING { self.0.try_read().expect("lock was already held") } else { @@ -589,25 +589,25 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] - pub fn try_write(&self) -> Result, ()> { + pub fn try_write(&self) -> Result, ()> { self.0.try_borrow_mut().map_err(|_| ()) } #[cfg(parallel_compiler)] #[inline(always)] - pub fn try_write(&self) -> Result, ()> { + pub fn try_write(&self) -> Result, ()> { self.0.try_write().ok_or(()) } #[cfg(not(parallel_compiler))] #[inline(always)] - pub fn write(&self) -> WriteGuard { + pub fn write(&self) -> WriteGuard<'_, T> { self.0.borrow_mut() } #[cfg(parallel_compiler)] #[inline(always)] - pub fn write(&self) -> WriteGuard { + pub fn write(&self) -> WriteGuard<'_, T> { if ERROR_CHECKING { self.0.try_write().expect("lock was already held") } else { @@ -621,12 +621,12 @@ impl RwLock { } #[inline(always)] - pub fn borrow(&self) -> ReadGuard { + pub fn borrow(&self) -> ReadGuard<'_, T> { self.read() } #[inline(always)] - pub fn borrow_mut(&self) -> WriteGuard { + pub fn borrow_mut(&self) -> WriteGuard<'_, T> { self.write() } } diff --git a/src/librustc_data_structures/tiny_list.rs b/src/librustc_data_structures/tiny_list.rs index d660486d58446..3d74516d9c326 100644 --- a/src/librustc_data_structures/tiny_list.rs +++ b/src/librustc_data_structures/tiny_list.rs @@ -123,7 +123,7 @@ impl Element { mod test { use super::*; extern crate test; - use self::test::Bencher; + use test::Bencher; #[test] fn test_contains_and_insert() { diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index 9d675ed3096e0..39aed9833607f 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -1,8 +1,8 @@ -use bit_set::BitMatrix; -use fx::FxHashMap; -use sync::Lock; +use crate::bit_set::BitMatrix; +use crate::fx::FxHashMap; +use crate::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +use crate::sync::Lock; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; -use stable_hasher::{HashStable, StableHasher, StableHasherResult}; use std::fmt::Debug; use std::hash::Hash; use std::mem; diff --git a/src/librustc_data_structures/vec_linked_list.rs b/src/librustc_data_structures/vec_linked_list.rs index 3b6984dd07599..c00c707a43542 100644 --- a/src/librustc_data_structures/vec_linked_list.rs +++ b/src/librustc_data_structures/vec_linked_list.rs @@ -1,4 +1,4 @@ -use indexed_vec::{Idx, IndexVec}; +use crate::indexed_vec::{Idx, IndexVec}; pub fn iter( first: Option, diff --git a/src/librustc_data_structures/work_queue.rs b/src/librustc_data_structures/work_queue.rs index 0a928de7961b5..06418b1051ac3 100644 --- a/src/librustc_data_structures/work_queue.rs +++ b/src/librustc_data_structures/work_queue.rs @@ -1,5 +1,5 @@ -use bit_set::BitSet; -use indexed_vec::Idx; +use crate::bit_set::BitSet; +use crate::indexed_vec::Idx; use std::collections::VecDeque; /// A work queue is a handy data structure for tracking work left to From 7854067044466de2dd123ca4a3fb6251c0683ead Mon Sep 17 00:00:00 2001 From: Patrick McCarter Date: Fri, 8 Feb 2019 13:04:11 -0500 Subject: [PATCH 0774/1064] Saturating add/sub intrinsic emulation refactor/comments #58030 --- src/librustc_mir/interpret/intrinsics.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index e8dc22b8a596f..48fa856839602 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -132,15 +132,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> BinOp::Sub }, l, r)?; let val = if overflowed { - // For signed ints the saturated value depends on the - // sign of the first term - let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?; let num_bits = l.layout.size.bits(); if l.layout.abi.is_signed() { - if first_term & (1 << (num_bits-1)) == 0 { // first term is positive + // For signed ints the saturated value depends on the sign of the first + // term since the sign of the second term can be inferred from this and + // the fact that the operation has overflowed (if either is 0 no + // overflow can occur) + let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?; + let first_term_pos = first_term & (1 << (num_bits-1)) == 0; + if first_term_pos { + // Negative overflow not possible since the positive first term + // can only increase an (in range) negative term for addition + // or corresponding negated positive term for subtraction Scalar::from_uint((1u128 << (num_bits - 1)) - 1, // max positive Size::from_bits(num_bits)) - } else { // first term is negative + } else { + // Positive overflow not possible for similar reason // max negative Scalar::from_uint(1u128 << (num_bits - 1), Size::from_bits(num_bits)) } From caf7126ee83ad0ebbc6e8c15df54bf02a1e3b9e6 Mon Sep 17 00:00:00 2001 From: Robert Hayek Date: Sat, 9 Feb 2019 00:46:27 -0500 Subject: [PATCH 0775/1064] Some writing improvement, conciseness of intro --- src/doc/rustdoc/src/unstable-features.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index d3eb8cb3d3b8a..3463cdb126cc6 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -1,9 +1,8 @@ # Unstable features Rustdoc is under active development, and like the Rust compiler, some features are only available -on the nightly releases. Some of these are new and need some more testing before they're able to get -released to the world at large, and some of them are tied to features in the Rust compiler that are -themselves unstable. Several features here require a matching `#![feature(...)]` attribute to +on nightly releases. Some of these features are new and need some more testing before they're able to be +released to the world at large, and some of them are tied to features in the Rust compiler that are unstable. Several features here require a matching `#![feature(...)]` attribute to enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over there as necessary. @@ -428,4 +427,4 @@ $ rustdoc src/lib.rs --test -Z unstable-options --persist-doctests target/rustdo This flag allows you to keep doctest executables around after they're compiled or run. Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but -with this option, you can keep those binaries around for farther testing. \ No newline at end of file +with this option, you can keep those binaries around for farther testing. From 360e65db7a75817b957e0b9d5f69e024fb5a78c3 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 9 Feb 2019 17:12:04 +0900 Subject: [PATCH 0776/1064] Move some tests into the tests directory This moves tests in opaque.rs and tests other than tests that require private items in json.rs into tests/opaque.rs and tests/json.rs. --- src/libserialize/json.rs | 1285 +----------------------------- src/libserialize/lib.rs | 4 - src/libserialize/opaque.rs | 285 ------- src/libserialize/tests/json.rs | 1282 +++++++++++++++++++++++++++++ src/libserialize/tests/opaque.rs | 282 +++++++ 5 files changed, 1568 insertions(+), 1570 deletions(-) create mode 100644 src/libserialize/tests/json.rs create mode 100644 src/libserialize/tests/opaque.rs diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index dc089218a9fac..60b1d2e17f12a 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2584,1220 +2584,13 @@ impl FromStr for Json { #[cfg(test)] mod tests { + // Benchmarks and tests that require private items + extern crate test; - use self::Animal::*; - use self::test::Bencher; - use crate::{Encodable, Decodable}; - use super::Json::*; - use super::ErrorCode::*; - use super::ParserError::*; - use super::DecoderError::*; - use super::JsonEvent::*; - use super::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser, - StackElement, Stack, Decoder, Encoder, EncoderError}; - use std::{i64, u64, f32, f64}; - use std::io::prelude::*; - use std::collections::BTreeMap; + use test::Bencher; + use super::{from_str, Parser, StackElement, Stack}; use std::string; - #[derive(RustcDecodable, Eq, PartialEq, Debug)] - struct OptionData { - opt: Option, - } - - #[test] - fn test_decode_option_none() { - let s ="{}"; - let obj: OptionData = super::decode(s).unwrap(); - assert_eq!(obj, OptionData { opt: None }); - } - - #[test] - fn test_decode_option_some() { - let s = "{ \"opt\": 10 }"; - let obj: OptionData = super::decode(s).unwrap(); - assert_eq!(obj, OptionData { opt: Some(10) }); - } - - #[test] - fn test_decode_option_malformed() { - check_err::("{ \"opt\": [] }", - ExpectedError("Number".to_string(), "[]".to_string())); - check_err::("{ \"opt\": false }", - ExpectedError("Number".to_string(), "false".to_string())); - } - - #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] - enum Animal { - Dog, - Frog(string::String, isize) - } - - #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] - struct Inner { - a: (), - b: usize, - c: Vec, - } - - #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] - struct Outer { - inner: Vec, - } - - fn mk_object(items: &[(string::String, Json)]) -> Json { - let mut d = BTreeMap::new(); - - for item in items { - match *item { - (ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); }, - } - }; - - Object(d) - } - - #[test] - fn test_from_str_trait() { - let s = "null"; - assert!(s.parse::().unwrap() == s.parse().unwrap()); - } - - #[test] - fn test_write_null() { - assert_eq!(Null.to_string(), "null"); - assert_eq!(Null.pretty().to_string(), "null"); - } - - #[test] - fn test_write_i64() { - assert_eq!(U64(0).to_string(), "0"); - assert_eq!(U64(0).pretty().to_string(), "0"); - - assert_eq!(U64(1234).to_string(), "1234"); - assert_eq!(U64(1234).pretty().to_string(), "1234"); - - assert_eq!(I64(-5678).to_string(), "-5678"); - assert_eq!(I64(-5678).pretty().to_string(), "-5678"); - - assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); - assert_eq!(U64(7650007200025252000).pretty().to_string(), "7650007200025252000"); - } - - #[test] - fn test_write_f64() { - assert_eq!(F64(3.0).to_string(), "3.0"); - assert_eq!(F64(3.0).pretty().to_string(), "3.0"); - - assert_eq!(F64(3.1).to_string(), "3.1"); - assert_eq!(F64(3.1).pretty().to_string(), "3.1"); - - assert_eq!(F64(-1.5).to_string(), "-1.5"); - assert_eq!(F64(-1.5).pretty().to_string(), "-1.5"); - - assert_eq!(F64(0.5).to_string(), "0.5"); - assert_eq!(F64(0.5).pretty().to_string(), "0.5"); - - assert_eq!(F64(f64::NAN).to_string(), "null"); - assert_eq!(F64(f64::NAN).pretty().to_string(), "null"); - - assert_eq!(F64(f64::INFINITY).to_string(), "null"); - assert_eq!(F64(f64::INFINITY).pretty().to_string(), "null"); - - assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null"); - assert_eq!(F64(f64::NEG_INFINITY).pretty().to_string(), "null"); - } - - #[test] - fn test_write_str() { - assert_eq!(String("".to_string()).to_string(), "\"\""); - assert_eq!(String("".to_string()).pretty().to_string(), "\"\""); - - assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); - assert_eq!(String("madoka".to_string()).pretty().to_string(), "\"madoka\""); - } - - #[test] - fn test_write_bool() { - assert_eq!(Boolean(true).to_string(), "true"); - assert_eq!(Boolean(true).pretty().to_string(), "true"); - - assert_eq!(Boolean(false).to_string(), "false"); - assert_eq!(Boolean(false).pretty().to_string(), "false"); - } - - #[test] - fn test_write_array() { - assert_eq!(Array(vec![]).to_string(), "[]"); - assert_eq!(Array(vec![]).pretty().to_string(), "[]"); - - assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]"); - assert_eq!( - Array(vec![Boolean(true)]).pretty().to_string(), - "\ - [\n \ - true\n\ - ]" - ); - - let long_test_array = Array(vec![ - Boolean(false), - Null, - Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); - - assert_eq!(long_test_array.to_string(), - "[false,null,[\"foo\\nbar\",3.5]]"); - assert_eq!( - long_test_array.pretty().to_string(), - "\ - [\n \ - false,\n \ - null,\n \ - [\n \ - \"foo\\nbar\",\n \ - 3.5\n \ - ]\n\ - ]" - ); - } - - #[test] - fn test_write_object() { - assert_eq!(mk_object(&[]).to_string(), "{}"); - assert_eq!(mk_object(&[]).pretty().to_string(), "{}"); - - assert_eq!( - mk_object(&[ - ("a".to_string(), Boolean(true)) - ]).to_string(), - "{\"a\":true}" - ); - assert_eq!( - mk_object(&[("a".to_string(), Boolean(true))]).pretty().to_string(), - "\ - {\n \ - \"a\": true\n\ - }" - ); - - let complex_obj = mk_object(&[ - ("b".to_string(), Array(vec![ - mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), - mk_object(&[("d".to_string(), String("".to_string()))]) - ])) - ]); - - assert_eq!( - complex_obj.to_string(), - "{\ - \"b\":[\ - {\"c\":\"\\f\\r\"},\ - {\"d\":\"\"}\ - ]\ - }" - ); - assert_eq!( - complex_obj.pretty().to_string(), - "\ - {\n \ - \"b\": [\n \ - {\n \ - \"c\": \"\\f\\r\"\n \ - },\n \ - {\n \ - \"d\": \"\"\n \ - }\n \ - ]\n\ - }" - ); - - let a = mk_object(&[ - ("a".to_string(), Boolean(true)), - ("b".to_string(), Array(vec![ - mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), - mk_object(&[("d".to_string(), String("".to_string()))]) - ])) - ]); - - // We can't compare the strings directly because the object fields be - // printed in a different order. - assert_eq!(a.clone(), a.to_string().parse().unwrap()); - assert_eq!(a.clone(), a.pretty().to_string().parse().unwrap()); - } - - #[test] - fn test_write_enum() { - let animal = Dog; - assert_eq!( - super::as_json(&animal).to_string(), - "\"Dog\"" - ); - assert_eq!( - super::as_pretty_json(&animal).to_string(), - "\"Dog\"" - ); - - let animal = Frog("Henry".to_string(), 349); - assert_eq!( - super::as_json(&animal).to_string(), - "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" - ); - assert_eq!( - super::as_pretty_json(&animal).to_string(), - "{\n \ - \"variant\": \"Frog\",\n \ - \"fields\": [\n \ - \"Henry\",\n \ - 349\n \ - ]\n\ - }" - ); - } - - macro_rules! check_encoder_for_simple { - ($value:expr, $expected:expr) => ({ - let s = super::as_json(&$value).to_string(); - assert_eq!(s, $expected); - - let s = super::as_pretty_json(&$value).to_string(); - assert_eq!(s, $expected); - }) - } - - #[test] - fn test_write_some() { - check_encoder_for_simple!(Some("jodhpurs".to_string()), "\"jodhpurs\""); - } - - #[test] - fn test_write_none() { - check_encoder_for_simple!(None::, "null"); - } - - #[test] - fn test_write_char() { - check_encoder_for_simple!('a', "\"a\""); - check_encoder_for_simple!('\t', "\"\\t\""); - check_encoder_for_simple!('\u{0000}', "\"\\u0000\""); - check_encoder_for_simple!('\u{001b}', "\"\\u001b\""); - check_encoder_for_simple!('\u{007f}', "\"\\u007f\""); - check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); - check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); - check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); - } - - #[test] - fn test_trailing_characters() { - assert_eq!(from_str("nulla"), Err(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(from_str("truea"), Err(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(from_str("falsea"), Err(SyntaxError(TrailingCharacters, 1, 6))); - assert_eq!(from_str("1a"), Err(SyntaxError(TrailingCharacters, 1, 2))); - assert_eq!(from_str("[]a"), Err(SyntaxError(TrailingCharacters, 1, 3))); - assert_eq!(from_str("{}a"), Err(SyntaxError(TrailingCharacters, 1, 3))); - } - - #[test] - fn test_read_identifiers() { - assert_eq!(from_str("n"), Err(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(from_str("nul"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(from_str("t"), Err(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(from_str("truz"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(from_str("f"), Err(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(from_str("faz"), Err(SyntaxError(InvalidSyntax, 1, 3))); - - assert_eq!(from_str("null"), Ok(Null)); - assert_eq!(from_str("true"), Ok(Boolean(true))); - assert_eq!(from_str("false"), Ok(Boolean(false))); - assert_eq!(from_str(" null "), Ok(Null)); - assert_eq!(from_str(" true "), Ok(Boolean(true))); - assert_eq!(from_str(" false "), Ok(Boolean(false))); - } - - #[test] - fn test_decode_identifiers() { - let v: () = super::decode("null").unwrap(); - assert_eq!(v, ()); - - let v: bool = super::decode("true").unwrap(); - assert_eq!(v, true); - - let v: bool = super::decode("false").unwrap(); - assert_eq!(v, false); - } - - #[test] - fn test_read_number() { - assert_eq!(from_str("+"), Err(SyntaxError(InvalidSyntax, 1, 1))); - assert_eq!(from_str("."), Err(SyntaxError(InvalidSyntax, 1, 1))); - assert_eq!(from_str("NaN"), Err(SyntaxError(InvalidSyntax, 1, 1))); - assert_eq!(from_str("-"), Err(SyntaxError(InvalidNumber, 1, 2))); - assert_eq!(from_str("00"), Err(SyntaxError(InvalidNumber, 1, 2))); - assert_eq!(from_str("1."), Err(SyntaxError(InvalidNumber, 1, 3))); - assert_eq!(from_str("1e"), Err(SyntaxError(InvalidNumber, 1, 3))); - assert_eq!(from_str("1e+"), Err(SyntaxError(InvalidNumber, 1, 4))); - - assert_eq!(from_str("18446744073709551616"), Err(SyntaxError(InvalidNumber, 1, 20))); - assert_eq!(from_str("-9223372036854775809"), Err(SyntaxError(InvalidNumber, 1, 21))); - - assert_eq!(from_str("3"), Ok(U64(3))); - assert_eq!(from_str("3.1"), Ok(F64(3.1))); - assert_eq!(from_str("-1.2"), Ok(F64(-1.2))); - assert_eq!(from_str("0.4"), Ok(F64(0.4))); - assert_eq!(from_str("0.4e5"), Ok(F64(0.4e5))); - assert_eq!(from_str("0.4e+15"), Ok(F64(0.4e15))); - assert_eq!(from_str("0.4e-01"), Ok(F64(0.4e-01))); - assert_eq!(from_str(" 3 "), Ok(U64(3))); - - assert_eq!(from_str("-9223372036854775808"), Ok(I64(i64::MIN))); - assert_eq!(from_str("9223372036854775807"), Ok(U64(i64::MAX as u64))); - assert_eq!(from_str("18446744073709551615"), Ok(U64(u64::MAX))); - } - - #[test] - fn test_decode_numbers() { - let v: f64 = super::decode("3").unwrap(); - assert_eq!(v, 3.0); - - let v: f64 = super::decode("3.1").unwrap(); - assert_eq!(v, 3.1); - - let v: f64 = super::decode("-1.2").unwrap(); - assert_eq!(v, -1.2); - - let v: f64 = super::decode("0.4").unwrap(); - assert_eq!(v, 0.4); - - let v: f64 = super::decode("0.4e5").unwrap(); - assert_eq!(v, 0.4e5); - - let v: f64 = super::decode("0.4e15").unwrap(); - assert_eq!(v, 0.4e15); - - let v: f64 = super::decode("0.4e-01").unwrap(); - assert_eq!(v, 0.4e-01); - - let v: u64 = super::decode("0").unwrap(); - assert_eq!(v, 0); - - let v: u64 = super::decode("18446744073709551615").unwrap(); - assert_eq!(v, u64::MAX); - - let v: i64 = super::decode("-9223372036854775808").unwrap(); - assert_eq!(v, i64::MIN); - - let v: i64 = super::decode("9223372036854775807").unwrap(); - assert_eq!(v, i64::MAX); - - let res: DecodeResult = super::decode("765.25"); - assert_eq!(res, Err(ExpectedError("Integer".to_string(), - "765.25".to_string()))); - } - - #[test] - fn test_read_str() { - assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2))); - assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5))); - - assert_eq!(from_str("\"\""), Ok(String("".to_string()))); - assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string()))); - assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string()))); - assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string()))); - assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string()))); - assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string()))); - assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string()))); - assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string()))); - assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u{12ab}".to_string()))); - assert_eq!(from_str("\"\\uAB12\""), Ok(String("\u{AB12}".to_string()))); - } - - #[test] - fn test_decode_str() { - let s = [("\"\"", ""), - ("\"foo\"", "foo"), - ("\"\\\"\"", "\""), - ("\"\\b\"", "\x08"), - ("\"\\n\"", "\n"), - ("\"\\r\"", "\r"), - ("\"\\t\"", "\t"), - ("\"\\u12ab\"", "\u{12ab}"), - ("\"\\uAB12\"", "\u{AB12}")]; - - for &(i, o) in &s { - let v: string::String = super::decode(i).unwrap(); - assert_eq!(v, o); - } - } - - #[test] - fn test_read_array() { - assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); - assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); - assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); - assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - - assert_eq!(from_str("[]"), Ok(Array(vec![]))); - assert_eq!(from_str("[ ]"), Ok(Array(vec![]))); - assert_eq!(from_str("[true]"), Ok(Array(vec![Boolean(true)]))); - assert_eq!(from_str("[ false ]"), Ok(Array(vec![Boolean(false)]))); - assert_eq!(from_str("[null]"), Ok(Array(vec![Null]))); - assert_eq!(from_str("[3, 1]"), - Ok(Array(vec![U64(3), U64(1)]))); - assert_eq!(from_str("\n[3, 2]\n"), - Ok(Array(vec![U64(3), U64(2)]))); - assert_eq!(from_str("[2, [4, 1]]"), - Ok(Array(vec![U64(2), Array(vec![U64(4), U64(1)])]))); - } - - #[test] - fn test_decode_array() { - let v: Vec<()> = super::decode("[]").unwrap(); - assert_eq!(v, []); - - let v: Vec<()> = super::decode("[null]").unwrap(); - assert_eq!(v, [()]); - - let v: Vec = super::decode("[true]").unwrap(); - assert_eq!(v, [true]); - - let v: Vec = super::decode("[3, 1]").unwrap(); - assert_eq!(v, [3, 1]); - - let v: Vec> = super::decode("[[3], [1, 2]]").unwrap(); - assert_eq!(v, [vec![3], vec![1, 2]]); - } - - #[test] - fn test_decode_tuple() { - let t: (usize, usize, usize) = super::decode("[1, 2, 3]").unwrap(); - assert_eq!(t, (1, 2, 3)); - - let t: (usize, string::String) = super::decode("[1, \"two\"]").unwrap(); - assert_eq!(t, (1, "two".to_string())); - } - - #[test] - fn test_decode_tuple_malformed_types() { - assert!(super::decode::<(usize, string::String)>("[1, 2]").is_err()); - } - - #[test] - fn test_decode_tuple_malformed_length() { - assert!(super::decode::<(usize, usize)>("[1, 2, 3]").is_err()); - } - - #[test] - fn test_read_object() { - assert_eq!(from_str("{"), Err(SyntaxError(EOFWhileParsingObject, 1, 2))); - assert_eq!(from_str("{ "), Err(SyntaxError(EOFWhileParsingObject, 1, 3))); - assert_eq!(from_str("{1"), Err(SyntaxError(KeyMustBeAString, 1, 2))); - assert_eq!(from_str("{ \"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); - assert_eq!(from_str("{\"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 5))); - assert_eq!(from_str("{\"a\" "), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); - - assert_eq!(from_str("{\"a\" 1"), Err(SyntaxError(ExpectedColon, 1, 6))); - assert_eq!(from_str("{\"a\":"), Err(SyntaxError(EOFWhileParsingValue, 1, 6))); - assert_eq!(from_str("{\"a\":1"), Err(SyntaxError(EOFWhileParsingObject, 1, 7))); - assert_eq!(from_str("{\"a\":1 1"), Err(SyntaxError(InvalidSyntax, 1, 8))); - assert_eq!(from_str("{\"a\":1,"), Err(SyntaxError(EOFWhileParsingObject, 1, 8))); - - assert_eq!(from_str("{}").unwrap(), mk_object(&[])); - assert_eq!(from_str("{\"a\": 3}").unwrap(), - mk_object(&[("a".to_string(), U64(3))])); - - assert_eq!(from_str( - "{ \"a\": null, \"b\" : true }").unwrap(), - mk_object(&[ - ("a".to_string(), Null), - ("b".to_string(), Boolean(true))])); - assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), - mk_object(&[ - ("a".to_string(), Null), - ("b".to_string(), Boolean(true))])); - assert_eq!(from_str( - "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), - mk_object(&[ - ("a".to_string(), F64(1.0)), - ("b".to_string(), Array(vec![Boolean(true)])) - ])); - assert_eq!(from_str( - "{\ - \"a\": 1.0, \ - \"b\": [\ - true,\ - \"foo\\nbar\", \ - { \"c\": {\"d\": null} } \ - ]\ - }").unwrap(), - mk_object(&[ - ("a".to_string(), F64(1.0)), - ("b".to_string(), Array(vec![ - Boolean(true), - String("foo\nbar".to_string()), - mk_object(&[ - ("c".to_string(), mk_object(&[("d".to_string(), Null)])) - ]) - ])) - ])); - } - - #[test] - fn test_decode_struct() { - let s = "{ - \"inner\": [ - { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } - ] - }"; - - let v: Outer = super::decode(s).unwrap(); - assert_eq!( - v, - Outer { - inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } - ] - } - ); - } - - #[derive(RustcDecodable)] - struct FloatStruct { - f: f64, - a: Vec - } - #[test] - fn test_decode_struct_with_nan() { - let s = "{\"f\":null,\"a\":[null,123]}"; - let obj: FloatStruct = super::decode(s).unwrap(); - assert!(obj.f.is_nan()); - assert!(obj.a[0].is_nan()); - assert_eq!(obj.a[1], 123f64); - } - - #[test] - fn test_decode_option() { - let value: Option = super::decode("null").unwrap(); - assert_eq!(value, None); - - let value: Option = super::decode("\"jodhpurs\"").unwrap(); - assert_eq!(value, Some("jodhpurs".to_string())); - } - - #[test] - fn test_decode_enum() { - let value: Animal = super::decode("\"Dog\"").unwrap(); - assert_eq!(value, Dog); - - let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; - let value: Animal = super::decode(s).unwrap(); - assert_eq!(value, Frog("Henry".to_string(), 349)); - } - - #[test] - fn test_decode_map() { - let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ - \"fields\":[\"Henry\", 349]}}"; - let mut map: BTreeMap = super::decode(s).unwrap(); - - assert_eq!(map.remove(&"a".to_string()), Some(Dog)); - assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); - } - - #[test] - fn test_multiline_errors() { - assert_eq!(from_str("{\n \"foo\":\n \"bar\""), - Err(SyntaxError(EOFWhileParsingObject, 3, 8))); - } - - #[derive(RustcDecodable)] - #[allow(dead_code)] - struct DecodeStruct { - x: f64, - y: bool, - z: string::String, - w: Vec - } - #[derive(RustcDecodable)] - enum DecodeEnum { - A(f64), - B(string::String) - } - fn check_err(to_parse: &'static str, expected: DecoderError) { - let res: DecodeResult = match from_str(to_parse) { - Err(e) => Err(ParseError(e)), - Ok(json) => Decodable::decode(&mut Decoder::new(json)) - }; - match res { - Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", - to_parse, expected), - Err(ParseError(e)) => panic!("`{:?}` is not valid json: {:?}", - to_parse, e), - Err(e) => { - assert_eq!(e, expected); - } - } - } - #[test] - fn test_decode_errors_struct() { - check_err::("[]", ExpectedError("Object".to_string(), "[]".to_string())); - check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", - ExpectedError("Number".to_string(), "true".to_string())); - check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", - ExpectedError("Boolean".to_string(), "[]".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", - ExpectedError("String".to_string(), "{}".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", - ExpectedError("Array".to_string(), "null".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", - MissingFieldError("w".to_string())); - } - #[test] - fn test_decode_errors_enum() { - check_err::("{}", - MissingFieldError("variant".to_string())); - check_err::("{\"variant\": 1}", - ExpectedError("String".to_string(), "1".to_string())); - check_err::("{\"variant\": \"A\"}", - MissingFieldError("fields".to_string())); - check_err::("{\"variant\": \"A\", \"fields\": null}", - ExpectedError("Array".to_string(), "null".to_string())); - check_err::("{\"variant\": \"C\", \"fields\": []}", - UnknownVariantError("C".to_string())); - } - - #[test] - fn test_find(){ - let json_value = from_str("{\"dog\" : \"cat\"}").unwrap(); - let found_str = json_value.find("dog"); - assert!(found_str.unwrap().as_string().unwrap() == "cat"); - } - - #[test] - fn test_find_path(){ - let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.find_path(&["dog", "cat", "mouse"]); - assert!(found_str.unwrap().as_string().unwrap() == "cheese"); - } - - #[test] - fn test_search(){ - let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.search("mouse").and_then(|j| j.as_string()); - assert!(found_str.unwrap() == "cheese"); - } - - #[test] - fn test_index(){ - let json_value = from_str("{\"animals\":[\"dog\",\"cat\",\"mouse\"]}").unwrap(); - let ref array = json_value["animals"]; - assert_eq!(array[0].as_string().unwrap(), "dog"); - assert_eq!(array[1].as_string().unwrap(), "cat"); - assert_eq!(array[2].as_string().unwrap(), "mouse"); - } - - #[test] - fn test_is_object(){ - let json_value = from_str("{}").unwrap(); - assert!(json_value.is_object()); - } - - #[test] - fn test_as_object(){ - let json_value = from_str("{}").unwrap(); - let json_object = json_value.as_object(); - assert!(json_object.is_some()); - } - - #[test] - fn test_is_array(){ - let json_value = from_str("[1, 2, 3]").unwrap(); - assert!(json_value.is_array()); - } - - #[test] - fn test_as_array(){ - let json_value = from_str("[1, 2, 3]").unwrap(); - let json_array = json_value.as_array(); - let expected_length = 3; - assert!(json_array.is_some() && json_array.unwrap().len() == expected_length); - } - - #[test] - fn test_is_string(){ - let json_value = from_str("\"dog\"").unwrap(); - assert!(json_value.is_string()); - } - - #[test] - fn test_as_string(){ - let json_value = from_str("\"dog\"").unwrap(); - let json_str = json_value.as_string(); - let expected_str = "dog"; - assert_eq!(json_str, Some(expected_str)); - } - - #[test] - fn test_is_number(){ - let json_value = from_str("12").unwrap(); - assert!(json_value.is_number()); - } - - #[test] - fn test_is_i64(){ - let json_value = from_str("-12").unwrap(); - assert!(json_value.is_i64()); - - let json_value = from_str("12").unwrap(); - assert!(!json_value.is_i64()); - - let json_value = from_str("12.0").unwrap(); - assert!(!json_value.is_i64()); - } - - #[test] - fn test_is_u64(){ - let json_value = from_str("12").unwrap(); - assert!(json_value.is_u64()); - - let json_value = from_str("-12").unwrap(); - assert!(!json_value.is_u64()); - - let json_value = from_str("12.0").unwrap(); - assert!(!json_value.is_u64()); - } - - #[test] - fn test_is_f64(){ - let json_value = from_str("12").unwrap(); - assert!(!json_value.is_f64()); - - let json_value = from_str("-12").unwrap(); - assert!(!json_value.is_f64()); - - let json_value = from_str("12.0").unwrap(); - assert!(json_value.is_f64()); - - let json_value = from_str("-12.0").unwrap(); - assert!(json_value.is_f64()); - } - - #[test] - fn test_as_i64(){ - let json_value = from_str("-12").unwrap(); - let json_num = json_value.as_i64(); - assert_eq!(json_num, Some(-12)); - } - - #[test] - fn test_as_u64(){ - let json_value = from_str("12").unwrap(); - let json_num = json_value.as_u64(); - assert_eq!(json_num, Some(12)); - } - - #[test] - fn test_as_f64(){ - let json_value = from_str("12.0").unwrap(); - let json_num = json_value.as_f64(); - assert_eq!(json_num, Some(12f64)); - } - - #[test] - fn test_is_boolean(){ - let json_value = from_str("false").unwrap(); - assert!(json_value.is_boolean()); - } - - #[test] - fn test_as_boolean(){ - let json_value = from_str("false").unwrap(); - let json_bool = json_value.as_boolean(); - let expected_bool = false; - assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); - } - - #[test] - fn test_is_null(){ - let json_value = from_str("null").unwrap(); - assert!(json_value.is_null()); - } - - #[test] - fn test_as_null(){ - let json_value = from_str("null").unwrap(); - let json_null = json_value.as_null(); - let expected_null = (); - assert!(json_null.is_some() && json_null.unwrap() == expected_null); - } - - #[test] - fn test_encode_hashmap_with_numeric_key() { - use std::str::from_utf8; - use std::collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let mut mem_buf = Vec::new(); - write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); - let json_str = from_utf8(&mem_buf[..]).unwrap(); - match from_str(json_str) { - Err(_) => panic!("Unable to parse json_str: {:?}", json_str), - _ => {} // it parsed and we are good to go - } - } - - #[test] - fn test_prettyencode_hashmap_with_numeric_key() { - use std::str::from_utf8; - use std::collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let mut mem_buf = Vec::new(); - write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); - let json_str = from_utf8(&mem_buf[..]).unwrap(); - match from_str(json_str) { - Err(_) => panic!("Unable to parse json_str: {:?}", json_str), - _ => {} // it parsed and we are good to go - } - } - - #[test] - fn test_prettyencoder_indent_level_param() { - use std::str::from_utf8; - use std::collections::BTreeMap; - - let mut tree = BTreeMap::new(); - - tree.insert("hello".to_string(), String("guten tag".to_string())); - tree.insert("goodbye".to_string(), String("sayonara".to_string())); - - let json = Array( - // The following layout below should look a lot like - // the pretty-printed JSON (indent * x) - vec! - ( // 0x - String("greetings".to_string()), // 1x - Object(tree), // 1x + 2x + 2x + 1x - ) // 0x - // End JSON array (7 lines) - ); - - // Helper function for counting indents - fn indents(source: &str) -> usize { - let trimmed = source.trim_start_matches(' '); - source.len() - trimmed.len() - } - - // Test up to 4 spaces of indents (more?) - for i in 0..4 { - let mut writer = Vec::new(); - write!(&mut writer, "{}", - super::as_pretty_json(&json).indent(i)).unwrap(); - - let printed = from_utf8(&writer[..]).unwrap(); - - // Check for indents at each line - let lines: Vec<&str> = printed.lines().collect(); - assert_eq!(lines.len(), 7); // JSON should be 7 lines - - assert_eq!(indents(lines[0]), 0 * i); // [ - assert_eq!(indents(lines[1]), 1 * i); // "greetings", - assert_eq!(indents(lines[2]), 1 * i); // { - assert_eq!(indents(lines[3]), 2 * i); // "hello": "guten tag", - assert_eq!(indents(lines[4]), 2 * i); // "goodbye": "sayonara" - assert_eq!(indents(lines[5]), 1 * i); // }, - assert_eq!(indents(lines[6]), 0 * i); // ] - - // Finally, test that the pretty-printed JSON is valid - from_str(printed).ok().expect("Pretty-printed JSON is invalid!"); - } - } - - #[test] - fn test_hashmap_with_enum_key() { - use std::collections::HashMap; - use crate::json; - #[derive(RustcEncodable, Eq, Hash, PartialEq, RustcDecodable, Debug)] - enum Enum { - Foo, - #[allow(dead_code)] - Bar, - } - let mut map = HashMap::new(); - map.insert(Enum::Foo, 0); - let result = json::encode(&map).unwrap(); - assert_eq!(&result[..], r#"{"Foo":0}"#); - let decoded: HashMap = json::decode(&result).unwrap(); - assert_eq!(map, decoded); - } - - #[test] - fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { - use std::collections::HashMap; - use Decodable; - let json_str = "{\"1\":true}"; - let json_obj = match from_str(json_str) { - Err(_) => panic!("Unable to parse json_str: {:?}", json_str), - Ok(o) => o - }; - let mut decoder = Decoder::new(json_obj); - let _hm: HashMap = Decodable::decode(&mut decoder).unwrap(); - } - - #[test] - fn test_hashmap_with_numeric_key_will_error_with_string_keys() { - use std::collections::HashMap; - use Decodable; - let json_str = "{\"a\":true}"; - let json_obj = match from_str(json_str) { - Err(_) => panic!("Unable to parse json_str: {:?}", json_str), - Ok(o) => o - }; - let mut decoder = Decoder::new(json_obj); - let result: Result, DecoderError> = Decodable::decode(&mut decoder); - assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string()))); - } - - fn assert_stream_equal(src: &str, - expected: Vec<(JsonEvent, Vec)>) { - let mut parser = Parser::new(src.chars()); - let mut i = 0; - loop { - let evt = match parser.next() { - Some(e) => e, - None => { break; } - }; - let (ref expected_evt, ref expected_stack) = expected[i]; - if !parser.stack().is_equal_to(expected_stack) { - panic!("Parser stack is not equal to {:?}", expected_stack); - } - assert_eq!(&evt, expected_evt); - i+=1; - } - } - #[test] - fn test_streaming_parser() { - assert_stream_equal( - r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#, - vec![ - (ObjectStart, vec![]), - (StringValue("bar".to_string()), vec![StackElement::Key("foo")]), - (ArrayStart, vec![StackElement::Key("array")]), - (U64Value(0), vec![StackElement::Key("array"), StackElement::Index(0)]), - (U64Value(1), vec![StackElement::Key("array"), StackElement::Index(1)]), - (U64Value(2), vec![StackElement::Key("array"), StackElement::Index(2)]), - (U64Value(3), vec![StackElement::Key("array"), StackElement::Index(3)]), - (U64Value(4), vec![StackElement::Key("array"), StackElement::Index(4)]), - (U64Value(5), vec![StackElement::Key("array"), StackElement::Index(5)]), - (ArrayEnd, vec![StackElement::Key("array")]), - (ArrayStart, vec![StackElement::Key("idents")]), - (NullValue, vec![StackElement::Key("idents"), - StackElement::Index(0)]), - (BooleanValue(true), vec![StackElement::Key("idents"), - StackElement::Index(1)]), - (BooleanValue(false), vec![StackElement::Key("idents"), - StackElement::Index(2)]), - (ArrayEnd, vec![StackElement::Key("idents")]), - (ObjectEnd, vec![]), - ] - ); - } - fn last_event(src: &str) -> JsonEvent { - let mut parser = Parser::new(src.chars()); - let mut evt = NullValue; - loop { - evt = match parser.next() { - Some(e) => e, - None => return evt, - } - } - } - - #[test] - fn test_read_object_streaming() { - assert_eq!(last_event("{ "), Error(SyntaxError(EOFWhileParsingObject, 1, 3))); - assert_eq!(last_event("{1"), Error(SyntaxError(KeyMustBeAString, 1, 2))); - assert_eq!(last_event("{ \"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); - assert_eq!(last_event("{\"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 5))); - assert_eq!(last_event("{\"a\" "), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); - - assert_eq!(last_event("{\"a\" 1"), Error(SyntaxError(ExpectedColon, 1, 6))); - assert_eq!(last_event("{\"a\":"), Error(SyntaxError(EOFWhileParsingValue, 1, 6))); - assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7))); - assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8))); - assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8))); - assert_eq!(last_event("{\"a\":1,}"), Error(SyntaxError(TrailingComma, 1, 8))); - - assert_stream_equal( - "{}", - vec![(ObjectStart, vec![]), (ObjectEnd, vec![])] - ); - assert_stream_equal( - "{\"a\": 3}", - vec![ - (ObjectStart, vec![]), - (U64Value(3), vec![StackElement::Key("a")]), - (ObjectEnd, vec![]), - ] - ); - assert_stream_equal( - "{ \"a\": null, \"b\" : true }", - vec![ - (ObjectStart, vec![]), - (NullValue, vec![StackElement::Key("a")]), - (BooleanValue(true), vec![StackElement::Key("b")]), - (ObjectEnd, vec![]), - ] - ); - assert_stream_equal( - "{\"a\" : 1.0 ,\"b\": [ true ]}", - vec![ - (ObjectStart, vec![]), - (F64Value(1.0), vec![StackElement::Key("a")]), - (ArrayStart, vec![StackElement::Key("b")]), - (BooleanValue(true),vec![StackElement::Key("b"), StackElement::Index(0)]), - (ArrayEnd, vec![StackElement::Key("b")]), - (ObjectEnd, vec![]), - ] - ); - assert_stream_equal( - r#"{ - "a": 1.0, - "b": [ - true, - "foo\nbar", - { "c": {"d": null} } - ] - }"#, - vec![ - (ObjectStart, vec![]), - (F64Value(1.0), vec![StackElement::Key("a")]), - (ArrayStart, vec![StackElement::Key("b")]), - (BooleanValue(true), vec![StackElement::Key("b"), - StackElement::Index(0)]), - (StringValue("foo\nbar".to_string()), vec![StackElement::Key("b"), - StackElement::Index(1)]), - (ObjectStart, vec![StackElement::Key("b"), - StackElement::Index(2)]), - (ObjectStart, vec![StackElement::Key("b"), - StackElement::Index(2), - StackElement::Key("c")]), - (NullValue, vec![StackElement::Key("b"), - StackElement::Index(2), - StackElement::Key("c"), - StackElement::Key("d")]), - (ObjectEnd, vec![StackElement::Key("b"), - StackElement::Index(2), - StackElement::Key("c")]), - (ObjectEnd, vec![StackElement::Key("b"), - StackElement::Index(2)]), - (ArrayEnd, vec![StackElement::Key("b")]), - (ObjectEnd, vec![]), - ] - ); - } - #[test] - fn test_read_array_streaming() { - assert_stream_equal( - "[]", - vec![ - (ArrayStart, vec![]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[ ]", - vec![ - (ArrayStart, vec![]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[true]", - vec![ - (ArrayStart, vec![]), - (BooleanValue(true), vec![StackElement::Index(0)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[ false ]", - vec![ - (ArrayStart, vec![]), - (BooleanValue(false), vec![StackElement::Index(0)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[null]", - vec![ - (ArrayStart, vec![]), - (NullValue, vec![StackElement::Index(0)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[3, 1]", - vec![ - (ArrayStart, vec![]), - (U64Value(3), vec![StackElement::Index(0)]), - (U64Value(1), vec![StackElement::Index(1)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "\n[3, 2]\n", - vec![ - (ArrayStart, vec![]), - (U64Value(3), vec![StackElement::Index(0)]), - (U64Value(2), vec![StackElement::Index(1)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[2, [4, 1]]", - vec![ - (ArrayStart, vec![]), - (U64Value(2), vec![StackElement::Index(0)]), - (ArrayStart, vec![StackElement::Index(1)]), - (U64Value(4), vec![StackElement::Index(1), StackElement::Index(0)]), - (U64Value(1), vec![StackElement::Index(1), StackElement::Index(1)]), - (ArrayEnd, vec![StackElement::Index(1)]), - (ArrayEnd, vec![]), - ] - ); - - assert_eq!(last_event("["), Error(SyntaxError(EOFWhileParsingValue, 1, 2))); - - assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); - assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); - assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); - assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - - } - #[test] - fn test_trailing_characters_streaming() { - assert_eq!(last_event("nulla"), Error(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(last_event("truea"), Error(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(last_event("falsea"), Error(SyntaxError(TrailingCharacters, 1, 6))); - assert_eq!(last_event("1a"), Error(SyntaxError(TrailingCharacters, 1, 2))); - assert_eq!(last_event("[]a"), Error(SyntaxError(TrailingCharacters, 1, 3))); - assert_eq!(last_event("{}a"), Error(SyntaxError(TrailingCharacters, 1, 3))); - } - #[test] - fn test_read_identifiers_streaming() { - assert_eq!(Parser::new("null".chars()).next(), Some(NullValue)); - assert_eq!(Parser::new("true".chars()).next(), Some(BooleanValue(true))); - assert_eq!(Parser::new("false".chars()).next(), Some(BooleanValue(false))); - - assert_eq!(last_event("n"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("nul"), Error(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(last_event("t"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("truz"), Error(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(last_event("f"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("faz"), Error(SyntaxError(InvalidSyntax, 1, 3))); - } - #[test] fn test_stack() { let mut stack = Stack::new(); @@ -3862,76 +2655,6 @@ mod tests { assert!(stack.get(1) == StackElement::Key("foo")); } - #[test] - fn test_to_json() { - use std::collections::{HashMap,BTreeMap}; - use super::ToJson; - - let array2 = Array(vec![U64(1), U64(2)]); - let array3 = Array(vec![U64(1), U64(2), U64(3)]); - let object = { - let mut tree_map = BTreeMap::new(); - tree_map.insert("a".to_string(), U64(1)); - tree_map.insert("b".to_string(), U64(2)); - Object(tree_map) - }; - - assert_eq!(array2.to_json(), array2); - assert_eq!(object.to_json(), object); - assert_eq!(3_isize.to_json(), I64(3)); - assert_eq!(4_i8.to_json(), I64(4)); - assert_eq!(5_i16.to_json(), I64(5)); - assert_eq!(6_i32.to_json(), I64(6)); - assert_eq!(7_i64.to_json(), I64(7)); - assert_eq!(8_usize.to_json(), U64(8)); - assert_eq!(9_u8.to_json(), U64(9)); - assert_eq!(10_u16.to_json(), U64(10)); - assert_eq!(11_u32.to_json(), U64(11)); - assert_eq!(12_u64.to_json(), U64(12)); - assert_eq!(13.0_f32.to_json(), F64(13.0_f64)); - assert_eq!(14.0_f64.to_json(), F64(14.0_f64)); - assert_eq!(().to_json(), Null); - assert_eq!(f32::INFINITY.to_json(), Null); - assert_eq!(f64::NAN.to_json(), Null); - assert_eq!(true.to_json(), Boolean(true)); - assert_eq!(false.to_json(), Boolean(false)); - assert_eq!("abc".to_json(), String("abc".to_string())); - assert_eq!("abc".to_string().to_json(), String("abc".to_string())); - assert_eq!((1_usize, 2_usize).to_json(), array2); - assert_eq!((1_usize, 2_usize, 3_usize).to_json(), array3); - assert_eq!([1_usize, 2_usize].to_json(), array2); - assert_eq!((&[1_usize, 2_usize, 3_usize]).to_json(), array3); - assert_eq!((vec![1_usize, 2_usize]).to_json(), array2); - assert_eq!(vec![1_usize, 2_usize, 3_usize].to_json(), array3); - let mut tree_map = BTreeMap::new(); - tree_map.insert("a".to_string(), 1 as usize); - tree_map.insert("b".to_string(), 2); - assert_eq!(tree_map.to_json(), object); - let mut hash_map = HashMap::new(); - hash_map.insert("a".to_string(), 1 as usize); - hash_map.insert("b".to_string(), 2); - assert_eq!(hash_map.to_json(), object); - assert_eq!(Some(15).to_json(), I64(15)); - assert_eq!(Some(15 as usize).to_json(), U64(15)); - assert_eq!(None::.to_json(), Null); - } - - #[test] - fn test_encode_hashmap_with_arbitrary_key() { - use std::collections::HashMap; - #[derive(PartialEq, Eq, Hash, RustcEncodable)] - struct ArbitraryType(usize); - let mut hm: HashMap = HashMap::new(); - hm.insert(ArbitraryType(1), true); - let mut mem_buf = string::String::new(); - let mut encoder = Encoder::new(&mut mem_buf); - let result = hm.encode(&mut encoder); - match result.unwrap_err() { - EncoderError::BadHashmapKey => (), - _ => panic!("expected bad hash map key") - } - } - #[bench] fn bench_streaming_small(b: &mut Bencher) { b.iter( || { diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 9b73a5e686ead..1fb0d773d6ad2 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -32,7 +32,3 @@ pub mod json; pub mod opaque; pub mod leb128; - -mod rustc_serialize { - pub use crate::serialize::*; -} diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs index 8636c202d66ef..d6e8560195c2b 100644 --- a/src/libserialize/opaque.rs +++ b/src/libserialize/opaque.rs @@ -324,288 +324,3 @@ impl<'a> serialize::Decoder for Decoder<'a> { err.to_string() } } - - -#[cfg(test)] -mod tests { - use crate::serialize::{Encodable, Decodable}; - use std::fmt::Debug; - use super::{Encoder, Decoder}; - - #[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)] - struct Struct { - a: (), - b: u8, - c: u16, - d: u32, - e: u64, - f: usize, - - g: i8, - h: i16, - i: i32, - j: i64, - k: isize, - - l: char, - m: String, - n: f32, - o: f64, - p: bool, - q: Option, - } - - - fn check_round_trip(values: Vec) { - let mut encoder = Encoder::new(Vec::new()); - - for value in &values { - Encodable::encode(&value, &mut encoder).unwrap(); - } - - let data = encoder.into_inner(); - let mut decoder = Decoder::new(&data[..], 0); - - for value in values { - let decoded = Decodable::decode(&mut decoder).unwrap(); - assert_eq!(value, decoded); - } - } - - #[test] - fn test_unit() { - check_round_trip(vec![(), (), (), ()]); - } - - #[test] - fn test_u8() { - let mut vec = vec![]; - for i in ::std::u8::MIN..::std::u8::MAX { - vec.push(i); - } - check_round_trip(vec); - } - - #[test] - fn test_u16() { - for i in ::std::u16::MIN..::std::u16::MAX { - check_round_trip(vec![1, 2, 3, i, i, i]); - } - } - - #[test] - fn test_u32() { - check_round_trip(vec![1, 2, 3, ::std::u32::MIN, 0, 1, ::std::u32::MAX, 2, 1]); - } - - #[test] - fn test_u64() { - check_round_trip(vec![1, 2, 3, ::std::u64::MIN, 0, 1, ::std::u64::MAX, 2, 1]); - } - - #[test] - fn test_usize() { - check_round_trip(vec![1, 2, 3, ::std::usize::MIN, 0, 1, ::std::usize::MAX, 2, 1]); - } - - #[test] - fn test_i8() { - let mut vec = vec![]; - for i in ::std::i8::MIN..::std::i8::MAX { - vec.push(i); - } - check_round_trip(vec); - } - - #[test] - fn test_i16() { - for i in ::std::i16::MIN..::std::i16::MAX { - check_round_trip(vec![-1, 2, -3, i, i, i, 2]); - } - } - - #[test] - fn test_i32() { - check_round_trip(vec![-1, 2, -3, ::std::i32::MIN, 0, 1, ::std::i32::MAX, 2, 1]); - } - - #[test] - fn test_i64() { - check_round_trip(vec![-1, 2, -3, ::std::i64::MIN, 0, 1, ::std::i64::MAX, 2, 1]); - } - - #[test] - fn test_isize() { - check_round_trip(vec![-1, 2, -3, ::std::isize::MIN, 0, 1, ::std::isize::MAX, 2, 1]); - } - - #[test] - fn test_bool() { - check_round_trip(vec![false, true, true, false, false]); - } - - #[test] - fn test_f32() { - let mut vec = vec![]; - for i in -100..100 { - vec.push((i as f32) / 3.0); - } - check_round_trip(vec); - } - - #[test] - fn test_f64() { - let mut vec = vec![]; - for i in -100..100 { - vec.push((i as f64) / 3.0); - } - check_round_trip(vec); - } - - #[test] - fn test_char() { - let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€']; - check_round_trip(vec); - } - - #[test] - fn test_string() { - let vec = vec!["abcbuÖeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(), - "abcbuÖganeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(), - "abcbuÖganeiovÄnameÜavmpßvmea€µsbpapmaebn".to_string(), - "abcbuÖganeiovÄnameÜavmpßvmeabpnvapeapmaebn".to_string(), - "abcbuÖganeiÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(), - "abcbuÖganeiovÄnameÜavmpßvmea€µsbpmaebn".to_string(), - "abcbuÖganeiovÄnameÜavmpßvmea€µnvapeapmaebn".to_string()]; - - check_round_trip(vec); - } - - #[test] - fn test_option() { - check_round_trip(vec![Some(-1i8)]); - check_round_trip(vec![Some(-2i16)]); - check_round_trip(vec![Some(-3i32)]); - check_round_trip(vec![Some(-4i64)]); - check_round_trip(vec![Some(-5isize)]); - - let none_i8: Option = None; - check_round_trip(vec![none_i8]); - - let none_i16: Option = None; - check_round_trip(vec![none_i16]); - - let none_i32: Option = None; - check_round_trip(vec![none_i32]); - - let none_i64: Option = None; - check_round_trip(vec![none_i64]); - - let none_isize: Option = None; - check_round_trip(vec![none_isize]); - } - - #[test] - fn test_struct() { - check_round_trip(vec![Struct { - a: (), - b: 10, - c: 11, - d: 12, - e: 13, - f: 14, - - g: 15, - h: 16, - i: 17, - j: 18, - k: 19, - - l: 'x', - m: "abc".to_string(), - n: 20.5, - o: 21.5, - p: false, - q: None, - }]); - - check_round_trip(vec![Struct { - a: (), - b: 101, - c: 111, - d: 121, - e: 131, - f: 141, - - g: -15, - h: -16, - i: -17, - j: -18, - k: -19, - - l: 'y', - m: "def".to_string(), - n: -20.5, - o: -21.5, - p: true, - q: Some(1234567), - }]); - } - - #[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)] - enum Enum { - Variant1, - Variant2(usize, f32), - Variant3 { - a: i32, - b: char, - c: bool, - }, - } - - #[test] - fn test_enum() { - check_round_trip(vec![Enum::Variant1, - Enum::Variant2(1, 2.5), - Enum::Variant3 { - a: 3, - b: 'b', - c: false, - }, - Enum::Variant3 { - a: -4, - b: 'f', - c: true, - }]); - } - - #[test] - fn test_sequence() { - let mut vec = vec![]; - for i in -100i64..100i64 { - vec.push(i * 100000); - } - - check_round_trip(vec![vec]); - } - - #[test] - fn test_hash_map() { - use std::collections::HashMap; - let mut map = HashMap::new(); - for i in -100i64..100i64 { - map.insert(i * 100000, i * 10000); - } - - check_round_trip(vec![map]); - } - - #[test] - fn test_tuples() { - check_round_trip(vec![('x', (), false, 0.5f32)]); - check_round_trip(vec![(9i8, 10u16, 1.5f64)]); - check_round_trip(vec![(-12i16, 11u8, 12usize)]); - check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]); - check_round_trip(vec![(String::new(), "some string".to_string())]); - } -} diff --git a/src/libserialize/tests/json.rs b/src/libserialize/tests/json.rs new file mode 100644 index 0000000000000..3fb6bda679bc1 --- /dev/null +++ b/src/libserialize/tests/json.rs @@ -0,0 +1,1282 @@ +extern crate serialize as rustc_serialize; + +use rustc_serialize::{Encodable, Decodable}; +use rustc_serialize::json; +use json::Json::*; +use json::ErrorCode::*; +use json::ParserError::*; +use json::DecoderError::*; +use json::JsonEvent::*; +use json::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser, StackElement, + Decoder, Encoder, EncoderError}; + +use Animal::*; +use std::{i64, u64, f32, f64}; +use std::io::prelude::*; +use std::collections::BTreeMap; +use std::string; + +#[derive(RustcDecodable, Eq, PartialEq, Debug)] +struct OptionData { + opt: Option, +} + +#[test] +fn test_decode_option_none() { + let s ="{}"; + let obj: OptionData = json::decode(s).unwrap(); + assert_eq!(obj, OptionData { opt: None }); +} + +#[test] +fn test_decode_option_some() { + let s = "{ \"opt\": 10 }"; + let obj: OptionData = json::decode(s).unwrap(); + assert_eq!(obj, OptionData { opt: Some(10) }); +} + +#[test] +fn test_decode_option_malformed() { + check_err::("{ \"opt\": [] }", + ExpectedError("Number".to_string(), "[]".to_string())); + check_err::("{ \"opt\": false }", + ExpectedError("Number".to_string(), "false".to_string())); +} + +#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] +enum Animal { + Dog, + Frog(string::String, isize) +} + +#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] +struct Inner { + a: (), + b: usize, + c: Vec, +} + +#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] +struct Outer { + inner: Vec, +} + +fn mk_object(items: &[(string::String, Json)]) -> Json { + let mut d = BTreeMap::new(); + + for item in items { + match *item { + (ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); }, + } + }; + + Object(d) +} + +#[test] +fn test_from_str_trait() { + let s = "null"; + assert!(s.parse::().unwrap() == s.parse().unwrap()); +} + +#[test] +fn test_write_null() { + assert_eq!(Null.to_string(), "null"); + assert_eq!(Null.pretty().to_string(), "null"); +} + +#[test] +fn test_write_i64() { + assert_eq!(U64(0).to_string(), "0"); + assert_eq!(U64(0).pretty().to_string(), "0"); + + assert_eq!(U64(1234).to_string(), "1234"); + assert_eq!(U64(1234).pretty().to_string(), "1234"); + + assert_eq!(I64(-5678).to_string(), "-5678"); + assert_eq!(I64(-5678).pretty().to_string(), "-5678"); + + assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); + assert_eq!(U64(7650007200025252000).pretty().to_string(), "7650007200025252000"); +} + +#[test] +fn test_write_f64() { + assert_eq!(F64(3.0).to_string(), "3.0"); + assert_eq!(F64(3.0).pretty().to_string(), "3.0"); + + assert_eq!(F64(3.1).to_string(), "3.1"); + assert_eq!(F64(3.1).pretty().to_string(), "3.1"); + + assert_eq!(F64(-1.5).to_string(), "-1.5"); + assert_eq!(F64(-1.5).pretty().to_string(), "-1.5"); + + assert_eq!(F64(0.5).to_string(), "0.5"); + assert_eq!(F64(0.5).pretty().to_string(), "0.5"); + + assert_eq!(F64(f64::NAN).to_string(), "null"); + assert_eq!(F64(f64::NAN).pretty().to_string(), "null"); + + assert_eq!(F64(f64::INFINITY).to_string(), "null"); + assert_eq!(F64(f64::INFINITY).pretty().to_string(), "null"); + + assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null"); + assert_eq!(F64(f64::NEG_INFINITY).pretty().to_string(), "null"); +} + +#[test] +fn test_write_str() { + assert_eq!(String("".to_string()).to_string(), "\"\""); + assert_eq!(String("".to_string()).pretty().to_string(), "\"\""); + + assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); + assert_eq!(String("madoka".to_string()).pretty().to_string(), "\"madoka\""); +} + +#[test] +fn test_write_bool() { + assert_eq!(Boolean(true).to_string(), "true"); + assert_eq!(Boolean(true).pretty().to_string(), "true"); + + assert_eq!(Boolean(false).to_string(), "false"); + assert_eq!(Boolean(false).pretty().to_string(), "false"); +} + +#[test] +fn test_write_array() { + assert_eq!(Array(vec![]).to_string(), "[]"); + assert_eq!(Array(vec![]).pretty().to_string(), "[]"); + + assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]"); + assert_eq!( + Array(vec![Boolean(true)]).pretty().to_string(), + "\ + [\n \ + true\n\ + ]" + ); + + let long_test_array = Array(vec![ + Boolean(false), + Null, + Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); + + assert_eq!(long_test_array.to_string(), + "[false,null,[\"foo\\nbar\",3.5]]"); + assert_eq!( + long_test_array.pretty().to_string(), + "\ + [\n \ + false,\n \ + null,\n \ + [\n \ + \"foo\\nbar\",\n \ + 3.5\n \ + ]\n\ + ]" + ); +} + +#[test] +fn test_write_object() { + assert_eq!(mk_object(&[]).to_string(), "{}"); + assert_eq!(mk_object(&[]).pretty().to_string(), "{}"); + + assert_eq!( + mk_object(&[ + ("a".to_string(), Boolean(true)) + ]).to_string(), + "{\"a\":true}" + ); + assert_eq!( + mk_object(&[("a".to_string(), Boolean(true))]).pretty().to_string(), + "\ + {\n \ + \"a\": true\n\ + }" + ); + + let complex_obj = mk_object(&[ + ("b".to_string(), Array(vec![ + mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), + mk_object(&[("d".to_string(), String("".to_string()))]) + ])) + ]); + + assert_eq!( + complex_obj.to_string(), + "{\ + \"b\":[\ + {\"c\":\"\\f\\r\"},\ + {\"d\":\"\"}\ + ]\ + }" + ); + assert_eq!( + complex_obj.pretty().to_string(), + "\ + {\n \ + \"b\": [\n \ + {\n \ + \"c\": \"\\f\\r\"\n \ + },\n \ + {\n \ + \"d\": \"\"\n \ + }\n \ + ]\n\ + }" + ); + + let a = mk_object(&[ + ("a".to_string(), Boolean(true)), + ("b".to_string(), Array(vec![ + mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), + mk_object(&[("d".to_string(), String("".to_string()))]) + ])) + ]); + + // We can't compare the strings directly because the object fields be + // printed in a different order. + assert_eq!(a.clone(), a.to_string().parse().unwrap()); + assert_eq!(a.clone(), a.pretty().to_string().parse().unwrap()); +} + +#[test] +fn test_write_enum() { + let animal = Dog; + assert_eq!( + json::as_json(&animal).to_string(), + "\"Dog\"" + ); + assert_eq!( + json::as_pretty_json(&animal).to_string(), + "\"Dog\"" + ); + + let animal = Frog("Henry".to_string(), 349); + assert_eq!( + json::as_json(&animal).to_string(), + "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" + ); + assert_eq!( + json::as_pretty_json(&animal).to_string(), + "{\n \ + \"variant\": \"Frog\",\n \ + \"fields\": [\n \ + \"Henry\",\n \ + 349\n \ + ]\n\ + }" + ); +} + +macro_rules! check_encoder_for_simple { + ($value:expr, $expected:expr) => ({ + let s = json::as_json(&$value).to_string(); + assert_eq!(s, $expected); + + let s = json::as_pretty_json(&$value).to_string(); + assert_eq!(s, $expected); + }) +} + +#[test] +fn test_write_some() { + check_encoder_for_simple!(Some("jodhpurs".to_string()), "\"jodhpurs\""); +} + +#[test] +fn test_write_none() { + check_encoder_for_simple!(None::, "null"); +} + +#[test] +fn test_write_char() { + check_encoder_for_simple!('a', "\"a\""); + check_encoder_for_simple!('\t', "\"\\t\""); + check_encoder_for_simple!('\u{0000}', "\"\\u0000\""); + check_encoder_for_simple!('\u{001b}', "\"\\u001b\""); + check_encoder_for_simple!('\u{007f}', "\"\\u007f\""); + check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); + check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); + check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); +} + +#[test] +fn test_trailing_characters() { + assert_eq!(from_str("nulla"), Err(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(from_str("truea"), Err(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(from_str("falsea"), Err(SyntaxError(TrailingCharacters, 1, 6))); + assert_eq!(from_str("1a"), Err(SyntaxError(TrailingCharacters, 1, 2))); + assert_eq!(from_str("[]a"), Err(SyntaxError(TrailingCharacters, 1, 3))); + assert_eq!(from_str("{}a"), Err(SyntaxError(TrailingCharacters, 1, 3))); +} + +#[test] +fn test_read_identifiers() { + assert_eq!(from_str("n"), Err(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(from_str("nul"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("t"), Err(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(from_str("truz"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("f"), Err(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(from_str("faz"), Err(SyntaxError(InvalidSyntax, 1, 3))); + + assert_eq!(from_str("null"), Ok(Null)); + assert_eq!(from_str("true"), Ok(Boolean(true))); + assert_eq!(from_str("false"), Ok(Boolean(false))); + assert_eq!(from_str(" null "), Ok(Null)); + assert_eq!(from_str(" true "), Ok(Boolean(true))); + assert_eq!(from_str(" false "), Ok(Boolean(false))); +} + +#[test] +fn test_decode_identifiers() { + let v: () = json::decode("null").unwrap(); + assert_eq!(v, ()); + + let v: bool = json::decode("true").unwrap(); + assert_eq!(v, true); + + let v: bool = json::decode("false").unwrap(); + assert_eq!(v, false); +} + +#[test] +fn test_read_number() { + assert_eq!(from_str("+"), Err(SyntaxError(InvalidSyntax, 1, 1))); + assert_eq!(from_str("."), Err(SyntaxError(InvalidSyntax, 1, 1))); + assert_eq!(from_str("NaN"), Err(SyntaxError(InvalidSyntax, 1, 1))); + assert_eq!(from_str("-"), Err(SyntaxError(InvalidNumber, 1, 2))); + assert_eq!(from_str("00"), Err(SyntaxError(InvalidNumber, 1, 2))); + assert_eq!(from_str("1."), Err(SyntaxError(InvalidNumber, 1, 3))); + assert_eq!(from_str("1e"), Err(SyntaxError(InvalidNumber, 1, 3))); + assert_eq!(from_str("1e+"), Err(SyntaxError(InvalidNumber, 1, 4))); + + assert_eq!(from_str("18446744073709551616"), Err(SyntaxError(InvalidNumber, 1, 20))); + assert_eq!(from_str("-9223372036854775809"), Err(SyntaxError(InvalidNumber, 1, 21))); + + assert_eq!(from_str("3"), Ok(U64(3))); + assert_eq!(from_str("3.1"), Ok(F64(3.1))); + assert_eq!(from_str("-1.2"), Ok(F64(-1.2))); + assert_eq!(from_str("0.4"), Ok(F64(0.4))); + assert_eq!(from_str("0.4e5"), Ok(F64(0.4e5))); + assert_eq!(from_str("0.4e+15"), Ok(F64(0.4e15))); + assert_eq!(from_str("0.4e-01"), Ok(F64(0.4e-01))); + assert_eq!(from_str(" 3 "), Ok(U64(3))); + + assert_eq!(from_str("-9223372036854775808"), Ok(I64(i64::MIN))); + assert_eq!(from_str("9223372036854775807"), Ok(U64(i64::MAX as u64))); + assert_eq!(from_str("18446744073709551615"), Ok(U64(u64::MAX))); +} + +#[test] +fn test_decode_numbers() { + let v: f64 = json::decode("3").unwrap(); + assert_eq!(v, 3.0); + + let v: f64 = json::decode("3.1").unwrap(); + assert_eq!(v, 3.1); + + let v: f64 = json::decode("-1.2").unwrap(); + assert_eq!(v, -1.2); + + let v: f64 = json::decode("0.4").unwrap(); + assert_eq!(v, 0.4); + + let v: f64 = json::decode("0.4e5").unwrap(); + assert_eq!(v, 0.4e5); + + let v: f64 = json::decode("0.4e15").unwrap(); + assert_eq!(v, 0.4e15); + + let v: f64 = json::decode("0.4e-01").unwrap(); + assert_eq!(v, 0.4e-01); + + let v: u64 = json::decode("0").unwrap(); + assert_eq!(v, 0); + + let v: u64 = json::decode("18446744073709551615").unwrap(); + assert_eq!(v, u64::MAX); + + let v: i64 = json::decode("-9223372036854775808").unwrap(); + assert_eq!(v, i64::MIN); + + let v: i64 = json::decode("9223372036854775807").unwrap(); + assert_eq!(v, i64::MAX); + + let res: DecodeResult = json::decode("765.25"); + assert_eq!(res, Err(ExpectedError("Integer".to_string(), + "765.25".to_string()))); +} + +#[test] +fn test_read_str() { + assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2))); + assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5))); + + assert_eq!(from_str("\"\""), Ok(String("".to_string()))); + assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string()))); + assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string()))); + assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string()))); + assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string()))); + assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string()))); + assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string()))); + assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string()))); + assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u{12ab}".to_string()))); + assert_eq!(from_str("\"\\uAB12\""), Ok(String("\u{AB12}".to_string()))); +} + +#[test] +fn test_decode_str() { + let s = [("\"\"", ""), + ("\"foo\"", "foo"), + ("\"\\\"\"", "\""), + ("\"\\b\"", "\x08"), + ("\"\\n\"", "\n"), + ("\"\\r\"", "\r"), + ("\"\\t\"", "\t"), + ("\"\\u12ab\"", "\u{12ab}"), + ("\"\\uAB12\"", "\u{AB12}")]; + + for &(i, o) in &s { + let v: string::String = json::decode(i).unwrap(); + assert_eq!(v, o); + } +} + +#[test] +fn test_read_array() { + assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); + assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); + assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); + assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + + assert_eq!(from_str("[]"), Ok(Array(vec![]))); + assert_eq!(from_str("[ ]"), Ok(Array(vec![]))); + assert_eq!(from_str("[true]"), Ok(Array(vec![Boolean(true)]))); + assert_eq!(from_str("[ false ]"), Ok(Array(vec![Boolean(false)]))); + assert_eq!(from_str("[null]"), Ok(Array(vec![Null]))); + assert_eq!(from_str("[3, 1]"), + Ok(Array(vec![U64(3), U64(1)]))); + assert_eq!(from_str("\n[3, 2]\n"), + Ok(Array(vec![U64(3), U64(2)]))); + assert_eq!(from_str("[2, [4, 1]]"), + Ok(Array(vec![U64(2), Array(vec![U64(4), U64(1)])]))); +} + +#[test] +fn test_decode_array() { + let v: Vec<()> = json::decode("[]").unwrap(); + assert_eq!(v, []); + + let v: Vec<()> = json::decode("[null]").unwrap(); + assert_eq!(v, [()]); + + let v: Vec = json::decode("[true]").unwrap(); + assert_eq!(v, [true]); + + let v: Vec = json::decode("[3, 1]").unwrap(); + assert_eq!(v, [3, 1]); + + let v: Vec> = json::decode("[[3], [1, 2]]").unwrap(); + assert_eq!(v, [vec![3], vec![1, 2]]); +} + +#[test] +fn test_decode_tuple() { + let t: (usize, usize, usize) = json::decode("[1, 2, 3]").unwrap(); + assert_eq!(t, (1, 2, 3)); + + let t: (usize, string::String) = json::decode("[1, \"two\"]").unwrap(); + assert_eq!(t, (1, "two".to_string())); +} + +#[test] +fn test_decode_tuple_malformed_types() { + assert!(json::decode::<(usize, string::String)>("[1, 2]").is_err()); +} + +#[test] +fn test_decode_tuple_malformed_length() { + assert!(json::decode::<(usize, usize)>("[1, 2, 3]").is_err()); +} + +#[test] +fn test_read_object() { + assert_eq!(from_str("{"), Err(SyntaxError(EOFWhileParsingObject, 1, 2))); + assert_eq!(from_str("{ "), Err(SyntaxError(EOFWhileParsingObject, 1, 3))); + assert_eq!(from_str("{1"), Err(SyntaxError(KeyMustBeAString, 1, 2))); + assert_eq!(from_str("{ \"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); + assert_eq!(from_str("{\"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 5))); + assert_eq!(from_str("{\"a\" "), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); + + assert_eq!(from_str("{\"a\" 1"), Err(SyntaxError(ExpectedColon, 1, 6))); + assert_eq!(from_str("{\"a\":"), Err(SyntaxError(EOFWhileParsingValue, 1, 6))); + assert_eq!(from_str("{\"a\":1"), Err(SyntaxError(EOFWhileParsingObject, 1, 7))); + assert_eq!(from_str("{\"a\":1 1"), Err(SyntaxError(InvalidSyntax, 1, 8))); + assert_eq!(from_str("{\"a\":1,"), Err(SyntaxError(EOFWhileParsingObject, 1, 8))); + + assert_eq!(from_str("{}").unwrap(), mk_object(&[])); + assert_eq!(from_str("{\"a\": 3}").unwrap(), + mk_object(&[("a".to_string(), U64(3))])); + + assert_eq!(from_str( + "{ \"a\": null, \"b\" : true }").unwrap(), + mk_object(&[ + ("a".to_string(), Null), + ("b".to_string(), Boolean(true))])); + assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), + mk_object(&[ + ("a".to_string(), Null), + ("b".to_string(), Boolean(true))])); + assert_eq!(from_str( + "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), + mk_object(&[ + ("a".to_string(), F64(1.0)), + ("b".to_string(), Array(vec![Boolean(true)])) + ])); + assert_eq!(from_str( + "{\ + \"a\": 1.0, \ + \"b\": [\ + true,\ + \"foo\\nbar\", \ + { \"c\": {\"d\": null} } \ + ]\ + }").unwrap(), + mk_object(&[ + ("a".to_string(), F64(1.0)), + ("b".to_string(), Array(vec![ + Boolean(true), + String("foo\nbar".to_string()), + mk_object(&[ + ("c".to_string(), mk_object(&[("d".to_string(), Null)])) + ]) + ])) + ])); +} + +#[test] +fn test_decode_struct() { + let s = "{ + \"inner\": [ + { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } + ] + }"; + + let v: Outer = json::decode(s).unwrap(); + assert_eq!( + v, + Outer { + inner: vec![ + Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } + ] + } + ); +} + +#[derive(RustcDecodable)] +struct FloatStruct { + f: f64, + a: Vec +} +#[test] +fn test_decode_struct_with_nan() { + let s = "{\"f\":null,\"a\":[null,123]}"; + let obj: FloatStruct = json::decode(s).unwrap(); + assert!(obj.f.is_nan()); + assert!(obj.a[0].is_nan()); + assert_eq!(obj.a[1], 123f64); +} + +#[test] +fn test_decode_option() { + let value: Option = json::decode("null").unwrap(); + assert_eq!(value, None); + + let value: Option = json::decode("\"jodhpurs\"").unwrap(); + assert_eq!(value, Some("jodhpurs".to_string())); +} + +#[test] +fn test_decode_enum() { + let value: Animal = json::decode("\"Dog\"").unwrap(); + assert_eq!(value, Dog); + + let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; + let value: Animal = json::decode(s).unwrap(); + assert_eq!(value, Frog("Henry".to_string(), 349)); +} + +#[test] +fn test_decode_map() { + let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ + \"fields\":[\"Henry\", 349]}}"; + let mut map: BTreeMap = json::decode(s).unwrap(); + + assert_eq!(map.remove(&"a".to_string()), Some(Dog)); + assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); +} + +#[test] +fn test_multiline_errors() { + assert_eq!(from_str("{\n \"foo\":\n \"bar\""), + Err(SyntaxError(EOFWhileParsingObject, 3, 8))); +} + +#[derive(RustcDecodable)] +#[allow(dead_code)] +struct DecodeStruct { + x: f64, + y: bool, + z: string::String, + w: Vec +} +#[derive(RustcDecodable)] +enum DecodeEnum { + A(f64), + B(string::String) +} +fn check_err(to_parse: &'static str, expected: DecoderError) { + let res: DecodeResult = match from_str(to_parse) { + Err(e) => Err(ParseError(e)), + Ok(json) => Decodable::decode(&mut Decoder::new(json)) + }; + match res { + Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", + to_parse, expected), + Err(ParseError(e)) => panic!("`{:?}` is not valid json: {:?}", + to_parse, e), + Err(e) => { + assert_eq!(e, expected); + } + } +} +#[test] +fn test_decode_errors_struct() { + check_err::("[]", ExpectedError("Object".to_string(), "[]".to_string())); + check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", + ExpectedError("Number".to_string(), "true".to_string())); + check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", + ExpectedError("Boolean".to_string(), "[]".to_string())); + check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", + ExpectedError("String".to_string(), "{}".to_string())); + check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", + ExpectedError("Array".to_string(), "null".to_string())); + check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", + MissingFieldError("w".to_string())); +} +#[test] +fn test_decode_errors_enum() { + check_err::("{}", + MissingFieldError("variant".to_string())); + check_err::("{\"variant\": 1}", + ExpectedError("String".to_string(), "1".to_string())); + check_err::("{\"variant\": \"A\"}", + MissingFieldError("fields".to_string())); + check_err::("{\"variant\": \"A\", \"fields\": null}", + ExpectedError("Array".to_string(), "null".to_string())); + check_err::("{\"variant\": \"C\", \"fields\": []}", + UnknownVariantError("C".to_string())); +} + +#[test] +fn test_find(){ + let json_value = from_str("{\"dog\" : \"cat\"}").unwrap(); + let found_str = json_value.find("dog"); + assert!(found_str.unwrap().as_string().unwrap() == "cat"); +} + +#[test] +fn test_find_path(){ + let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); + let found_str = json_value.find_path(&["dog", "cat", "mouse"]); + assert!(found_str.unwrap().as_string().unwrap() == "cheese"); +} + +#[test] +fn test_search(){ + let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); + let found_str = json_value.search("mouse").and_then(|j| j.as_string()); + assert!(found_str.unwrap() == "cheese"); +} + +#[test] +fn test_index(){ + let json_value = from_str("{\"animals\":[\"dog\",\"cat\",\"mouse\"]}").unwrap(); + let ref array = json_value["animals"]; + assert_eq!(array[0].as_string().unwrap(), "dog"); + assert_eq!(array[1].as_string().unwrap(), "cat"); + assert_eq!(array[2].as_string().unwrap(), "mouse"); +} + +#[test] +fn test_is_object(){ + let json_value = from_str("{}").unwrap(); + assert!(json_value.is_object()); +} + +#[test] +fn test_as_object(){ + let json_value = from_str("{}").unwrap(); + let json_object = json_value.as_object(); + assert!(json_object.is_some()); +} + +#[test] +fn test_is_array(){ + let json_value = from_str("[1, 2, 3]").unwrap(); + assert!(json_value.is_array()); +} + +#[test] +fn test_as_array(){ + let json_value = from_str("[1, 2, 3]").unwrap(); + let json_array = json_value.as_array(); + let expected_length = 3; + assert!(json_array.is_some() && json_array.unwrap().len() == expected_length); +} + +#[test] +fn test_is_string(){ + let json_value = from_str("\"dog\"").unwrap(); + assert!(json_value.is_string()); +} + +#[test] +fn test_as_string(){ + let json_value = from_str("\"dog\"").unwrap(); + let json_str = json_value.as_string(); + let expected_str = "dog"; + assert_eq!(json_str, Some(expected_str)); +} + +#[test] +fn test_is_number(){ + let json_value = from_str("12").unwrap(); + assert!(json_value.is_number()); +} + +#[test] +fn test_is_i64(){ + let json_value = from_str("-12").unwrap(); + assert!(json_value.is_i64()); + + let json_value = from_str("12").unwrap(); + assert!(!json_value.is_i64()); + + let json_value = from_str("12.0").unwrap(); + assert!(!json_value.is_i64()); +} + +#[test] +fn test_is_u64(){ + let json_value = from_str("12").unwrap(); + assert!(json_value.is_u64()); + + let json_value = from_str("-12").unwrap(); + assert!(!json_value.is_u64()); + + let json_value = from_str("12.0").unwrap(); + assert!(!json_value.is_u64()); +} + +#[test] +fn test_is_f64(){ + let json_value = from_str("12").unwrap(); + assert!(!json_value.is_f64()); + + let json_value = from_str("-12").unwrap(); + assert!(!json_value.is_f64()); + + let json_value = from_str("12.0").unwrap(); + assert!(json_value.is_f64()); + + let json_value = from_str("-12.0").unwrap(); + assert!(json_value.is_f64()); +} + +#[test] +fn test_as_i64(){ + let json_value = from_str("-12").unwrap(); + let json_num = json_value.as_i64(); + assert_eq!(json_num, Some(-12)); +} + +#[test] +fn test_as_u64(){ + let json_value = from_str("12").unwrap(); + let json_num = json_value.as_u64(); + assert_eq!(json_num, Some(12)); +} + +#[test] +fn test_as_f64(){ + let json_value = from_str("12.0").unwrap(); + let json_num = json_value.as_f64(); + assert_eq!(json_num, Some(12f64)); +} + +#[test] +fn test_is_boolean(){ + let json_value = from_str("false").unwrap(); + assert!(json_value.is_boolean()); +} + +#[test] +fn test_as_boolean(){ + let json_value = from_str("false").unwrap(); + let json_bool = json_value.as_boolean(); + let expected_bool = false; + assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); +} + +#[test] +fn test_is_null(){ + let json_value = from_str("null").unwrap(); + assert!(json_value.is_null()); +} + +#[test] +fn test_as_null(){ + let json_value = from_str("null").unwrap(); + let json_null = json_value.as_null(); + let expected_null = (); + assert!(json_null.is_some() && json_null.unwrap() == expected_null); +} + +#[test] +fn test_encode_hashmap_with_numeric_key() { + use std::str::from_utf8; + use std::collections::HashMap; + let mut hm: HashMap = HashMap::new(); + hm.insert(1, true); + let mut mem_buf = Vec::new(); + write!(&mut mem_buf, "{}", json::as_pretty_json(&hm)).unwrap(); + let json_str = from_utf8(&mem_buf[..]).unwrap(); + match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {:?}", json_str), + _ => {} // it parsed and we are good to go + } +} + +#[test] +fn test_prettyencode_hashmap_with_numeric_key() { + use std::str::from_utf8; + use std::collections::HashMap; + let mut hm: HashMap = HashMap::new(); + hm.insert(1, true); + let mut mem_buf = Vec::new(); + write!(&mut mem_buf, "{}", json::as_pretty_json(&hm)).unwrap(); + let json_str = from_utf8(&mem_buf[..]).unwrap(); + match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {:?}", json_str), + _ => {} // it parsed and we are good to go + } +} + +#[test] +fn test_prettyencoder_indent_level_param() { + use std::str::from_utf8; + use std::collections::BTreeMap; + + let mut tree = BTreeMap::new(); + + tree.insert("hello".to_string(), String("guten tag".to_string())); + tree.insert("goodbye".to_string(), String("sayonara".to_string())); + + let json = Array( + // The following layout below should look a lot like + // the pretty-printed JSON (indent * x) + vec! + ( // 0x + String("greetings".to_string()), // 1x + Object(tree), // 1x + 2x + 2x + 1x + ) // 0x + // End JSON array (7 lines) + ); + + // Helper function for counting indents + fn indents(source: &str) -> usize { + let trimmed = source.trim_start_matches(' '); + source.len() - trimmed.len() + } + + // Test up to 4 spaces of indents (more?) + for i in 0..4 { + let mut writer = Vec::new(); + write!(&mut writer, "{}", + json::as_pretty_json(&json).indent(i)).unwrap(); + + let printed = from_utf8(&writer[..]).unwrap(); + + // Check for indents at each line + let lines: Vec<&str> = printed.lines().collect(); + assert_eq!(lines.len(), 7); // JSON should be 7 lines + + assert_eq!(indents(lines[0]), 0 * i); // [ + assert_eq!(indents(lines[1]), 1 * i); // "greetings", + assert_eq!(indents(lines[2]), 1 * i); // { + assert_eq!(indents(lines[3]), 2 * i); // "hello": "guten tag", + assert_eq!(indents(lines[4]), 2 * i); // "goodbye": "sayonara" + assert_eq!(indents(lines[5]), 1 * i); // }, + assert_eq!(indents(lines[6]), 0 * i); // ] + + // Finally, test that the pretty-printed JSON is valid + from_str(printed).ok().expect("Pretty-printed JSON is invalid!"); + } +} + +#[test] +fn test_hashmap_with_enum_key() { + use std::collections::HashMap; + #[derive(RustcEncodable, Eq, Hash, PartialEq, RustcDecodable, Debug)] + enum Enum { + Foo, + #[allow(dead_code)] + Bar, + } + let mut map = HashMap::new(); + map.insert(Enum::Foo, 0); + let result = json::encode(&map).unwrap(); + assert_eq!(&result[..], r#"{"Foo":0}"#); + let decoded: HashMap = json::decode(&result).unwrap(); + assert_eq!(map, decoded); +} + +#[test] +fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { + use std::collections::HashMap; + let json_str = "{\"1\":true}"; + let json_obj = match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {:?}", json_str), + Ok(o) => o + }; + let mut decoder = Decoder::new(json_obj); + let _hm: HashMap = Decodable::decode(&mut decoder).unwrap(); +} + +#[test] +fn test_hashmap_with_numeric_key_will_error_with_string_keys() { + use std::collections::HashMap; + let json_str = "{\"a\":true}"; + let json_obj = match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {:?}", json_str), + Ok(o) => o + }; + let mut decoder = Decoder::new(json_obj); + let result: Result, DecoderError> = Decodable::decode(&mut decoder); + assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string()))); +} + +fn assert_stream_equal(src: &str, + expected: Vec<(JsonEvent, Vec>)>) { + let mut parser = Parser::new(src.chars()); + let mut i = 0; + loop { + let evt = match parser.next() { + Some(e) => e, + None => { break; } + }; + let (ref expected_evt, ref expected_stack) = expected[i]; + if !parser.stack().is_equal_to(expected_stack) { + panic!("Parser stack is not equal to {:?}", expected_stack); + } + assert_eq!(&evt, expected_evt); + i+=1; + } +} +#[test] +fn test_streaming_parser() { + assert_stream_equal( + r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#, + vec![ + (ObjectStart, vec![]), + (StringValue("bar".to_string()), vec![StackElement::Key("foo")]), + (ArrayStart, vec![StackElement::Key("array")]), + (U64Value(0), vec![StackElement::Key("array"), StackElement::Index(0)]), + (U64Value(1), vec![StackElement::Key("array"), StackElement::Index(1)]), + (U64Value(2), vec![StackElement::Key("array"), StackElement::Index(2)]), + (U64Value(3), vec![StackElement::Key("array"), StackElement::Index(3)]), + (U64Value(4), vec![StackElement::Key("array"), StackElement::Index(4)]), + (U64Value(5), vec![StackElement::Key("array"), StackElement::Index(5)]), + (ArrayEnd, vec![StackElement::Key("array")]), + (ArrayStart, vec![StackElement::Key("idents")]), + (NullValue, vec![StackElement::Key("idents"), + StackElement::Index(0)]), + (BooleanValue(true), vec![StackElement::Key("idents"), + StackElement::Index(1)]), + (BooleanValue(false), vec![StackElement::Key("idents"), + StackElement::Index(2)]), + (ArrayEnd, vec![StackElement::Key("idents")]), + (ObjectEnd, vec![]), + ] + ); +} +fn last_event(src: &str) -> JsonEvent { + let mut parser = Parser::new(src.chars()); + let mut evt = NullValue; + loop { + evt = match parser.next() { + Some(e) => e, + None => return evt, + } + } +} + +#[test] +fn test_read_object_streaming() { + assert_eq!(last_event("{ "), Error(SyntaxError(EOFWhileParsingObject, 1, 3))); + assert_eq!(last_event("{1"), Error(SyntaxError(KeyMustBeAString, 1, 2))); + assert_eq!(last_event("{ \"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); + assert_eq!(last_event("{\"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 5))); + assert_eq!(last_event("{\"a\" "), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); + + assert_eq!(last_event("{\"a\" 1"), Error(SyntaxError(ExpectedColon, 1, 6))); + assert_eq!(last_event("{\"a\":"), Error(SyntaxError(EOFWhileParsingValue, 1, 6))); + assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7))); + assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8))); + assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8))); + assert_eq!(last_event("{\"a\":1,}"), Error(SyntaxError(TrailingComma, 1, 8))); + + assert_stream_equal( + "{}", + vec![(ObjectStart, vec![]), (ObjectEnd, vec![])] + ); + assert_stream_equal( + "{\"a\": 3}", + vec![ + (ObjectStart, vec![]), + (U64Value(3), vec![StackElement::Key("a")]), + (ObjectEnd, vec![]), + ] + ); + assert_stream_equal( + "{ \"a\": null, \"b\" : true }", + vec![ + (ObjectStart, vec![]), + (NullValue, vec![StackElement::Key("a")]), + (BooleanValue(true), vec![StackElement::Key("b")]), + (ObjectEnd, vec![]), + ] + ); + assert_stream_equal( + "{\"a\" : 1.0 ,\"b\": [ true ]}", + vec![ + (ObjectStart, vec![]), + (F64Value(1.0), vec![StackElement::Key("a")]), + (ArrayStart, vec![StackElement::Key("b")]), + (BooleanValue(true),vec![StackElement::Key("b"), StackElement::Index(0)]), + (ArrayEnd, vec![StackElement::Key("b")]), + (ObjectEnd, vec![]), + ] + ); + assert_stream_equal( + r#"{ + "a": 1.0, + "b": [ + true, + "foo\nbar", + { "c": {"d": null} } + ] + }"#, + vec![ + (ObjectStart, vec![]), + (F64Value(1.0), vec![StackElement::Key("a")]), + (ArrayStart, vec![StackElement::Key("b")]), + (BooleanValue(true), vec![StackElement::Key("b"), + StackElement::Index(0)]), + (StringValue("foo\nbar".to_string()), vec![StackElement::Key("b"), + StackElement::Index(1)]), + (ObjectStart, vec![StackElement::Key("b"), + StackElement::Index(2)]), + (ObjectStart, vec![StackElement::Key("b"), + StackElement::Index(2), + StackElement::Key("c")]), + (NullValue, vec![StackElement::Key("b"), + StackElement::Index(2), + StackElement::Key("c"), + StackElement::Key("d")]), + (ObjectEnd, vec![StackElement::Key("b"), + StackElement::Index(2), + StackElement::Key("c")]), + (ObjectEnd, vec![StackElement::Key("b"), + StackElement::Index(2)]), + (ArrayEnd, vec![StackElement::Key("b")]), + (ObjectEnd, vec![]), + ] + ); +} +#[test] +fn test_read_array_streaming() { + assert_stream_equal( + "[]", + vec![ + (ArrayStart, vec![]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[ ]", + vec![ + (ArrayStart, vec![]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[true]", + vec![ + (ArrayStart, vec![]), + (BooleanValue(true), vec![StackElement::Index(0)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[ false ]", + vec![ + (ArrayStart, vec![]), + (BooleanValue(false), vec![StackElement::Index(0)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[null]", + vec![ + (ArrayStart, vec![]), + (NullValue, vec![StackElement::Index(0)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[3, 1]", + vec![ + (ArrayStart, vec![]), + (U64Value(3), vec![StackElement::Index(0)]), + (U64Value(1), vec![StackElement::Index(1)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "\n[3, 2]\n", + vec![ + (ArrayStart, vec![]), + (U64Value(3), vec![StackElement::Index(0)]), + (U64Value(2), vec![StackElement::Index(1)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[2, [4, 1]]", + vec![ + (ArrayStart, vec![]), + (U64Value(2), vec![StackElement::Index(0)]), + (ArrayStart, vec![StackElement::Index(1)]), + (U64Value(4), vec![StackElement::Index(1), StackElement::Index(0)]), + (U64Value(1), vec![StackElement::Index(1), StackElement::Index(1)]), + (ArrayEnd, vec![StackElement::Index(1)]), + (ArrayEnd, vec![]), + ] + ); + + assert_eq!(last_event("["), Error(SyntaxError(EOFWhileParsingValue, 1, 2))); + + assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); + assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); + assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); + assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + +} +#[test] +fn test_trailing_characters_streaming() { + assert_eq!(last_event("nulla"), Error(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(last_event("truea"), Error(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(last_event("falsea"), Error(SyntaxError(TrailingCharacters, 1, 6))); + assert_eq!(last_event("1a"), Error(SyntaxError(TrailingCharacters, 1, 2))); + assert_eq!(last_event("[]a"), Error(SyntaxError(TrailingCharacters, 1, 3))); + assert_eq!(last_event("{}a"), Error(SyntaxError(TrailingCharacters, 1, 3))); +} +#[test] +fn test_read_identifiers_streaming() { + assert_eq!(Parser::new("null".chars()).next(), Some(NullValue)); + assert_eq!(Parser::new("true".chars()).next(), Some(BooleanValue(true))); + assert_eq!(Parser::new("false".chars()).next(), Some(BooleanValue(false))); + + assert_eq!(last_event("n"), Error(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(last_event("nul"), Error(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(last_event("t"), Error(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(last_event("truz"), Error(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(last_event("f"), Error(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(last_event("faz"), Error(SyntaxError(InvalidSyntax, 1, 3))); +} + +#[test] +fn test_to_json() { + use std::collections::{HashMap,BTreeMap}; + use json::ToJson; + + let array2 = Array(vec![U64(1), U64(2)]); + let array3 = Array(vec![U64(1), U64(2), U64(3)]); + let object = { + let mut tree_map = BTreeMap::new(); + tree_map.insert("a".to_string(), U64(1)); + tree_map.insert("b".to_string(), U64(2)); + Object(tree_map) + }; + + assert_eq!(array2.to_json(), array2); + assert_eq!(object.to_json(), object); + assert_eq!(3_isize.to_json(), I64(3)); + assert_eq!(4_i8.to_json(), I64(4)); + assert_eq!(5_i16.to_json(), I64(5)); + assert_eq!(6_i32.to_json(), I64(6)); + assert_eq!(7_i64.to_json(), I64(7)); + assert_eq!(8_usize.to_json(), U64(8)); + assert_eq!(9_u8.to_json(), U64(9)); + assert_eq!(10_u16.to_json(), U64(10)); + assert_eq!(11_u32.to_json(), U64(11)); + assert_eq!(12_u64.to_json(), U64(12)); + assert_eq!(13.0_f32.to_json(), F64(13.0_f64)); + assert_eq!(14.0_f64.to_json(), F64(14.0_f64)); + assert_eq!(().to_json(), Null); + assert_eq!(f32::INFINITY.to_json(), Null); + assert_eq!(f64::NAN.to_json(), Null); + assert_eq!(true.to_json(), Boolean(true)); + assert_eq!(false.to_json(), Boolean(false)); + assert_eq!("abc".to_json(), String("abc".to_string())); + assert_eq!("abc".to_string().to_json(), String("abc".to_string())); + assert_eq!((1_usize, 2_usize).to_json(), array2); + assert_eq!((1_usize, 2_usize, 3_usize).to_json(), array3); + assert_eq!([1_usize, 2_usize].to_json(), array2); + assert_eq!((&[1_usize, 2_usize, 3_usize]).to_json(), array3); + assert_eq!((vec![1_usize, 2_usize]).to_json(), array2); + assert_eq!(vec![1_usize, 2_usize, 3_usize].to_json(), array3); + let mut tree_map = BTreeMap::new(); + tree_map.insert("a".to_string(), 1 as usize); + tree_map.insert("b".to_string(), 2); + assert_eq!(tree_map.to_json(), object); + let mut hash_map = HashMap::new(); + hash_map.insert("a".to_string(), 1 as usize); + hash_map.insert("b".to_string(), 2); + assert_eq!(hash_map.to_json(), object); + assert_eq!(Some(15).to_json(), I64(15)); + assert_eq!(Some(15 as usize).to_json(), U64(15)); + assert_eq!(None::.to_json(), Null); +} + +#[test] +fn test_encode_hashmap_with_arbitrary_key() { + use std::collections::HashMap; + #[derive(PartialEq, Eq, Hash, RustcEncodable)] + struct ArbitraryType(usize); + let mut hm: HashMap = HashMap::new(); + hm.insert(ArbitraryType(1), true); + let mut mem_buf = string::String::new(); + let mut encoder = Encoder::new(&mut mem_buf); + let result = hm.encode(&mut encoder); + match result.unwrap_err() { + EncoderError::BadHashmapKey => (), + _ => panic!("expected bad hash map key") + } +} diff --git a/src/libserialize/tests/opaque.rs b/src/libserialize/tests/opaque.rs new file mode 100644 index 0000000000000..fff6fc69e7842 --- /dev/null +++ b/src/libserialize/tests/opaque.rs @@ -0,0 +1,282 @@ +extern crate serialize as rustc_serialize; + +use rustc_serialize::{Encodable, Decodable}; +use rustc_serialize::opaque::{Encoder, Decoder}; +use std::fmt::Debug; + +#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)] +struct Struct { + a: (), + b: u8, + c: u16, + d: u32, + e: u64, + f: usize, + + g: i8, + h: i16, + i: i32, + j: i64, + k: isize, + + l: char, + m: String, + n: f32, + o: f64, + p: bool, + q: Option, +} + + +fn check_round_trip(values: Vec) { + let mut encoder = Encoder::new(Vec::new()); + + for value in &values { + Encodable::encode(&value, &mut encoder).unwrap(); + } + + let data = encoder.into_inner(); + let mut decoder = Decoder::new(&data[..], 0); + + for value in values { + let decoded = Decodable::decode(&mut decoder).unwrap(); + assert_eq!(value, decoded); + } +} + +#[test] +fn test_unit() { + check_round_trip(vec![(), (), (), ()]); +} + +#[test] +fn test_u8() { + let mut vec = vec![]; + for i in ::std::u8::MIN..::std::u8::MAX { + vec.push(i); + } + check_round_trip(vec); +} + +#[test] +fn test_u16() { + for i in ::std::u16::MIN..::std::u16::MAX { + check_round_trip(vec![1, 2, 3, i, i, i]); + } +} + +#[test] +fn test_u32() { + check_round_trip(vec![1, 2, 3, ::std::u32::MIN, 0, 1, ::std::u32::MAX, 2, 1]); +} + +#[test] +fn test_u64() { + check_round_trip(vec![1, 2, 3, ::std::u64::MIN, 0, 1, ::std::u64::MAX, 2, 1]); +} + +#[test] +fn test_usize() { + check_round_trip(vec![1, 2, 3, ::std::usize::MIN, 0, 1, ::std::usize::MAX, 2, 1]); +} + +#[test] +fn test_i8() { + let mut vec = vec![]; + for i in ::std::i8::MIN..::std::i8::MAX { + vec.push(i); + } + check_round_trip(vec); +} + +#[test] +fn test_i16() { + for i in ::std::i16::MIN..::std::i16::MAX { + check_round_trip(vec![-1, 2, -3, i, i, i, 2]); + } +} + +#[test] +fn test_i32() { + check_round_trip(vec![-1, 2, -3, ::std::i32::MIN, 0, 1, ::std::i32::MAX, 2, 1]); +} + +#[test] +fn test_i64() { + check_round_trip(vec![-1, 2, -3, ::std::i64::MIN, 0, 1, ::std::i64::MAX, 2, 1]); +} + +#[test] +fn test_isize() { + check_round_trip(vec![-1, 2, -3, ::std::isize::MIN, 0, 1, ::std::isize::MAX, 2, 1]); +} + +#[test] +fn test_bool() { + check_round_trip(vec![false, true, true, false, false]); +} + +#[test] +fn test_f32() { + let mut vec = vec![]; + for i in -100..100 { + vec.push((i as f32) / 3.0); + } + check_round_trip(vec); +} + +#[test] +fn test_f64() { + let mut vec = vec![]; + for i in -100..100 { + vec.push((i as f64) / 3.0); + } + check_round_trip(vec); +} + +#[test] +fn test_char() { + let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€']; + check_round_trip(vec); +} + +#[test] +fn test_string() { + let vec = vec!["abcbuÖeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(), + "abcbuÖganeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(), + "abcbuÖganeiovÄnameÜavmpßvmea€µsbpapmaebn".to_string(), + "abcbuÖganeiovÄnameÜavmpßvmeabpnvapeapmaebn".to_string(), + "abcbuÖganeiÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(), + "abcbuÖganeiovÄnameÜavmpßvmea€µsbpmaebn".to_string(), + "abcbuÖganeiovÄnameÜavmpßvmea€µnvapeapmaebn".to_string()]; + + check_round_trip(vec); +} + +#[test] +fn test_option() { + check_round_trip(vec![Some(-1i8)]); + check_round_trip(vec![Some(-2i16)]); + check_round_trip(vec![Some(-3i32)]); + check_round_trip(vec![Some(-4i64)]); + check_round_trip(vec![Some(-5isize)]); + + let none_i8: Option = None; + check_round_trip(vec![none_i8]); + + let none_i16: Option = None; + check_round_trip(vec![none_i16]); + + let none_i32: Option = None; + check_round_trip(vec![none_i32]); + + let none_i64: Option = None; + check_round_trip(vec![none_i64]); + + let none_isize: Option = None; + check_round_trip(vec![none_isize]); +} + +#[test] +fn test_struct() { + check_round_trip(vec![Struct { + a: (), + b: 10, + c: 11, + d: 12, + e: 13, + f: 14, + + g: 15, + h: 16, + i: 17, + j: 18, + k: 19, + + l: 'x', + m: "abc".to_string(), + n: 20.5, + o: 21.5, + p: false, + q: None, + }]); + + check_round_trip(vec![Struct { + a: (), + b: 101, + c: 111, + d: 121, + e: 131, + f: 141, + + g: -15, + h: -16, + i: -17, + j: -18, + k: -19, + + l: 'y', + m: "def".to_string(), + n: -20.5, + o: -21.5, + p: true, + q: Some(1234567), + }]); +} + +#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)] +enum Enum { + Variant1, + Variant2(usize, f32), + Variant3 { + a: i32, + b: char, + c: bool, + }, +} + +#[test] +fn test_enum() { + check_round_trip(vec![Enum::Variant1, + Enum::Variant2(1, 2.5), + Enum::Variant3 { + a: 3, + b: 'b', + c: false, + }, + Enum::Variant3 { + a: -4, + b: 'f', + c: true, + }]); +} + +#[test] +fn test_sequence() { + let mut vec = vec![]; + for i in -100i64..100i64 { + vec.push(i * 100000); + } + + check_round_trip(vec![vec]); +} + +#[test] +fn test_hash_map() { + use std::collections::HashMap; + let mut map = HashMap::new(); + for i in -100i64..100i64 { + map.insert(i * 100000, i * 10000); + } + + check_round_trip(vec![map]); +} + +#[test] +fn test_tuples() { + check_round_trip(vec![('x', (), false, 0.5f32)]); + check_round_trip(vec![(9i8, 10u16, 1.5f64)]); + check_round_trip(vec![(-12i16, 11u8, 12usize)]); + check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]); + check_round_trip(vec![(String::new(), "some string".to_string())]); +} From 06b63046b298fad478e69007ee207396bc1a9a2d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 9 Feb 2019 17:13:39 +0900 Subject: [PATCH 0777/1064] Cleanup imports --- src/libserialize/hex.rs | 2 +- src/libserialize/json.rs | 1 - src/libserialize/opaque.rs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index c5217b962ce79..73b9122b13cea 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -145,7 +145,7 @@ impl FromHex for str { #[cfg(test)] mod tests { extern crate test; - use self::test::Bencher; + use test::Bencher; use crate::hex::{FromHex, ToHex}; #[test] diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 60b1d2e17f12a..5b3444b9f456f 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -199,7 +199,6 @@ use std::ops::Index; use std::str::FromStr; use std::string; use std::{char, f64, fmt, str}; -use std; use crate::Encodable; diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs index d6e8560195c2b..a6a5c318079f1 100644 --- a/src/libserialize/opaque.rs +++ b/src/libserialize/opaque.rs @@ -1,6 +1,6 @@ use crate::leb128::{self, read_signed_leb128, write_signed_leb128}; -use std::borrow::Cow; use crate::serialize; +use std::borrow::Cow; // ----------------------------------------------------------------------------- // Encoder From f5bbcf3818285abd253930554da90fc97cba3690 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 22 Nov 2018 17:17:45 +0100 Subject: [PATCH 0778/1064] use pass infrastructure for mir shims, so that they can get dumped --- src/librustc_mir/shim.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 942e7a1f1bbbd..7edd725544c5e 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -16,8 +16,10 @@ use syntax_pos::Span; use std::fmt; use std::iter; -use crate::transform::{add_moves_for_packed_drops, add_call_guards}; -use crate::transform::{remove_noop_landing_pads, no_landing_pads, simplify}; +use crate::transform::{ + add_moves_for_packed_drops, add_call_guards, + remove_noop_landing_pads, no_landing_pads, simplify, run_passes +}; use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode}; use crate::util::patch::MirPatch; @@ -113,12 +115,15 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }; debug!("make_shim({:?}) = untransformed {:?}", instance, result); - add_moves_for_packed_drops::add_moves_for_packed_drops( - tcx, &mut result, instance.def_id()); - no_landing_pads::no_landing_pads(tcx, &mut result); - remove_noop_landing_pads::remove_noop_landing_pads(tcx, &mut result); - simplify::simplify_cfg(&mut result); - add_call_guards::CriticalCallEdges.add_call_guards(&mut result); + + run_passes(tcx, &mut result, instance.def_id(), MirPhase::Const, &[ + &add_moves_for_packed_drops::AddMovesForPackedDrops, + &no_landing_pads::NoLandingPads, + &remove_noop_landing_pads::RemoveNoopLandingPads, + &simplify::SimplifyCfg::new("make_shim"), + &add_call_guards::CriticalCallEdges, + ]); + debug!("make_shim({:?}) = {:?}", instance, result); tcx.alloc_mir(result) From 276219e0e2ead9dfbe38c4f80ce53f078d25cd63 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 Feb 2019 16:59:20 +0100 Subject: [PATCH 0779/1064] fix dumping MIR from another crate --- src/librustc_mir/util/pretty.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 2e1fc756833b8..bef880ad38609 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -1,4 +1,3 @@ -use rustc::hir; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::*; use rustc::mir::visit::Visitor; @@ -184,7 +183,7 @@ fn dump_path( let mut file_path = PathBuf::new(); file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); - let item_name = tcx.hir() + let item_name = tcx .def_path(source.def_id) .to_filename_friendly_no_crate(); @@ -574,15 +573,17 @@ fn write_mir_sig( mir: &Mir<'_>, w: &mut dyn Write, ) -> io::Result<()> { - let id = tcx.hir().as_local_node_id(src.def_id).unwrap(); - let body_owner_kind = tcx.hir().body_owner_kind(id); - match (body_owner_kind, src.promoted) { + use rustc::hir::def::Def; + + debug!("write_mir_sig: {:?}", src.def_id); + let descr = tcx.describe_def(src.def_id).unwrap(); + match (descr, src.promoted) { (_, Some(i)) => write!(w, "{:?} in", i)?, - (hir::BodyOwnerKind::Closure, _) | - (hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?, - (hir::BodyOwnerKind::Const, _) => write!(w, "const")?, - (hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?, - (hir::BodyOwnerKind::Static(hir::MutMutable), _) => write!(w, "static mut")?, + (Def::Fn(_), _) => write!(w, "fn")?, + (Def::Const(_), _) => write!(w, "const")?, + (Def::Static(_, /*is_mutbl*/false), _) => write!(w, "static")?, + (Def::Static(_, /*is_mutbl*/true), _) => write!(w, "static mut")?, + _ => bug!("Unexpected def description {:?}", descr), } item_path::with_forced_impl_filename_line(|| { @@ -590,9 +591,8 @@ fn write_mir_sig( write!(w, " {}", tcx.item_path_str(src.def_id)) })?; - match (body_owner_kind, src.promoted) { - (hir::BodyOwnerKind::Closure, None) | - (hir::BodyOwnerKind::Fn, None) => { + match (descr, src.promoted) { + (Def::Fn(_), None) => { write!(w, "(")?; // fn argument types. @@ -605,10 +605,11 @@ fn write_mir_sig( write!(w, ") -> {}", mir.return_ty())?; } - (hir::BodyOwnerKind::Const, _) | (hir::BodyOwnerKind::Static(_), _) | (_, Some(_)) => { + (Def::Const(_), _) | (Def::Static(_, _), _) | (_, Some(_)) => { assert_eq!(mir.arg_count, 0); write!(w, ": {} =", mir.return_ty())?; } + _ => bug!("Unexpected def description {:?}", descr), } if let Some(yield_ty) = mir.yield_ty { From cd2169682e456f8d8cd3d505b2206d4ed07ecd07 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 10:06:57 +0100 Subject: [PATCH 0780/1064] fix rebase fallout: AnonConsts are Consts, and Methods are functions --- src/librustc/hir/map/mod.rs | 5 ++++- src/librustc_mir/util/pretty.rs | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 91fc12639baf5..470bec9757831 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -371,8 +371,11 @@ impl<'hir> Map<'hir> { let def_id = self.local_def_id(variant.node.data.id()); Some(Def::Variant(def_id)) } + Node::AnonConst(item) => { + let def_id = self.local_def_id(item.id); + Some(Def::Const(def_id)) + } Node::Field(_) | - Node::AnonConst(_) | Node::Expr(_) | Node::Stmt(_) | Node::PathSegment(_) | diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index bef880ad38609..0e4cfe03bf9ce 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -575,11 +575,11 @@ fn write_mir_sig( ) -> io::Result<()> { use rustc::hir::def::Def; - debug!("write_mir_sig: {:?}", src.def_id); + debug!("write_mir_sig: {:?} {:?}", src.def_id, tcx.hir().get_if_local(src.def_id)); let descr = tcx.describe_def(src.def_id).unwrap(); match (descr, src.promoted) { (_, Some(i)) => write!(w, "{:?} in", i)?, - (Def::Fn(_), _) => write!(w, "fn")?, + (Def::Fn(_), _) | (Def::Method(_), _) => write!(w, "fn")?, (Def::Const(_), _) => write!(w, "const")?, (Def::Static(_, /*is_mutbl*/false), _) => write!(w, "static")?, (Def::Static(_, /*is_mutbl*/true), _) => write!(w, "static mut")?, @@ -592,7 +592,7 @@ fn write_mir_sig( })?; match (descr, src.promoted) { - (Def::Fn(_), None) => { + (Def::Fn(_), None) | (Def::Method(_), None) => { write!(w, "(")?; // fn argument types. From 270894678792fa9a30acc6ebc3a13caf5fa0b9c6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 11:51:07 +0100 Subject: [PATCH 0781/1064] pass full InstanceDef to run_passes --- .../borrow_check/nll/type_check/mod.rs | 2 +- src/librustc_mir/shim.rs | 2 +- .../transform/add_moves_for_packed_drops.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 40 +++++++++---------- src/librustc_mir/transform/elaborate_drops.rs | 4 +- src/librustc_mir/transform/generator.rs | 4 +- src/librustc_mir/transform/inline.rs | 10 ++--- src/librustc_mir/transform/mod.rs | 27 ++++++++----- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_mir/transform/rustc_peek.rs | 2 +- src/librustc_mir/util/liveness.rs | 4 +- src/librustc_mir/util/pretty.rs | 16 ++++---- 12 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 19ff47f9c390d..cc09b2ca530e1 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -2428,7 +2428,7 @@ pub struct TypeckMir; impl MirPass for TypeckMir { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { - let def_id = src.def_id; + let def_id = src.def_id(); debug!("run_pass: {:?}", def_id); // When NLL is enabled, the borrow checker runs the typeck diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 7edd725544c5e..7f3e4a2e1bc4f 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -116,7 +116,7 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; debug!("make_shim({:?}) = untransformed {:?}", instance, result); - run_passes(tcx, &mut result, instance.def_id(), MirPhase::Const, &[ + run_passes(tcx, &mut result, instance, MirPhase::Const, &[ &add_moves_for_packed_drops::AddMovesForPackedDrops, &no_landing_pads::NoLandingPads, &remove_noop_landing_pads::RemoveNoopLandingPads, diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index 1492f0c50a31a..fd31ba0422b57 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -46,7 +46,7 @@ impl MirPass for AddMovesForPackedDrops { mir: &mut Mir<'tcx>) { debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span); - add_moves_for_packed_drops(tcx, mir, src.def_id); + add_moves_for_packed_drops(tcx, mir, src.def_id()); } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index dd1f37a591888..018f71c39e513 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -30,7 +30,7 @@ pub struct ConstProp; impl MirPass for ConstProp { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { // will be evaluated by miri and produce its errors there if source.promoted.is_some() { @@ -38,11 +38,11 @@ impl MirPass for ConstProp { } use rustc::hir::map::blocks::FnLikeNode; - let node_id = tcx.hir().as_local_node_id(source.def_id) + let node_id = tcx.hir().as_local_node_id(source.def_id()) .expect("Non-local call to local provider is_const_fn"); let is_fn_like = FnLikeNode::from_node(tcx.hir().get(node_id)).is_some(); - let is_assoc_const = match tcx.describe_def(source.def_id) { + let is_assoc_const = match tcx.describe_def(source.def_id()) { Some(Def::AssociatedConst(_)) => true, _ => false, }; @@ -50,11 +50,11 @@ impl MirPass for ConstProp { // Only run const prop on functions, methods, closures and associated constants if !is_fn_like && !is_assoc_const { // skip anon_const/statics/consts because they'll be evaluated by miri anyway - trace!("ConstProp skipped for {:?}", source.def_id); + trace!("ConstProp skipped for {:?}", source.def_id()); return } - trace!("ConstProp starting for {:?}", source.def_id); + trace!("ConstProp starting for {:?}", source.def_id()); // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold // constants, instead of just checking for const-folding succeeding. @@ -63,7 +63,7 @@ impl MirPass for ConstProp { let mut optimization_finder = ConstPropagator::new(mir, tcx, source); optimization_finder.visit_mir(mir); - trace!("ConstProp done for {:?}", source.def_id); + trace!("ConstProp done for {:?}", source.def_id()); } } @@ -74,7 +74,7 @@ struct ConstPropagator<'a, 'mir, 'tcx:'a+'mir> { ecx: EvalContext<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>, mir: &'mir Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, places: IndexVec>>, can_const_prop: IndexVec, param_env: ParamEnv<'tcx>, @@ -107,10 +107,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { fn new( mir: &'mir Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, ) -> ConstPropagator<'a, 'mir, 'tcx> { - let param_env = tcx.param_env(source.def_id); - let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id), param_env); + let param_env = tcx.param_env(source.def_id()); + let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id()), param_env); ConstPropagator { ecx, mir, @@ -284,13 +284,13 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { _ => None, }, Place::Promoted(ref promoted) => { - let generics = self.tcx.generics_of(self.source.def_id); + let generics = self.tcx.generics_of(self.source.def_id()); if generics.requires_monomorphization(self.tcx) { // FIXME: can't handle code with generics return None; } - let substs = Substs::identity_for_item(self.tcx, self.source.def_id); - let instance = Instance::new(self.source.def_id, substs); + let substs = Substs::identity_for_item(self.tcx, self.source.def_id()); + let instance = Instance::new(self.source.def_id(), substs); let cid = GlobalId { instance, promoted: Some(promoted.0), @@ -358,10 +358,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { ))) } Rvalue::UnaryOp(op, ref arg) => { - let def_id = if self.tcx.is_closure(self.source.def_id) { - self.tcx.closure_base_def_id(self.source.def_id) + let def_id = if self.tcx.is_closure(self.source.def_id()) { + self.tcx.closure_base_def_id(self.source.def_id()) } else { - self.source.def_id + self.source.def_id() }; let generics = self.tcx.generics_of(def_id); if generics.requires_monomorphization(self.tcx) { @@ -398,10 +398,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { Rvalue::BinaryOp(op, ref left, ref right) => { trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right); let right = self.eval_operand(right, source_info)?; - let def_id = if self.tcx.is_closure(self.source.def_id) { - self.tcx.closure_base_def_id(self.source.def_id) + let def_id = if self.tcx.is_closure(self.source.def_id()) { + self.tcx.closure_base_def_id(self.source.def_id()) } else { - self.source.def_id + self.source.def_id() }; let generics = self.tcx.generics_of(def_id); if generics.requires_monomorphization(self.tcx) { @@ -608,7 +608,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { let node_id = self .tcx .hir() - .as_local_node_id(self.source.def_id) + .as_local_node_id(self.source.def_id()) .expect("some part of a failing const eval must be local"); use rustc::mir::interpret::EvalErrorKind::*; let msg = match msg { diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 4aaa0be7964a4..b3f72e3a7fc4e 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -28,8 +28,8 @@ impl MirPass for ElaborateDrops { { debug!("elaborate_drops({:?} @ {:?})", src, mir.span); - let id = tcx.hir().as_local_node_id(src.def_id).unwrap(); - let param_env = tcx.param_env(src.def_id).with_reveal_all(); + let id = tcx.hir().as_local_node_id(src.def_id()).unwrap(); + let param_env = tcx.param_env(src.def_id()).with_reveal_all(); let move_data = match MoveData::gather_moves(mir, tcx) { Ok(move_data) => move_data, Err((move_data, _move_errors)) => { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 9897f9833ca62..ae2ba55c5083c 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -383,7 +383,7 @@ fn locals_live_across_suspend_points( FxHashMap>, ) { let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); - let node_id = tcx.hir().as_local_node_id(source.def_id).unwrap(); + let node_id = tcx.hir().as_local_node_id(source.def_id()).unwrap(); // Calculate when MIR locals have live storage. This gives us an upper bound of their // lifetimes. @@ -880,7 +880,7 @@ impl MirPass for StateTransform { assert!(mir.generator_drop.is_none()); - let def_id = source.def_id; + let def_id = source.def_id(); // The first argument is the generator type passed by value let gen_ty = mir.local_decls.raw[1].ty; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 4fddf6f8e09c2..4cb7826698466 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -40,7 +40,7 @@ struct CallSite<'tcx> { impl MirPass for Inline { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { Inliner { tcx, source }.run_pass(mir); @@ -50,7 +50,7 @@ impl MirPass for Inline { struct Inliner<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, } impl<'a, 'tcx> Inliner<'a, 'tcx> { @@ -69,10 +69,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let mut callsites = VecDeque::new(); - let param_env = self.tcx.param_env(self.source.def_id); + let param_env = self.tcx.param_env(self.source.def_id()); // Only do inlining into fn bodies. - let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap(); + let id = self.tcx.hir().as_local_node_id(self.source.def_id()).unwrap(); if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() { for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() { if let Some(callsite) = self.get_valid_function_call(bb, @@ -274,7 +274,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // FIXME: Give a bonus to functions with only a single caller - let param_env = tcx.param_env(self.source.def_id); + let param_env = tcx.param_env(self.source.def_id()); let mut first_block = true; let mut cost = 0; diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index cc37a8381f234..44061e689b3be 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -2,7 +2,7 @@ use crate::borrow_check::nll::type_check; use crate::build; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::mir::{Mir, MirPhase, Promoted}; -use rustc::ty::TyCtxt; +use rustc::ty::{TyCtxt, InstanceDef}; use rustc::ty::query::Providers; use rustc::ty::steal::Steal; use rustc::hir; @@ -104,20 +104,25 @@ fn mir_built<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea /// Where a specific Mir comes from. #[derive(Debug, Copy, Clone)] -pub struct MirSource { - pub def_id: DefId, +pub struct MirSource<'tcx> { + pub instance: InstanceDef<'tcx>, /// If `Some`, this is a promoted rvalue within the parent function. pub promoted: Option, } -impl MirSource { +impl<'tcx> MirSource<'tcx> { pub fn item(def_id: DefId) -> Self { MirSource { - def_id, + instance: InstanceDef::Item(def_id), promoted: None } } + + #[inline] + pub fn def_id(&self) -> DefId { + self.instance.def_id() + } } /// Generates a default name for the pass based on the name of the @@ -141,14 +146,14 @@ pub trait MirPass { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, mir: &mut Mir<'tcx>); } pub fn run_passes( tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>, - def_id: DefId, + instance: InstanceDef<'tcx>, mir_phase: MirPhase, passes: &[&dyn MirPass], ) { @@ -160,7 +165,7 @@ pub fn run_passes( } let source = MirSource { - def_id, + instance, promoted, }; let mut index = 0; @@ -198,7 +203,7 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea let _ = tcx.unsafety_check_result(def_id); let mut mir = tcx.mir_built(def_id).steal(); - run_passes(tcx, &mut mir, def_id, MirPhase::Const, &[ + run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Const, &[ // What we need to do constant evaluation. &simplify::SimplifyCfg::new("initial"), &type_check::TypeckMir, @@ -217,7 +222,7 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx } let mut mir = tcx.mir_const(def_id).steal(); - run_passes(tcx, &mut mir, def_id, MirPhase::Validated, &[ + run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Validated, &[ // What we need to run borrowck etc. &qualify_consts::QualifyAndPromoteConstants, &simplify::SimplifyCfg::new("qualify-consts"), @@ -235,7 +240,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx } let mut mir = tcx.mir_validated(def_id).steal(); - run_passes(tcx, &mut mir, def_id, MirPhase::Optimized, &[ + run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Optimized, &[ // Remove all things not needed by analysis &no_landing_pads::NoLandingPads, &simplify_branches::SimplifyBranches::new("initial"), diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index ab4e3ad23f69a..9b5c4f51a91a3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1171,7 +1171,7 @@ impl MirPass for QualifyAndPromoteConstants { return; } - let def_id = src.def_id; + let def_id = src.def_id(); let id = tcx.hir().as_local_node_id(def_id).unwrap(); let mut const_promoted_temps = None; let mode = match tcx.hir().body_owner_kind(id) { diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 806c1c1cca457..d9a5d2fe8ce0b 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -25,7 +25,7 @@ pub struct SanityCheck; impl MirPass for SanityCheck { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { - let def_id = src.def_id; + let def_id = src.def_id(); let id = tcx.hir().as_local_node_id(def_id).unwrap(); if !tcx.has_attr(def_id, "rustc_mir") { debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 08ef58a232170..f72052c6e2840 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -317,7 +317,7 @@ pub fn dump_mir<'a, 'tcx, V: Idx>( } let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id) + tcx.item_path_str(source.def_id()) }); dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, map, result); } @@ -333,7 +333,7 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>( ) { let mut file_path = PathBuf::new(); file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); - let item_id = tcx.hir().as_local_node_id(source.def_id).unwrap(); + let item_id = tcx.hir().as_local_node_id(source.def_id()).unwrap(); let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name); file_path.push(&file_name); let _ = fs::File::create(&file_path).and_then(|mut file| { diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 0e4cfe03bf9ce..120055ad39764 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -80,7 +80,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>( let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id) + tcx.item_path_str(source.def_id()) }); dump_matched_mir_node( tcx, @@ -105,7 +105,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( }; let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id) + tcx.item_path_str(source.def_id()) }); filters.split('|').any(|or_filter| { or_filter.split('&').all(|and_filter| { @@ -150,7 +150,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( let _: io::Result<()> = try { let mut file = create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?; - write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?; + write_mir_fn_graphviz(tcx, source.def_id(), mir, &mut file)?; }; } } @@ -184,7 +184,7 @@ fn dump_path( file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); let item_name = tcx - .def_path(source.def_id) + .def_path(source.def_id()) .to_filename_friendly_no_crate(); let file_name = format!( @@ -252,7 +252,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>( for (i, mir) in mir.promoted.iter_enumerated() { writeln!(w, "")?; let src = MirSource { - def_id, + instance: ty::InstanceDef::Item(def_id), promoted: Some(i), }; write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?; @@ -575,8 +575,8 @@ fn write_mir_sig( ) -> io::Result<()> { use rustc::hir::def::Def; - debug!("write_mir_sig: {:?} {:?}", src.def_id, tcx.hir().get_if_local(src.def_id)); - let descr = tcx.describe_def(src.def_id).unwrap(); + trace!("write_mir_sig: {:?} {:?}", src, tcx.hir().get_if_local(src.def_id())); + let descr = tcx.describe_def(src.def_id()).unwrap(); match (descr, src.promoted) { (_, Some(i)) => write!(w, "{:?} in", i)?, (Def::Fn(_), _) | (Def::Method(_), _) => write!(w, "fn")?, @@ -588,7 +588,7 @@ fn write_mir_sig( item_path::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere - write!(w, " {}", tcx.item_path_str(src.def_id)) + write!(w, " {}", tcx.item_path_str(src.def_id())) })?; match (descr, src.promoted) { From fed4c5d9e13e7cde3399336342a64ba23308d4f5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 13:31:50 +0100 Subject: [PATCH 0782/1064] disambiguate filenames of multiple drop shims being dumped --- src/librustc_mir/util/pretty.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 120055ad39764..48a6fd3a95df6 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -186,10 +186,29 @@ fn dump_path( let item_name = tcx .def_path(source.def_id()) .to_filename_friendly_no_crate(); + // All drop shims have the same DefId, so we have to add the type + // to get unique file names. + let shim_disambiguator = match source.instance { + ty::InstanceDef::DropGlue(_, Some(ty)) => { + // Unfortunately, pretty-printed typed are not very filename-friendly. + // We dome some filtering. + let mut s = ".".to_owned(); + s.extend(ty.to_string() + .chars() + .filter_map(|c| match c { + ' ' => None, + ':' => Some('_'), + c => Some(c) + })); + s + } + _ => String::new(), + }; let file_name = format!( - "rustc.{}{}{}.{}.{}.{}", + "rustc.{}{}{}{}.{}.{}.{}", item_name, + shim_disambiguator, promotion_id, pass_num, pass_name, From 27ce224a8f84d8ed2fdb01410d7b931fd29655c1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 3 Feb 2019 14:09:56 +0100 Subject: [PATCH 0783/1064] fix --emit=mir: StructCtors are functions --- src/librustc/hir/map/mod.rs | 5 ++++- src/librustc_mir/util/pretty.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 470bec9757831..8db4e52f3d630 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -375,6 +375,10 @@ impl<'hir> Map<'hir> { let def_id = self.local_def_id(item.id); Some(Def::Const(def_id)) } + Node::StructCtor(variant) => { + let def_id = self.local_def_id(variant.id()); + Some(Def::Fn(def_id)) + } Node::Field(_) | Node::Expr(_) | Node::Stmt(_) | @@ -383,7 +387,6 @@ impl<'hir> Map<'hir> { Node::TraitRef(_) | Node::Pat(_) | Node::Binding(_) | - Node::StructCtor(_) | Node::Lifetime(_) | Node::Visibility(_) | Node::Block(_) | diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 48a6fd3a95df6..ae07aad31172f 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -594,7 +594,7 @@ fn write_mir_sig( ) -> io::Result<()> { use rustc::hir::def::Def; - trace!("write_mir_sig: {:?} {:?}", src, tcx.hir().get_if_local(src.def_id())); + trace!("write_mir_sig: {:?}", src.instance); let descr = tcx.describe_def(src.def_id()).unwrap(); match (descr, src.promoted) { (_, Some(i)) => write!(w, "{:?} in", i)?, From 84d75dbd7ed128f8694b8a9807cffd5794a0c918 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Feb 2019 21:49:53 +0100 Subject: [PATCH 0784/1064] fix node classification --- src/librustc/hir/map/mod.rs | 7 ++----- src/librustc_mir/util/pretty.rs | 27 +++++++++++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 8db4e52f3d630..955f834e40398 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -371,14 +371,11 @@ impl<'hir> Map<'hir> { let def_id = self.local_def_id(variant.node.data.id()); Some(Def::Variant(def_id)) } - Node::AnonConst(item) => { - let def_id = self.local_def_id(item.id); - Some(Def::Const(def_id)) - } Node::StructCtor(variant) => { let def_id = self.local_def_id(variant.id()); - Some(Def::Fn(def_id)) + Some(Def::StructCtor(def_id, def::CtorKind::from_hir(variant))) } + Node::AnonConst(_) | Node::Field(_) | Node::Expr(_) | Node::Stmt(_) | diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index ae07aad31172f..7bbce405a8425 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -595,23 +595,28 @@ fn write_mir_sig( use rustc::hir::def::Def; trace!("write_mir_sig: {:?}", src.instance); - let descr = tcx.describe_def(src.def_id()).unwrap(); + let descr = tcx.describe_def(src.def_id()); match (descr, src.promoted) { - (_, Some(i)) => write!(w, "{:?} in", i)?, - (Def::Fn(_), _) | (Def::Method(_), _) => write!(w, "fn")?, - (Def::Const(_), _) => write!(w, "const")?, - (Def::Static(_, /*is_mutbl*/false), _) => write!(w, "static")?, - (Def::Static(_, /*is_mutbl*/true), _) => write!(w, "static mut")?, + (_, Some(i)) => write!(w, "{:?} in ", i)?, + (Some(Def::Fn(_)), _) | (Some(Def::Method(_)), _) => write!(w, "fn ")?, + (Some(Def::StructCtor(..)), _) => write!(w, "struct ")?, + (Some(Def::Const(_)), _) => write!(w, "const ")?, + (Some(Def::Static(_, /*is_mutbl*/false)), _) => write!(w, "static ")?, + (Some(Def::Static(_, /*is_mutbl*/true)), _) => write!(w, "static mut ")?, + (None, _) => {}, // things like anon const, not an item _ => bug!("Unexpected def description {:?}", descr), } item_path::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere - write!(w, " {}", tcx.item_path_str(src.def_id())) + write!(w, "{}", tcx.item_path_str(src.def_id())) })?; match (descr, src.promoted) { - (Def::Fn(_), None) | (Def::Method(_), None) => { + (Some(Def::Fn(_)), None) | + (Some(Def::Method(_)), None) | + (Some(Def::StructCtor(..)), None) => + { write!(w, "(")?; // fn argument types. @@ -624,11 +629,10 @@ fn write_mir_sig( write!(w, ") -> {}", mir.return_ty())?; } - (Def::Const(_), _) | (Def::Static(_, _), _) | (_, Some(_)) => { + _ => { assert_eq!(mir.arg_count, 0); write!(w, ": {} =", mir.return_ty())?; } - _ => bug!("Unexpected def description {:?}", descr), } if let Some(yield_ty) = mir.yield_ty { @@ -636,6 +640,9 @@ fn write_mir_sig( writeln!(w, "yields {}", yield_ty)?; } + write!(w, " ")?; + // Next thing that gets printed is the opening { + Ok(()) } From a413242efef8e398c385a695eecb255f2713d49d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Feb 2019 23:40:29 +0100 Subject: [PATCH 0785/1064] fix printing closures --- src/librustc_mir/util/pretty.rs | 38 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 7bbce405a8425..b1aef28ca9808 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -596,13 +596,17 @@ fn write_mir_sig( trace!("write_mir_sig: {:?}", src.instance); let descr = tcx.describe_def(src.def_id()); + let is_function = match descr { + Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true, + _ => tcx.is_closure(src.def_id()), + }; match (descr, src.promoted) { (_, Some(i)) => write!(w, "{:?} in ", i)?, - (Some(Def::Fn(_)), _) | (Some(Def::Method(_)), _) => write!(w, "fn ")?, (Some(Def::StructCtor(..)), _) => write!(w, "struct ")?, (Some(Def::Const(_)), _) => write!(w, "const ")?, (Some(Def::Static(_, /*is_mutbl*/false)), _) => write!(w, "static ")?, (Some(Def::Static(_, /*is_mutbl*/true)), _) => write!(w, "static mut ")?, + (_, _) if is_function => write!(w, "fn ")?, (None, _) => {}, // things like anon const, not an item _ => bug!("Unexpected def description {:?}", descr), } @@ -612,27 +616,21 @@ fn write_mir_sig( write!(w, "{}", tcx.item_path_str(src.def_id())) })?; - match (descr, src.promoted) { - (Some(Def::Fn(_)), None) | - (Some(Def::Method(_)), None) | - (Some(Def::StructCtor(..)), None) => - { - write!(w, "(")?; - - // fn argument types. - for (i, arg) in mir.args_iter().enumerate() { - if i != 0 { - write!(w, ", ")?; - } - write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?; - } + if src.promoted.is_none() && is_function { + write!(w, "(")?; - write!(w, ") -> {}", mir.return_ty())?; - } - _ => { - assert_eq!(mir.arg_count, 0); - write!(w, ": {} =", mir.return_ty())?; + // fn argument types. + for (i, arg) in mir.args_iter().enumerate() { + if i != 0 { + write!(w, ", ")?; + } + write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?; } + + write!(w, ") -> {}", mir.return_ty())?; + } else { + assert_eq!(mir.arg_count, 0); + write!(w, ": {} =", mir.return_ty())?; } if let Some(yield_ty) = mir.yield_ty { From 544b3a1bb476364f1e5d149cf82beb98a219dda5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 9 Feb 2019 12:19:04 +0100 Subject: [PATCH 0786/1064] fix rebase fallout --- src/librustc_mir/borrow_check/nll/mod.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 7 ++++++- src/librustc_mir/transform/add_call_guards.rs | 2 +- .../transform/add_moves_for_packed_drops.rs | 2 +- src/librustc_mir/transform/add_retag.rs | 2 +- .../transform/cleanup_post_borrowck.rs | 4 ++-- src/librustc_mir/transform/copy_prop.rs | 2 +- src/librustc_mir/transform/deaggregator.rs | 2 +- src/librustc_mir/transform/dump_mir.rs | 4 ++-- src/librustc_mir/transform/elaborate_drops.rs | 2 +- src/librustc_mir/transform/erase_regions.rs | 2 +- src/librustc_mir/transform/generator.rs | 10 +++++----- src/librustc_mir/transform/instcombine.rs | 2 +- src/librustc_mir/transform/lower_128bit.rs | 2 +- src/librustc_mir/transform/no_landing_pads.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- .../transform/remove_noop_landing_pads.rs | 2 +- src/librustc_mir/transform/rustc_peek.rs | 2 +- src/librustc_mir/transform/simplify.rs | 4 ++-- src/librustc_mir/transform/simplify_branches.rs | 2 +- .../transform/uniform_array_move_out.rs | 4 ++-- src/librustc_mir/util/liveness.rs | 6 +++--- src/librustc_mir/util/pretty.rs | 16 ++++++++-------- 23 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 1fca104cd3825..84fdbb9423e0a 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -209,7 +209,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( fn dump_mir_results<'a, 'gcx, 'tcx>( infcx: &InferCtxt<'a, 'gcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, mir: &Mir<'tcx>, regioncx: &RegionInferenceContext<'_>, closure_region_requirements: &Option>, diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index cc09b2ca530e1..add07b1ddfe05 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -2427,7 +2427,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { pub struct TypeckMir; impl MirPass for TypeckMir { - fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { + fn run_pass<'a, 'tcx>( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + src: MirSource<'tcx>, + mir: &mut Mir<'tcx>, + ) { let def_id = src.def_id(); debug!("run_pass: {:?}", def_id); diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index dab96faaa2a5e..88042d64e96b7 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -33,7 +33,7 @@ pub use self::AddCallGuards::*; impl MirPass for AddCallGuards { fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { self.add_call_guards(mir); } diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index fd31ba0422b57..4d4c89b8b6a40 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -42,7 +42,7 @@ pub struct AddMovesForPackedDrops; impl MirPass for AddMovesForPackedDrops { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, + src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span); diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index 7bfcd318afe2d..e66c11aa36e0e 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -77,7 +77,7 @@ fn may_have_reference<'a, 'gcx, 'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) impl MirPass for AddRetag { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { if !tcx.sess.opts.debugging_opts.mir_emit_retag { diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index 240ef7c8ba42a..890d2c56f42b2 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -35,7 +35,7 @@ pub struct DeleteAscribeUserType; impl MirPass for CleanAscribeUserType { fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _source: MirSource, + _source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let mut delete = DeleteAscribeUserType; delete.visit_mir(mir); @@ -69,7 +69,7 @@ pub struct DeleteFakeBorrows { impl MirPass for CleanFakeReadsAndBorrows { fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _source: MirSource, + _source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let mut delete_reads = DeleteAndRecordFakeReads::default(); delete_reads.visit_mir(mir); diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 4789c35740eb3..7d907ca3a215e 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -30,7 +30,7 @@ pub struct CopyPropagation; impl MirPass for CopyPropagation { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _source: MirSource, + _source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { // We only run when the MIR optimization level is > 1. // This avoids a slow pass, and messing up debug info. diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index 669384e31dac3..9061dfff76fe8 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -8,7 +8,7 @@ pub struct Deaggregator; impl MirPass for Deaggregator { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _source: MirSource, + _source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut(); let local_decls = &*local_decls; diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index d7f697a320049..81e48fe2dbe3b 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -20,7 +20,7 @@ impl MirPass for Marker { fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _source: MirSource, + _source: MirSource<'tcx>, _mir: &mut Mir<'tcx>) { } @@ -41,7 +41,7 @@ impl fmt::Display for Disambiguator { pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pass_num: &dyn fmt::Display, pass_name: &str, - source: MirSource, + source: MirSource<'tcx>, mir: &Mir<'tcx>, is_after: bool) { if mir_util::dump_enabled(tcx, pass_name, source) { diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index b3f72e3a7fc4e..6e093a7e240b3 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -23,7 +23,7 @@ pub struct ElaborateDrops; impl MirPass for ElaborateDrops { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, + src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { debug!("elaborate_drops({:?} @ {:?})", src, mir.span); diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index b555a2aa83ee3..d59bb3ec5b1c0 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -53,7 +53,7 @@ pub struct EraseRegions; impl MirPass for EraseRegions { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _: MirSource, + _: MirSource<'tcx>, mir: &mut Mir<'tcx>) { EraseRegionsVisitor::new(tcx).visit_mir(mir); } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index ae2ba55c5083c..33d98d8f076c8 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -376,7 +376,7 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored { fn locals_live_across_suspend_points( tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, - source: MirSource, + source: MirSource<'tcx>, movable: bool, ) -> ( liveness::LiveVarSet, @@ -484,7 +484,7 @@ fn locals_live_across_suspend_points( } fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, upvars: Vec>, interior: Ty<'tcx>, movable: bool, @@ -635,7 +635,7 @@ fn create_generator_drop_shim<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, transform: &TransformVisitor<'a, 'tcx>, def_id: DefId, - source: MirSource, + source: MirSource<'tcx>, gen_ty: Ty<'tcx>, mir: &Mir<'tcx>, drop_clean: BasicBlock) -> Mir<'tcx> { @@ -758,7 +758,7 @@ fn create_generator_resume_function<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, transform: TransformVisitor<'a, 'tcx>, def_id: DefId, - source: MirSource, + source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { // Poison the generator when it unwinds for block in mir.basic_blocks_mut() { @@ -869,7 +869,7 @@ fn create_cases<'a, 'tcx, F>(mir: &mut Mir<'tcx>, impl MirPass for StateTransform { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - source: MirSource, + source: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let yield_ty = if let Some(yield_ty) = mir.yield_ty { yield_ty diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 21772e1f1cd5b..290915763e275 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -13,7 +13,7 @@ pub struct InstCombine; impl MirPass for InstCombine { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _: MirSource, + _: MirSource<'tcx>, mir: &mut Mir<'tcx>) { // We only run when optimizing MIR (at any level). if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index aa248ba7c53df..3d1f55e530e62 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -12,7 +12,7 @@ pub struct Lower128Bit; impl MirPass for Lower128Bit { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops; let target_default = tcx.sess.host.options.i128_lowering; diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index 15b59d36d363c..089d9b9b54454 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -11,7 +11,7 @@ pub struct NoLandingPads; impl MirPass for NoLandingPads { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _: MirSource, + _: MirSource<'tcx>, mir: &mut Mir<'tcx>) { no_landing_pads(tcx, mir) } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 9b5c4f51a91a3..76b8b83031a0a 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1159,7 +1159,7 @@ pub struct QualifyAndPromoteConstants; impl MirPass for QualifyAndPromoteConstants { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, + src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { // There's not really any point in promoting errorful MIR. if mir.return_ty().references_error() { diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 4fcb4c10f9e6d..68832b73ccd87 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -24,7 +24,7 @@ pub fn remove_noop_landing_pads<'a, 'tcx>( impl MirPass for RemoveNoopLandingPads { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { remove_noop_landing_pads(tcx, mir); } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index d9a5d2fe8ce0b..40e02e712c156 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -24,7 +24,7 @@ pub struct SanityCheck; impl MirPass for SanityCheck { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, mir: &mut Mir<'tcx>) { + src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let def_id = src.def_id(); let id = tcx.hir().as_local_node_id(def_id).unwrap(); if !tcx.has_attr(def_id, "rustc_mir") { diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 90486d1566413..14e7895af0419 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -59,7 +59,7 @@ impl MirPass for SimplifyCfg { fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir); simplify_cfg(mir); @@ -298,7 +298,7 @@ pub struct SimplifyLocals; impl MirPass for SimplifyLocals { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _: MirSource, + _: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) }; marker.visit_mir(mir); diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 0dc89bfe14709..3c4d1227a691c 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -21,7 +21,7 @@ impl MirPass for SimplifyBranches { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { for block in mir.basic_blocks_mut() { let terminator = block.terminator_mut(); diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 09918436817f3..fd8d68a482262 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -39,7 +39,7 @@ pub struct UniformArrayMoveOut; impl MirPass for UniformArrayMoveOut { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let mut patch = MirPatch::new(mir); { @@ -161,7 +161,7 @@ pub struct RestoreSubsliceArrayMoveOut; impl MirPass for RestoreSubsliceArrayMoveOut { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - _src: MirSource, + _src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let mut patch = MirPatch::new(mir); { diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index f72052c6e2840..847699cc500c9 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -307,7 +307,7 @@ fn block<'tcx, V: Idx>( pub fn dump_mir<'a, 'tcx, V: Idx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, pass_name: &str, - source: MirSource, + source: MirSource<'tcx>, mir: &Mir<'tcx>, map: &impl LiveVariableMap, result: &LivenessResult, @@ -326,7 +326,7 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, pass_name: &str, node_path: &str, - source: MirSource, + source: MirSource<'tcx>, mir: &Mir<'tcx>, map: &dyn LiveVariableMap, result: &LivenessResult, @@ -348,7 +348,7 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>( pub fn write_mir_fn<'a, 'tcx, V: Idx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, + src: MirSource<'tcx>, mir: &Mir<'tcx>, map: &dyn LiveVariableMap, w: &mut dyn Write, diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index b1aef28ca9808..1357f8fe79a0d 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -68,7 +68,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>( pass_num: Option<&dyn Display>, pass_name: &str, disambiguator: &dyn Display, - source: MirSource, + source: MirSource<'tcx>, mir: &Mir<'tcx>, extra_data: F, ) where @@ -97,7 +97,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>( pub fn dump_enabled<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, pass_name: &str, - source: MirSource, + source: MirSource<'tcx>, ) -> bool { let filters = match tcx.sess.opts.debugging_opts.dump_mir { None => return false, @@ -124,7 +124,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( pass_name: &str, node_path: &str, disambiguator: &dyn Display, - source: MirSource, + source: MirSource<'tcx>, mir: &Mir<'tcx>, mut extra_data: F, ) where @@ -164,7 +164,7 @@ fn dump_path( pass_num: Option<&dyn Display>, pass_name: &str, disambiguator: &dyn Display, - source: MirSource, + source: MirSource<'tcx>, ) -> PathBuf { let promotion_id = match source.promoted { Some(id) => format!("-{:?}", id), @@ -231,7 +231,7 @@ pub(crate) fn create_dump_file( pass_num: Option<&dyn Display>, pass_name: &str, disambiguator: &dyn Display, - source: MirSource, + source: MirSource<'tcx>, ) -> io::Result { let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source); if let Some(parent) = file_path.parent() { @@ -282,7 +282,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>( pub fn write_mir_fn<'a, 'gcx, 'tcx, F>( tcx: TyCtxt<'a, 'gcx, 'tcx>, - src: MirSource, + src: MirSource<'tcx>, mir: &Mir<'tcx>, extra_data: &mut F, w: &mut dyn Write, @@ -546,7 +546,7 @@ fn write_scope_tree( /// local variables (both user-defined bindings and compiler temporaries). pub fn write_mir_intro<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, - src: MirSource, + src: MirSource<'tcx>, mir: &Mir<'_>, w: &mut dyn Write, ) -> io::Result<()> { @@ -588,7 +588,7 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>( fn write_mir_sig( tcx: TyCtxt<'_, '_, '_>, - src: MirSource, + src: MirSource<'tcx>, mir: &Mir<'_>, w: &mut dyn Write, ) -> io::Result<()> { From d26475505b4c2bfc6299d3c6c38b1963c3bd86e0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 9 Feb 2019 01:07:38 +0100 Subject: [PATCH 0787/1064] put back macro redirect --- src/librustdoc/html/render.rs | 9 +++++++++ src/test/rustdoc/without-redirect.rs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ecc5bcff12dba..105bf611282f7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2245,6 +2245,15 @@ impl Context { try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst); } } + // If the item is a macro, redirect from the old macro URL (with !) + // to the new one (without). + if item_type == ItemType::Macro { + let redir_name = format!("{}.{}!.html", item_type, name); + let redir_dst = self.dst.join(redir_name); + let redirect_out = try_err!(File::create(&redir_dst), &redir_dst); + let mut redirect_out = BufWriter::new(redirect_out); + try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst); + } } } Ok(()) diff --git a/src/test/rustdoc/without-redirect.rs b/src/test/rustdoc/without-redirect.rs index d473dd8f428d2..a076f8a3c5ec7 100644 --- a/src/test/rustdoc/without-redirect.rs +++ b/src/test/rustdoc/without-redirect.rs @@ -1,7 +1,7 @@ #![crate_name = "foo"] // @has foo/macro.bar.html -// @!has foo/macro.bar!.html +// @has foo/macro.bar!.html // @!has foo/bar.m.html #[macro_export] macro_rules! bar { From be71fccf11525118b62b40f78c65b6bb6abca823 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 9 Feb 2019 23:31:47 +0900 Subject: [PATCH 0788/1064] librustc_codegen_ssa => 2018 --- src/librustc_codegen_ssa/Cargo.toml | 1 + src/librustc_codegen_ssa/back/link.rs | 2 +- src/librustc_codegen_ssa/back/lto.rs | 4 ++-- src/librustc_codegen_ssa/back/write.rs | 7 +++--- src/librustc_codegen_ssa/base.rs | 24 +++++++++---------- src/librustc_codegen_ssa/callee.rs | 2 +- src/librustc_codegen_ssa/common.rs | 8 +++---- src/librustc_codegen_ssa/glue.rs | 8 +++---- src/librustc_codegen_ssa/lib.rs | 25 ++++---------------- src/librustc_codegen_ssa/meth.rs | 4 ++-- src/librustc_codegen_ssa/mir/analyze.rs | 2 +- src/librustc_codegen_ssa/mir/block.rs | 10 ++++---- src/librustc_codegen_ssa/mir/constant.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 6 ++--- src/librustc_codegen_ssa/mir/operand.rs | 8 +++---- src/librustc_codegen_ssa/mir/place.rs | 8 +++---- src/librustc_codegen_ssa/mir/rvalue.rs | 10 ++++---- src/librustc_codegen_ssa/mir/statement.rs | 4 ++-- src/librustc_codegen_ssa/mono_item.rs | 4 ++-- src/librustc_codegen_ssa/traits/asm.rs | 2 +- src/librustc_codegen_ssa/traits/builder.rs | 9 +++---- src/librustc_codegen_ssa/traits/consts.rs | 2 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 2 +- src/librustc_codegen_ssa/traits/intrinsic.rs | 2 +- src/librustc_codegen_ssa/traits/type_.rs | 4 ++-- src/librustc_codegen_ssa/traits/write.rs | 6 ++--- 26 files changed, 75 insertions(+), 91 deletions(-) diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 50994497c2843..0aba43580f1f6 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -2,6 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustc_codegen_ssa" version = "0.0.0" +edition = "2018" [lib] name = "rustc_codegen_ssa" diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 2a5ecf9a0593f..7f1aebace8fc6 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -9,7 +9,7 @@ use rustc_target::spec::LinkerFlavor; use rustc::hir::def_id::CrateNum; use super::command::Command; -use CrateInfo; +use crate::CrateInfo; use cc::windows_registry; use std::fs; diff --git a/src/librustc_codegen_ssa/back/lto.rs b/src/librustc_codegen_ssa/back/lto.rs index f0fb115f91b94..7f0eba7b0850b 100644 --- a/src/librustc_codegen_ssa/back/lto.rs +++ b/src/librustc_codegen_ssa/back/lto.rs @@ -1,6 +1,6 @@ use super::write::CodegenContext; -use traits::*; -use ModuleCodegen; +use crate::traits::*; +use crate::ModuleCodegen; use rustc::util::time_graph::Timeline; use rustc_errors::FatalError; diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 67d4d408babfa..eeb191b09e249 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1,12 +1,12 @@ -use {ModuleCodegen, ModuleKind, CachedModuleCodegen, CompiledModule, CrateInfo, CodegenResults, - RLIB_BYTECODE_EXTENSION}; +use crate::{ModuleCodegen, ModuleKind, CachedModuleCodegen, CompiledModule, CrateInfo, + CodegenResults, RLIB_BYTECODE_EXTENSION}; use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; use super::link::{self, remove, get_linker}; use super::command::Command; use super::symbol_export::ExportedSymbols; -use memmap; +use crate::traits::*; use rustc_incremental::{copy_cgu_workproducts_to_incr_comp_cache_dir, in_incr_comp_dir, in_incr_comp_dir_sess}; use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; @@ -16,7 +16,6 @@ use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Sanitize use rustc::session::Session; use rustc::util::nodemap::FxHashMap; use rustc::util::time_graph::{self, TimeGraph, Timeline}; -use traits::*; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::ty::TyCtxt; use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry}; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 84e55ce0f22c6..988e3bbd71d8a 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -13,7 +13,7 @@ //! but one llvm::Type corresponds to many `Ty`s; for instance, tup(int, int, //! int) and rec(x=int, y=int, z=int) will have the same llvm::Type. -use {ModuleCodegen, ModuleKind, CachedModuleCodegen}; +use crate::{ModuleCodegen, ModuleKind, CachedModuleCodegen}; use rustc::dep_graph::cgu_reuse_tracker::CguReuse; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -28,26 +28,26 @@ use rustc::util::common::{time, print_time_passes_entry}; use rustc::util::profiling::ProfileCategory; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; -use mir::place::PlaceRef; -use back::write::{OngoingCodegen, start_async_codegen, submit_pre_lto_module_to_llvm, - submit_post_lto_module_to_llvm}; -use {MemFlags, CrateInfo}; -use callee; use rustc_mir::monomorphize::item::DefPathBasedNames; -use common::{RealPredicate, TypeKind, IntPredicate}; -use meth; -use mir; use rustc::util::time_graph; use rustc_mir::monomorphize::Instance; use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt}; -use mono_item::MonoItem; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; use rustc_codegen_utils::{symbol_names_test, check_for_rustc_errors_attr}; use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; +use crate::mir::place::PlaceRef; +use crate::back::write::{OngoingCodegen, start_async_codegen, submit_pre_lto_module_to_llvm, + submit_post_lto_module_to_llvm}; +use crate::{MemFlags, CrateInfo}; +use crate::callee; +use crate::common::{RealPredicate, TypeKind, IntPredicate}; +use crate::meth; +use crate::mir; +use crate::mono_item::MonoItem; -use traits::*; +use crate::traits::*; use std::any::Any; use std::cmp; @@ -58,7 +58,7 @@ use syntax_pos::Span; use syntax::attr; use rustc::hir; -use mir::operand::OperandValue; +use crate::mir::operand::OperandValue; use std::marker::PhantomData; diff --git a/src/librustc_codegen_ssa/callee.rs b/src/librustc_codegen_ssa/callee.rs index aa13e525a73bf..3665d45d1e9c7 100644 --- a/src/librustc_codegen_ssa/callee.rs +++ b/src/librustc_codegen_ssa/callee.rs @@ -1,4 +1,4 @@ -use traits::*; +use crate::traits::*; use rustc::ty; use rustc::ty::subst::Substs; use rustc::hir::def_id::DefId; diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs index cfb5d24fc12ef..1b87f160cc35d 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/src/librustc_codegen_ssa/common.rs @@ -5,11 +5,11 @@ use syntax_pos::{DUMMY_SP, Span}; use rustc::hir::def_id::DefId; use rustc::middle::lang_items::LangItem; -use base; -use traits::*; +use crate::base; +use crate::traits::*; use rustc::hir; -use traits::BuilderMethods; +use crate::traits::BuilderMethods; pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) @@ -123,7 +123,7 @@ pub enum TypeKind { mod temp_stable_hash_impls { use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable}; - use ModuleCodegen; + use crate::ModuleCodegen; impl HashStable for ModuleCodegen { fn hash_stable(&self, diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs index ed63e1e62ee5f..e2b49de05bd11 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/src/librustc_codegen_ssa/glue.rs @@ -2,12 +2,10 @@ // // Code relating to drop glue. -use std; - -use common::IntPredicate; -use meth; use rustc::ty::{self, Ty}; -use traits::*; +use crate::common::IntPredicate; +use crate::meth; +use crate::traits::*; pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 58b3f0434a623..ad894bfe1cdf1 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -10,6 +10,9 @@ #![feature(nll)] #![allow(unused_attributes)] #![allow(dead_code)] +#![deny(rust_2018_idioms)] +#![allow(explicit_outlives_requirements)] +#![allow(elided_lifetimes_in_paths)] #![recursion_limit="256"] @@ -17,27 +20,9 @@ //! The backend-agnostic functions of this crate use functions defined in various traits that //! have to be implemented by each backends. -#[macro_use] extern crate bitflags; #[macro_use] extern crate log; -extern crate rustc_apfloat; -#[macro_use] extern crate rustc; -extern crate rustc_target; -extern crate rustc_mir; +#[macro_use] extern crate rustc; #[macro_use] extern crate syntax; -extern crate syntax_pos; -extern crate rustc_incremental; -extern crate rustc_codegen_utils; -extern crate rustc_data_structures; -extern crate rustc_allocator; -extern crate rustc_fs_util; -extern crate serialize; -extern crate rustc_errors; -extern crate rustc_demangle; -extern crate cc; -extern crate libc; -extern crate jobserver; -extern crate memmap; -extern crate num_cpus; use std::path::PathBuf; use rustc::dep_graph::WorkProduct; @@ -133,7 +118,7 @@ pub enum ModuleKind { Allocator, } -bitflags! { +bitflags::bitflags! { pub struct MemFlags: u8 { const VOLATILE = 1 << 0; const NONTEMPORAL = 1 << 1; diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 98ad2616eeaae..49f3c87ee2d9d 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -1,8 +1,8 @@ use rustc_target::abi::call::FnType; -use callee; use rustc_mir::monomorphize; -use traits::*; +use crate::callee; +use crate::traits::*; use rustc::ty::{self, Ty}; diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index f3475d1c48968..9fe2e58bc203c 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -10,7 +10,7 @@ use rustc::mir::traversal; use rustc::ty; use rustc::ty::layout::{LayoutOf, HasTyCtxt}; use super::FunctionCx; -use traits::*; +use crate::traits::*; pub fn non_ssa_locals<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx> diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index aa82c853257a3..af510d402eb8a 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -5,13 +5,13 @@ use rustc::mir; use rustc::mir::interpret::EvalErrorKind; use rustc_target::abi::call::{ArgType, FnType, PassMode}; use rustc_target::spec::abi::Abi; -use base; -use MemFlags; -use common::{self, IntPredicate}; -use meth; use rustc_mir::monomorphize; +use crate::base; +use crate::MemFlags; +use crate::common::{self, IntPredicate}; +use crate::meth; -use traits::*; +use crate::traits::*; use syntax::symbol::Symbol; use syntax_pos::Pos; diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 56d4342e6e161..6bc69efa4a7d5 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -6,7 +6,7 @@ use rustc::mir::interpret::GlobalId; use rustc::ty::{self, Ty}; use rustc::ty::layout; use syntax::source_map::Span; -use traits::*; +use crate::traits::*; use super::FunctionCx; diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index c7e2131eed5da..2e2cb3dd46717 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -4,11 +4,11 @@ use rustc::ty::layout::{TyLayout, HasTyCtxt}; use rustc::mir::{self, Mir}; use rustc::ty::subst::Substs; use rustc::session::config::DebugInfo; -use base; -use debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext}; use rustc_mir::monomorphize::Instance; use rustc_target::abi::call::{FnType, PassMode}; -use traits::*; +use crate::base; +use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext}; +use crate::traits::*; use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; use syntax::symbol::keywords; diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 8aad4c1f6e1c0..2c6d968bb032a 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -3,11 +3,11 @@ use rustc::mir; use rustc::ty; use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; -use base; -use MemFlags; -use glue; +use crate::base; +use crate::MemFlags; +use crate::glue; -use traits::*; +use crate::traits::*; use std::fmt; diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 596f97a038892..ffc774c38ea36 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -2,11 +2,11 @@ use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::mir; use rustc::mir::tcx::PlaceTy; -use MemFlags; -use common::IntPredicate; -use glue; +use crate::MemFlags; +use crate::common::IntPredicate; +use crate::glue; -use traits::*; +use crate::traits::*; use super::{FunctionCx, LocalRef}; use super::operand::OperandValue; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 9ca5414fa717e..25a7754d118d7 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -6,13 +6,13 @@ use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc_apfloat::{ieee, Float, Status, Round}; use std::{u128, i128}; -use base; -use MemFlags; -use callee; -use common::{self, RealPredicate, IntPredicate}; +use crate::base; +use crate::MemFlags; +use crate::callee; +use crate::common::{self, RealPredicate, IntPredicate}; use rustc_mir::monomorphize; -use traits::*; +use crate::traits::*; use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 9561a57d0a7de..a1bd919c43354 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -1,10 +1,10 @@ use rustc::mir; -use traits::BuilderMethods; +use crate::traits::BuilderMethods; use super::FunctionCx; use super::LocalRef; use super::OperandValue; -use traits::*; +use crate::traits::*; impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_statement( diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 8488ab2ae862f..bfb6a9153809a 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -1,10 +1,10 @@ -use base; use rustc::hir; use rustc::hir::def::Def; use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::layout::HasTyCtxt; use std::fmt; -use traits::*; +use crate::base; +use crate::traits::*; pub use rustc::mir::mono::MonoItem; diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs index 7fe16925a3f97..a95bf3af5bf27 100644 --- a/src/librustc_codegen_ssa/traits/asm.rs +++ b/src/librustc_codegen_ssa/traits/asm.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use mir::place::PlaceRef; +use crate::mir::place::PlaceRef; use rustc::hir::{GlobalAsm, InlineAsm}; pub trait AsmBuilderMethods<'tcx>: BackendTypes { diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index bc66087d3ce70..bda0f3dc77966 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -4,13 +4,14 @@ use super::debuginfo::DebugInfoBuilderMethods; use super::intrinsic::IntrinsicCallMethods; use super::type_::ArgTypeMethods; use super::{HasCodegen, StaticBuilderMethods}; -use common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope}; -use mir::operand::OperandRef; -use mir::place::PlaceRef; +use crate::common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, + SynchronizationScope}; +use crate::mir::operand::OperandRef; +use crate::mir::place::PlaceRef; +use crate::MemFlags; use rustc::ty::Ty; use rustc::ty::layout::{Align, Size}; use std::ffi::CStr; -use MemFlags; use std::borrow::Cow; use std::ops::Range; diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 482fb67e2b0c2..319f4b4e5e4b5 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use mir::place::PlaceRef; +use crate::mir::place::PlaceRef; use rustc::mir::interpret::Allocation; use rustc::mir::interpret::Scalar; use rustc::ty::layout; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 4163faa591462..0e606e744c629 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind}; +use crate::debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind}; use rustc::hir::def_id::CrateNum; use rustc::mir; use rustc::ty::{self, Ty}; diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs index a2d6b0550f8ca..3cd0c39d4139a 100644 --- a/src/librustc_codegen_ssa/traits/intrinsic.rs +++ b/src/librustc_codegen_ssa/traits/intrinsic.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use mir::operand::OperandRef; +use crate::mir::operand::OperandRef; use rustc::ty::Ty; use rustc_target::abi::call::FnType; use syntax_pos::Span; diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 2ec0c8e5a75cc..122aea035cea5 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -1,8 +1,8 @@ use super::misc::MiscMethods; use super::Backend; use super::HasCodegen; -use common::{self, TypeKind}; -use mir::place::PlaceRef; +use crate::common::{self, TypeKind}; +use crate::mir::place::PlaceRef; use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc::ty::{self, Ty}; use rustc::util::nodemap::FxHashMap; diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs index cea89a7f99b1b..e8ef815b32acb 100644 --- a/src/librustc_codegen_ssa/traits/write.rs +++ b/src/librustc_codegen_ssa/traits/write.rs @@ -1,6 +1,6 @@ -use back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; -use back::write::{CodegenContext, ModuleConfig}; -use {CompiledModule, ModuleCodegen}; +use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; +use crate::back::write::{CodegenContext, ModuleConfig}; +use crate::{CompiledModule, ModuleCodegen}; use rustc::dep_graph::WorkProduct; use rustc::util::time_graph::Timeline; From 66adf52e7dfd68f04e60744ea9bf130c45befe5e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 9 Feb 2019 15:44:54 +0100 Subject: [PATCH 0789/1064] miri: give non-generic functions a stable address --- src/librustc/mir/interpret/mod.rs | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index efd233f1f3854..bb25d1b42095a 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -27,7 +27,7 @@ pub use self::pointer::{Pointer, PointerArithmetic}; use std::fmt; use crate::mir; use crate::hir::def_id::DefId; -use crate::ty::{self, TyCtxt, Instance}; +use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind}; use crate::ty::layout::{self, Size}; use std::io; use crate::rustc_serialize::{Encoder, Decodable, Encodable}; @@ -318,14 +318,29 @@ impl<'tcx> AllocMap<'tcx> { id } - /// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated - /// by the linker and functions can be duplicated across crates. - /// We thus generate a new `AllocId` for every mention of a function. This means that - /// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true. pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId { - let id = self.reserve(); - self.id_to_kind.insert(id, AllocKind::Function(instance)); - id + // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated + // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be + // duplicated across crates. + // We thus generate a new `AllocId` for every mention of a function. This means that + // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true. + // However, formatting code relies on function identity (see #58320), so we only do + // this for generic functions. Lifetime parameters are ignored. + let is_generic = instance.substs.into_iter().any(|kind| { + match kind.unpack() { + UnpackedKind::Lifetime(_) => false, + _ => true, + } + }); + if is_generic { + // Get a fresh ID + let id = self.reserve(); + self.id_to_kind.insert(id, AllocKind::Function(instance)); + id + } else { + // Deduplicate + self.intern(AllocKind::Function(instance)) + } } /// Returns `None` in case the `AllocId` is dangling. An `EvalContext` can still have a From f06af1ff178014dadd62391a4a06e7fff8f2a6a1 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 7 Feb 2019 16:10:34 +0100 Subject: [PATCH 0790/1064] impl iter_sources() and iter_chain() for dyn Error Examples: ```rust let next_error_type_a = err .iter_chain() .filter_map(Error::downcast_ref::) .next(); ``` ```rust let source_root_error = err.iter_chain().last(); ``` Credit for the ErrorIter goes to Tim Diekmann https://www.reddit.com/r/rust/comments/aj3lpg/is_an_iterator_impl_over_errorsource_possible/ --- src/libstd/error.rs | 152 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 50415d9aeb9c8..de27333d28c64 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -667,6 +667,158 @@ impl dyn Error { Err(self) } } + + /// Returns an iterator starting with the current error and continuing with + /// recursively calling [`source`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(error_iter)] + /// use std::error::Error; + /// use std::fmt; + /// + /// #[derive(Debug)] + /// struct A; + /// + /// #[derive(Debug)] + /// struct B(Option>); + /// + /// impl fmt::Display for A { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "A") + /// } + /// } + /// + /// impl fmt::Display for B { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "B") + /// } + /// } + /// + /// impl Error for A {} + /// + /// impl Error for B { + /// fn source(&self) -> Option<&(dyn Error + 'static)> { + /// self.0.as_ref().map(|e| e.as_ref()) + /// } + /// } + /// + /// let b = B(Some(Box::new(A))); + /// + /// // let err : Box = b.into(); // or + /// let err = &b as &(dyn Error); + /// + /// let mut iter = err.iter_chain(); + /// + /// assert_eq!("B".to_string(), iter.next().unwrap().to_string()); + /// assert_eq!("A".to_string(), iter.next().unwrap().to_string()); + /// assert!(iter.next().is_none()); + /// assert!(iter.next().is_none()); + /// ``` + /// + /// [`source`]: trait.Error.html#method.source + #[unstable(feature = "error_iter", issue = "58289")] + #[inline] + pub fn iter_chain(&self) -> ErrorIter { + ErrorIter { + current: Some(self), + } + } + + /// Returns an iterator starting with the [`source`] of this error + /// and continuing with recursively calling [`source`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(error_iter)] + /// use std::error::Error; + /// use std::fmt; + /// + /// #[derive(Debug)] + /// struct A; + /// + /// #[derive(Debug)] + /// struct B(Option>); + /// + /// #[derive(Debug)] + /// struct C(Option>); + /// + /// impl fmt::Display for A { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "A") + /// } + /// } + /// + /// impl fmt::Display for B { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "B") + /// } + /// } + /// + /// impl fmt::Display for C { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "C") + /// } + /// } + /// + /// impl Error for A {} + /// + /// impl Error for B { + /// fn source(&self) -> Option<&(dyn Error + 'static)> { + /// self.0.as_ref().map(|e| e.as_ref()) + /// } + /// } + /// + /// impl Error for C { + /// fn source(&self) -> Option<&(dyn Error + 'static)> { + /// self.0.as_ref().map(|e| e.as_ref()) + /// } + /// } + /// + /// let b = B(Some(Box::new(A))); + /// let c = C(Some(Box::new(b))); + /// + /// // let err : Box = c.into(); // or + /// let err = &c as &(dyn Error); + /// + /// let mut iter = err.iter_sources(); + /// + /// assert_eq!("B".to_string(), iter.next().unwrap().to_string()); + /// assert_eq!("A".to_string(), iter.next().unwrap().to_string()); + /// assert!(iter.next().is_none()); + /// assert!(iter.next().is_none()); + /// ``` + /// + /// [`source`]: trait.Error.html#method.source + #[inline] + #[unstable(feature = "error_iter", issue = "58289")] + pub fn iter_sources(&self) -> ErrorIter { + ErrorIter { + current: self.source(), + } + } +} + +/// An iterator over [`Error`] +/// +/// [`Error`]: trait.Error.html +#[unstable(feature = "error_iter", issue = "58289")] +#[derive(Copy, Clone, Debug)] +pub struct ErrorIter<'a> { + current: Option<&'a (dyn Error + 'static)>, +} + +#[unstable(feature = "error_iter", issue = "58289")] +impl<'a> Iterator for ErrorIter<'a> { + type Item = &'a (dyn Error + 'static); + + fn next(&mut self) -> Option { + let current = self.current; + self.current = self.current.and_then(Error::source); + current + } } impl dyn Error + Send { From 3a1a704903e5e671032811a2dc6fc958663bf4d7 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 4 Feb 2019 09:38:11 +0100 Subject: [PATCH 0791/1064] cleanup: rename node_id_to_type(_opt) --- .../infer/error_reporting/need_type_info.rs | 4 ++-- .../error_reporting/nice_region_error/util.rs | 2 +- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/mem_categorization.rs | 4 ++-- src/librustc/ty/context.rs | 21 ++++++++----------- src/librustc/ty/item_path.rs | 1 - .../borrowck/gather_loans/mod.rs | 2 +- src/librustc_lint/builtin.rs | 4 ++-- src/librustc_lint/types.rs | 6 +++--- src/librustc_metadata/encoder.rs | 2 +- .../borrow_check/error_reporting.rs | 2 +- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/build/mod.rs | 4 ++-- src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 14 ++++++------- src/librustc_mir/hair/pattern/check_match.rs | 6 +++--- src/librustc_mir/hair/pattern/mod.rs | 6 +++--- src/librustc_mir/hair/util.rs | 2 +- src/librustc_passes/rvalue_promotion.rs | 4 ++-- src/librustc_privacy/lib.rs | 4 ++-- src/librustc_save_analysis/dump_visitor.rs | 8 +++---- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- 24 files changed, 52 insertions(+), 56 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index fac498bd6dd78..e63fa230b3eba 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -16,9 +16,9 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { } impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { - fn node_matches_type(&mut self, node_id: HirId) -> bool { + fn node_matches_type(&mut self, hir_id: HirId) -> bool { let ty_opt = self.infcx.in_progress_tables.and_then(|tables| { - tables.borrow().node_id_to_type_opt(node_id) + tables.borrow().node_type_opt(hir_id) }); match ty_opt { Some(ty) => { diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index f73f8d8bb82be..6db1bc382afe9 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -64,7 +64,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { // May return None; sometimes the tables are not yet populated. let ty_hir_id = fn_decl.inputs[index].hir_id; let arg_ty_span = hir.span(hir.hir_to_node_id(ty_hir_id)); - let ty = tables.node_id_to_type_opt(arg.hir_id)?; + let ty = tables.node_type_opt(arg.hir_id)?; let mut found_anon_region = false; let new_arg_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| { if *r == *anon_region { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 6dffe8efba612..569968bd6d4bf 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def, pats: &[source_map::Spanned]) { - let variant = match self.tables.node_id_to_type(lhs.hir_id).sty { + let variant = match self.tables.node_type(lhs.hir_id).sty { ty::Adt(adt, _) => adt.variant_of_def(def), _ => span_bug!(lhs.span, "non-ADT in struct pattern") }; diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index ee361e9776313..ce20ca39533b1 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -165,7 +165,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> { }; if let Def::Fn(did) = def { if self.def_id_is_transmute(did) { - let typ = self.tables.node_id_to_type(expr.hir_id); + let typ = self.tables.node_type(expr.hir_id); let sig = typ.fn_sig(self.tcx); let from = sig.inputs().skip_binder()[0]; let to = *sig.output().skip_binder(); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 04e4a0b39a2ca..edc2a112b95ed 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -174,7 +174,7 @@ pub enum Note { // which the value is stored. // // *WARNING* The field `cmt.type` is NOT necessarily the same as the -// result of `node_id_to_type(cmt.id)`. +// result of `node_type(cmt.id)`. // // (FIXME: rewrite the following comment given that `@x` managed // pointers have been obsolete for quite some time.) @@ -497,7 +497,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { hir_id: hir::HirId) -> McResult> { self.resolve_type_vars_or_error(hir_id, - self.tables.node_id_to_type_opt(hir_id)) + self.tables.node_type_opt(hir_id)) } pub fn expr_ty(&self, expr: &hir::Expr) -> McResult> { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c955b042e44d1..6934373e981c8 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -525,17 +525,14 @@ impl<'tcx> TypeckTables<'tcx> { } } - pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> { - self.node_id_to_type_opt(id).unwrap_or_else(|| - bug!("node_id_to_type: no type for node `{}`", - tls::with(|tcx| { - let id = tcx.hir().hir_to_node_id(id); - tcx.hir().node_to_string(id) - })) + pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> { + self.node_type_opt(id).unwrap_or_else(|| + bug!("node_type: no type for node `{}`", + tls::with(|tcx| tcx.hir().hir_to_string(id))) ) } - pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option> { + pub fn node_type_opt(&self, id: hir::HirId) -> Option> { validate_hir_id_for_typeck_tables(self.local_id_root, id, false); self.node_types.get(&id.local_id).cloned() } @@ -560,11 +557,11 @@ impl<'tcx> TypeckTables<'tcx> { // Returns the type of a pattern as a monotype. Like @expr_ty, this function // doesn't provide type parameter substitutions. pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> { - self.node_id_to_type(pat.hir_id) + self.node_type(pat.hir_id) } pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option> { - self.node_id_to_type_opt(pat.hir_id) + self.node_type_opt(pat.hir_id) } // Returns the type of an expression as a monotype. @@ -578,11 +575,11 @@ impl<'tcx> TypeckTables<'tcx> { // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize" // instead of "fn(ty) -> T with T = isize". pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> { - self.node_id_to_type(expr.hir_id) + self.node_type(expr.hir_id) } pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option> { - self.node_id_to_type_opt(expr.hir_id) + self.node_type_opt(expr.hir_id) } pub fn adjustments(&self) -> LocalTableInContext<'_, Vec>> { diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 8214c8bacc704..df09cf629d407 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -1,4 +1,3 @@ -use crate::hir; use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index c21a43bc68333..ee3aabe89d004 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) { let ty = self.bccx .tables - .node_id_to_type(self.bccx.tcx.hir().node_to_hir_id(id)); + .node_type(self.bccx.tcx.hir().node_to_hir_id(id)); gather_moves::gather_decl(self.bccx, &self.move_data, id, ty); } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index cbcc7f3574d03..442e54dc48696 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -155,7 +155,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { } fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { - let ty = cx.tables.node_id_to_type(e.hir_id); + let ty = cx.tables.node_type(e.hir_id); self.check_heap_type(cx, e.span, ty); } } @@ -1000,7 +1000,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { if !def_id_is_transmute(cx, did) { return None; } - let sig = cx.tables.node_id_to_type(expr.hir_id).fn_sig(cx.tcx); + let sig = cx.tables.node_type(expr.hir_id).fn_sig(cx.tcx); let from = sig.inputs().skip_binder()[0]; let to = *sig.output().skip_binder(); return Some((&from.sty, &to.sty)); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index f6b7ccfe2ecd8..3e02c14fc1baf 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -85,7 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } hir::ExprKind::Lit(ref lit) => { - match cx.tables.node_id_to_type(e.hir_id).sty { + match cx.tables.node_type(e.hir_id).sty { ty::Int(t) => { match lit.node { ast::LitKind::Int(v, ast::LitIntType::Signed(_)) | @@ -257,7 +257,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { // Normalize the binop so that the literal is always on the RHS in // the comparison let norm_binop = if swap { rev_binop(binop) } else { binop }; - match cx.tables.node_id_to_type(expr.hir_id).sty { + match cx.tables.node_type(expr.hir_id).sty { ty::Int(int_ty) => { let (min, max) = int_ty_range(int_ty); let lit_val: i128 = match lit.node { @@ -400,7 +400,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { repr_str, val, t, actually, t )); if let Some(sugg_ty) = - get_type_suggestion(&cx.tables.node_id_to_type(expr.hir_id).sty, val, negative) + get_type_suggestion(&cx.tables.node_type(expr.hir_id).sty, val, negative) { if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { let (sans_suffix, _) = repr_str.split_at(pos); diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d68ab9750b970..ec49ef3f6e046 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1338,7 +1338,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let tables = self.tcx.typeck_tables_of(def_id); let node_id = self.tcx.hir().as_local_node_id(def_id).unwrap(); let hir_id = self.tcx.hir().node_to_hir_id(node_id); - let kind = match tables.node_id_to_type(hir_id).sty { + let kind = match tables.node_type(hir_id).sty { ty::Generator(def_id, ..) => { let layout = self.tcx.generator_layout(def_id); let data = GeneratorData { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index afb26963217ff..c7d3bf14f5e0c 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1178,7 +1178,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let escapes_from = if tcx.is_closure(self.mir_def_id) { let tables = tcx.typeck_tables_of(self.mir_def_id); let mir_hir_id = tcx.hir().def_index_to_hir_id(self.mir_def_id.index); - match tables.node_id_to_type(mir_hir_id).sty { + match tables.node_type(mir_hir_id).sty { ty::Closure(..) => "closure", ty::Generator(..) => "generator", _ => bug!("Closure body doesn't have a closure or generator type"), diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 0a214e60bdd78..cdd0c6f807595 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -482,7 +482,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { tcx.type_of(closure_base_def_id) } else { let tables = tcx.typeck_tables_of(self.mir_def_id); - tables.node_id_to_type(self.mir_hir_id) + tables.node_type(self.mir_hir_id) }; debug!("defining_ty (pre-replacement): {:?}", defining_ty); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index a52b032aeb508..dfe9c16cb5893 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -92,7 +92,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)) } ty::Generator(..) => { - let gen_ty = tcx.body_tables(body_id).node_id_to_type(fn_hir_id); + let gen_ty = tcx.body_tables(body_id).node_type(fn_hir_id); Some(ArgInfo(gen_ty, None, None, None)) } _ => None, @@ -263,7 +263,7 @@ fn liberated_closure_env_ty<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, body_id: hir::BodyId) -> Ty<'tcx> { let closure_expr_hir_id = tcx.hir().node_to_hir_id(closure_expr_id); - let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_hir_id); + let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_hir_id); let (closure_def_id, closure_substs) = match closure_ty.sty { ty::Closure(closure_def_id, closure_substs) => (closure_def_id, closure_substs), diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index c24cf956504da..4e7bfbc4ab5d2 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -115,7 +115,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { - let block_ty = cx.tables().node_id_to_type(block.hir_id); + let block_ty = cx.tables().node_type(block.hir_id); let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id); let expr = Expr { ty: block_ty, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 7e1365f5dc12d..10d04a80d7341 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -304,7 +304,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } else { ExprKind::Call { - ty: cx.tables().node_id_to_type(fun.hir_id), + ty: cx.tables().node_type(fun.hir_id), fun: fun.to_ref(), args: args.to_ref(), from_hir_call: true, @@ -677,7 +677,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let def = cx.tables().qpath_def(qpath, source.hir_id); cx .tables() - .node_id_to_type(source.hir_id) + .node_type(source.hir_id) .ty_adt_def() .and_then(|adt_def| { match def { @@ -919,7 +919,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, debug!("convert_path_expr: user_ty={:?}", user_ty); ExprKind::Literal { literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized( - cx.tables().node_id_to_type(expr.hir_id), + cx.tables().node_type(expr.hir_id), ))), user_ty, } @@ -940,7 +940,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_provided_types = cx.tables.user_provided_types(); let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty); debug!("convert_path_expr: user_provided_type={:?}", user_provided_type); - match cx.tables().node_id_to_type(expr.hir_id).sty { + match cx.tables().node_type(expr.hir_id).sty { // A unit struct/variant which is used as a value. // We return a completely different ExprKind here to account for this special case. ty::Adt(adt_def, substs) => { @@ -980,11 +980,11 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, index, closure_expr_id); let var_hir_id = cx.tcx.hir().node_to_hir_id(var_id); - let var_ty = cx.tables().node_id_to_type(var_hir_id); + let var_ty = cx.tables().node_type(var_hir_id); // FIXME free regions in closures are not right let closure_ty = cx.tables() - .node_id_to_type(cx.tcx.hir().node_to_hir_id(closure_expr_id)); + .node_type(cx.tcx.hir().node_to_hir_id(closure_expr_id)); // FIXME we're just hard-coding the idea that the // signature will be &self or &mut self and hence will @@ -1188,7 +1188,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }; let upvar_capture = cx.tables().upvar_capture(upvar_id); let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); - let var_ty = cx.tables().node_id_to_type(var_hir_id); + let var_ty = cx.tables().node_type(var_hir_id); let captured_var = Expr { temp_lifetime, ty: var_ty, diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 978051aab591b..5616a5c2feeba 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -202,7 +202,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { // Then, if the match has no arms, check whether the scrutinee // is uninhabited. - let pat_ty = self.tables.node_id_to_type(scrut.hir_id); + let pat_ty = self.tables.node_type(scrut.hir_id); let module = self.tcx.hir().get_module_parent(scrut.id); if inlined_arms.is_empty() { let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns { @@ -235,7 +235,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { .flat_map(|arm| &arm.0) .map(|pat| smallvec![pat.0]) .collect(); - let scrut_ty = self.tables.node_id_to_type(scrut.hir_id); + let scrut_ty = self.tables.node_type(scrut.hir_id); check_exhaustive(cx, scrut_ty, scrut.span, &matrix); }) } @@ -507,7 +507,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor<'_, '_>, if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { match bm { ty::BindByValue(..) => { - let pat_ty = cx.tables.node_id_to_type(p.hir_id); + let pat_ty = cx.tables.node_type(p.hir_id); if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { check_move(p, sub.as_ref().map(|p| &**p), span_vec); } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 84d8f32954c81..18e1af27bab38 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -406,7 +406,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> { - let mut ty = self.tables.node_id_to_type(pat.hir_id); + let mut ty = self.tables.node_type(pat.hir_id); let kind = match pat.node { PatKind::Wild => PatternKind::Wild, @@ -539,7 +539,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } PatKind::Binding(_, id, _, ident, ref sub) => { - let var_ty = self.tables.node_id_to_type(pat.hir_id); + let var_ty = self.tables.node_type(pat.hir_id); if let ty::Error = var_ty.sty { // Avoid ICE return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) }; @@ -773,7 +773,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { id: hir::HirId, span: Span) -> Pattern<'tcx> { - let ty = self.tables.node_id_to_type(id); + let ty = self.tables.node_type(id); let def = self.tables.qpath_def(qpath, id); let is_associated_const = match def { Def::AssociatedConst(_) => true, diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index cb4a72387fa16..4618cd42686fa 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -16,7 +16,7 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { let user_provided_types = self.tables().user_provided_types(); let mut user_ty = *user_provided_types.get(hir_id)?; debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty); - match &self.tables().node_id_to_type(hir_id).sty { + match &self.tables().node_type(hir_id).sty { ty::Adt(adt_def, ..) => { if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value { *did = adt_def.did; diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 8d33fef5303ed..7f245c48166d6 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -244,7 +244,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { } fn check_expr(&mut self, ex: &'tcx hir::Expr) -> Promotability { - let node_ty = self.tables.node_id_to_type(ex.hir_id); + let node_ty = self.tables.node_type(ex.hir_id); let mut outer = check_expr_kind(self, ex, node_ty); outer &= check_adjustments(self, ex); @@ -306,7 +306,7 @@ fn check_expr_kind<'a, 'tcx>( if v.tables.is_method_call(e) { return NotPromotable; } - match v.tables.node_id_to_type(lhs.hir_id).sty { + match v.tables.node_type(lhs.hir_id).sty { ty::RawPtr(_) | ty::FnPtr(..) => { assert!(op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne || op.node == hir::BinOpKind::Le || op.node == hir::BinOpKind::Lt || diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 14a0922c47740..c395dffdc9799 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -932,7 +932,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> { // Take node-id of an expression or pattern and check its type for privacy. fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool { self.span = span; - if self.visit(self.tables.node_id_to_type(id)) || self.visit(self.tables.node_substs(id)) { + if self.visit(self.tables.node_type(id)) || self.visit(self.tables.node_substs(id)) { return true; } if let Some(adjustments) = self.tables.adjustments().get(id) { @@ -979,7 +979,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { self.span = hir_ty.span; if self.in_body { // Types in bodies. - if self.visit(self.tables.node_id_to_type(hir_ty.hir_id)) { + if self.visit(self.tables.node_type(hir_ty.hir_id)) { return; } } else { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 1a49056bc7f26..0bb1ce9e4bde9 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -245,7 +245,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { for (id, ident, ..) in collector.collected_idents { let hir_id = self.tcx.hir().node_to_hir_id(id); - let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) { + let typ = match self.save_ctxt.tables.node_type_opt(hir_id) { Some(s) => s.to_string(), None => continue, }; @@ -863,7 +863,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { PatKind::Struct(ref _path, ref fields, _) => { // FIXME do something with _path? let hir_id = self.tcx.hir().node_to_hir_id(p.id); - let adt = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) { + let adt = match self.save_ctxt.tables.node_type_opt(hir_id) { Some(ty) => ty.ty_adt_def().unwrap(), None => { visit::walk_pat(self, p); @@ -910,7 +910,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let hir_id = self.tcx.hir().node_to_hir_id(id); let typ = self.save_ctxt .tables - .node_id_to_type_opt(hir_id) + .node_type_opt(hir_id) .map(|t| t.to_string()) .unwrap_or_default(); value.push_str(": "); @@ -979,7 +979,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { _ => String::new(), }; let hir_id = self.tcx.hir().node_to_hir_id(id); - let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) { + let typ = match self.save_ctxt.tables.node_type_opt(hir_id) { Some(typ) => { let typ = typ.to_string(); if !value.is_empty() { diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 0d4690c83170a..cc04f84440af1 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -224,7 +224,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { node: hir::ExprKind::MethodCall(path, span, expr), .. })), 1) = (self.tcx.hir().find(parent), decl.inputs.len()) { - let self_ty = self.tables.borrow().node_id_to_type(expr[0].hir_id); + let self_ty = self.tables.borrow().node_type(expr[0].hir_id); let self_ty = format!("{:?}", self_ty); let name = path.ident.as_str(); let is_as_ref_able = ( diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 9dc74c5d63a4e..1c45a75cf4052 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1253,7 +1253,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> { }) => { if gen.is_some() { let hir_id = tcx.hir().node_to_hir_id(node_id); - return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id); + return tcx.typeck_tables_of(def_id).node_type(hir_id); } let substs = ty::ClosureSubsts { From eb669b3a83dc1c1195ade3bff7f237afdd569ba2 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Thu, 7 Feb 2019 12:35:40 +0100 Subject: [PATCH 0792/1064] cleanup: remove hir_path_str --- src/librustc/ty/item_path.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index df09cf629d407..388eafb826fb1 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -76,11 +76,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.item_path_str(self.hir().local_def_id(id)) } - // FIXME(@ljedrz): replace the NodeId variant - pub fn hir_path_str(self, id: hir::HirId) -> String { - self.item_path_str(self.hir().local_def_id_from_hir_id(id)) - } - /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String { From 0a16b8754abe419f8541788c1092e4ef91fcf137 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 9 Feb 2019 16:29:31 +0000 Subject: [PATCH 0793/1064] Use ? in librustc macros --- src/librustc/macros.rs | 56 +++-- src/librustc/mir/visit.rs | 450 +++++++++++++++++++------------------- 2 files changed, 246 insertions(+), 260 deletions(-) diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index 2978b35319944..ccae9d3ad5a82 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -62,38 +62,36 @@ macro_rules! __impl_stable_hash_field { #[macro_export] macro_rules! impl_stable_hash_for { // Enums - // FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change - // them back when `?` is supported again. (enum $enum_name:path { $( $variant:ident // this incorrectly allows specifying both tuple-like and struct-like fields, as in `Variant(a,b){c,d}`, // when it should be only one or the other - $( ( $($field:ident $(-> $delegate:tt)*),* ) )* - $( { $($named_field:ident $(-> $named_delegate:tt)*),* } )* - ),* $(,)* + $( ( $($field:ident $(-> $delegate:tt)?),* ) )? + $( { $($named_field:ident $(-> $named_delegate:tt)?),* } )? + ),* $(,)? }) => { impl_stable_hash_for!( impl<> for enum $enum_name [ $enum_name ] { $( $variant - $( ( $($field $(-> $delegate)*),* ) )* - $( { $($named_field $(-> $named_delegate)*),* } )* + $( ( $($field $(-> $delegate)?),* ) )? + $( { $($named_field $(-> $named_delegate)?),* } )? ),* } ); }; // We want to use the enum name both in the `impl ... for $enum_name` as well as for // importing all the variants. Unfortunately it seems we have to take the name // twice for this purpose - (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> + (impl<$($lt:lifetime $(: $lt_bound:lifetime)? ),* $(,)? $($T:ident),* $(,)?> for enum $enum_name:path [ $enum_path:path ] { $( $variant:ident // this incorrectly allows specifying both tuple-like and struct-like fields, as in `Variant(a,b){c,d}`, // when it should be only one or the other - $( ( $($field:ident $(-> $delegate:tt)*),* ) )* - $( { $($named_field:ident $(-> $named_delegate:tt)*),* } )* - ),* $(,)* + $( ( $($field:ident $(-> $delegate:tt)?),* ) )? + $( { $($named_field:ident $(-> $named_delegate:tt)?),* } )? + ),* $(,)? }) => { - impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*> + impl<'a, $($lt $(: $lt_bound)?,)* $($T,)*> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),* @@ -107,9 +105,9 @@ macro_rules! impl_stable_hash_for { match *self { $( - $variant $( ( $(ref $field),* ) )* $( { $(ref $named_field),* } )* => { - $($( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*)* - $($( __impl_stable_hash_field!($named_field, __ctx, __hasher $(, $named_delegate)*) );*)* + $variant $( ( $(ref $field),* ) )? $( { $(ref $named_field),* } )? => { + $($( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)?) );*)? + $($( __impl_stable_hash_field!($named_field, __ctx, __hasher $(, $named_delegate)?) );*)? } )* } @@ -117,16 +115,15 @@ macro_rules! impl_stable_hash_for { } }; // Structs - // FIXME(mark-i-m): same here. - (struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => { + (struct $struct_name:path { $($field:ident $(-> $delegate:tt)?),* $(,)? }) => { impl_stable_hash_for!( - impl<'tcx> for struct $struct_name { $($field $(-> $delegate)*),* } + impl<'tcx> for struct $struct_name { $($field $(-> $delegate)?),* } ); }; - (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> for struct $struct_name:path { - $($field:ident $(-> $delegate:tt)*),* $(,)* + (impl<$($lt:lifetime $(: $lt_bound:lifetime)? ),* $(,)? $($T:ident),* $(,)?> for struct $struct_name:path { + $($field:ident $(-> $delegate:tt)?),* $(,)? }) => { - impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*> + impl<'a, $($lt $(: $lt_bound)?,)* $($T,)*> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),* { @@ -138,21 +135,20 @@ macro_rules! impl_stable_hash_for { $(ref $field),* } = *self; - $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );* + $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)?) );* } } }; // Tuple structs - // We cannot use normale parentheses here, the parser won't allow it - // FIXME(mark-i-m): same here. - (tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => { + // We cannot use normal parentheses here, the parser won't allow it + (tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)?),* $(,)? }) => { impl_stable_hash_for!( - impl<'tcx> for tuple_struct $struct_name { $($field $(-> $delegate)*),* } + impl<'tcx> for tuple_struct $struct_name { $($field $(-> $delegate)?),* } ); }; - (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> - for tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => { - impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*> + (impl<$($lt:lifetime $(: $lt_bound:lifetime)? ),* $(,)? $($T:ident),* $(,)?> + for tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)?),* $(,)? }) => { + impl<'a, $($lt $(: $lt_bound)?,)* $($T,)*> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),* { @@ -164,7 +160,7 @@ macro_rules! impl_stable_hash_for { $(ref $field),* ) = *self; - $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );* + $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)?) );* } } }; diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 0180256661630..e5828039ac29c 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -38,10 +38,10 @@ use syntax_pos::Span; // ```rust // fn super_basic_block_data(&mut self, // block: BasicBlock, -// data: & $($mutability)* BasicBlockData<'tcx>) { +// data: & $($mutability)? BasicBlockData<'tcx>) { // let BasicBlockData { -// ref $($mutability)* statements, -// ref $($mutability)* terminator, +// statements, +// terminator, // is_cleanup: _ // } = *data; // @@ -67,111 +67,111 @@ use syntax_pos::Span; // `is_cleanup` above. macro_rules! make_mir_visitor { - ($visitor_trait_name:ident, $($mutability:ident)*) => { + ($visitor_trait_name:ident, $($mutability:ident)?) => { pub trait $visitor_trait_name<'tcx> { // Override these, and call `self.super_xxx` to revert back to the // default behavior. - fn visit_mir(&mut self, mir: & $($mutability)* Mir<'tcx>) { + fn visit_mir(&mut self, mir: & $($mutability)? Mir<'tcx>) { self.super_mir(mir); } fn visit_basic_block_data(&mut self, block: BasicBlock, - data: & $($mutability)* BasicBlockData<'tcx>) { + data: & $($mutability)? BasicBlockData<'tcx>) { self.super_basic_block_data(block, data); } fn visit_source_scope_data(&mut self, - scope_data: & $($mutability)* SourceScopeData) { + scope_data: & $($mutability)? SourceScopeData) { self.super_source_scope_data(scope_data); } fn visit_statement(&mut self, block: BasicBlock, - statement: & $($mutability)* Statement<'tcx>, + statement: & $($mutability)? Statement<'tcx>, location: Location) { self.super_statement(block, statement, location); } fn visit_assign(&mut self, block: BasicBlock, - place: & $($mutability)* Place<'tcx>, - rvalue: & $($mutability)* Rvalue<'tcx>, + place: & $($mutability)? Place<'tcx>, + rvalue: & $($mutability)? Rvalue<'tcx>, location: Location) { self.super_assign(block, place, rvalue, location); } fn visit_terminator(&mut self, block: BasicBlock, - terminator: & $($mutability)* Terminator<'tcx>, + terminator: & $($mutability)? Terminator<'tcx>, location: Location) { self.super_terminator(block, terminator, location); } fn visit_terminator_kind(&mut self, block: BasicBlock, - kind: & $($mutability)* TerminatorKind<'tcx>, + kind: & $($mutability)? TerminatorKind<'tcx>, location: Location) { self.super_terminator_kind(block, kind, location); } fn visit_assert_message(&mut self, - msg: & $($mutability)* AssertMessage<'tcx>, + msg: & $($mutability)? AssertMessage<'tcx>, location: Location) { self.super_assert_message(msg, location); } fn visit_rvalue(&mut self, - rvalue: & $($mutability)* Rvalue<'tcx>, + rvalue: & $($mutability)? Rvalue<'tcx>, location: Location) { self.super_rvalue(rvalue, location); } fn visit_operand(&mut self, - operand: & $($mutability)* Operand<'tcx>, + operand: & $($mutability)? Operand<'tcx>, location: Location) { self.super_operand(operand, location); } fn visit_ascribe_user_ty(&mut self, - place: & $($mutability)* Place<'tcx>, - variance: & $($mutability)* ty::Variance, - user_ty: & $($mutability)* UserTypeProjection<'tcx>, + place: & $($mutability)? Place<'tcx>, + variance: & $($mutability)? ty::Variance, + user_ty: & $($mutability)? UserTypeProjection<'tcx>, location: Location) { self.super_ascribe_user_ty(place, variance, user_ty, location); } fn visit_retag(&mut self, - kind: & $($mutability)* RetagKind, - place: & $($mutability)* Place<'tcx>, + kind: & $($mutability)? RetagKind, + place: & $($mutability)? Place<'tcx>, location: Location) { self.super_retag(kind, place, location); } fn visit_place(&mut self, - place: & $($mutability)* Place<'tcx>, + place: & $($mutability)? Place<'tcx>, context: PlaceContext<'tcx>, location: Location) { self.super_place(place, context, location); } fn visit_static(&mut self, - static_: & $($mutability)* Static<'tcx>, + static_: & $($mutability)? Static<'tcx>, context: PlaceContext<'tcx>, location: Location) { self.super_static(static_, context, location); } fn visit_projection(&mut self, - place: & $($mutability)* PlaceProjection<'tcx>, + place: & $($mutability)? PlaceProjection<'tcx>, context: PlaceContext<'tcx>, location: Location) { self.super_projection(place, context, location); } fn visit_projection_elem(&mut self, - place: & $($mutability)* PlaceElem<'tcx>, + place: & $($mutability)? PlaceElem<'tcx>, location: Location) { self.super_projection_elem(place, location); } @@ -183,36 +183,36 @@ macro_rules! make_mir_visitor { } fn visit_constant(&mut self, - constant: & $($mutability)* Constant<'tcx>, + constant: & $($mutability)? Constant<'tcx>, location: Location) { self.super_constant(constant, location); } fn visit_def_id(&mut self, - def_id: & $($mutability)* DefId, + def_id: & $($mutability)? DefId, _: Location) { self.super_def_id(def_id); } fn visit_span(&mut self, - span: & $($mutability)* Span) { + span: & $($mutability)? Span) { self.super_span(span); } fn visit_source_info(&mut self, - source_info: & $($mutability)* SourceInfo) { + source_info: & $($mutability)? SourceInfo) { self.super_source_info(source_info); } fn visit_ty(&mut self, - ty: & $($mutability)* Ty<'tcx>, + ty: & $($mutability)? Ty<'tcx>, _: TyContext) { self.super_ty(ty); } fn visit_user_type_projection( &mut self, - ty: & $($mutability)* UserTypeProjection<'tcx>, + ty: & $($mutability)? UserTypeProjection<'tcx>, ) { self.super_user_type_projection(ty); } @@ -220,55 +220,55 @@ macro_rules! make_mir_visitor { fn visit_user_type_annotation( &mut self, index: UserTypeAnnotationIndex, - ty: & $($mutability)* CanonicalUserTypeAnnotation<'tcx>, + ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>, ) { self.super_user_type_annotation(index, ty); } fn visit_region(&mut self, - region: & $($mutability)* ty::Region<'tcx>, + region: & $($mutability)? ty::Region<'tcx>, _: Location) { self.super_region(region); } fn visit_const(&mut self, - constant: & $($mutability)* &'tcx ty::LazyConst<'tcx>, + constant: & $($mutability)? &'tcx ty::LazyConst<'tcx>, _: Location) { self.super_const(constant); } fn visit_substs(&mut self, - substs: & $($mutability)* &'tcx Substs<'tcx>, + substs: & $($mutability)? &'tcx Substs<'tcx>, _: Location) { self.super_substs(substs); } fn visit_closure_substs(&mut self, - substs: & $($mutability)* ClosureSubsts<'tcx>, + substs: & $($mutability)? ClosureSubsts<'tcx>, _: Location) { self.super_closure_substs(substs); } fn visit_generator_substs(&mut self, - substs: & $($mutability)* GeneratorSubsts<'tcx>, + substs: & $($mutability)? GeneratorSubsts<'tcx>, _: Location) { self.super_generator_substs(substs); } fn visit_local_decl(&mut self, local: Local, - local_decl: & $($mutability)* LocalDecl<'tcx>) { + local_decl: & $($mutability)? LocalDecl<'tcx>) { self.super_local_decl(local, local_decl); } fn visit_local(&mut self, - _local: & $($mutability)* Local, + _local: & $($mutability)? Local, _context: PlaceContext<'tcx>, _location: Location) { } fn visit_source_scope(&mut self, - scope: & $($mutability)* SourceScope) { + scope: & $($mutability)? SourceScope) { self.super_source_scope(scope); } @@ -276,8 +276,8 @@ macro_rules! make_mir_visitor { // not meant to be overridden. fn super_mir(&mut self, - mir: & $($mutability)* Mir<'tcx>) { - if let Some(yield_ty) = &$($mutability)* mir.yield_ty { + mir: & $($mutability)? Mir<'tcx>) { + if let Some(yield_ty) = &$($mutability)? mir.yield_ty { self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo { span: mir.span, scope: OUTERMOST_SOURCE_SCOPE, @@ -291,21 +291,21 @@ macro_rules! make_mir_visitor { (mut) => (mir.basic_blocks_mut().iter_enumerated_mut()); () => (mir.basic_blocks().iter_enumerated()); }; - for (bb, data) in basic_blocks!($($mutability)*) { + for (bb, data) in basic_blocks!($($mutability)?) { self.visit_basic_block_data(bb, data); } - for scope in &$($mutability)* mir.source_scopes { + for scope in &$($mutability)? mir.source_scopes { self.visit_source_scope_data(scope); } - self.visit_ty(&$($mutability)* mir.return_ty(), TyContext::ReturnTy(SourceInfo { + self.visit_ty(&$($mutability)? mir.return_ty(), TyContext::ReturnTy(SourceInfo { span: mir.span, scope: OUTERMOST_SOURCE_SCOPE, })); for local in mir.local_decls.indices() { - self.visit_local_decl(local, & $($mutability)* mir.local_decls[local]); + self.visit_local_decl(local, & $($mutability)? mir.local_decls[local]); } macro_rules! type_annotations { @@ -313,23 +313,23 @@ macro_rules! make_mir_visitor { () => (mir.user_type_annotations.iter_enumerated()); }; - for (index, annotation) in type_annotations!($($mutability)*) { + for (index, annotation) in type_annotations!($($mutability)?) { self.visit_user_type_annotation( index, annotation ); } - self.visit_span(&$($mutability)* mir.span); + self.visit_span(&$($mutability)? mir.span); } fn super_basic_block_data(&mut self, block: BasicBlock, - data: & $($mutability)* BasicBlockData<'tcx>) { + data: & $($mutability)? BasicBlockData<'tcx>) { let BasicBlockData { - ref $($mutability)* statements, - ref $($mutability)* terminator, + statements, + terminator, is_cleanup: _ - } = *data; + } = data; let mut index = 0; for statement in statements { @@ -338,92 +338,83 @@ macro_rules! make_mir_visitor { index += 1; } - if let Some(ref $($mutability)* terminator) = *terminator { + if let Some(terminator) = terminator { let location = Location { block: block, statement_index: index }; self.visit_terminator(block, terminator, location); } } - fn super_source_scope_data(&mut self, - scope_data: & $($mutability)* SourceScopeData) { + fn super_source_scope_data(&mut self, scope_data: & $($mutability)? SourceScopeData) { let SourceScopeData { - ref $($mutability)* span, - ref $($mutability)* parent_scope, - } = *scope_data; + span, + parent_scope, + } = scope_data; self.visit_span(span); - if let Some(ref $($mutability)* parent_scope) = *parent_scope { + if let Some(parent_scope) = parent_scope { self.visit_source_scope(parent_scope); } } fn super_statement(&mut self, block: BasicBlock, - statement: & $($mutability)* Statement<'tcx>, + statement: & $($mutability)? Statement<'tcx>, location: Location) { let Statement { - ref $($mutability)* source_info, - ref $($mutability)* kind, - } = *statement; + source_info, + kind, + } = statement; self.visit_source_info(source_info); - match *kind { - StatementKind::Assign(ref $($mutability)* place, - ref $($mutability)* rvalue) => { + match kind { + StatementKind::Assign(place, rvalue) => { self.visit_assign(block, place, rvalue, location); } - StatementKind::FakeRead(_, ref $($mutability)* place) => { + StatementKind::FakeRead(_, place) => { self.visit_place( place, PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), location ); } - StatementKind::SetDiscriminant{ ref $($mutability)* place, .. } => { + StatementKind::SetDiscriminant { place, .. } => { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Store), location ); } - StatementKind::StorageLive(ref $($mutability)* local) => { + StatementKind::StorageLive(local) => { self.visit_local( local, PlaceContext::NonUse(NonUseContext::StorageLive), location ); } - StatementKind::StorageDead(ref $($mutability)* local) => { + StatementKind::StorageDead(local) => { self.visit_local( local, PlaceContext::NonUse(NonUseContext::StorageDead), location ); } - StatementKind::InlineAsm { ref $($mutability)* outputs, - ref $($mutability)* inputs, - asm: _ } => { - for output in & $($mutability)* outputs[..] { + StatementKind::InlineAsm { outputs, inputs, asm: _ } => { + for output in & $($mutability)? outputs[..] { self.visit_place( output, PlaceContext::MutatingUse(MutatingUseContext::AsmOutput), location ); } - for (span, input) in & $($mutability)* inputs[..] { + for (span, input) in & $($mutability)? inputs[..] { self.visit_span(span); self.visit_operand(input, location); } } - StatementKind::Retag ( ref $($mutability)* kind, - ref $($mutability)* place ) => { + StatementKind::Retag(kind, place) => { self.visit_retag(kind, place, location); } - StatementKind::AscribeUserType( - ref $($mutability)* place, - ref $($mutability)* variance, - ref $($mutability)* user_ty, - ) => { + StatementKind::AscribeUserType(place, variance, user_ty) => { self.visit_ascribe_user_ty(place, variance, user_ty, location); } StatementKind::Nop => {} @@ -432,8 +423,8 @@ macro_rules! make_mir_visitor { fn super_assign(&mut self, _block: BasicBlock, - place: &$($mutability)* Place<'tcx>, - rvalue: &$($mutability)* Rvalue<'tcx>, + place: &$($mutability)? Place<'tcx>, + rvalue: &$($mutability)? Rvalue<'tcx>, location: Location) { self.visit_place( place, @@ -445,12 +436,9 @@ macro_rules! make_mir_visitor { fn super_terminator(&mut self, block: BasicBlock, - terminator: &$($mutability)* Terminator<'tcx>, + terminator: &$($mutability)? Terminator<'tcx>, location: Location) { - let Terminator { - ref $($mutability)* source_info, - ref $($mutability)* kind, - } = *terminator; + let Terminator { source_info, kind } = terminator; self.visit_source_info(source_info); self.visit_terminator_kind(block, kind, location); @@ -458,21 +446,23 @@ macro_rules! make_mir_visitor { fn super_terminator_kind(&mut self, block: BasicBlock, - kind: & $($mutability)* TerminatorKind<'tcx>, + kind: & $($mutability)? TerminatorKind<'tcx>, source_location: Location) { - match *kind { + match kind { TerminatorKind::Goto { target } => { - self.visit_branch(block, target); + self.visit_branch(block, *target); } - TerminatorKind::SwitchInt { ref $($mutability)* discr, - ref $($mutability)* switch_ty, - values: _, - ref targets } => { + TerminatorKind::SwitchInt { + discr, + switch_ty, + values: _, + targets + } => { self.visit_operand(discr, source_location); self.visit_ty(switch_ty, TyContext::Location(source_location)); - for &target in targets { - self.visit_branch(block, target); + for target in targets { + self.visit_branch(block, *target); } } @@ -483,113 +473,120 @@ macro_rules! make_mir_visitor { TerminatorKind::Unreachable => { } - TerminatorKind::Drop { ref $($mutability)* location, - target, - unwind } => { + TerminatorKind::Drop { + location, + target, + unwind, + } => { self.visit_place( location, PlaceContext::MutatingUse(MutatingUseContext::Drop), source_location ); - self.visit_branch(block, target); + self.visit_branch(block, *target); unwind.map(|t| self.visit_branch(block, t)); } - TerminatorKind::DropAndReplace { ref $($mutability)* location, - ref $($mutability)* value, - target, - unwind } => { + TerminatorKind::DropAndReplace { + location, + value, + target, + unwind, + } => { self.visit_place( location, PlaceContext::MutatingUse(MutatingUseContext::Drop), source_location ); self.visit_operand(value, source_location); - self.visit_branch(block, target); + self.visit_branch(block, *target); unwind.map(|t| self.visit_branch(block, t)); } - TerminatorKind::Call { ref $($mutability)* func, - ref $($mutability)* args, - ref $($mutability)* destination, - cleanup, - from_hir_call: _, } => { + TerminatorKind::Call { + func, + args, + destination, + cleanup, + from_hir_call: _, + } => { self.visit_operand(func, source_location); for arg in args { self.visit_operand(arg, source_location); } - if let Some((ref $($mutability)* destination, target)) = *destination { + if let Some((destination, target)) = destination { self.visit_place( destination, PlaceContext::MutatingUse(MutatingUseContext::Call), source_location ); - self.visit_branch(block, target); + self.visit_branch(block, *target); } cleanup.map(|t| self.visit_branch(block, t)); } - TerminatorKind::Assert { ref $($mutability)* cond, - expected: _, - ref $($mutability)* msg, - target, - cleanup } => { + TerminatorKind::Assert { + cond, + expected: _, + msg, + target, + cleanup, + } => { self.visit_operand(cond, source_location); self.visit_assert_message(msg, source_location); - self.visit_branch(block, target); + self.visit_branch(block, *target); cleanup.map(|t| self.visit_branch(block, t)); } - TerminatorKind::Yield { ref $($mutability)* value, - resume, - drop } => { + TerminatorKind::Yield { + value, + resume, + drop, + } => { self.visit_operand(value, source_location); - self.visit_branch(block, resume); + self.visit_branch(block, *resume); drop.map(|t| self.visit_branch(block, t)); } - TerminatorKind::FalseEdges { real_target, ref imaginary_targets} => { - self.visit_branch(block, real_target); + TerminatorKind::FalseEdges { real_target, imaginary_targets } => { + self.visit_branch(block, *real_target); for target in imaginary_targets { self.visit_branch(block, *target); } } TerminatorKind::FalseUnwind { real_target, unwind } => { - self.visit_branch(block, real_target); + self.visit_branch(block, *real_target); if let Some(unwind) = unwind { - self.visit_branch(block, unwind); + self.visit_branch(block, *unwind); } } } } fn super_assert_message(&mut self, - msg: & $($mutability)* AssertMessage<'tcx>, + msg: & $($mutability)? AssertMessage<'tcx>, location: Location) { use crate::mir::interpret::EvalErrorKind::*; - if let BoundsCheck { - ref $($mutability)* len, - ref $($mutability)* index - } = *msg { + if let BoundsCheck { len, index } = msg { self.visit_operand(len, location); self.visit_operand(index, location); } } fn super_rvalue(&mut self, - rvalue: & $($mutability)* Rvalue<'tcx>, + rvalue: & $($mutability)? Rvalue<'tcx>, location: Location) { - match *rvalue { - Rvalue::Use(ref $($mutability)* operand) => { + match rvalue { + Rvalue::Use(operand) => { self.visit_operand(operand, location); } - Rvalue::Repeat(ref $($mutability)* value, _) => { + Rvalue::Repeat(value, _) => { self.visit_operand(value, location); } - Rvalue::Ref(ref $($mutability)* r, bk, ref $($mutability)* path) => { + Rvalue::Ref(r, bk, path) => { self.visit_region(r, location); let ctx = match bk { BorrowKind::Shared => PlaceContext::NonMutatingUse( @@ -607,7 +604,7 @@ macro_rules! make_mir_visitor { self.visit_place(path, ctx, location); } - Rvalue::Len(ref $($mutability)* path) => { + Rvalue::Len(path) => { self.visit_place( path, PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), @@ -615,28 +612,22 @@ macro_rules! make_mir_visitor { ); } - Rvalue::Cast(_cast_kind, - ref $($mutability)* operand, - ref $($mutability)* ty) => { + Rvalue::Cast(_cast_kind, operand, ty) => { self.visit_operand(operand, location); self.visit_ty(ty, TyContext::Location(location)); } - Rvalue::BinaryOp(_bin_op, - ref $($mutability)* lhs, - ref $($mutability)* rhs) | - Rvalue::CheckedBinaryOp(_bin_op, - ref $($mutability)* lhs, - ref $($mutability)* rhs) => { + Rvalue::BinaryOp(_bin_op, lhs, rhs) + | Rvalue::CheckedBinaryOp(_bin_op, lhs, rhs) => { self.visit_operand(lhs, location); self.visit_operand(rhs, location); } - Rvalue::UnaryOp(_un_op, ref $($mutability)* op) => { + Rvalue::UnaryOp(_un_op, op) => { self.visit_operand(op, location); } - Rvalue::Discriminant(ref $($mutability)* place) => { + Rvalue::Discriminant(place) => { self.visit_place( place, PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), @@ -644,34 +635,39 @@ macro_rules! make_mir_visitor { ); } - Rvalue::NullaryOp(_op, ref $($mutability)* ty) => { + Rvalue::NullaryOp(_op, ty) => { self.visit_ty(ty, TyContext::Location(location)); } - Rvalue::Aggregate(ref $($mutability)* kind, - ref $($mutability)* operands) => { - let kind = &$($mutability)* **kind; - match *kind { - AggregateKind::Array(ref $($mutability)* ty) => { + Rvalue::Aggregate(kind, operands) => { + let kind = &$($mutability)? **kind; + match kind { + AggregateKind::Array(ty) => { self.visit_ty(ty, TyContext::Location(location)); } AggregateKind::Tuple => { } - AggregateKind::Adt(_adt_def, - _variant_index, - ref $($mutability)* substs, - _user_substs, - _active_field_index) => { + AggregateKind::Adt( + _adt_def, + _variant_index, + substs, + _user_substs, + _active_field_index + ) => { self.visit_substs(substs, location); } - AggregateKind::Closure(ref $($mutability)* def_id, - ref $($mutability)* closure_substs) => { + AggregateKind::Closure( + def_id, + closure_substs + ) => { self.visit_def_id(def_id, location); self.visit_closure_substs(closure_substs, location); } - AggregateKind::Generator(ref $($mutability)* def_id, - ref $($mutability)* generator_substs, - _movability) => { + AggregateKind::Generator( + def_id, + generator_substs, + _movability, + ) => { self.visit_def_id(def_id, location); self.visit_generator_substs(generator_substs, location); } @@ -685,33 +681,33 @@ macro_rules! make_mir_visitor { } fn super_operand(&mut self, - operand: & $($mutability)* Operand<'tcx>, + operand: & $($mutability)? Operand<'tcx>, location: Location) { - match *operand { - Operand::Copy(ref $($mutability)* place) => { + match operand { + Operand::Copy(place) => { self.visit_place( place, PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), location ); } - Operand::Move(ref $($mutability)* place) => { + Operand::Move(place) => { self.visit_place( place, PlaceContext::NonMutatingUse(NonMutatingUseContext::Move), location ); } - Operand::Constant(ref $($mutability)* constant) => { + Operand::Constant(constant) => { self.visit_constant(constant, location); } } } fn super_ascribe_user_ty(&mut self, - place: & $($mutability)* Place<'tcx>, - _variance: & $($mutability)* ty::Variance, - user_ty: & $($mutability)* UserTypeProjection<'tcx>, + place: & $($mutability)? Place<'tcx>, + _variance: & $($mutability)? ty::Variance, + user_ty: & $($mutability)? UserTypeProjection<'tcx>, location: Location) { self.visit_place( place, @@ -722,8 +718,8 @@ macro_rules! make_mir_visitor { } fn super_retag(&mut self, - _kind: & $($mutability)* RetagKind, - place: & $($mutability)* Place<'tcx>, + _kind: & $($mutability)? RetagKind, + place: & $($mutability)? Place<'tcx>, location: Location) { self.visit_place( place, @@ -733,45 +729,39 @@ macro_rules! make_mir_visitor { } fn super_place(&mut self, - place: & $($mutability)* Place<'tcx>, + place: & $($mutability)? Place<'tcx>, context: PlaceContext<'tcx>, location: Location) { - match *place { - Place::Local(ref $($mutability)* local) => { + match place { + Place::Local(local) => { self.visit_local(local, context, location); } - Place::Static(ref $($mutability)* static_) => { + Place::Static(static_) => { self.visit_static(static_, context, location); } - Place::Promoted(ref $($mutability)* promoted) => { - self.visit_ty(& $($mutability)* promoted.1, TyContext::Location(location)); + Place::Promoted(promoted) => { + self.visit_ty(& $($mutability)? promoted.1, TyContext::Location(location)); }, - Place::Projection(ref $($mutability)* proj) => { + Place::Projection(proj) => { self.visit_projection(proj, context, location); } } } fn super_static(&mut self, - static_: & $($mutability)* Static<'tcx>, + static_: & $($mutability)? Static<'tcx>, _context: PlaceContext<'tcx>, location: Location) { - let Static { - ref $($mutability)* def_id, - ref $($mutability)* ty, - } = *static_; + let Static { def_id, ty } = static_; self.visit_def_id(def_id, location); self.visit_ty(ty, TyContext::Location(location)); } fn super_projection(&mut self, - proj: & $($mutability)* PlaceProjection<'tcx>, + proj: & $($mutability)? PlaceProjection<'tcx>, context: PlaceContext<'tcx>, location: Location) { - let Projection { - ref $($mutability)* base, - ref $($mutability)* elem, - } = *proj; + let Projection { base, elem } = proj; let context = if context.is_mutating_use() { PlaceContext::MutatingUse(MutatingUseContext::Projection) } else { @@ -782,17 +772,17 @@ macro_rules! make_mir_visitor { } fn super_projection_elem(&mut self, - proj: & $($mutability)* PlaceElem<'tcx>, + proj: & $($mutability)? PlaceElem<'tcx>, location: Location) { - match *proj { + match proj { ProjectionElem::Deref => { } ProjectionElem::Subslice { from: _, to: _ } => { } - ProjectionElem::Field(_field, ref $($mutability)* ty) => { + ProjectionElem::Field(_field, ty) => { self.visit_ty(ty, TyContext::Location(location)); } - ProjectionElem::Index(ref $($mutability)* local) => { + ProjectionElem::Index(local) => { self.visit_local( local, PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), @@ -810,24 +800,24 @@ macro_rules! make_mir_visitor { fn super_local_decl(&mut self, local: Local, - local_decl: & $($mutability)* LocalDecl<'tcx>) { + local_decl: & $($mutability)? LocalDecl<'tcx>) { let LocalDecl { mutability: _, - ref $($mutability)* ty, - ref $($mutability)* user_ty, + ty, + user_ty, name: _, - ref $($mutability)* source_info, - ref $($mutability)* visibility_scope, + source_info, + visibility_scope, internal: _, is_user_variable: _, is_block_tail: _, - } = *local_decl; + } = local_decl; self.visit_ty(ty, TyContext::LocalDecl { local, source_info: *source_info, }); - for (user_ty, _) in & $($mutability)* user_ty.contents { + for (user_ty, _) in & $($mutability)? user_ty.contents { self.visit_user_type_projection(user_ty); } self.visit_source_info(source_info); @@ -835,7 +825,7 @@ macro_rules! make_mir_visitor { } fn super_source_scope(&mut self, - _scope: & $($mutability)* SourceScope) { + _scope: & $($mutability)? SourceScope) { } fn super_branch(&mut self, @@ -844,14 +834,14 @@ macro_rules! make_mir_visitor { } fn super_constant(&mut self, - constant: & $($mutability)* Constant<'tcx>, + constant: & $($mutability)? Constant<'tcx>, location: Location) { let Constant { - ref $($mutability)* span, - ref $($mutability)* ty, - ref $($mutability)* user_ty, - ref $($mutability)* literal, - } = *constant; + span, + ty, + user_ty, + literal, + } = constant; self.visit_span(span); self.visit_ty(ty, TyContext::Location(location)); @@ -859,17 +849,17 @@ macro_rules! make_mir_visitor { self.visit_const(literal, location); } - fn super_def_id(&mut self, _def_id: & $($mutability)* DefId) { + fn super_def_id(&mut self, _def_id: & $($mutability)? DefId) { } - fn super_span(&mut self, _span: & $($mutability)* Span) { + fn super_span(&mut self, _span: & $($mutability)? Span) { } - fn super_source_info(&mut self, source_info: & $($mutability)* SourceInfo) { + fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) { let SourceInfo { - ref $($mutability)* span, - ref $($mutability)* scope, - } = *source_info; + span, + scope, + } = source_info; self.visit_span(span); self.visit_source_scope(scope); @@ -877,49 +867,49 @@ macro_rules! make_mir_visitor { fn super_user_type_projection( &mut self, - _ty: & $($mutability)* UserTypeProjection<'tcx>, + _ty: & $($mutability)? UserTypeProjection<'tcx>, ) { } fn super_user_type_annotation( &mut self, _index: UserTypeAnnotationIndex, - ty: & $($mutability)* CanonicalUserTypeAnnotation<'tcx>, + ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>, ) { - self.visit_span(& $($mutability)* ty.span); - self.visit_ty(& $($mutability)* ty.inferred_ty, TyContext::UserTy(ty.span)); + self.visit_span(& $($mutability)? ty.span); + self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span)); } - fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) { + fn super_ty(&mut self, _ty: & $($mutability)? Ty<'tcx>) { } - fn super_region(&mut self, _region: & $($mutability)* ty::Region<'tcx>) { + fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) { } - fn super_const(&mut self, _const: & $($mutability)* &'tcx ty::LazyConst<'tcx>) { + fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::LazyConst<'tcx>) { } - fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) { + fn super_substs(&mut self, _substs: & $($mutability)? &'tcx Substs<'tcx>) { } fn super_generator_substs(&mut self, - _substs: & $($mutability)* GeneratorSubsts<'tcx>) { + _substs: & $($mutability)? GeneratorSubsts<'tcx>) { } fn super_closure_substs(&mut self, - _substs: & $($mutability)* ClosureSubsts<'tcx>) { + _substs: & $($mutability)? ClosureSubsts<'tcx>) { } // Convenience methods - fn visit_location(&mut self, mir: & $($mutability)* Mir<'tcx>, location: Location) { - let basic_block = & $($mutability)* mir[location.block]; + fn visit_location(&mut self, mir: & $($mutability)? Mir<'tcx>, location: Location) { + let basic_block = & $($mutability)? mir[location.block]; if basic_block.statements.len() == location.statement_index { - if let Some(ref $($mutability)* terminator) = basic_block.terminator { + if let Some(ref $($mutability)? terminator) = basic_block.terminator { self.visit_terminator(location.block, terminator, location) } } else { - let statement = & $($mutability)* + let statement = & $($mutability)? basic_block.statements[location.statement_index]; self.visit_statement(location.block, statement, location) } From 1ef34a5a39641846e824b6450a705d6031002beb Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Fri, 8 Feb 2019 18:47:19 -0800 Subject: [PATCH 0794/1064] Remove rustdoc test which referenced unstable API --- src/test/rustdoc-js/substring.js | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/test/rustdoc-js/substring.js diff --git a/src/test/rustdoc-js/substring.js b/src/test/rustdoc-js/substring.js deleted file mode 100644 index 3a6750151f7d8..0000000000000 --- a/src/test/rustdoc-js/substring.js +++ /dev/null @@ -1,10 +0,0 @@ -// exact-check - -const QUERY = 'waker_from'; - -const EXPECTED = { - 'others': [ - { 'path': 'std::task', 'name': 'local_waker_from_nonlocal' }, - { 'path': 'alloc::task', 'name': 'local_waker_from_nonlocal' }, - ], -}; From a01efbcbec2123429a7eaa73ce1c9198007af7cf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 9 Feb 2019 19:58:41 +0100 Subject: [PATCH 0795/1064] operand-to-place copies should never be overlapping --- src/librustc_mir/interpret/place.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 9ca7f9d8e27ff..3d6fcae0cab8c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -823,6 +823,8 @@ where let src = match self.try_read_immediate(src)? { Ok(src_val) => { // Yay, we got a value that we can write directly. + // FIXME: Add a check to make sure that if `src` is indirect, + // it does not overlap with `dest`. return self.write_immediate_no_validate(src_val, dest); } Err(mplace) => mplace, @@ -836,7 +838,8 @@ where self.memory.copy( src_ptr, src_align, dest_ptr, dest_align, - dest.layout.size, false + dest.layout.size, + /*nonoverlapping*/ true, )?; Ok(()) From 69d948d3477c208e4954d603f20d87782c7ea401 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Feb 2019 00:37:44 +0100 Subject: [PATCH 0796/1064] Fix search results interactions --- src/librustdoc/html/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 877ac9a62bbec..5ec938ae106a9 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1197,7 +1197,7 @@ if (!DOMTokenList.prototype.remove) { var actives = [[], [], []]; // "current" is used to know which tab we're looking into. var current = 0; - onEachLazy(document.getElementsByClassName("search-results"), function(e) { + onEachLazy(document.getElementById("results").childNodes, function(e) { onEachLazy(e.getElementsByClassName("highlighted"), function(e) { actives[current].push(e); }); @@ -1214,7 +1214,7 @@ if (!DOMTokenList.prototype.remove) { removeClass(actives[currentTab][0], "highlighted"); } else if (e.which === 40) { // down if (!actives[currentTab].length) { - var results = document.getElementsByClassName("search-results"); + var results = document.getElementById("results").childNodes; if (results.length > 0) { var res = results[currentTab].getElementsByClassName("result"); if (res.length > 0) { From 80942e95ea42e4ffb40dbdf5315f39775368261d Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 9 Feb 2019 19:42:23 -0700 Subject: [PATCH 0797/1064] Add EmbeddedBook to test list in bootstrap --- src/bootstrap/builder.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 8540d92f74917..f512e1d7a0c62 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -400,6 +400,7 @@ impl<'a> Builder<'a> { test::TheBook, test::UnstableBook, test::RustcBook, + test::EmbeddedBook, test::Rustfmt, test::Miri, test::Clippy, From 2be0993c4e219994b355a06e82394c966a2cfa5d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 10 Feb 2019 16:13:30 +0900 Subject: [PATCH 0798/1064] Revert removed #![feature(nll)] --- src/libfmt_macros/lib.rs | 1 + src/libgraphviz/lib.rs | 1 + src/libpanic_abort/lib.rs | 1 + src/libproc_macro/lib.rs | 1 + src/libprofiler_builtins/lib.rs | 1 + src/librustc_allocator/lib.rs | 1 + src/librustc_apfloat/lib.rs | 1 + src/librustc_asan/lib.rs | 1 + src/librustc_errors/lib.rs | 1 + src/librustc_llvm/lib.rs | 1 + src/librustc_lsan/lib.rs | 1 + src/librustc_msan/lib.rs | 1 + src/librustc_plugin/lib.rs | 1 + src/librustc_privacy/lib.rs | 1 + src/librustc_resolve/lib.rs | 1 + src/librustc_save_analysis/lib.rs | 1 + src/librustc_tsan/lib.rs | 1 + src/libsyntax/lib.rs | 1 + src/libsyntax_ext/lib.rs | 1 + src/libsyntax_pos/lib.rs | 1 + src/libunwind/lib.rs | 1 + 21 files changed, 21 insertions(+) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index ea67c01dfc9ea..aacd6cec565a5 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -10,6 +10,7 @@ #![deny(rust_2018_idioms)] +#![feature(nll)] #![feature(rustc_private)] pub use Piece::*; diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 8ce0f755df035..fadcfaec4b268 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -276,6 +276,7 @@ #![deny(rust_2018_idioms)] +#![feature(nll)] #![feature(str_escape)] use LabelText::*; diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 7c6f36ece3c83..edc97cd28a52a 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -14,6 +14,7 @@ #![feature(core_intrinsics)] #![feature(libc)] +#![feature(nll)] #![feature(panic_runtime)] #![feature(staged_api)] #![feature(rustc_attrs)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 2cdc5a48a5316..09a4a964abf09 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -17,6 +17,7 @@ #![deny(rust_2018_idioms)] +#![feature(nll)] #![feature(staged_api)] #![feature(const_fn)] #![feature(extern_types)] diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index 9c8d3a13b0812..2ce1a110b44c0 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -5,5 +5,6 @@ reason = "internal implementation detail of rustc right now", issue = "0")] #![allow(unused_features)] +#![feature(nll)] #![feature(staged_api)] #![deny(rust_2018_idioms)] diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs index 16b9ccfda8010..9d6e728e13557 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/librustc_allocator/lib.rs @@ -1,3 +1,4 @@ +#![feature(nll)] #![feature(rustc_private)] #![deny(rust_2018_idioms)] diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index f79d448edce9f..6653df8ffe92e 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -34,6 +34,7 @@ #![forbid(unsafe_code)] #![deny(rust_2018_idioms)] +#![feature(nll)] #![feature(try_from)] // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. #[allow(unused_extern_crates)] diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 568bb540c4719..3bdb86d313dcb 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -1,4 +1,5 @@ #![sanitizer_runtime] +#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index ea530fa1bfb73..0fc7b59ff1548 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -4,6 +4,7 @@ #![allow(unused_attributes)] #![feature(range_contains)] #![cfg_attr(unix, feature(libc))] +#![feature(nll)] #![feature(optin_builtin_traits)] #![deny(rust_2018_idioms)] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 3fcb20a29ddc9..292ce8b0a01b0 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -1,4 +1,5 @@ #![deny(rust_2018_idioms)] +#![feature(nll)] #![feature(static_nobundle)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 568bb540c4719..3bdb86d313dcb 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -1,4 +1,5 @@ #![sanitizer_runtime] +#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 568bb540c4719..3bdb86d313dcb 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -1,4 +1,5 @@ #![sanitizer_runtime] +#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index 32e003ff10747..0ea1634c0b4c5 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -52,6 +52,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(nll)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 14a0922c47740..d31dadd340292 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -2,6 +2,7 @@ #![deny(rust_2018_idioms)] +#![feature(nll)] #![feature(rustc_diagnostic_macros)] #![recursion_limit="256"] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ecbfcec3c5eb4..ad73b30ae3fd9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2,6 +2,7 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(nll)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c4a2ebeba6529..1f7b6d7733327 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1,5 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(custom_attribute)] +#![feature(nll)] #![deny(rust_2018_idioms)] #![allow(unused_attributes)] diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs index 568bb540c4719..3bdb86d313dcb 100644 --- a/src/librustc_tsan/lib.rs +++ b/src/librustc_tsan/lib.rs @@ -1,4 +1,5 @@ #![sanitizer_runtime] +#![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 878d06c0f1458..c844f9e2a91ee 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -11,6 +11,7 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(nll)] #![feature(rustc_attrs)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 670d71fe25bb8..7d7fd03085912 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -9,6 +9,7 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_span)] #![feature(decl_macro)] +#![feature(nll)] #![feature(str_escape)] #![feature(rustc_diagnostic_macros)] diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 70c45f7f9a7a6..dbb4f8f8159dc 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -11,6 +11,7 @@ #![feature(const_fn)] #![feature(crate_visibility_modifier)] #![feature(custom_attribute)] +#![feature(nll)] #![feature(non_exhaustive)] #![feature(optin_builtin_traits)] #![feature(rustc_attrs)] diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index b9a9929ef8b87..0ccffea317053 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -4,6 +4,7 @@ #![deny(rust_2018_idioms)] #![feature(link_cfg)] +#![feature(nll)] #![feature(staged_api)] #![feature(unwind_attributes)] #![feature(static_nobundle)] From 3a3691f1878bf3727585c982526c9db5a79c746c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Feb 2019 12:58:08 +0100 Subject: [PATCH 0799/1064] when there are multiple filenames, print what got interpreted as 2nd filename --- src/librustc_driver/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a95ce810ffaeb..fe02dd27072f7 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -839,7 +839,15 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { early_error(sopts.error_format, "no input filename given"); } 1 => panic!("make_input should have provided valid inputs"), - _ => early_error(sopts.error_format, "multiple input filenames provided"), + _ => + early_error( + sopts.error_format, + &format!( + "multiple input filenames provided (first two filenames are `{}` and `{}`)", + matches.free[0], + matches.free[1], + ), + ) } } From adb33008f703320727d5022640e9a09cdc4fa8a6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Feb 2019 13:05:37 +0100 Subject: [PATCH 0800/1064] rpath computation: explain why we pop() --- src/librustc_codegen_llvm/back/rpath.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/back/rpath.rs b/src/librustc_codegen_llvm/back/rpath.rs index aeff23dec41bb..a5c828e089f39 100644 --- a/src/librustc_codegen_llvm/back/rpath.rs +++ b/src/librustc_codegen_llvm/back/rpath.rs @@ -101,9 +101,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String let cwd = env::current_dir().unwrap(); let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or_else(|_| cwd.join(lib)); - lib.pop(); + lib.pop(); // strip filename let mut output = cwd.join(&config.out_filename); - output.pop(); + output.pop(); // strip filename let output = fs::canonicalize(&output).unwrap_or(output); let relative = path_relative_from(&lib, &output).unwrap_or_else(|| panic!("couldn't create relative path from {:?} to {:?}", output, lib)); From 55f90c77e8eeb114e1bbbb7d7cc536d050c3786b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 10 Feb 2019 16:21:47 +0300 Subject: [PATCH 0801/1064] Fix failing tidy (line endings on Windows) --- src/doc/embedded-book | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/embedded-book b/src/doc/embedded-book index d663113d1d9fb..bd2778f304989 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit d663113d1d9fbd35f1145c29f6080a6350b7f419 +Subproject commit bd2778f304989ee52be8201504d6ec621dd60ca9 From 74e97f338143c78e3cb511d82fba40c9c96cb6a0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 5 Feb 2019 14:27:09 +0100 Subject: [PATCH 0802/1064] Add trait alias support in rustdoc --- src/librustdoc/clean/mod.rs | 39 +++++++++++++++++++++++++--- src/librustdoc/doctree.rs | 44 +++++++++++++++++++++----------- src/librustdoc/html/item_type.rs | 33 ++++++++++++++---------- src/librustdoc/html/render.rs | 42 ++++++++++++++++++++++-------- src/librustdoc/passes/mod.rs | 1 + src/librustdoc/visit_ast.rs | 15 +++++++++-- src/test/rustdoc/trait_alias.rs | 21 +++++++++++++++ 7 files changed, 149 insertions(+), 46 deletions(-) create mode 100644 src/test/rustdoc/trait_alias.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bd0525583f2cd..64395da74211f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -517,6 +517,7 @@ pub enum ItemEnum { StaticItem(Static), ConstantItem(Constant), TraitItem(Trait), + TraitAliasItem(TraitAlias), ImplItem(Impl), /// A method signature only. Used for required methods in traits (ie, /// non-default-methods). @@ -554,6 +555,7 @@ impl ItemEnum { ItemEnum::TyMethodItem(ref i) => &i.generics, ItemEnum::MethodItem(ref i) => &i.generics, ItemEnum::ForeignFunctionItem(ref f) => &f.generics, + ItemEnum::TraitAliasItem(ref ta) => &ta.generics, _ => return None, }) } @@ -603,6 +605,7 @@ impl Clean for doctree::Module { items.extend(self.impls.iter().flat_map(|x| x.clean(cx))); items.extend(self.macros.iter().map(|x| x.clean(cx))); items.extend(self.proc_macros.iter().map(|x| x.clean(cx))); + items.extend(self.trait_aliases.iter().map(|x| x.clean(cx))); // determine if we should display the inner contents or // the outer `mod` item for the source code. @@ -1885,13 +1888,41 @@ impl Clean for doctree::Trait { items: self.items.clean(cx), generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), - is_spotlight: is_spotlight, + is_spotlight, is_auto: self.is_auto.clean(cx), }), } } } +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub struct TraitAlias { + pub generics: Generics, + pub bounds: Vec, + pub is_spotlight: bool, +} + +impl Clean for doctree::TraitAlias { + fn clean(&self, cx: &DocContext) -> Item { + let attrs = self.attrs.clean(cx); + let is_spotlight = attrs.has_doc_flag("spotlight"); + Item { + name: Some(self.name.clean(cx)), + attrs, + source: self.whence.clean(cx), + def_id: cx.tcx.hir().local_def_id(self.id), + visibility: self.vis.clean(cx), + stability: self.stab.clean(cx), + deprecation: self.depr.clean(cx), + inner: TraitAliasItem(TraitAlias { + generics: self.generics.clean(cx), + bounds: self.bounds.clean(cx), + is_spotlight, + }), + } + } +} + impl Clean for hir::IsAuto { fn clean(&self, _: &DocContext) -> bool { match *self { @@ -2223,6 +2254,7 @@ pub enum TypeKind { Macro, Attr, Derive, + TraitAlias, } pub trait GetDefId { @@ -3819,10 +3851,9 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId { MacroKind::Derive => (i, TypeKind::Derive), MacroKind::ProcMacroStub => unreachable!(), }, + Def::TraitAlias(i) => (i, TypeKind::TraitAlias), Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait), - Def::SelfTy(_, Some(impl_def_id)) => { - return impl_def_id - } + Def::SelfTy(_, Some(impl_def_id)) => return impl_def_id, _ => return def.def_id() }; if did.is_local() { return did } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index cc27da70b16d7..e8458385739df 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -38,6 +38,7 @@ pub struct Module { pub foreigns: Vec, pub macros: Vec, pub proc_macros: Vec, + pub trait_aliases: Vec, pub is_crate: bool, } @@ -53,21 +54,22 @@ impl Module { where_inner: syntax_pos::DUMMY_SP, attrs : hir::HirVec::new(), extern_crates: Vec::new(), - imports : Vec::new(), - structs : Vec::new(), - unions : Vec::new(), - enums : Vec::new(), - fns : Vec::new(), - mods : Vec::new(), - typedefs : Vec::new(), - existentials: Vec::new(), - statics : Vec::new(), - constants : Vec::new(), - traits : Vec::new(), - impls : Vec::new(), - foreigns : Vec::new(), - macros : Vec::new(), - proc_macros: Vec::new(), + imports : Vec::new(), + structs : Vec::new(), + unions : Vec::new(), + enums : Vec::new(), + fns : Vec::new(), + mods : Vec::new(), + typedefs : Vec::new(), + existentials: Vec::new(), + statics : Vec::new(), + constants : Vec::new(), + traits : Vec::new(), + impls : Vec::new(), + foreigns : Vec::new(), + macros : Vec::new(), + proc_macros: Vec::new(), + trait_aliases: Vec::new(), is_crate : false, } } @@ -208,6 +210,18 @@ pub struct Trait { pub depr: Option, } +pub struct TraitAlias { + pub name: Name, + pub generics: hir::Generics, + pub bounds: hir::HirVec, + pub attrs: hir::HirVec, + pub id: ast::NodeId, + pub whence: Span, + pub vis: hir::Visibility, + pub stab: Option, + pub depr: Option, +} + #[derive(Debug)] pub struct Impl { pub unsafety: hir::Unsafety, diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index e20d385c487b3..8a3b5484f395d 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -42,6 +42,7 @@ pub enum ItemType { Existential = 22, ProcAttribute = 23, ProcDerive = 24, + TraitAlias = 25, } @@ -86,6 +87,7 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::AssociatedTypeItem(..) => ItemType::AssociatedType, clean::ForeignTypeItem => ItemType::ForeignType, clean::KeywordItem(..) => ItemType::Keyword, + clean::TraitAliasItem(..) => ItemType::TraitAlias, clean::ProcMacroItem(ref mac) => match mac.kind { MacroKind::Bang => ItemType::Macro, MacroKind::Attr => ItemType::ProcAttribute, @@ -100,20 +102,21 @@ impl<'a> From<&'a clean::Item> for ItemType { impl From for ItemType { fn from(kind: clean::TypeKind) -> ItemType { match kind { - clean::TypeKind::Struct => ItemType::Struct, - clean::TypeKind::Union => ItemType::Union, - clean::TypeKind::Enum => ItemType::Enum, - clean::TypeKind::Function => ItemType::Function, - clean::TypeKind::Trait => ItemType::Trait, - clean::TypeKind::Module => ItemType::Module, - clean::TypeKind::Static => ItemType::Static, - clean::TypeKind::Const => ItemType::Constant, - clean::TypeKind::Variant => ItemType::Variant, - clean::TypeKind::Typedef => ItemType::Typedef, - clean::TypeKind::Foreign => ItemType::ForeignType, - clean::TypeKind::Macro => ItemType::Macro, - clean::TypeKind::Attr => ItemType::ProcAttribute, - clean::TypeKind::Derive => ItemType::ProcDerive, + clean::TypeKind::Struct => ItemType::Struct, + clean::TypeKind::Union => ItemType::Union, + clean::TypeKind::Enum => ItemType::Enum, + clean::TypeKind::Function => ItemType::Function, + clean::TypeKind::Trait => ItemType::Trait, + clean::TypeKind::Module => ItemType::Module, + clean::TypeKind::Static => ItemType::Static, + clean::TypeKind::Const => ItemType::Constant, + clean::TypeKind::Variant => ItemType::Variant, + clean::TypeKind::Typedef => ItemType::Typedef, + clean::TypeKind::Foreign => ItemType::ForeignType, + clean::TypeKind::Macro => ItemType::Macro, + clean::TypeKind::Attr => ItemType::ProcAttribute, + clean::TypeKind::Derive => ItemType::ProcDerive, + clean::TypeKind::TraitAlias => ItemType::TraitAlias, } } } @@ -146,6 +149,7 @@ impl ItemType { ItemType::Existential => "existential", ItemType::ProcAttribute => "attr", ItemType::ProcDerive => "derive", + ItemType::TraitAlias => "traitalias", } } @@ -160,6 +164,7 @@ impl ItemType { ItemType::Primitive | ItemType::AssociatedType | ItemType::Existential | + ItemType::TraitAlias | ItemType::ForeignType => NameSpace::Type, ItemType::ExternCrate | diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a85ac19286af5..9bcf574651539 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1836,6 +1836,7 @@ struct AllTypes { keywords: FxHashSet, attributes: FxHashSet, derives: FxHashSet, + trait_aliases: FxHashSet, } impl AllTypes { @@ -1856,6 +1857,7 @@ impl AllTypes { keywords: new_set(100), attributes: new_set(100), derives: new_set(100), + trait_aliases: new_set(100), } } @@ -1879,6 +1881,7 @@ impl AllTypes { ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)), ItemType::ProcAttribute => self.attributes.insert(ItemEntry::new(new_url, name)), ItemType::ProcDerive => self.derives.insert(ItemEntry::new(new_url, name)), + ItemType::TraitAlias => self.trait_aliases.insert(ItemEntry::new(new_url, name)), _ => true, }; } @@ -1922,6 +1925,7 @@ impl fmt::Display for AllTypes { print_entries(f, &self.derives, "Derive Macros", "derives")?; print_entries(f, &self.functions, "Functions", "functions")?; print_entries(f, &self.typedefs, "Typedefs", "typedefs")?; + print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-alias")?; print_entries(f, &self.existentials, "Existentials", "existentials")?; print_entries(f, &self.statics, "Statics", "statics")?; print_entries(f, &self.constants, "Constants", "constants") @@ -2419,6 +2423,7 @@ impl<'a> fmt::Display for Item<'a> { clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?, clean::KeywordItem(..) => write!(fmt, "Keyword ")?, clean::ExistentialItem(..) => write!(fmt, "Existential Type ")?, + clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?, _ => { // We don't generate pages for any other type. unreachable!(); @@ -2457,6 +2462,7 @@ impl<'a> fmt::Display for Item<'a> { clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item), clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k), clean::ExistentialItem(ref e, _) => item_existential(fmt, self.cx, self.item, e), + clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta), _ => { // We don't generate pages for any other type. unreachable!(); @@ -3014,23 +3020,17 @@ fn render_impls(cx: &Context, w: &mut fmt::Formatter, Ok(()) } -fn bounds(t_bounds: &[clean::GenericBound]) -> String { +fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool) -> String { let mut bounds = String::new(); - let mut bounds_plain = String::new(); if !t_bounds.is_empty() { - if !bounds.is_empty() { - bounds.push(' '); - bounds_plain.push(' '); + if !trait_alias { + bounds.push_str(": "); } - bounds.push_str(": "); - bounds_plain.push_str(": "); for (i, p) in t_bounds.iter().enumerate() { if i > 0 { bounds.push_str(" + "); - bounds_plain.push_str(" + "); } bounds.push_str(&(*p).to_string()); - bounds_plain.push_str(&format!("{:#}", *p)); } } bounds @@ -3050,7 +3050,7 @@ fn item_trait( it: &clean::Item, t: &clean::Trait, ) -> fmt::Result { - let bounds = bounds(&t.bounds); + let bounds = bounds(&t.bounds, false); let types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>(); let required = t.items.iter().filter(|m| m.is_ty_method()).collect::>(); @@ -4280,7 +4280,26 @@ fn item_existential( it.name.as_ref().unwrap(), t.generics, where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, - bounds = bounds(&t.bounds))?; + bounds = bounds(&t.bounds, false))?; + + document(w, cx, it)?; + + // Render any items associated directly to this alias, as otherwise they + // won't be visible anywhere in the docs. It would be nice to also show + // associated items from the aliased type (see discussion in #32077), but + // we need #14072 to make sense of the generics. + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) +} + +fn item_trait_alias(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, + t: &clean::TraitAlias) -> fmt::Result { + write!(w, "

    (self, predicate: P) -> TakeWhile where From 652f2c753aed97261f5d988f0a2b50aa6508964c Mon Sep 17 00:00:00 2001 From: ishitatsuyuki Date: Mon, 4 Feb 2019 19:26:46 +0900 Subject: [PATCH 0583/1064] Add test --- src/test/ui/stability-in-private-module.rs | 4 ++++ src/test/ui/stability-in-private-module.stderr | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/ui/stability-in-private-module.rs create mode 100644 src/test/ui/stability-in-private-module.stderr diff --git a/src/test/ui/stability-in-private-module.rs b/src/test/ui/stability-in-private-module.rs new file mode 100644 index 0000000000000..f12e9198b0d7c --- /dev/null +++ b/src/test/ui/stability-in-private-module.rs @@ -0,0 +1,4 @@ +fn main() { + let _ = std::thread::thread_info::current_thread(); + //~^ERROR module `thread_info` is private +} diff --git a/src/test/ui/stability-in-private-module.stderr b/src/test/ui/stability-in-private-module.stderr new file mode 100644 index 0000000000000..c3edd62a15eda --- /dev/null +++ b/src/test/ui/stability-in-private-module.stderr @@ -0,0 +1,9 @@ +error[E0603]: module `thread_info` is private + --> $DIR/stability-in-private-module.rs:2:26 + | +LL | let _ = std::thread::thread_info::current_thread(); + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0603`. From 82df9d7434c949b4357fb4c80c36961404226f93 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 4 Feb 2019 16:02:54 +0530 Subject: [PATCH 0584/1064] Remove stray FIXME --- src/libstd/sys/sgx/rwlock.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 43ceae7d33b8d..33163a556c16d 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -19,9 +19,6 @@ unsafe fn rw_lock_size_assert(r: RWLock) { mem::transmute::(r); } -//unsafe impl Send for RWLock {} -//unsafe impl Sync for RWLock {} // FIXME - impl RWLock { pub const fn new() -> RWLock { RWLock { From 4633cca157d9730d75e3fc6144ae952b76f5559f Mon Sep 17 00:00:00 2001 From: James Munns Date: Mon, 4 Feb 2019 11:34:50 +0100 Subject: [PATCH 0585/1064] Update embedded book dependency --- src/doc/embedded-book | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 36bc507044a95..d663113d1d9fb 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 36bc507044a9596df426e67e2e1685a3ed6e3c60 +Subproject commit d663113d1d9fbd35f1145c29f6080a6350b7f419 From c40fa3271a939ee34662482052be64929978ca6a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 4 Feb 2019 12:38:26 +0100 Subject: [PATCH 0586/1064] sort elements in the sidebar --- src/librustdoc/html/render.rs | 156 ++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 72 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86fb51419c270..c4c3b635b59e0 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4470,15 +4470,17 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { { let used_links_bor = Rc::new(RefCell::new(&mut used_links)); - let ret = v.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(move |i| get_methods(i.inner_impl(), - false, - &mut used_links_bor.borrow_mut())) - .collect::(); + let mut ret = v.iter() + .filter(|i| i.inner_impl().trait_.is_none()) + .flat_map(move |i| get_methods(i.inner_impl(), + false, + &mut used_links_bor.borrow_mut())) + .collect::>(); + // We want links' order to be reproducible so we don't use unstable sort. + ret.sort(); if !ret.is_empty() { out.push_str(&format!("Methods\ -