Skip to content

Commit cac6821

Browse files
committed
Auto merge of #65907 - Centril:rollup-9i8ev23, r=Centril
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
2 parents b497e18 + 30431a3 commit cac6821

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+342
-215
lines changed

src/liballoc/vec.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ use crate::raw_vec::RawVec;
154154
/// println!("{}", v[6]); // it will panic!
155155
/// ```
156156
///
157-
/// In conclusion: always check if the index you want to get really exists
158-
/// before doing it.
157+
/// Use [`get`] and [`get_mut`] if you want to check whether the index is in
158+
/// the `Vec`.
159159
///
160160
/// # Slicing
161161
///
@@ -277,6 +277,8 @@ use crate::raw_vec::RawVec;
277277
/// The order has changed in the past and may change again.
278278
///
279279
/// [`vec!`]: ../../std/macro.vec.html
280+
/// [`get`]: ../../std/vec/struct.Vec.html#method.get
281+
/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut
280282
/// [`Index`]: ../../std/ops/trait.Index.html
281283
/// [`String`]: ../../std/string/struct.String.html
282284
/// [`&str`]: ../../std/primitive.str.html

src/libcore/iter/traits/iterator.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ pub trait Iterator {
384384
///
385385
/// In other words, it links two iterators together, in a chain. 🔗
386386
///
387+
/// [`once`] is commonly used to adapt a single value into a chain of
388+
/// other kinds of iteration.
389+
///
387390
/// # Examples
388391
///
389392
/// Basic usage:
@@ -408,9 +411,6 @@ pub trait Iterator {
408411
/// [`Iterator`] itself. For example, slices (`&[T]`) implement
409412
/// [`IntoIterator`], and so can be passed to `chain()` directly:
410413
///
411-
/// [`IntoIterator`]: trait.IntoIterator.html
412-
/// [`Iterator`]: trait.Iterator.html
413-
///
414414
/// ```
415415
/// let s1 = &[1, 2, 3];
416416
/// let s2 = &[4, 5, 6];
@@ -425,6 +425,21 @@ pub trait Iterator {
425425
/// assert_eq!(iter.next(), Some(&6));
426426
/// assert_eq!(iter.next(), None);
427427
/// ```
428+
///
429+
/// If you work with Windows API, you may wish to convert [`OsStr`] to `Vec<u16>`:
430+
///
431+
/// ```
432+
/// #[cfg(windows)]
433+
/// fn os_str_to_utf16(s: &std::ffi::OsStr) -> Vec<u16> {
434+
/// use std::os::windows::ffi::OsStrExt;
435+
/// s.encode_wide().chain(std::iter::once(0)).collect()
436+
/// }
437+
/// ```
438+
///
439+
/// [`once`]: fn.once.html
440+
/// [`Iterator`]: trait.Iterator.html
441+
/// [`IntoIterator`]: trait.IntoIterator.html
442+
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
428443
#[inline]
429444
#[stable(feature = "rust1", since = "1.0.0")]
430445
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where

src/librustc/hir/lowering/expr.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,20 @@ impl LoweringContext<'_> {
235235
/// ```
236236
fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind {
237237
// If we got here, the `let` expression is not allowed.
238-
self.sess
239-
.struct_span_err(span, "`let` expressions are not supported here")
240-
.note("only supported directly in conditions of `if`- and `while`-expressions")
241-
.note("as well as when nested within `&&` and parenthesis in those conditions")
242-
.emit();
238+
239+
if self.sess.opts.unstable_features.is_nightly_build() {
240+
self.sess
241+
.struct_span_err(span, "`let` expressions are not supported here")
242+
.note("only supported directly in conditions of `if`- and `while`-expressions")
243+
.note("as well as when nested within `&&` and parenthesis in those conditions")
244+
.emit();
245+
}
246+
else {
247+
self.sess
248+
.struct_span_err(span, "expected expression, found statement (`let`)")
249+
.note("variable declaration using `let` is a statement")
250+
.emit();
251+
}
243252

244253
// For better recovery, we emit:
245254
// ```

src/librustc/hir/map/collector.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
149149
let mut collector = NodeCollector {
150150
krate,
151151
source_map: sess.source_map(),
152-
map: vec![None; definitions.def_index_count()],
152+
map: IndexVec::from_elem_n(IndexVec::new(), definitions.def_index_count()),
153153
parent_node: hir::CRATE_HIR_ID,
154154
current_signature_dep_index: root_mod_sig_dep_index,
155155
current_full_dep_index: root_mod_full_dep_index,
@@ -227,12 +227,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
227227

228228
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
229229
debug!("hir_map: {:?} => {:?}", id, entry);
230-
let local_map = &mut self.map[id.owner.index()];
230+
let local_map = &mut self.map[id.owner];
231231
let i = id.local_id.as_u32() as usize;
232-
if local_map.is_none() {
233-
*local_map = Some(IndexVec::with_capacity(i + 1));
234-
}
235-
let local_map = local_map.as_mut().unwrap();
236232
let len = local_map.len();
237233
if i >= len {
238234
local_map.extend(repeat(None).take(i - len + 1));

src/librustc/hir/map/definitions.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ use syntax_pos::{Span, DUMMY_SP};
2727
/// There is one `DefPathTable` for each crate.
2828
#[derive(Clone, Default, RustcDecodable, RustcEncodable)]
2929
pub struct DefPathTable {
30-
index_to_key: Vec<DefKey>,
31-
def_path_hashes: Vec<DefPathHash>,
30+
index_to_key: IndexVec<DefIndex, DefKey>,
31+
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
3232
}
3333

3434
impl DefPathTable {
@@ -53,14 +53,14 @@ impl DefPathTable {
5353

5454
#[inline(always)]
5555
pub fn def_key(&self, index: DefIndex) -> DefKey {
56-
self.index_to_key[index.index()]
56+
self.index_to_key[index]
5757
}
5858

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

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

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

src/librustc/hir/map/mod.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ impl Forest {
156156

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

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

229229
/// Registers a read in the dependency graph of the AST node with
@@ -1031,14 +1031,12 @@ impl<'hir> Map<'hir> {
10311031
// see the comment on `HirEntryMap`.
10321032
// Iterate over all the indices and return a reference to
10331033
// local maps and their index given that they exist.
1034-
self.map.iter().enumerate().filter_map(|(i, local_map)| {
1035-
local_map.as_ref().map(|m| (i, m))
1036-
}).flat_map(move |(array_index, local_map)| {
1034+
self.map.iter_enumerated().flat_map(move |(owner, local_map)| {
10371035
// Iterate over each valid entry in the local map.
10381036
local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| {
10391037
// Reconstruct the `HirId` based on the 3 indices we used to find it.
10401038
HirId {
1041-
owner: DefIndex::from(array_index),
1039+
owner,
10421040
local_id: i,
10431041
}
10441042
}))

src/librustc/traits/error_reporting.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -2112,9 +2112,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
21122112
err.note(&format!("required by cast to type `{}`",
21132113
self.ty_to_string(target)));
21142114
}
2115-
ObligationCauseCode::RepeatVec => {
2115+
ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expression) => {
21162116
err.note("the `Copy` trait is required because the \
21172117
repeated element will be copied");
2118+
if suggest_const_in_array_repeat_expression {
2119+
err.note("this array initializer can be evaluated at compile-time, for more \
2120+
information, see issue \
2121+
https://github.com/rust-lang/rust/issues/49147");
2122+
if tcx.sess.opts.unstable_features.is_nightly_build() {
2123+
err.help("add `#![feature(const_in_array_repeat_expression)]` to the \
2124+
crate attributes to enable");
2125+
}
2126+
}
21182127
}
21192128
ObligationCauseCode::VariableType(_) => {
21202129
err.note("all local variables must have a statically known size");

src/librustc/traits/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,9 @@ pub enum ObligationCauseCode<'tcx> {
206206
SizedReturnType,
207207
/// Yield type must be Sized
208208
SizedYieldType,
209-
/// [T,..n] --> T must be Copy
210-
RepeatVec,
209+
/// [T,..n] --> T must be Copy. If `true`, suggest `const_in_array_repeat_expression` feature
210+
/// flag.
211+
RepeatVec(bool),
211212

212213
/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
213214
FieldSized { adt_kind: AdtKind, last: bool },

src/librustc/traits/structural_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
494494
super::SizedArgumentType => Some(super::SizedArgumentType),
495495
super::SizedReturnType => Some(super::SizedReturnType),
496496
super::SizedYieldType => Some(super::SizedYieldType),
497-
super::RepeatVec => Some(super::RepeatVec),
497+
super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)),
498498
super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
499499
super::ConstSized => Some(super::ConstSized),
500500
super::ConstPatternStructural => Some(super::ConstPatternStructural),

src/librustc/ty/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,7 @@ impl<'tcx> TyCtxt<'tcx> {
14081408
}
14091409

14101410
pub fn encode_metadata(self)-> EncodedMetadata {
1411+
let _prof_timer = self.prof.generic_activity("generate_crate_metadata");
14111412
self.cstore.encode_metadata(self)
14121413
}
14131414

src/librustc/ty/flags.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ impl FlagComputation {
114114
}
115115

116116
&ty::Placeholder(..) => {
117+
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
117118
self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
118119
}
119120

@@ -123,8 +124,7 @@ impl FlagComputation {
123124
match infer {
124125
ty::FreshTy(_) |
125126
ty::FreshIntTy(_) |
126-
ty::FreshFloatTy(_) => {
127-
}
127+
ty::FreshFloatTy(_) => {}
128128

129129
ty::TyVar(_) |
130130
ty::IntVar(_) |
@@ -245,14 +245,16 @@ impl FlagComputation {
245245
}
246246
ConstValue::Bound(debruijn, _) => self.add_binder(debruijn),
247247
ConstValue::Param(_) => {
248-
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_PARAMS);
248+
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
249+
self.add_flags(TypeFlags::HAS_PARAMS);
249250
}
250251
ConstValue::Placeholder(_) => {
251-
self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER);
252+
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
253+
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
252254
}
253-
ConstValue::Scalar(_) => { }
254-
ConstValue::Slice { data: _, start: _, end: _ } => { }
255-
ConstValue::ByRef { alloc: _, offset: _ } => { }
255+
ConstValue::Scalar(_) => {}
256+
ConstValue::Slice { .. } => {}
257+
ConstValue::ByRef { .. } => {}
256258
}
257259
}
258260

src/librustc_codegen_ssa/base.rs

-2
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,6 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
574574

575575
if need_metadata_module {
576576
// Codegen the encoded metadata.
577-
let _prof_timer = tcx.prof.generic_activity("codegen_crate_metadata");
578-
579577
let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
580578
&["crate"],
581579
Some("metadata")).as_str()

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::borrow_check::nll::type_check::free_region_relations::{
1616
};
1717
use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
1818
use crate::borrow_check::nll::ToRegionVid;
19+
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
1920
use crate::dataflow::move_paths::MoveData;
2021
use crate::dataflow::FlowAtLocation;
2122
use crate::dataflow::MaybeInitializedPlaces;
@@ -1983,12 +1984,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19831984
let span = body.source_info(location).span;
19841985
let ty = operand.ty(body, tcx);
19851986
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
1987+
// To determine if `const_in_array_repeat_expression` feature gate should
1988+
// be mentioned, need to check if the rvalue is promotable.
1989+
let should_suggest =
1990+
should_suggest_const_in_array_repeat_expressions_attribute(
1991+
tcx, self.mir_def_id, body, operand);
1992+
debug!("check_rvalue: should_suggest={:?}", should_suggest);
1993+
19861994
self.infcx.report_selection_error(
19871995
&traits::Obligation::new(
19881996
ObligationCause::new(
19891997
span,
19901998
self.tcx().hir().def_index_to_hir_id(self.mir_def_id.index),
1991-
traits::ObligationCauseCode::RepeatVec,
1999+
traits::ObligationCauseCode::RepeatVec(should_suggest),
19922000
),
19932001
self.param_env,
19942002
ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate {

src/librustc_mir/transform/promote_consts.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1110,3 +1110,28 @@ pub fn promote_candidates<'tcx>(
11101110

11111111
promotions
11121112
}
1113+
1114+
/// This function returns `true` if the `const_in_array_repeat_expression` feature attribute should
1115+
/// be suggested. This function is probably quite expensive, it shouldn't be run in the happy path.
1116+
/// Feature attribute should be suggested if `operand` can be promoted and the feature is not
1117+
/// enabled.
1118+
crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>(
1119+
tcx: TyCtxt<'tcx>,
1120+
mir_def_id: DefId,
1121+
body: &Body<'tcx>,
1122+
operand: &Operand<'tcx>,
1123+
) -> bool {
1124+
let mut rpo = traversal::reverse_postorder(body);
1125+
let (temps, _) = collect_temps_and_candidates(tcx, body, &mut rpo);
1126+
let validator = Validator {
1127+
item: Item::new(tcx, mir_def_id, body),
1128+
temps: &temps,
1129+
explicit: false,
1130+
};
1131+
1132+
let should_promote = validator.validate_operand(operand).is_ok();
1133+
let feature_flag = tcx.features().const_in_array_repeat_expressions;
1134+
debug!("should_suggest_const_in_array_repeat_expressions_flag: mir_def_id={:?} \
1135+
should_promote={:?} feature_flag={:?}", mir_def_id, should_promote, feature_flag);
1136+
should_promote && !feature_flag
1137+
}

src/librustc_mir/transform/qualify_consts.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -878,13 +878,11 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
878878
}
879879
},
880880
ValueSource::Rvalue(&Rvalue::Repeat(ref operand, _)) => {
881-
let candidate = Candidate::Repeat(location);
882-
let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
883-
IsNotPromotable::in_operand(self, operand);
884-
debug!("assign: self.def_id={:?} operand={:?}", self.def_id, operand);
885-
if !not_promotable && self.tcx.features().const_in_array_repeat_expressions {
886-
debug!("assign: candidate={:?}", candidate);
887-
self.promotion_candidates.push(candidate);
881+
debug!("assign: self.cx.mode={:?} self.def_id={:?} location={:?} operand={:?}",
882+
self.cx.mode, self.def_id, location, operand);
883+
if self.should_promote_repeat_expression(operand) &&
884+
self.tcx.features().const_in_array_repeat_expressions {
885+
self.promotion_candidates.push(Candidate::Repeat(location));
888886
}
889887
},
890888
_ => {},
@@ -1149,6 +1147,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
11491147

11501148
candidates
11511149
}
1150+
1151+
/// Returns `true` if the operand of a repeat expression is promotable.
1152+
fn should_promote_repeat_expression(&self, operand: &Operand<'tcx>) -> bool {
1153+
let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
1154+
IsNotPromotable::in_operand(self, operand);
1155+
debug!("should_promote_repeat_expression: operand={:?} not_promotable={:?}",
1156+
operand, not_promotable);
1157+
!not_promotable
1158+
}
11521159
}
11531160

11541161
impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {

0 commit comments

Comments
 (0)