Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #65907

Merged
merged 21 commits into from
Oct 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
76b8fd8
Add long error explanation for E0587
GuillaumeGomez Oct 18, 2019
42a805e
Update ui tests
GuillaumeGomez Oct 18, 2019
6661db0
Correct handling of type flags with `ConstValue::Placeholder`
varkor Oct 20, 2019
9c4f60e
doc: introduce `once` in `iter::chain` document
tesuji Oct 28, 2019
e2c450b
doc: mention `get(_mut)` in Vec
tesuji Oct 28, 2019
cc575a6
rustc: use IndexVec<DefIndex, T> instead of Vec<T>.
eddyb Oct 25, 2019
46a39a2
self-profiling: Record something more useful for crate metadata gener…
michaelwoerister Oct 28, 2019
d673d0a
Use heuristics to recover parsing of missing `;`
estebank Oct 20, 2019
1b0836d
Tweak unexpected token wording
estebank Oct 22, 2019
e8016c2
review comments
estebank Oct 24, 2019
92b1512
suggest `const_in_array_repeat_expression` flag
davidtwco Oct 26, 2019
f1aa8b2
Output previous stable error messaging when using stable build.
Oct 28, 2019
eec3a9c
Rollup merge of #65563 - GuillaumeGomez:long-err-explanation-E0587, r…
Centril Oct 28, 2019
2fe6f22
Rollup merge of #65640 - estebank:recover-missing-semi, r=Centril
Centril Oct 28, 2019
216e50d
Rollup merge of #65643 - varkor:remove-free-regions-from-const-placeh…
Centril Oct 28, 2019
531240c
Rollup merge of #65825 - eddyb:def-index-vec, r=varkor
Centril Oct 28, 2019
d887232
Rollup merge of #65858 - davidtwco:rfc-2203-feature-gate-in-error, r=…
Centril Oct 28, 2019
23dbdb4
Rollup merge of #65877 - lzutao:iter-chain-once, r=Centril
Centril Oct 28, 2019
cceefd3
Rollup merge of #65887 - lzutao:doc-vec-get, r=rkruppe
Centril Oct 28, 2019
5451664
Rollup merge of #65891 - michaelwoerister:sp-crate-metadata, r=wesley…
Centril Oct 28, 2019
30431a3
Rollup merge of #65893 - jafern14:let-expr-stable-error-messaging, r=…
Centril Oct 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:/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