Skip to content

Commit

Permalink
Auto merge of #65907 - Centril:rollup-9i8ev23, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - #65563 (Add long error explanation for E0587)
 - #65640 (Use heuristics to recover parsing of missing `;`)
 - #65643 (Correct handling of type flags with `ConstValue::Placeholder`)
 - #65825 (rustc: use IndexVec<DefIndex, T> instead of Vec<T>.)
 - #65858 (suggest `const_in_array_repeat_expression` flag)
 - #65877 (doc: introduce `once` in `iter::chain` document)
 - #65887 (doc: mention `get(_mut)` in Vec)
 - #65891 (self-profiling: Record something more useful for crate metadata generation event.)
 - #65893 (Output previous stable  error messaging when using stable build.)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Oct 28, 2019
2 parents b497e18 + 30431a3 commit cac6821
Show file tree
Hide file tree
Showing 55 changed files with 342 additions and 215 deletions.
6 changes: 4 additions & 2 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ use crate::raw_vec::RawVec;
/// println!("{}", v[6]); // it will panic!
/// ```
///
/// In conclusion: always check if the index you want to get really exists
/// before doing it.
/// Use [`get`] and [`get_mut`] if you want to check whether the index is in
/// the `Vec`.
///
/// # Slicing
///
Expand Down Expand Up @@ -277,6 +277,8 @@ use crate::raw_vec::RawVec;
/// The order has changed in the past and may change again.
///
/// [`vec!`]: ../../std/macro.vec.html
/// [`get`]: ../../std/vec/struct.Vec.html#method.get
/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut
/// [`Index`]: ../../std/ops/trait.Index.html
/// [`String`]: ../../std/string/struct.String.html
/// [`&str`]: ../../std/primitive.str.html
Expand Down
21 changes: 18 additions & 3 deletions src/libcore/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,9 @@ pub trait Iterator {
///
/// In other words, it links two iterators together, in a chain. 🔗
///
/// [`once`] is commonly used to adapt a single value into a chain of
/// other kinds of iteration.
///
/// # Examples
///
/// Basic usage:
Expand All @@ -408,9 +411,6 @@ pub trait Iterator {
/// [`Iterator`] itself. For example, slices (`&[T]`) implement
/// [`IntoIterator`], and so can be passed to `chain()` directly:
///
/// [`IntoIterator`]: trait.IntoIterator.html
/// [`Iterator`]: trait.Iterator.html
///
/// ```
/// let s1 = &[1, 2, 3];
/// let s2 = &[4, 5, 6];
Expand All @@ -425,6 +425,21 @@ pub trait Iterator {
/// assert_eq!(iter.next(), Some(&6));
/// assert_eq!(iter.next(), None);
/// ```
///
/// If you work with Windows API, you may wish to convert [`OsStr`] to `Vec<u16>`:
///
/// ```
/// #[cfg(windows)]
/// fn os_str_to_utf16(s: &std::ffi::OsStr) -> Vec<u16> {
/// use std::os::windows::ffi::OsStrExt;
/// s.encode_wide().chain(std::iter::once(0)).collect()
/// }
/// ```
///
/// [`once`]: fn.once.html
/// [`Iterator`]: trait.Iterator.html
/// [`IntoIterator`]: trait.IntoIterator.html
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where
Expand Down
19 changes: 14 additions & 5 deletions src/librustc/hir/lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,20 @@ impl LoweringContext<'_> {
/// ```
fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind {
// If we got here, the `let` expression is not allowed.
self.sess
.struct_span_err(span, "`let` expressions are not supported here")
.note("only supported directly in conditions of `if`- and `while`-expressions")
.note("as well as when nested within `&&` and parenthesis in those conditions")
.emit();

if self.sess.opts.unstable_features.is_nightly_build() {
self.sess
.struct_span_err(span, "`let` expressions are not supported here")
.note("only supported directly in conditions of `if`- and `while`-expressions")
.note("as well as when nested within `&&` and parenthesis in those conditions")
.emit();
}
else {
self.sess
.struct_span_err(span, "expected expression, found statement (`let`)")
.note("variable declaration using `let` is a statement")
.emit();
}

// For better recovery, we emit:
// ```
Expand Down
8 changes: 2 additions & 6 deletions src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
let mut collector = NodeCollector {
krate,
source_map: sess.source_map(),
map: vec![None; definitions.def_index_count()],
map: IndexVec::from_elem_n(IndexVec::new(), definitions.def_index_count()),
parent_node: hir::CRATE_HIR_ID,
current_signature_dep_index: root_mod_sig_dep_index,
current_full_dep_index: root_mod_full_dep_index,
Expand Down Expand Up @@ -227,12 +227,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {

fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
debug!("hir_map: {:?} => {:?}", id, entry);
let local_map = &mut self.map[id.owner.index()];
let local_map = &mut self.map[id.owner];
let i = id.local_id.as_u32() as usize;
if local_map.is_none() {
*local_map = Some(IndexVec::with_capacity(i + 1));
}
let local_map = local_map.as_mut().unwrap();
let len = local_map.len();
if i >= len {
local_map.extend(repeat(None).take(i - len + 1));
Expand Down
18 changes: 9 additions & 9 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use syntax_pos::{Span, DUMMY_SP};
/// There is one `DefPathTable` for each crate.
#[derive(Clone, Default, RustcDecodable, RustcEncodable)]
pub struct DefPathTable {
index_to_key: Vec<DefKey>,
def_path_hashes: Vec<DefPathHash>,
index_to_key: IndexVec<DefIndex, DefKey>,
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
}

impl DefPathTable {
Expand All @@ -53,14 +53,14 @@ impl DefPathTable {

#[inline(always)]
pub fn def_key(&self, index: DefIndex) -> DefKey {
self.index_to_key[index.index()]
self.index_to_key[index]
}

#[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
let ret = self.def_path_hashes[index.index()];
debug!("def_path_hash({:?}) = {:?}", index, ret);
return ret
let hash = self.def_path_hashes[index];
debug!("def_path_hash({:?}) = {:?}", index, hash);
hash
}

pub fn add_def_path_hashes_to(&self,
Expand Down Expand Up @@ -92,7 +92,7 @@ impl DefPathTable {
pub struct Definitions {
table: DefPathTable,
node_to_def_index: NodeMap<DefIndex>,
def_index_to_node: Vec<ast::NodeId>,
def_index_to_node: IndexVec<DefIndex, ast::NodeId>,
pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
/// If `ExpnId` is an ID of some macro expansion,
/// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
Expand Down Expand Up @@ -375,7 +375,7 @@ impl Definitions {
#[inline]
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
if def_id.krate == LOCAL_CRATE {
let node_id = self.def_index_to_node[def_id.index.index()];
let node_id = self.def_index_to_node[def_id.index];
if node_id != ast::DUMMY_NODE_ID {
return Some(node_id);
}
Expand Down Expand Up @@ -404,7 +404,7 @@ impl Definitions {

#[inline]
pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
let node_id = self.def_index_to_node[def_index.index()];
let node_id = self.def_index_to_node[def_index];
self.node_to_hir_id[node_id]
}

Expand Down
14 changes: 6 additions & 8 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ impl Forest {

/// This type is effectively a `HashMap<HirId, Entry<'hir>>`,
/// but it is implemented as 2 layers of arrays.
/// - first we have `A = Vec<Option<B>>` mapping a `DefIndex`'s index to an inner value
/// - first we have `A = IndexVec<DefIndex, B>` mapping `DefIndex`s to an inner value
/// - which is `B = IndexVec<ItemLocalId, Option<Entry<'hir>>` which gives you the `Entry`.
pub(super) type HirEntryMap<'hir> = Vec<Option<IndexVec<ItemLocalId, Option<Entry<'hir>>>>>;
pub(super) type HirEntryMap<'hir> = IndexVec<DefIndex, IndexVec<ItemLocalId, Option<Entry<'hir>>>>;

/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
#[derive(Clone)]
Expand Down Expand Up @@ -222,8 +222,8 @@ impl<'map> Iterator for ParentHirIterator<'map> {
impl<'hir> Map<'hir> {
#[inline]
fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> {
let local_map = self.map.get(id.owner.index())?;
local_map.as_ref()?.get(id.local_id)?.as_ref()
let local_map = self.map.get(id.owner)?;
local_map.get(id.local_id)?.as_ref()
}

/// Registers a read in the dependency graph of the AST node with
Expand Down Expand Up @@ -1031,14 +1031,12 @@ impl<'hir> Map<'hir> {
// see the comment on `HirEntryMap`.
// Iterate over all the indices and return a reference to
// local maps and their index given that they exist.
self.map.iter().enumerate().filter_map(|(i, local_map)| {
local_map.as_ref().map(|m| (i, m))
}).flat_map(move |(array_index, local_map)| {
self.map.iter_enumerated().flat_map(move |(owner, local_map)| {
// Iterate over each valid entry in the local map.
local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| {
// Reconstruct the `HirId` based on the 3 indices we used to find it.
HirId {
owner: DefIndex::from(array_index),
owner,
local_id: i,
}
}))
Expand Down
11 changes: 10 additions & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2112,9 +2112,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err.note(&format!("required by cast to type `{}`",
self.ty_to_string(target)));
}
ObligationCauseCode::RepeatVec => {
ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expression) => {
err.note("the `Copy` trait is required because the \
repeated element will be copied");
if suggest_const_in_array_repeat_expression {
err.note("this array initializer can be evaluated at compile-time, for more \
information, see issue \
https://github.com/rust-lang/rust/issues/49147");
if tcx.sess.opts.unstable_features.is_nightly_build() {
err.help("add `#![feature(const_in_array_repeat_expression)]` to the \
crate attributes to enable");
}
}
}
ObligationCauseCode::VariableType(_) => {
err.note("all local variables must have a statically known size");
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,9 @@ pub enum ObligationCauseCode<'tcx> {
SizedReturnType,
/// Yield type must be Sized
SizedYieldType,
/// [T,..n] --> T must be Copy
RepeatVec,
/// [T,..n] --> T must be Copy. If `true`, suggest `const_in_array_repeat_expression` feature
/// flag.
RepeatVec(bool),

/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
FieldSized { adt_kind: AdtKind, last: bool },
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
super::SizedArgumentType => Some(super::SizedArgumentType),
super::SizedReturnType => Some(super::SizedReturnType),
super::SizedYieldType => Some(super::SizedYieldType),
super::RepeatVec => Some(super::RepeatVec),
super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)),
super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
super::ConstSized => Some(super::ConstSized),
super::ConstPatternStructural => Some(super::ConstPatternStructural),
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,7 @@ impl<'tcx> TyCtxt<'tcx> {
}

pub fn encode_metadata(self)-> EncodedMetadata {
let _prof_timer = self.prof.generic_activity("generate_crate_metadata");
self.cstore.encode_metadata(self)
}

Expand Down
16 changes: 9 additions & 7 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ impl FlagComputation {
}

&ty::Placeholder(..) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
}

Expand All @@ -123,8 +124,7 @@ impl FlagComputation {
match infer {
ty::FreshTy(_) |
ty::FreshIntTy(_) |
ty::FreshFloatTy(_) => {
}
ty::FreshFloatTy(_) => {}

ty::TyVar(_) |
ty::IntVar(_) |
Expand Down Expand Up @@ -245,14 +245,16 @@ impl FlagComputation {
}
ConstValue::Bound(debruijn, _) => self.add_binder(debruijn),
ConstValue::Param(_) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_PARAMS);
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_PARAMS);
}
ConstValue::Placeholder(_) => {
self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER);
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
}
ConstValue::Scalar(_) => { }
ConstValue::Slice { data: _, start: _, end: _ } => { }
ConstValue::ByRef { alloc: _, offset: _ } => { }
ConstValue::Scalar(_) => {}
ConstValue::Slice { .. } => {}
ConstValue::ByRef { .. } => {}
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/librustc_codegen_ssa/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,6 @@ pub fn codegen_crate<B: ExtraBackendMethods>(

if need_metadata_module {
// Codegen the encoded metadata.
let _prof_timer = tcx.prof.generic_activity("codegen_crate_metadata");

let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
&["crate"],
Some("metadata")).as_str()
Expand Down
10 changes: 9 additions & 1 deletion src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::borrow_check::nll::type_check::free_region_relations::{
};
use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
use crate::borrow_check::nll::ToRegionVid;
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
use crate::dataflow::move_paths::MoveData;
use crate::dataflow::FlowAtLocation;
use crate::dataflow::MaybeInitializedPlaces;
Expand Down Expand Up @@ -1983,12 +1984,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let span = body.source_info(location).span;
let ty = operand.ty(body, tcx);
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
// To determine if `const_in_array_repeat_expression` feature gate should
// be mentioned, need to check if the rvalue is promotable.
let should_suggest =
should_suggest_const_in_array_repeat_expressions_attribute(
tcx, self.mir_def_id, body, operand);
debug!("check_rvalue: should_suggest={:?}", should_suggest);

self.infcx.report_selection_error(
&traits::Obligation::new(
ObligationCause::new(
span,
self.tcx().hir().def_index_to_hir_id(self.mir_def_id.index),
traits::ObligationCauseCode::RepeatVec,
traits::ObligationCauseCode::RepeatVec(should_suggest),
),
self.param_env,
ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate {
Expand Down
25 changes: 25 additions & 0 deletions src/librustc_mir/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,3 +1110,28 @@ pub fn promote_candidates<'tcx>(

promotions
}

/// This function returns `true` if the `const_in_array_repeat_expression` feature attribute should
/// be suggested. This function is probably quite expensive, it shouldn't be run in the happy path.
/// Feature attribute should be suggested if `operand` can be promoted and the feature is not
/// enabled.
crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>(
tcx: TyCtxt<'tcx>,
mir_def_id: DefId,
body: &Body<'tcx>,
operand: &Operand<'tcx>,
) -> bool {
let mut rpo = traversal::reverse_postorder(body);
let (temps, _) = collect_temps_and_candidates(tcx, body, &mut rpo);
let validator = Validator {
item: Item::new(tcx, mir_def_id, body),
temps: &temps,
explicit: false,
};

let should_promote = validator.validate_operand(operand).is_ok();
let feature_flag = tcx.features().const_in_array_repeat_expressions;
debug!("should_suggest_const_in_array_repeat_expressions_flag: mir_def_id={:?} \
should_promote={:?} feature_flag={:?}", mir_def_id, should_promote, feature_flag);
should_promote && !feature_flag
}
21 changes: 14 additions & 7 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,13 +878,11 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
}
},
ValueSource::Rvalue(&Rvalue::Repeat(ref operand, _)) => {
let candidate = Candidate::Repeat(location);
let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
IsNotPromotable::in_operand(self, operand);
debug!("assign: self.def_id={:?} operand={:?}", self.def_id, operand);
if !not_promotable && self.tcx.features().const_in_array_repeat_expressions {
debug!("assign: candidate={:?}", candidate);
self.promotion_candidates.push(candidate);
debug!("assign: self.cx.mode={:?} self.def_id={:?} location={:?} operand={:?}",
self.cx.mode, self.def_id, location, operand);
if self.should_promote_repeat_expression(operand) &&
self.tcx.features().const_in_array_repeat_expressions {
self.promotion_candidates.push(Candidate::Repeat(location));
}
},
_ => {},
Expand Down Expand Up @@ -1149,6 +1147,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {

candidates
}

/// Returns `true` if the operand of a repeat expression is promotable.
fn should_promote_repeat_expression(&self, operand: &Operand<'tcx>) -> bool {
let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
IsNotPromotable::in_operand(self, operand);
debug!("should_promote_repeat_expression: operand={:?} not_promotable={:?}",
operand, not_promotable);
!not_promotable
}
}

impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
Expand Down
Loading

0 comments on commit cac6821

Please sign in to comment.