From 89ddd717caf7084c9fe292ceaa46828c65573097 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 18 Mar 2017 12:24:42 -0400 Subject: [PATCH 01/12] Revert "Auto merge of #39485 - canndrew:inference-fix-39297, r=nikomatsakis" This reverts commit dc0bb3f2839c13ab42feacd423f728fbfd2f2f7a, reversing changes made to e879aa43ef63962f8e4d797292194a9f40a22a13. This is a temporary step intended to fix regressions. A more comprehensive fix for type inference and dead-code is in the works. --- src/librustc_typeck/check/mod.rs | 11 +++++++++++ .../issue-10176.rs} | 8 ++++---- src/test/compile-fail/issue-5500.rs | 17 +++++++++++++++++ src/test/run-pass/issue-15763.rs | 7 +++---- src/test/run-pass/project-defer-unification.rs | 4 +--- 5 files changed, 36 insertions(+), 11 deletions(-) rename src/test/{run-pass/inference-changes-39485.rs => compile-fail/issue-10176.rs} (82%) create mode 100644 src/test/compile-fail/issue-5500.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c857388106d5a..9c62fd486d45a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4099,6 +4099,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; if self.diverges.get().always() { + if let ExpectHasType(ety) = expected { + // Avoid forcing a type (only `!` for now) in unreachable code. + // FIXME(aburka) do we need this special case? and should it be is_uninhabited? + if !ety.is_never() { + if let Some(ref e) = blk.expr { + // Coerce the tail expression to the right type. + self.demand_coerce(e, ty, ety); + } + } + } + ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span)); } else if let ExpectHasType(ety) = expected { if let Some(ref e) = blk.expr { diff --git a/src/test/run-pass/inference-changes-39485.rs b/src/test/compile-fail/issue-10176.rs similarity index 82% rename from src/test/run-pass/inference-changes-39485.rs rename to src/test/compile-fail/issue-10176.rs index 193c66b2a2afd..434b795ff31f5 100644 --- a/src/test/run-pass/inference-changes-39485.rs +++ b/src/test/compile-fail/issue-10176.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn g() { - &panic!() -} - fn f() -> isize { (return 1, return 2) +//~^ ERROR mismatched types +//~| expected type `isize` +//~| found type `(_, _)` +//~| expected isize, found tuple } fn main() {} diff --git a/src/test/compile-fail/issue-5500.rs b/src/test/compile-fail/issue-5500.rs new file mode 100644 index 0000000000000..1cbb7588e17df --- /dev/null +++ b/src/test/compile-fail/issue-5500.rs @@ -0,0 +1,17 @@ +// Copyright 2013 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() { + &panic!() + //~^ ERROR mismatched types + //~| expected type `()` + //~| found type `&_` + //~| expected (), found reference +} diff --git a/src/test/run-pass/issue-15763.rs b/src/test/run-pass/issue-15763.rs index f77888c29554d..0baaaac267685 100644 --- a/src/test/run-pass/issue-15763.rs +++ b/src/test/run-pass/issue-15763.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(unused_features)] -#![allow(unreachable_code)] +#![allow(unknown_features)] #![feature(box_syntax)] #[derive(PartialEq, Debug)] @@ -29,14 +28,14 @@ struct Foo { } fn foo() -> Result { - return Ok::(Foo { + return Ok(Foo { x: Bar { x: 22 }, a: return Err(32) }); } fn baz() -> Result { - Ok::(Foo { + Ok(Foo { x: Bar { x: 22 }, a: return Err(32) }) diff --git a/src/test/run-pass/project-defer-unification.rs b/src/test/run-pass/project-defer-unification.rs index 8e008c639b30e..9a6ea2272fea7 100644 --- a/src/test/run-pass/project-defer-unification.rs +++ b/src/test/run-pass/project-defer-unification.rs @@ -11,8 +11,6 @@ // A regression test extracted from image-0.3.11. The point of // failure was in `index_colors` below. -#![allow(unused)] - use std::ops::{Deref, DerefMut}; #[derive(Copy, Clone)] @@ -94,7 +92,7 @@ pub fn index_colors(image: &ImageBuffer>) -> ImageBuffer, Vec> where Pix: Pixel + 'static, { - let mut indices: ImageBuffer, Vec> = loop { }; + let mut indices: ImageBuffer<_,Vec<_>> = loop { }; for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) { // failured occurred here ^^ because we were requiring that we // could project Pixel or Subpixel from `T_indices` (type of From 0f1eb8a70f0f877eba4b55151949df8861377c65 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 18 Mar 2017 12:28:34 -0400 Subject: [PATCH 02/12] add regression test for #39984 Fixes #39984 --- src/test/run-pass/issue-39984.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/run-pass/issue-39984.rs diff --git a/src/test/run-pass/issue-39984.rs b/src/test/run-pass/issue-39984.rs new file mode 100644 index 0000000000000..a0019e7215c98 --- /dev/null +++ b/src/test/run-pass/issue-39984.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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 #39984. +// +// The key here is that the error type of the `Ok` call ought to be +// constrained to `String`, even though it is dead-code. + +fn main() {} + +fn t() -> Result<(), String> { + return Err("".into()); + Ok(()) +} From a033f1a8eeb55bdf93749a5d0c4d803bbe0d8dfc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 22 Mar 2017 10:32:38 -0700 Subject: [PATCH 03/12] Simplify hash table drops This replaces the `std::collections::hash::table::RevMoveBuckets` iterator with a simpler `while` loop. This iterator was only used for dropping the remaining elements of a `RawTable`, so instead we can just loop through directly and drop them in place. This should be functionally equivalent to the former code, but a little easier to read. I was hoping it might have some performance benefit too, but it seems the optimizer was already good enough to see through the iterator -- the generated code is nearly the same. Maybe it will still help if an element type has more complicated drop code. --- src/libstd/collections/hash/table.rs | 65 ++++++++-------------------- 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 211605bef1ee0..da5fb1a47333e 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -896,15 +896,23 @@ impl RawTable { } } - /// Returns an iterator that copies out each entry. Used while the table - /// is being dropped. - unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets { - let raw_bucket = self.first_bucket_raw(); - RevMoveBuckets { - raw: raw_bucket.offset(self.capacity as isize), - hashes_end: raw_bucket.hash, - elems_left: self.size, - marker: marker::PhantomData, + /// Drops buckets in reverse order. It leaves the table in an inconsistent + /// state and should only be used for dropping the table's remaining + /// entries. It's used in the implementation of Drop. + unsafe fn rev_drop_buckets(&mut self) { + let first_raw = self.first_bucket_raw(); + let mut raw = first_raw.offset(self.capacity as isize); + let mut elems_left = self.size; + + while elems_left != 0 { + debug_assert!(raw.hash != first_raw.hash); + + raw = raw.offset(-1); + + if *raw.hash != EMPTY_BUCKET { + elems_left -= 1; + ptr::drop_in_place(raw.pair as *mut (K, V)); + } } } @@ -964,43 +972,6 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> { } } -/// An iterator that moves out buckets in reverse order. It leaves the table -/// in an inconsistent state and should only be used for dropping -/// the table's remaining entries. It's used in the implementation of Drop. -struct RevMoveBuckets<'a, K, V> { - raw: RawBucket, - hashes_end: *mut HashUint, - elems_left: usize, - - // As above, `&'a (K,V)` would seem better, but we often use - // 'static for the lifetime, and this is not a publicly exposed - // type. - marker: marker::PhantomData<&'a ()>, -} - -impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> { - type Item = (K, V); - - fn next(&mut self) -> Option<(K, V)> { - if self.elems_left == 0 { - return None; - } - - loop { - debug_assert!(self.raw.hash != self.hashes_end); - - unsafe { - self.raw = self.raw.offset(-1); - - if *self.raw.hash != EMPTY_BUCKET { - self.elems_left -= 1; - return Some(ptr::read(self.raw.pair)); - } - } - } - } -} - /// Iterator over shared references to entries in a table. pub struct Iter<'a, K: 'a, V: 'a> { iter: RawBuckets<'a, K, V>, @@ -1227,7 +1198,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable { unsafe { if needs_drop::<(K, V)>() { // avoid linear runtime for types that don't need drop - for _ in self.rev_move_buckets() {} + self.rev_drop_buckets(); } } From 49c408e679653d8b5e01209b9fe01f952db9ca29 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Thu, 23 Mar 2017 12:20:13 +0100 Subject: [PATCH 04/12] Fix markdown links to pdqsort --- src/libcollections/slice.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index d3723ace9efb3..f7451f574ffa3 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1162,7 +1162,7 @@ impl [T] { /// /// # Current implementation /// - /// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort], + /// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort], /// which is a quicksort variant designed to be very fast on certain kinds of patterns, /// sometimes achieving linear time. It is randomized but deterministic, and falls back to /// heapsort on degenerate inputs. @@ -1199,7 +1199,7 @@ impl [T] { /// /// # Current implementation /// - /// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort], + /// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort], /// which is a quicksort variant designed to be very fast on certain kinds of patterns, /// sometimes achieving linear time. It is randomized but deterministic, and falls back to /// heapsort on degenerate inputs. @@ -1239,7 +1239,7 @@ impl [T] { /// /// # Current implementation /// - /// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort], + /// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort], /// which is a quicksort variant designed to be very fast on certain kinds of patterns, /// sometimes achieving linear time. It is randomized but deterministic, and falls back to /// heapsort on degenerate inputs. From c09083c3d1b077df9adf3d6b4048677a15ba666e Mon Sep 17 00:00:00 2001 From: Clar Charr Date: Thu, 16 Mar 2017 00:11:44 -0400 Subject: [PATCH 05/12] Fix for #39596: sort Trait1 before Trait2. --- src/librustdoc/html/render.rs | 50 ++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 7b60d497932de..1f891177797dc 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1700,6 +1700,23 @@ fn document_stability(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) Ok(()) } +fn name_key(name: &str) -> (&str, u64, usize) { + // find number at end + let split = name.bytes().rposition(|b| b < b'0' || b'9' < b).map_or(0, |s| s + 1); + + // count leading zeroes + let after_zeroes = + name[split..].bytes().position(|b| b != b'0').map_or(name.len(), |extra| split + extra); + + // sort leading zeroes last + let num_zeroes = after_zeroes - split; + + match name[split..].parse() { + Ok(n) => (&name[..split], n, num_zeroes), + Err(_) => (name, 0, num_zeroes), + } +} + fn item_module(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, items: &[clean::Item]) -> fmt::Result { document(w, cx, item)?; @@ -1744,7 +1761,9 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, (Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less, _ => {} } - i1.name.cmp(&i2.name) + let lhs = i1.name.as_ref().map_or("", |s| &**s); + let rhs = i2.name.as_ref().map_or("", |s| &**s); + name_key(lhs).cmp(&name_key(rhs)) } indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); @@ -3198,3 +3217,32 @@ fn test_unique_id() { reset_ids(true); test(); } + +#[cfg(test)] +#[test] +fn test_name_key() { + assert_eq!(name_key("0"), ("", 0, 1)); + assert_eq!(name_key("123"), ("", 123, 0)); + assert_eq!(name_key("Fruit"), ("Fruit", 0, 0)); + assert_eq!(name_key("Fruit0"), ("Fruit", 0, 1)); + assert_eq!(name_key("Fruit0000"), ("Fruit", 0, 4)); + assert_eq!(name_key("Fruit01"), ("Fruit", 1, 1)); + assert_eq!(name_key("Fruit10"), ("Fruit", 10, 0)); + assert_eq!(name_key("Fruit123"), ("Fruit", 123, 0)); +} + +#[cfg(test)] +#[test] +fn test_name_sorting() { + let names = ["Apple", + "Banana", + "Fruit", "Fruit0", "Fruit00", + "Fruit1", "Fruit01", + "Fruit2", "Fruit02", + "Fruit20", + "Fruit100", + "Pear"]; + let mut sorted = names.to_owned(); + sorted.sort_by_key(|&s| name_key(s)); + assert_eq!(names, sorted); +} From f97b3f08cde6dff89c8c236fce2479725d7f909e Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Fri, 24 Mar 2017 06:18:23 +0300 Subject: [PATCH 06/12] Unnecessary iteration in BTreeMap::drop `IntoIter::drop` already iterates. --- src/libcollections/btree/map.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index bed216ba3d111..dcacef4f0f0d5 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -141,8 +141,7 @@ pub struct BTreeMap { unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap { fn drop(&mut self) { unsafe { - for _ in ptr::read(self).into_iter() { - } + drop(ptr::read(self).into_iter()); } } } From 9b0a4a4e97c4977aae45934d2138d8db27b16843 Mon Sep 17 00:00:00 2001 From: Petr Zemek Date: Fri, 24 Mar 2017 09:42:21 +0100 Subject: [PATCH 07/12] Fix formatting in the docs for std::process::Command::envs(). An empty line between the "Basic usage:" text and the example is required to properly format the code. Without the empty line, the example is not formatted as code. --- src/libstd/process.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 7a85e58866236..b57a9883afe31 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -437,6 +437,7 @@ impl Command { /// # Examples /// /// Basic usage: + /// /// ```no_run /// use std::process::{Command, Stdio}; /// use std::env; From 432673a8ddbe5b62c8a15b7bc0141cf9a303866a Mon Sep 17 00:00:00 2001 From: Petr Zemek Date: Fri, 24 Mar 2017 15:47:45 +0100 Subject: [PATCH 08/12] Add a missing feature attribute to the example for std::process::Command::envs(). The person who originally wrote the example forgot to include this attribute. This caused Travis CI to fail on commit 9b0a4a4e97 (#40794), which just fixed formatting in the description of std::process::Command::envs(). --- src/libstd/process.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index b57a9883afe31..d46cf7a26daf0 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -439,6 +439,8 @@ impl Command { /// Basic usage: /// /// ```no_run + /// #![feature(command_envs)] + /// /// use std::process::{Command, Stdio}; /// use std::env; /// use std::collections::HashMap; From b0d9afbc04483a8c19f15e13e3a61ce11892536d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 7 Mar 2017 16:09:01 +0100 Subject: [PATCH 09/12] Represent function pointers in mir-constants as a Value instead of Item --- src/librustc/mir/mod.rs | 14 ++++----- src/librustc_mir/build/scope.rs | 6 ++-- src/librustc_mir/hair/cx/expr.rs | 33 +++++++++++--------- src/librustc_mir/hair/cx/mod.rs | 5 ++- src/librustc_mir/shim.rs | 5 ++- src/librustc_mir/transform/qualify_consts.rs | 5 --- src/librustc_mir/transform/type_check.rs | 5 ++- src/librustc_mir/util/elaborate_drops.rs | 6 ++-- src/librustc_trans/mir/analyze.rs | 7 +++-- src/librustc_trans/mir/constant.rs | 15 +++++---- 10 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9fdb866577699..01dc7f51e29d9 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -983,16 +983,16 @@ impl<'tcx> Debug for Operand<'tcx> { } impl<'tcx> Operand<'tcx> { - pub fn item<'a>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - substs: &'tcx Substs<'tcx>, - span: Span) - -> Self - { + pub fn function_handle<'a>( + tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + substs: &'tcx Substs<'tcx>, + span: Span, + ) -> Self { Operand::Constant(Constant { span: span, ty: tcx.item_type(def_id).subst(tcx, substs), - literal: Literal::Item { def_id, substs } + literal: Literal::Value { value: ConstVal::Function(def_id, substs) }, }) } diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 1de5b9218564f..dd4190a412dac 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -89,6 +89,7 @@ should go to. use build::{BlockAnd, BlockAndExtension, Builder, CFG}; use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::middle::lang_items; +use rustc::middle::const_val::ConstVal; use rustc::ty::subst::{Kind, Subst}; use rustc::ty::{Ty, TyCtxt}; use rustc::mir::*; @@ -784,9 +785,8 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, func: Operand::Constant(Constant { span: data.span, ty: tcx.item_type(free_func).subst(tcx, substs), - literal: Literal::Item { - def_id: free_func, - substs: substs + literal: Literal::Value { + value: ConstVal::Function(free_func, substs), } }), args: vec![Operand::Consume(data.value.clone())], diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index da58a1ed1f49b..44858a98e36f9 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -714,9 +714,8 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ty: callee.ty, span: expr.span, kind: ExprKind::Literal { - literal: Literal::Item { - def_id: callee.def_id, - substs: callee.substs, + literal: Literal::Value { + value: ConstVal::Function(callee.def_id, callee.substs), }, }, } @@ -743,14 +742,24 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> ExprKind<'tcx> { let substs = cx.tables().node_id_item_substs(expr.id) .unwrap_or_else(|| cx.tcx.intern_substs(&[])); - let def_id = match def { + match def { // A regular function, constructor function or a constant. Def::Fn(def_id) | Def::Method(def_id) | Def::StructCtor(def_id, CtorKind::Fn) | - Def::VariantCtor(def_id, CtorKind::Fn) | + Def::VariantCtor(def_id, CtorKind::Fn) => ExprKind::Literal { + literal: Literal::Value { + value: ConstVal::Function(def_id, substs), + }, + }, + Def::Const(def_id) | - Def::AssociatedConst(def_id) => def_id, + Def::AssociatedConst(def_id) => ExprKind::Literal { + literal: Literal::Item { + def_id: def_id, + substs: substs, + }, + }, Def::StructCtor(def_id, CtorKind::Const) | Def::VariantCtor(def_id, CtorKind::Const) => { @@ -758,7 +767,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // A unit struct/variant which is used as a value. // We return a completely different ExprKind here to account for this special case. ty::TyAdt(adt_def, substs) => { - return ExprKind::Adt { + ExprKind::Adt { adt_def: adt_def, variant_index: adt_def.variant_index_with_id(def_id), substs: substs, @@ -770,17 +779,11 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } - Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id }, + Def::Static(node_id, _) => ExprKind::StaticRef { id: node_id }, - Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def), + Def::Local(..) | Def::Upvar(..) => convert_var(cx, expr, def), _ => span_bug!(expr.span, "def `{:?}` not yet implemented", def), - }; - ExprKind::Literal { - literal: Literal::Item { - def_id: def_id, - substs: substs, - }, } } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index c555ce1ab9c42..3eef5d83b8ba0 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -132,9 +132,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { let method_ty = self.tcx.item_type(item.def_id); let method_ty = method_ty.subst(self.tcx, substs); return (method_ty, - Literal::Item { - def_id: item.def_id, - substs: substs, + Literal::Value { + value: ConstVal::Function(item.def_id, substs), }); } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 26d5b7fd38ab0..63d20be88feee 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -12,6 +12,7 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer; use rustc::middle::region::ROOT_CODE_EXTENT; +use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::transform::MirSource; use rustc::ty::{self, Ty}; @@ -335,7 +336,9 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, Operand::Constant(Constant { span: span, ty: tcx.item_type(def_id).subst(tcx, param_env.free_substs), - literal: Literal::Item { def_id, substs: param_env.free_substs }, + literal: Literal::Value { + value: ConstVal::Function(def_id, param_env.free_substs), + }, }), vec![rcvr] ) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index e998665e03536..ba42804c9262f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -568,11 +568,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { }); } Operand::Constant(ref constant) => { - // Only functions and methods can have these types. - if let ty::TyFnDef(..) = constant.ty.sty { - return; - } - if let Literal::Item { def_id, substs } = constant.literal { // Don't peek inside generic (associated) constants. if substs.types().next().is_some() { diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index f98bb73c504dc..3d604affbfea9 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -15,6 +15,7 @@ use rustc::infer::{self, InferCtxt, InferOk}; use rustc::traits::{self, Reveal}; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, Ty, TyCtxt, TypeVariants}; +use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::tcx::LvalueTy; use rustc::mir::transform::{MirPass, MirSource, Pass}; @@ -526,7 +527,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { fn is_box_free(&self, operand: &Operand<'tcx>) -> bool { match operand { &Operand::Constant(Constant { - literal: Literal::Item { def_id, .. }, .. + literal: Literal::Value { + value: ConstVal::Function(def_id, _), .. + }, .. }) => { Some(def_id) == self.tcx().lang_items.box_free_fn() } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index d0f142ad7d7a8..ccbc6700d89c1 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -525,8 +525,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }], terminator: Some(Terminator { kind: TerminatorKind::Call { - func: Operand::item(tcx, drop_fn.def_id, substs, - self.source_info.span), + func: Operand::function_handle(tcx, drop_fn.def_id, substs, + self.source_info.span), args: vec![Operand::Consume(Lvalue::Local(ref_lvalue))], destination: Some((unit_temp, succ)), cleanup: unwind, @@ -629,7 +629,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let substs = tcx.mk_substs(iter::once(Kind::from(ty))); let call = TerminatorKind::Call { - func: Operand::item(tcx, free_func, substs, self.source_info.span), + func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), args: vec![Operand::Consume(self.lvalue.clone())], destination: Some((unit_temp, target)), cleanup: None diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 2c3b479c7dd0f..a3968650043ba 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -13,7 +13,8 @@ use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use rustc::mir::{self, Location, TerminatorKind}; +use rustc::middle::const_val::ConstVal; +use rustc::mir::{self, Location, TerminatorKind, Literal}; use rustc::mir::visit::{Visitor, LvalueContext}; use rustc::mir::traversal; use common; @@ -109,7 +110,9 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { match *kind { mir::TerminatorKind::Call { func: mir::Operand::Constant(mir::Constant { - literal: mir::Literal::Item { def_id, .. }, .. + literal: Literal::Value { + value: ConstVal::Function(def_id, _), .. + }, .. }), ref args, .. } if Some(def_id) == self.cx.ccx.tcx().lang_items.box_free_fn() => { diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 107b0982af982..5d7f71848f828 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -101,9 +101,12 @@ impl<'tcx> Const<'tcx> { ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()), ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"), ConstVal::Struct(_) | ConstVal::Tuple(_) | - ConstVal::Array(..) | ConstVal::Repeat(..) | + ConstVal::Array(..) | ConstVal::Repeat(..) => { + bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv) + } ConstVal::Function(..) => { - bug!("MIR must not use `{:?}` (which refers to a local ID)", cv) + let llty = type_of::type_of(ccx, ty); + return Const::new(C_null(llty), ty); } ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false), }; @@ -476,8 +479,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let ty = self.monomorphize(&constant.ty); match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { - // Shortcut for zero-sized types, including function item - // types, which would not work with MirConstContext. + // Shortcut for zero-sized types + // which would not work with MirConstContext. if common::type_is_zero_size(self.ccx, ty) { let llty = type_of::type_of(self.ccx, ty); return Ok(Const::new(C_null(llty), ty)); @@ -924,8 +927,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let ty = self.monomorphize(&constant.ty); let result = match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { - // Shortcut for zero-sized types, including function item - // types, which would not work with MirConstContext. + // Shortcut for zero-sized types + // which would not work with MirConstContext. if common::type_is_zero_size(bcx.ccx, ty) { let llty = type_of::type_of(bcx.ccx, ty); return Const::new(C_null(llty), ty); From 9c918464e186c7b19550004a771104589c0952d2 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 17 Mar 2017 17:47:09 +0100 Subject: [PATCH 10/12] Remove zst hacks --- src/librustc_trans/mir/constant.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 5d7f71848f828..dbd928194c032 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -479,13 +479,6 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let ty = self.monomorphize(&constant.ty); match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { - // Shortcut for zero-sized types - // which would not work with MirConstContext. - if common::type_is_zero_size(self.ccx, ty) { - let llty = type_of::type_of(self.ccx, ty); - return Ok(Const::new(C_null(llty), ty)); - } - let substs = self.monomorphize(&substs); MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new()) } @@ -927,13 +920,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let ty = self.monomorphize(&constant.ty); let result = match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { - // Shortcut for zero-sized types - // which would not work with MirConstContext. - if common::type_is_zero_size(bcx.ccx, ty) { - let llty = type_of::type_of(bcx.ccx, ty); - return Const::new(C_null(llty), ty); - } - let substs = self.monomorphize(&substs); MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new()) } From 3b0add459c49efab85dd617d236aa5b0d9687aa2 Mon Sep 17 00:00:00 2001 From: lukaramu Date: Fri, 24 Mar 2017 21:16:00 +0100 Subject: [PATCH 11/12] Update CONTRIBUTING.md Changed link to documentation issues from A-docs to T-doc as this has just been migrated. Added a link to the documentation style guidelines. --- CONTRIBUTING.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f921fb2c94233..651fffb585add 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -311,9 +311,11 @@ To save @bors some work, and to get small changes through more quickly, when the other rollup-eligible patches too, and they'll get tested and merged at the same time. -To find documentation-related issues, sort by the [A-docs label][adocs]. +To find documentation-related issues, sort by the [T-doc label][tdoc]. +You can find documentation style guidelines in [RFC 1574][rfc1574]. -[adocs]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AA-docs +[tdoc]: https://github.com/rust-lang/rust/issues?q=is%3Aopen%20is%3Aissue%20label%3AT-doc +[rfc1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text In many cases, you don't need a full `./x.py doc`. You can use `rustdoc` directly to check small fixes. For example, `rustdoc src/doc/reference.md` will render From 7643ccd29ca708059cef446d2ef4446559bb4518 Mon Sep 17 00:00:00 2001 From: lukaramu Date: Fri, 24 Mar 2017 21:28:59 +0100 Subject: [PATCH 12/12] Split paragraph in CONTRIBUTING.md --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 651fffb585add..0314a5dfd8d02 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -312,9 +312,11 @@ the other rollup-eligible patches too, and they'll get tested and merged at the same time. To find documentation-related issues, sort by the [T-doc label][tdoc]. -You can find documentation style guidelines in [RFC 1574][rfc1574]. [tdoc]: https://github.com/rust-lang/rust/issues?q=is%3Aopen%20is%3Aissue%20label%3AT-doc + +You can find documentation style guidelines in [RFC 1574][rfc1574]. + [rfc1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text In many cases, you don't need a full `./x.py doc`. You can use `rustdoc` directly