From 033924464fedf2c68abd4605930a81569a02cbf9 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Thu, 12 Jul 2018 09:33:33 +0200 Subject: [PATCH 01/11] Deny bare trait objects in src/librustc_errors Enforce `#![deny(bare_trait_objects)]` in `src/librustc_errors`. --- src/librustc_errors/diagnostic.rs | 8 ++++---- src/librustc_errors/diagnostic_builder.rs | 8 ++++---- src/librustc_errors/emitter.rs | 6 +++--- src/librustc_errors/lib.rs | 11 +++++++---- src/librustc_errors/lock.rs | 4 ++-- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index de73295b499fa..d079102a4ba00 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -121,7 +121,7 @@ impl Diagnostic { } pub fn note_expected_found(&mut self, - label: &fmt::Display, + label: &dyn fmt::Display, expected: DiagnosticStyledString, found: DiagnosticStyledString) -> &mut Self @@ -130,11 +130,11 @@ impl Diagnostic { } pub fn note_expected_found_extra(&mut self, - label: &fmt::Display, + label: &dyn fmt::Display, expected: DiagnosticStyledString, found: DiagnosticStyledString, - expected_extra: &fmt::Display, - found_extra: &fmt::Display) + expected_extra: &dyn fmt::Display, + found_extra: &dyn fmt::Display) -> &mut Self { let mut msg: Vec<_> = vec![(format!("expected {} `", label), Style::NoStyle)]; diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 562c28f08405a..9c7b7ea339540 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -148,17 +148,17 @@ impl<'a> DiagnosticBuilder<'a> { } forward!(pub fn note_expected_found(&mut self, - label: &fmt::Display, + label: &dyn fmt::Display, expected: DiagnosticStyledString, found: DiagnosticStyledString) -> &mut Self); forward!(pub fn note_expected_found_extra(&mut self, - label: &fmt::Display, + label: &dyn fmt::Display, expected: DiagnosticStyledString, found: DiagnosticStyledString, - expected_extra: &fmt::Display, - found_extra: &fmt::Display) + expected_extra: &dyn fmt::Display, + found_extra: &dyn fmt::Display) -> &mut Self); forward!(pub fn note(&mut self, msg: &str) -> &mut Self); diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index e79a3a87738ec..2f71c3a7232de 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -148,7 +148,7 @@ impl EmitterWriter { } } - pub fn new(dst: Box, + pub fn new(dst: Box, code_map: Option>, short_message: bool, teach: bool) @@ -1469,13 +1469,13 @@ fn emit_to_destination(rendered_buffer: &Vec>, pub enum Destination { Terminal(StandardStream), Buffered(BufferWriter), - Raw(Box), + Raw(Box), } pub enum WritableDst<'a> { Terminal(&'a mut StandardStream), Buffered(&'a mut BufferWriter, Buffer), - Raw(&'a mut Box), + Raw(&'a mut Box), } impl Destination { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index fd90e1cbe0866..f18a7bd9136a2 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![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/")] @@ -110,7 +112,7 @@ pub struct SubstitutionPart { pub snippet: String, } -pub type CodeMapperDyn = CodeMapper + sync::Send + sync::Sync; +pub type CodeMapperDyn = dyn CodeMapper + sync::Send + sync::Sync; pub trait CodeMapper { fn lookup_char_pos(&self, pos: BytePos) -> Loc; @@ -270,7 +272,7 @@ pub struct Handler { pub flags: HandlerFlags, err_count: AtomicUsize, - emitter: Lock>, + emitter: Lock>, continue_after_error: LockCell, delayed_span_bug: Lock>, @@ -326,7 +328,7 @@ impl Handler { pub fn with_emitter(can_emit_warnings: bool, treat_err_as_bug: bool, - e: Box) + e: Box) -> Handler { Handler::with_emitter_and_flags( e, @@ -337,7 +339,8 @@ impl Handler { }) } - pub fn with_emitter_and_flags(e: Box, flags: HandlerFlags) -> Handler { + pub fn with_emitter_and_flags(e: Box, flags: HandlerFlags) -> Handler + { Handler { flags, err_count: AtomicUsize::new(0), diff --git a/src/librustc_errors/lock.rs b/src/librustc_errors/lock.rs index 4c298228c37c7..dff8d53986db5 100644 --- a/src/librustc_errors/lock.rs +++ b/src/librustc_errors/lock.rs @@ -23,7 +23,7 @@ use std::any::Any; #[cfg(windows)] #[allow(bad_style)] -pub fn acquire_global_lock(name: &str) -> Box { +pub fn acquire_global_lock(name: &str) -> Box { use std::ffi::CString; use std::io; @@ -110,6 +110,6 @@ pub fn acquire_global_lock(name: &str) -> Box { } #[cfg(unix)] -pub fn acquire_global_lock(_name: &str) -> Box { +pub fn acquire_global_lock(_name: &str) -> Box { Box::new(()) } From 384d04d31d35ef80324645d06e1afcf3ad48f4ed Mon Sep 17 00:00:00 2001 From: ljedrz Date: Thu, 12 Jul 2018 15:41:24 +0200 Subject: [PATCH 02/11] Reduce the number of clone()s needed in obligation_forest Some can be avoided by using remove_entry instead of remove. --- src/librustc_data_structures/obligation_forest/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index df34891ff033b..0d6cf260dcd98 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -496,9 +496,14 @@ impl ObligationForest { } } NodeState::Done => { - self.waiting_cache.remove(self.nodes[i].obligation.as_predicate()); - // FIXME(HashMap): why can't I get my key back? - self.done_cache.insert(self.nodes[i].obligation.as_predicate().clone()); + // Avoid cloning the key (predicate) in case it exists in the waiting cache + if let Some((predicate, _)) = self.waiting_cache + .remove_entry(self.nodes[i].obligation.as_predicate()) + { + self.done_cache.insert(predicate); + } else { + self.done_cache.insert(self.nodes[i].obligation.as_predicate().clone()); + } node_rewrites[i] = nodes_len; dead_nodes += 1; } From 65e6b2b4a8f01e453e2bc27df9e0f0666904af42 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 14 Jul 2018 20:45:44 +0200 Subject: [PATCH 03/11] Pass edition flags to compiler from rustdoc as expected --- src/librustdoc/test.rs | 3 ++- src/test/rustdoc/edition-flag.rs | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc/edition-flag.rs diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 53032b9b98c5d..eb57ca74755f6 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -37,7 +37,7 @@ use syntax::codemap::CodeMap; use syntax::edition::Edition; use syntax::feature_gate::UnstableFeatures; use syntax::with_globals; -use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName}; +use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName, hygiene}; use errors; use errors::emitter::ColorConfig; @@ -561,6 +561,7 @@ impl Collector { rustc_driver::in_rustc_thread(move || with_globals(move || { io::set_panic(panic); io::set_print(print); + hygiene::set_default_edition(edition); run_test(&test, &cratename, &filename, diff --git a/src/test/rustdoc/edition-flag.rs b/src/test/rustdoc/edition-flag.rs new file mode 100644 index 0000000000000..3475b657d2599 --- /dev/null +++ b/src/test/rustdoc/edition-flag.rs @@ -0,0 +1,24 @@ +// 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. + +// compile-flags:--test -Z unstable-options +// edition:2018 + +#![feature(async_await)] + +/// ```rust +/// #![feature(async_await)] +/// fn main() { +/// let _ = async { }; +/// } +/// ``` +fn main() { + let _ = async { }; +} From 02edc7e4ffde4c020832f5248cd4fc12650d9810 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Sun, 15 Jul 2018 10:16:36 +1000 Subject: [PATCH 04/11] AsRef doc wording tweaks --- src/libcore/convert.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 7324df95bc5d5..11cc4ffecf005 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -63,9 +63,9 @@ /// /// The key difference between the two traits is the intention: /// -/// - Use `AsRef` when goal is to simply convert into a reference -/// - Use `Borrow` when goal is related to writing code that is agnostic to the -/// type of borrow and if is reference or value +/// - Use `AsRef` when the goal is to simply convert into a reference +/// - Use `Borrow` when the goal is related to writing code that is agnostic to +/// the type of borrow and whether it is a reference or value /// /// See [the book][book] for a more detailed comparison. /// From 21a179649f0b08d0149646ed32df3eb91fe0de83 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 16 Jul 2018 16:36:32 +0200 Subject: [PATCH 05/11] update nomicon --- src/doc/nomicon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index 13e3745ca3991..66ef7373409d1 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 13e3745ca399118df05e8261e12e3ada6e616b48 +Subproject commit 66ef7373409d1979c2839db8886ac2ec9b6a58cd From 827f656ebb1230f31af6d968c4bfe69a79914ffc Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 16 Jul 2018 09:22:15 -0600 Subject: [PATCH 06/11] Enable incremental independent of stage Previously we'd only do so for stage 0 but with keep-stage improvements it seems likely that we'll see more developers working in the stage 1, so we should allow enabling incremental for them. Ideally, the check we probably want is to only enable incremental for the last compiler build scheduled, but there's no good way to do so today. Just enabling incremental in all stages should be sufficient; we may be doing extra work that's needles -- compiling incrementally something that will never be recompiled in-place -- but that should be sufficiently unlikely (i.e., users either don't care or won't be compiling the compiler twice). --- src/bootstrap/builder.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index eb534cb685e87..79167b1fd5e27 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -903,10 +903,7 @@ impl<'a> Builder<'a> { .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler)); } - // Ignore incremental modes except for stage0, since we're - // not guaranteeing correctness across builds if the compiler - // is changing under your feet.` - if self.config.incremental && compiler.stage == 0 { + if self.config.incremental { cargo.env("CARGO_INCREMENTAL", "1"); } From d85bcef4670ca816e04467bd287e58460c34750e Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 16 Jul 2018 16:01:29 +0200 Subject: [PATCH 07/11] Calculate the exact capacity for 2 HashMaps --- src/bootstrap/metadata.rs | 2 +- src/librustc_driver/profile/trace.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 718a6da363724..fa0b1983510b9 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -51,7 +51,7 @@ pub fn build(build: &mut Build) { build_krate("", build, &mut resolves, "src/libtest"); build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc"); - let mut id2name = HashMap::new(); + let mut id2name = HashMap::with_capacity(build.crates.len()); for (name, krate) in build.crates.iter() { id2name.insert(krate.id.clone(), name.clone()); } diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index 6426286ccbc6c..5f10c56e8e214 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -220,7 +220,8 @@ pub fn write_counts(count_file: &mut File, counts: &mut HashMap) { - let mut counts : HashMap = HashMap::new(); + let capacity = traces.iter().fold(0, |acc, t| acc + 1 + t.extent.len()); + let mut counts : HashMap = HashMap::with_capacity(capacity); compute_counts_rec(&mut counts, traces); write_counts(counts_file, &mut counts); From a9bcbb27b8d0cc3331ada98bc8cadcbb4073ff10 Mon Sep 17 00:00:00 2001 From: kennytm Date: Tue, 17 Jul 2018 05:35:19 +0800 Subject: [PATCH 08/11] Block beta if clippy breaks. Don't fail master pull request when an unrelated tool is not test-pass. --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index e8197e9085182..f6d375058a772 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -81,8 +81,8 @@ status_check() { check_dispatch $1 beta rust-by-example src/doc/rust-by-example check_dispatch $1 beta rls src/tools/rls check_dispatch $1 beta rustfmt src/tools/rustfmt + check_dispatch $1 beta clippy-driver src/tools/clippy # these tools are not required for beta to successfully branch - check_dispatch $1 nightly clippy-driver src/tools/clippy check_dispatch $1 nightly miri src/tools/miri } @@ -106,12 +106,14 @@ $COMMIT\t$(cat "$TOOLSTATE_FILE") fi } -if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then - . "$(dirname $0)/repo.sh" - MESSAGE_FILE=$(mktemp -t msg.XXXXXX) - echo "($OS CI update)" > "$MESSAGE_FILE" - commit_toolstate_change "$MESSAGE_FILE" change_toolstate - rm -f "$MESSAGE_FILE" +if [ "$RUST_RELEASE_CHANNEL" = nightly ]; then + if [ -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then + . "$(dirname $0)/repo.sh" + MESSAGE_FILE=$(mktemp -t msg.XXXXXX) + echo "($OS CI update)" > "$MESSAGE_FILE" + commit_toolstate_change "$MESSAGE_FILE" change_toolstate + rm -f "$MESSAGE_FILE" + fi exit 0 fi From f684f80e95bf1c895b631f205e7019f8746c7da8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 13 Jul 2018 10:34:50 +0200 Subject: [PATCH 09/11] update miri --- src/Cargo.lock | 27 +++++++++++++++++++++++++-- src/tools/miri | 2 +- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 27abcf61d63f8..ccc1ccce87aae 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -243,6 +243,18 @@ dependencies = [ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cargo_metadata" +version = "0.6.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)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -629,6 +641,14 @@ dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error_index_generator" version = "0.0.0" @@ -1216,12 +1236,13 @@ name = "miri" version = "0.1.0" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3031,6 +3052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0" +"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" "checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d" "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" "checksum chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a146c19172c7eea48ea55a7123ac95da786639bc665097f1e14034ee5f1d8699" @@ -3062,6 +3084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" diff --git a/src/tools/miri b/src/tools/miri index 5b7bb32b0e46d..ff64b420ecc17 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 5b7bb32b0e46d195b80c4da09b560ac7fc92015d +Subproject commit ff64b420ecc1762dee6c9b9b211850be68cd9765 From 114dc6916606c791a523f4f179570cbef6b2e031 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 16 Jul 2018 12:06:26 +0200 Subject: [PATCH 10/11] update miri (Windows tests fixed) --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index ff64b420ecc17..f18fc27b6f1b0 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit ff64b420ecc1762dee6c9b9b211850be68cd9765 +Subproject commit f18fc27b6f1b07e1bc6f61764cd74f59d29956b8 From 9e10b12f332a027a6397e3aa6b58effc2d64bb38 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 17 Jul 2018 09:13:47 +0200 Subject: [PATCH 11/11] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index f18fc27b6f1b0..911aedf736992 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit f18fc27b6f1b07e1bc6f61764cd74f59d29956b8 +Subproject commit 911aedf736992e907d11cb494167f41f28d02368