diff options
| author | Masaki Hara <ackie.h.gmai@gmail.com> | 2017-06-24 16:20:27 +0900 |
|---|---|---|
| committer | Masaki Hara <ackie.h.gmai@gmail.com> | 2017-06-29 21:25:35 +0900 |
| commit | 03660b647690c3dea12a20468f9f798bacd14d82 (patch) | |
| tree | d132feb401ad434efda260612205aaff4ce1d84a | |
| parent | b0bf1b46820d74c30a725a7ea332305098bf3def (diff) | |
| download | rust-03660b647690c3dea12a20468f9f798bacd14d82.tar.gz rust-03660b647690c3dea12a20468f9f798bacd14d82.zip | |
Move unsized_tuple_coercion behind a feature gate.
| -rw-r--r-- | src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md | 27 | ||||
| -rw-r--r-- | src/librustc_typeck/check/coercion.rs | 21 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/dst-bad-assign-3.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/dst-bad-coerce1.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/dst-bad-coerce3.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/dst-bad-coerce4.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/dst-bad-deep-2.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/feature-gate-unsized_tuple_coercion.rs | 14 | ||||
| -rw-r--r-- | src/test/run-pass-valgrind/dst-dtor-3.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass-valgrind/dst-dtor-4.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/dst-irrefutable-bind.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/dst-raw.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/dst-trait-tuple.rs | 1 | ||||
| -rw-r--r-- | src/test/run-pass/dst-tuple-sole.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/dst-tuple.rs | 1 |
16 files changed, 89 insertions, 1 deletions
diff --git a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md b/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md new file mode 100644 index 00000000000..c243737e1be --- /dev/null +++ b/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md @@ -0,0 +1,27 @@ +# `unsized_tuple_coercion` + +The tracking issue for this feature is: [#XXXXX] + +[#XXXXX]: https://github.com/rust-lang/rust/issues/XXXXX + +------------------------ + +This is a part of [RFC0401]. According to the RFC, there should be an implementation like this: + +```rust +impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {} +``` + +This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this: + +```rust +#![feature(unsized_tuple_coercion)] + +fn main() { + let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]); + let y : &([i32; 3], [i32]) = &x; + assert_eq!(y.1[0], 4); +} +``` + +[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 81aa59e956a..968e893b9a0 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -76,6 +76,7 @@ use rustc::ty::relate::RelateResult; use rustc::ty::subst::Subst; use errors::DiagnosticBuilder; use syntax::abi; +use syntax::feature_gate; use syntax::ptr::P; use syntax_pos; @@ -520,6 +521,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { coerce_source, &[coerce_target])); + let mut has_unsized_tuple_coercion = false; + // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where // inference might unify those two inner type variables later. @@ -527,7 +530,15 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { while let Some(obligation) = queue.pop_front() { debug!("coerce_unsized resolve step: {:?}", obligation); let trait_ref = match obligation.predicate { - ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => tr.clone(), + ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => { + if unsize_did == tr.def_id() { + if let ty::TyTuple(..) = tr.0.input_types().nth(1).unwrap().sty { + debug!("coerce_unsized: found unsized tuple coercion"); + has_unsized_tuple_coercion = true; + } + } + tr.clone() + } _ => { coercion.obligations.push(obligation); continue; @@ -557,6 +568,14 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { } } + if has_unsized_tuple_coercion && !self.tcx.sess.features.borrow().unsized_tuple_coercion { + feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, + "unsized_tuple_coercion", + self.cause.span, + feature_gate::GateIssue::Language, + feature_gate::EXPLAIN_UNSIZED_TUPLE_COERCION); + } + Ok(coercion) } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 74bf19b841e..5de9062de74 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -357,6 +357,9 @@ declare_features! ( // Allows a test to fail without failing the whole suite (active, allow_fail, "1.19.0", Some(42219)), + + // Allows unsized tuple coercion. + (active, unsized_tuple_coercion, "1.20.0", None), ); declare_features! ( @@ -1041,6 +1044,9 @@ pub const EXPLAIN_VIS_MATCHER: &'static str = pub const EXPLAIN_PLACEMENT_IN: &'static str = "placement-in expression syntax is experimental and subject to change."; +pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str = + "Unsized tuple coercion is not stable enough for use and is subject to change"; + struct PostExpansionVisitor<'a> { context: &'a Context<'a>, } diff --git a/src/test/compile-fail/dst-bad-assign-3.rs b/src/test/compile-fail/dst-bad-assign-3.rs index 3c089edf001..1c3bad5ba56 100644 --- a/src/test/compile-fail/dst-bad-assign-3.rs +++ b/src/test/compile-fail/dst-bad-assign-3.rs @@ -10,6 +10,8 @@ // Forbid assignment into a dynamically sized type. +#![feature(unsized_tuple_coercion)] + type Fat<T: ?Sized> = (isize, &'static str, T); //~^ WARNING trait bounds are not (yet) enforced diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs index 722ff8f25d6..b0de84a5300 100644 --- a/src/test/compile-fail/dst-bad-coerce1.rs +++ b/src/test/compile-fail/dst-bad-coerce1.rs @@ -10,6 +10,8 @@ // Attempt to change the type as well as unsizing. +#![feature(unsized_tuple_coercion)] + struct Fat<T: ?Sized> { ptr: T } diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs index 4dedae9331b..35a147c15bb 100644 --- a/src/test/compile-fail/dst-bad-coerce3.rs +++ b/src/test/compile-fail/dst-bad-coerce3.rs @@ -10,6 +10,8 @@ // Attempt to extend the lifetime as well as unsizing. +#![feature(unsized_tuple_coercion)] + struct Fat<T: ?Sized> { ptr: T } diff --git a/src/test/compile-fail/dst-bad-coerce4.rs b/src/test/compile-fail/dst-bad-coerce4.rs index 2e78108a8de..874b7588ff9 100644 --- a/src/test/compile-fail/dst-bad-coerce4.rs +++ b/src/test/compile-fail/dst-bad-coerce4.rs @@ -10,6 +10,8 @@ // Attempt to coerce from unsized to sized. +#![feature(unsized_tuple_coercion)] + struct Fat<T: ?Sized> { ptr: T } diff --git a/src/test/compile-fail/dst-bad-deep-2.rs b/src/test/compile-fail/dst-bad-deep-2.rs index 831afd27153..0c812b1d815 100644 --- a/src/test/compile-fail/dst-bad-deep-2.rs +++ b/src/test/compile-fail/dst-bad-deep-2.rs @@ -13,6 +13,8 @@ // because it would require stack allocation of an unsized temporary (*g in the // test). +#![feature(unsized_tuple_coercion)] + pub fn main() { let f: ([isize; 3],) = ([5, 6, 7],); let g: &([isize],) = &f; diff --git a/src/test/compile-fail/feature-gate-unsized_tuple_coercion.rs b/src/test/compile-fail/feature-gate-unsized_tuple_coercion.rs new file mode 100644 index 00000000000..4ddde011263 --- /dev/null +++ b/src/test/compile-fail/feature-gate-unsized_tuple_coercion.rs @@ -0,0 +1,14 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let _ : &(Send,) = &((),); + //~^ ERROR Unsized tuple coercion is not stable enough +} diff --git a/src/test/run-pass-valgrind/dst-dtor-3.rs b/src/test/run-pass-valgrind/dst-dtor-3.rs index b21f6434b54..1ae66a28a84 100644 --- a/src/test/run-pass-valgrind/dst-dtor-3.rs +++ b/src/test/run-pass-valgrind/dst-dtor-3.rs @@ -10,6 +10,8 @@ // no-prefer-dynamic +#![feature(unsized_tuple_coercion)] + static mut DROP_RAN: bool = false; struct Foo; diff --git a/src/test/run-pass-valgrind/dst-dtor-4.rs b/src/test/run-pass-valgrind/dst-dtor-4.rs index 810589de770..e416f25bc03 100644 --- a/src/test/run-pass-valgrind/dst-dtor-4.rs +++ b/src/test/run-pass-valgrind/dst-dtor-4.rs @@ -10,6 +10,8 @@ // no-prefer-dynamic +#![feature(unsized_tuple_coercion)] + static mut DROP_RAN: isize = 0; struct Foo; diff --git a/src/test/run-pass/dst-irrefutable-bind.rs b/src/test/run-pass/dst-irrefutable-bind.rs index bd6ad9207ad..b1d6c732e7f 100644 --- a/src/test/run-pass/dst-irrefutable-bind.rs +++ b/src/test/run-pass/dst-irrefutable-bind.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(unsized_tuple_coercion)] + struct Test<T: ?Sized>(T); fn main() { diff --git a/src/test/run-pass/dst-raw.rs b/src/test/run-pass/dst-raw.rs index c82cbd75044..9ebfbee8a33 100644 --- a/src/test/run-pass/dst-raw.rs +++ b/src/test/run-pass/dst-raw.rs @@ -11,6 +11,8 @@ // Test DST raw pointers +#![feature(unsized_tuple_coercion)] + trait Trait { fn foo(&self) -> isize; } diff --git a/src/test/run-pass/dst-trait-tuple.rs b/src/test/run-pass/dst-trait-tuple.rs index ab60e95c74e..9803e26f5f8 100644 --- a/src/test/run-pass/dst-trait-tuple.rs +++ b/src/test/run-pass/dst-trait-tuple.rs @@ -11,6 +11,7 @@ #![allow(unused_features)] #![feature(box_syntax)] +#![feature(unsized_tuple_coercion)] type Fat<T: ?Sized> = (isize, &'static str, T); diff --git a/src/test/run-pass/dst-tuple-sole.rs b/src/test/run-pass/dst-tuple-sole.rs index d3901a7555f..a788e25218e 100644 --- a/src/test/run-pass/dst-tuple-sole.rs +++ b/src/test/run-pass/dst-tuple-sole.rs @@ -11,6 +11,8 @@ // As dst-tuple.rs, but the unsized field is the only field in the tuple. +#![feature(unsized_tuple_coercion)] + type Fat<T: ?Sized> = (T,); // x is a fat pointer diff --git a/src/test/run-pass/dst-tuple.rs b/src/test/run-pass/dst-tuple.rs index 130294feb6c..2f5b28495b8 100644 --- a/src/test/run-pass/dst-tuple.rs +++ b/src/test/run-pass/dst-tuple.rs @@ -11,6 +11,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] +#![feature(unsized_tuple_coercion)] type Fat<T: ?Sized> = (isize, &'static str, T); |
