From ed2537b5a318649d9358bb4a882b46087269619b Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 1 May 2017 04:51:17 +0300 Subject: [PATCH 1/5] Try fixing bigendian metadata serialisation I compiled this on PPC to check and it seems to work, but not sure whether I didn't mess up anything in a major way. Maybe a good shot at #41443 --- src/librustc_metadata/index.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index 970a401177ba5..ebf9910e9c99c 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -58,7 +58,7 @@ impl Index { let pos = buf.position(); // First we write the length of the lower range ... - buf.write_all(words_to_bytes(&[self.positions[0].len() as u32])).unwrap(); + buf.write_all(words_to_bytes(&[(self.positions[0].len() as u32).to_le()])).unwrap(); // ... then the values in the lower range ... buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap(); // ... then the values in the higher range. From 9dd97695fd5caadceacd297b29257f25e68fa05d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 27 Apr 2017 16:40:49 +0300 Subject: [PATCH 2/5] typeck: resolve type vars before calling `try_index_step` `try_index_step` does not resolve type variables by itself and would fail otherwise. Also harden the failure path in `confirm` to cause less confusing errors. --- src/librustc/middle/mem_categorization.rs | 11 +++++++-- src/librustc_errors/lib.rs | 3 +++ src/librustc_typeck/check/method/confirm.rs | 11 +++++++++ src/test/run-pass/issue-41498.rs | 26 +++++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-41498.rs diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 188fcc9141492..7f414d3d5d617 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -451,7 +451,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // So peel off one-level, turning the &T into T. match base_ty.builtin_deref(false, ty::NoPreference) { Some(t) => t.ty, - None => { return Err(()); } + None => { + debug!("By-ref binding of non-derefable type {:?}", base_ty); + return Err(()); + } } } _ => base_ty, @@ -1039,6 +1042,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { match base_cmt.ty.builtin_index() { Some(ty) => (ty, ElementKind::VecElement), None => { + debug!("Explicit index of non-indexable type {:?}", base_cmt); return Err(()); } } @@ -1154,7 +1158,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) | PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => { match path.def { - Def::Err => return Err(()), + Def::Err => { + debug!("access to unresolvable pattern {:?}", pat); + return Err(()) + } Def::Variant(variant_did) | Def::VariantCtor(variant_did, ..) => { // univariant enums do not need downcasts diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index da29e354a7014..cc8012d965a76 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -375,6 +375,9 @@ impl Handler { panic!(ExplicitBug); } pub fn delay_span_bug>(&self, sp: S, msg: &str) { + if self.treat_err_as_bug { + self.span_bug(sp, msg); + } let mut delayed = self.delayed_span_bug.borrow_mut(); *delayed = Some((sp.into(), msg.to_string())); } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 26ba965fe5cc6..fb608b2494558 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -516,6 +516,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { }; let index_expr_ty = self.node_ty(index_expr.id); + let adjusted_base_ty = self.resolve_type_vars_if_possible(&adjusted_base_ty); + let index_expr_ty = self.resolve_type_vars_if_possible(&index_expr_ty); let result = self.try_index_step(ty::MethodCall::expr(expr.id), expr, @@ -531,6 +533,15 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { let expr_ty = self.node_ty(expr.id); self.demand_suptype(expr.span, expr_ty, return_ty); + } else { + // We could not perform a mutable index. Re-apply the + // immutable index adjustments - borrowck will detect + // this as an error. + if let Some(adjustment) = adjustment { + self.apply_adjustment(expr.id, adjustment); + } + self.tcx.sess.delay_span_bug( + expr.span, "convert_lvalue_derefs_to_mutable failed"); } } hir::ExprUnary(hir::UnDeref, ref base_expr) => { diff --git a/src/test/run-pass/issue-41498.rs b/src/test/run-pass/issue-41498.rs new file mode 100644 index 0000000000000..66fd30bdbbbe4 --- /dev/null +++ b/src/test/run-pass/issue-41498.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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. + +// regression test for issue #41498. + +struct S; +impl S { + fn mutate(&mut self) {} +} + +fn call_and_ref T>(x: &mut Option, f: F) -> &mut T { + *x = Some(f()); + x.as_mut().unwrap() +} + +fn main() { + let mut n = None; + call_and_ref(&mut n, || [S])[0].mutate(); +} From f8ba58799ac2eca5a31d3084044f1512665fcfd7 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 25 Apr 2017 17:43:33 +0000 Subject: [PATCH 3/5] Update release notes for 1.17 --- RELEASES.md | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index d7f28ae2909ac..041eef4984f8e 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,261 @@ +Version 1.17.0 (2017-04-27) +=========================== + +Language +-------- + +* [The lifetime of statics and consts defaults to `'static`][39265]. [RFC 1623] +* [Fields of structs may be initialized without duplicating the field/variable + names][39761]. [RFC 1682] +* [`Self` may be included in the `where` clause of `impls`][38864]. [RFC 1647] +* [When coercing to an unsized type lifetimes must be equal][40319]. That is, + there is no subtyping between `T` and `U` when `T: Unsize`. For example, + coercing `&mut [&'a X; N]` to `&mut [&'b X]` requires `'a` be equal to + `'b`. Soundness fix. +* [Values passed to the indexing operator, `[]`, automatically coerce][40166] +* [Static variables may contain references to other statics][40027] + +Compiler +-------- + +* [Exit quickly on only `--emit dep-info`][40336] +* [Make `-C relocation-model` more correctly determine whether the linker + creates a position-independent executable][40245] +* [Add `-C overflow-checks` to directly control whether integer overflow + panics][40037] +* [The rustc type checker now checks items on demand instead of in a single + in-order pass][40008]. This is mostly an internal refactoring in support of + future work, including incremental type checking, but also resolves [RFC + 1647], allowing `Self` to appear in `impl` `where` clauses. +* [Optimize vtable loads][39995] +* [Turn off vectorization for Emscripten targets][39990] +* [Provide suggestions for unknown macros imported with `use`][39953] +* [Fix ICEs in path resolution][39939] +* [Strip exception handling code on Emscripten when `panic=abort`][39193] +* [Add clearer error message using `&str + &str`][39116] + +Stabilized APIs +--------------- + +* [`Arc::into_raw`] +* [`Arc::from_raw`] +* [`Arc::ptr_eq`] +* [`Rc::into_raw`] +* [`Rc::from_raw`] +* [`Rc::ptr_eq`] +* [`Ordering::then`] +* [`Ordering::then_with`] +* [`BTreeMap::range`] +* [`BTreeMap::range_mut`] +* [`collections::Bound`] +* [`process::abort`] +* [`ptr::read_unaligned`] +* [`ptr::write_unaligned`] +* [`Result::expect_err`] +* [`Cell::swap`] +* [`Cell::replace`] +* [`Cell::into_inner`] +* [`Cell::take`] + +Libraries +--------- + +* [`BTreeMap` and `BTreeSet` can iterate over ranges][27787] +* [`Cell` can store non-`Copy` types][39793]. [RFC 1651] +* [`String` implements `FromIterator<&char>`][40028] +* `Box` [implements][40009] a number of new conversions: + `From> for String`, + `From> for Vec`, + `From> for CString`, + `From> for OsString`, + `From> for PathBuf`, + `Into> for String`, + `Into> for Vec`, + `Into> for CString`, + `Into> for OsString`, + `Into> for PathBuf`, + `Default for Box`, + `Default for Box`, + `Default for Box`, + `From<&CStr> for Box`, + `From<&OsStr> for Box`, + `From<&Path> for Box` +* [`ffi::FromBytesWithNulError` implements `Error` and `Display`][39960] +* [Specialize `PartialOrd for [A] where A: Ord`][39642] +* [Slightly optimize `slice::sort`][39538] +* [Add `ToString` trait specialization for `Cow<'a, str>` and `String`][39440] +* [`Box<[T]>` implements `From<&[T]> where T: Copy`, + `Box` implements `From<&str>`][39438] +* [`IpAddr` implements `From` for various arrays. `SocketAddr` implements + `From<(I, u16)> where I: Into`][39372] +* [`format!` estimates the needed capacity before writing a string][39356] +* [Support unprivileged symlink creation in Windows][38921] +* [`PathBuf` implements `Default`][38764] +* [Implement `PartialEq<[A]>` for `VecDeque`][38661] +* [`HashMap` resizes adaptively][38368] to guard against DOS attacks + and poor hash functions. + +Cargo +----- + +* [Add `cargo check --all`][cargo/3731] +* [Add an option to ignore SSL revocation checking][cargo/3699] +* [Add `cargo run --package`][cargo/3691] +* [Add `required_features`][cargo/3667] +* [Assume `build.rs` is a build script][cargo/3664] +* [Find workspace via `workspace_root` link in containing member][cargo/3562] + +Misc +---- + +* [Documentation is rendered with mdbook instead of the obsolete, in-tree + `rustbook`][39633] +* [The "Unstable Book" documents nightly-only features][ubook] +* [Improve the style of the sidebar in rustdoc output][40265] +* [Configure build correctly on 64-bit CPU's with the armhf ABI][40261] +* [Fix MSP430 breakage due to `i128`][40257] +* [Preliminary Solaris/SPARCv9 support][39903] +* [`rustc` is linked statically on Windows MSVC targets][39837], allowing it to + run without installing the MSVC runtime. +* [`rustdoc --test` includes file names in test names][39788] +* This release includes builds of `std` for `sparc64-unknown-linux-gnu`, + `aarch64-unknown-linux-fuchsia`, and `x86_64-unknown-linux-fuchsia`. +* [Initial support for `aarch64-unknown-freebsd`][39491] +* [Initial support for `i686-unknown-netbsd`][39426] +* [This release no longer includes the old makefile build system][39431]. Rust + is built with a custom build system, written in Rust, and with Cargo. +* [Add Debug implementations for libcollection structs][39002] +* [`TypeId` implements `PartialOrd` and `Ord`][38981] +* [`--test-threads=0` produces an error][38945] +* [`rustup` installs documentation by default][40526] +* [The Rust source includes NatVis visualizations][39843]. These can be used by + WinDbg and Visual Studio to improve the debugging experience. + +Compatibility Notes +------------------- + +* [Rust 1.17 does not correctly detect the MSVC 2017 linker][38584]. As a + workaround, either use MSVC 2015 or run vcvars.bat. +* [When coercing to an unsized type lifetimes must be equal][40319]. That is, + disallow subtyping between `T` and `U` when `T: Unsize`, e.g. coercing + `&mut [&'a X; N]` to `&mut [&'b X]` requires `'a` be equal to `'b`. Soundness + fix. +* [`format!` and `Display::to_string` panic if an underlying formatting + implementation returns an error][40117]. Previously the error was silently + ignored. It is incorrect for `write_fmt` to return an error when writing + to a string. +* [In-tree crates are verified to be unstable][39851]. Previously, some minor + crates were marked stable and could be accessed from the stable toolchain. +* [Rust git source no longer includes vendored crates][39728]. Those that need + to build with vendored crates should build from release tarballs. +* [Fix inert attributes from `proc_macro_derives`][39572] +* [During crate resolution, rustc prefers a crate in the sysroot if two crates + are otherwise identical][39518]. Unlikely to be encountered outside the Rust + build system. +* [Fixed bugs around how type inference interacts with dead-code][39485]. The + existing code generally ignores the type of dead-code unless a type-hint is + provided; this can cause surprising inference interactions particularly around + defaulting. The new code uniformly ignores the result type of dead-code. +* [Tuple-struct constructors with private fields are no longer visible][38932] +* [Lifetime parameters that do not appear in the arguments are now considered + early-bound][38897], resolving a soundness bug (#[32330]). The + `hr_lifetime_in_assoc_type` future-compatibility lint has been in effect since + April of 2016. +* [rustdoc: fix doctests with non-feature crate attributes][38161] +* [Make transmuting from fn item types to pointer-sized types a hard + error][34198] + +[27787]: https://github.com/rust-lang/rust/issues/27787 +[32330]: https://github.com/rust-lang/rust/issues/32330 +[34198]: https://github.com/rust-lang/rust/pull/34198 +[38161]: https://github.com/rust-lang/rust/pull/38161 +[38368]: https://github.com/rust-lang/rust/pull/38368 +[38584]: https://github.com/rust-lang/rust/issues/38584 +[38661]: https://github.com/rust-lang/rust/pull/38661 +[38764]: https://github.com/rust-lang/rust/pull/38764 +[38864]: https://github.com/rust-lang/rust/issues/38864 +[38897]: https://github.com/rust-lang/rust/pull/38897 +[38921]: https://github.com/rust-lang/rust/pull/38921 +[38932]: https://github.com/rust-lang/rust/pull/38932 +[38945]: https://github.com/rust-lang/rust/pull/38945 +[38981]: https://github.com/rust-lang/rust/pull/38981 +[39002]: https://github.com/rust-lang/rust/pull/39002 +[39116]: https://github.com/rust-lang/rust/pull/39116 +[39193]: https://github.com/rust-lang/rust/pull/39193 +[39265]: https://github.com/rust-lang/rust/pull/39265 +[39356]: https://github.com/rust-lang/rust/pull/39356 +[39372]: https://github.com/rust-lang/rust/pull/39372 +[39426]: https://github.com/rust-lang/rust/pull/39426 +[39431]: https://github.com/rust-lang/rust/pull/39431 +[39438]: https://github.com/rust-lang/rust/pull/39438 +[39440]: https://github.com/rust-lang/rust/pull/39440 +[39485]: https://github.com/rust-lang/rust/pull/39485 +[39491]: https://github.com/rust-lang/rust/pull/39491 +[39518]: https://github.com/rust-lang/rust/pull/39518 +[39538]: https://github.com/rust-lang/rust/pull/39538 +[39572]: https://github.com/rust-lang/rust/pull/39572 +[39633]: https://github.com/rust-lang/rust/pull/39633 +[39642]: https://github.com/rust-lang/rust/pull/39642 +[39728]: https://github.com/rust-lang/rust/pull/39728 +[39761]: https://github.com/rust-lang/rust/pull/39761 +[39788]: https://github.com/rust-lang/rust/pull/39788 +[39793]: https://github.com/rust-lang/rust/pull/39793 +[39837]: https://github.com/rust-lang/rust/pull/39837 +[39843]: https://github.com/rust-lang/rust/pull/39843 +[39851]: https://github.com/rust-lang/rust/pull/39851 +[39903]: https://github.com/rust-lang/rust/pull/39903 +[39939]: https://github.com/rust-lang/rust/pull/39939 +[39953]: https://github.com/rust-lang/rust/pull/39953 +[39960]: https://github.com/rust-lang/rust/pull/39960 +[39990]: https://github.com/rust-lang/rust/pull/39990 +[39995]: https://github.com/rust-lang/rust/pull/39995 +[40008]: https://github.com/rust-lang/rust/pull/40008 +[40009]: https://github.com/rust-lang/rust/pull/40009 +[40027]: https://github.com/rust-lang/rust/pull/40027 +[40028]: https://github.com/rust-lang/rust/pull/40028 +[40037]: https://github.com/rust-lang/rust/pull/40037 +[40117]: https://github.com/rust-lang/rust/pull/40117 +[40166]: https://github.com/rust-lang/rust/pull/40166 +[40245]: https://github.com/rust-lang/rust/pull/40245 +[40257]: https://github.com/rust-lang/rust/pull/40257 +[40261]: https://github.com/rust-lang/rust/pull/40261 +[40265]: https://github.com/rust-lang/rust/pull/40265 +[40319]: https://github.com/rust-lang/rust/pull/40319 +[40336]: https://github.com/rust-lang/rust/pull/40336 +[40526]: https://github.com/rust-lang/rust/pull/40526 +[RFC 1623]: https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md +[RFC 1647]: https://github.com/rust-lang/rfcs/blob/master/text/1647-allow-self-in-where-clauses.md +[RFC 1651]: https://github.com/rust-lang/rfcs/blob/master/text/1651-movecell.md +[RFC 1682]: https://github.com/rust-lang/rfcs/blob/master/text/1682-field-init-shorthand.md +[`Arc::from_raw`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.from_raw +[`Arc::into_raw`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.into_raw +[`Arc::ptr_eq`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.ptr_eq +[`BTreeMap::range_mut`]: https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.range_mut +[`BTreeMap::range`]: https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.range +[`Cell::into_inner`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.into_inner +[`Cell::replace`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.replace +[`Cell::swap`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.swap +[`Cell::take`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.take +[`Ordering::then_with`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then_with +[`Ordering::then`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then +[`Rc::from_raw`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.from_raw +[`Rc::into_raw`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.into_raw +[`Rc::ptr_eq`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.ptr_eq +[`Result::expect_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect_err +[`collections::Bound`]: https://doc.rust-lang.org/std/collections/enum.Bound.html +[`process::abort`]: https://doc.rust-lang.org/std/process/fn.abort.html +[`ptr::read_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html +[`ptr::write_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.write_unaligned.html +[cargo/3562]: https://github.com/rust-lang/cargo/pull/3562 +[cargo/3664]: https://github.com/rust-lang/cargo/pull/3664 +[cargo/3667]: https://github.com/rust-lang/cargo/pull/3667 +[cargo/3691]: https://github.com/rust-lang/cargo/pull/3691 +[cargo/3699]: https://github.com/rust-lang/cargo/pull/3699 +[cargo/3731]: https://github.com/rust-lang/cargo/pull/3731 +[mdbook]: https://crates.io/crates/mdbook +[ubook]: https://doc.rust-lang.org/unstable-book/ + + Version 1.16.0 (2017-03-16) =========================== From d0d3ae4bb1ad152fe645c7b88ce5b12e7e3df685 Mon Sep 17 00:00:00 2001 From: Cameron Hart Date: Tue, 25 Apr 2017 20:24:33 +1000 Subject: [PATCH 4/5] Add missing struct field index adjustments. Some accesses in OperandPairs were missing. Fixes #41479. --- src/librustc_trans/mir/operand.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 6889b5064b649..8b7c7d9d37232 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -85,8 +85,15 @@ impl<'a, 'tcx> OperandRef<'tcx> { assert!(common::type_is_zero_size(ccx, ty)); let llty = type_of::type_of(ccx, ty); let val = if common::type_is_imm_pair(ccx, ty) { + let layout = ccx.layout_of(ty); + let (ix0, ix1) = if let Layout::Univariant { ref variant, .. } = *layout { + (adt::struct_llfields_index(variant, 0), + adt::struct_llfields_index(variant, 1)) + } else { + (0, 1) + }; let fields = llty.field_types(); - OperandValue::Pair(C_null(fields[0]), C_null(fields[1])) + OperandValue::Pair(C_null(fields[ix0]), C_null(fields[ix1])) } else { OperandValue::Immediate(C_null(llty)) }; @@ -156,8 +163,16 @@ impl<'a, 'tcx> OperandRef<'tcx> { if common::type_is_imm_pair(bcx.ccx, self.ty) { debug!("Operand::unpack_if_pair: unpacking {:?}", self); - let mut a = bcx.extract_value(llval, 0); - let mut b = bcx.extract_value(llval, 1); + let layout = bcx.ccx.layout_of(self.ty); + let (ix0, ix1) = if let Layout::Univariant { ref variant, .. } = *layout { + (adt::struct_llfields_index(variant, 0), + adt::struct_llfields_index(variant, 1)) + } else { + (0, 1) + }; + + let mut a = bcx.extract_value(llval, ix0); + let mut b = bcx.extract_value(llval, ix1); let pair_fields = common::type_pair_fields(bcx.ccx, self.ty); if let Some([a_ty, b_ty]) = pair_fields { From 1fdce3dbc50ccfc351ce27b955c904856977c7ab Mon Sep 17 00:00:00 2001 From: Cameron Hart Date: Tue, 25 Apr 2017 21:16:41 +1000 Subject: [PATCH 5/5] Added test for #41479 from @eddyb. --- src/test/run-pass/issue-41479.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/run-pass/issue-41479.rs diff --git a/src/test/run-pass/issue-41479.rs b/src/test/run-pass/issue-41479.rs new file mode 100644 index 0000000000000..cc97b3323cf33 --- /dev/null +++ b/src/test/run-pass/issue-41479.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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 split(pair: (A, B)) { + let _a = pair.0; + let _b = pair.1; +} + +fn main() { + split(((), ((), ()))); +}