From 9a6ca413714271adac017cbdd764a7de8b244001 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 10 Jul 2019 12:22:07 +0200 Subject: [PATCH 01/41] HirIdify hir::Crate.modules --- src/librustc/hir/lowering.rs | 6 +++--- src/librustc/hir/lowering/item.rs | 6 ++++-- src/librustc/hir/map/hir_id_validator.rs | 2 +- src/librustc/hir/map/mod.rs | 4 +--- src/librustc/hir/mod.rs | 2 +- src/librustc/lint/context.rs | 2 +- src/librustc_interface/passes.rs | 15 ++++++++------- src/librustc_typeck/impl_wf_check.rs | 2 +- src/librustc_typeck/lib.rs | 4 ++-- 9 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ec3210613727..4a254d2123ecd 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -97,7 +97,7 @@ pub struct LoweringContext<'a> { trait_impls: BTreeMap>, - modules: BTreeMap, + modules: BTreeMap, generator_kind: Option, @@ -141,7 +141,7 @@ pub struct LoweringContext<'a> { /// vector. in_scope_lifetimes: Vec, - current_module: NodeId, + current_module: hir::HirId, type_def_lifetime_params: DefIdMap, @@ -262,7 +262,7 @@ pub fn lower_crate( is_in_dyn_type: false, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, type_def_lifetime_params: Default::default(), - current_module: CRATE_NODE_ID, + current_module: hir::CRATE_HIR_ID, current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)], item_local_id_counters: Default::default(), node_id_to_hir_id: IndexVec::new(), diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs index 4f9a9ed5673c7..780dd79435bf2 100644 --- a/src/librustc/hir/lowering/item.rs +++ b/src/librustc/hir/lowering/item.rs @@ -45,14 +45,16 @@ impl<'tcx, 'interner> ItemLowerer<'tcx, 'interner> { impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> { fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) { - self.lctx.modules.insert(n, hir::ModuleItems { + let hir_id = self.lctx.lower_node_id(n); + + self.lctx.modules.insert(hir_id, hir::ModuleItems { items: BTreeSet::new(), trait_items: BTreeSet::new(), impl_items: BTreeSet::new(), }); let old = self.lctx.current_module; - self.lctx.current_module = n; + self.lctx.current_module = hir_id; visit::walk_mod(self, m); self.lctx.current_module = old; } diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 889659382d060..b66c2ce1178a4 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -10,7 +10,7 @@ pub fn check_crate(hir_map: &hir::map::Map<'_>) { let errors = Lock::new(Vec::new()); par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| { - let local_def_id = hir_map.local_def_id_from_node_id(*module_id); + let local_def_id = hir_map.local_def_id(*module_id); hir_map.visit_item_likes_in_module(local_def_id, &mut OuterVisitor { hir_map, errors: &errors, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index f80e527dfd9b7..e833c2bb8f3d8 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -539,9 +539,7 @@ impl<'hir> Map<'hir> { // in the expect_* calls the loops below self.read(hir_id); - let node_id = self.hir_to_node_id[&hir_id]; - - let module = &self.forest.krate.modules[&node_id]; + let module = &self.forest.krate.modules[&hir_id]; for id in &module.items { visitor.visit_item(self.expect_item(*id)); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 983048188527f..d639fdf6abc2c 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -767,7 +767,7 @@ pub struct Crate { /// A list of modules written out in the order in which they /// appear in the crate. This includes the main crate module. - pub modules: BTreeMap, + pub modules: BTreeMap, } impl Crate { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6801fa8d8dbe5..a44dbff27ed6e 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1515,7 +1515,7 @@ pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( time(tcx.sess, "module lints", || { // Run per-module lints par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().lint_mod(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().lint_mod(tcx.hir().local_def_id(module)); }); }); }); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 8b0b5a5b7a2bd..68e799eced2f3 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -913,10 +913,10 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { }); }, { par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().check_mod_loops(tcx.hir().local_def_id_from_node_id(module)); - tcx.ensure().check_mod_attrs(tcx.hir().local_def_id_from_node_id(module)); - tcx.ensure().check_mod_unstable_api_usage( - tcx.hir().local_def_id_from_node_id(module)); + let local_def_id = tcx.hir().local_def_id(module); + tcx.ensure().check_mod_loops(local_def_id); + tcx.ensure().check_mod_attrs(local_def_id); + tcx.ensure().check_mod_unstable_api_usage(local_def_id); }); }); }); @@ -939,9 +939,10 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { // "not all control paths return a value" is reported here. // // maybe move the check to a MIR pass? - tcx.ensure().check_mod_liveness(tcx.hir().local_def_id_from_node_id(module)); + let local_def_id = tcx.hir().local_def_id(module); - tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().check_mod_liveness(local_def_id); + tcx.ensure().check_mod_intrinsics(local_def_id); }); }); }); @@ -1001,7 +1002,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { }, { time(sess, "privacy checking modules", || { par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().check_mod_privacy(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); }); }); }); diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index fcfd9adef54df..e3302f299ea71 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -54,7 +54,7 @@ pub fn impl_wf_check(tcx: TyCtxt<'_>) { // but it's one that we must perform earlier than the rest of // WfCheck. for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id(module)); } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 9d9a9d9b559e4..53506454be79e 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -306,7 +306,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { time(tcx.sess, "type collecting", || { for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module)); } }); })?; @@ -341,7 +341,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { time(tcx.sess, "item-types checking", || { for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().check_mod_item_types(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module)); } }); From 562903a0a684860c0e51971ea11f1ce97795d6a2 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Fri, 13 Sep 2019 10:20:17 +0200 Subject: [PATCH 02/41] use `sign` variable in abs and wrapping_abs methods This also makes the code easier to understand by hinting at the significance of `self >> ($BITS - 1)` and by including an explanation in the comments. Also, now overflowing_abs simply uses wrapping_abs, which is clearer and avoids a potential performance regression in the LLVM IR. --- src/libcore/num/mod.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index df1c00ccd184f..9860928427754 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1402,7 +1402,16 @@ $EndFeature, " #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] pub const fn wrapping_abs(self) -> Self { - (self ^ (self >> ($BITS - 1))).wrapping_sub(self >> ($BITS - 1)) + // sign is -1 (all ones) for negative numbers, 0 otherwise. + let sign = self >> ($BITS - 1); + // For positive self, sign == 0 so the expression is simply + // (self ^ 0).wrapping_sub(0) == self == abs(self). + // + // For negative self, self ^ sign == self ^ all_ones. + // But all_ones ^ self == all_ones - self == -1 - self. + // So for negative numbers, (self ^ sign).wrapping_sub(sign) is + // (-1 - self).wrapping_sub(-1) == -self == abs(self). + (self ^ sign).wrapping_sub(sign) } } @@ -1761,7 +1770,7 @@ $EndFeature, " #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] pub const fn overflowing_abs(self) -> (Self, bool) { - (self ^ (self >> ($BITS - 1))).overflowing_sub(self >> ($BITS - 1)) + (self.wrapping_abs(), self == Self::min_value()) } } @@ -1969,7 +1978,21 @@ $EndFeature, " // Note that the #[inline] above means that the overflow // semantics of the subtraction depend on the crate we're being // inlined into. - (self ^ (self >> ($BITS - 1))) - (self >> ($BITS - 1)) + + // sign is -1 (all ones) for negative numbers, 0 otherwise. + let sign = self >> ($BITS - 1); + // For positive self, sign == 0 so the expression is simply + // (self ^ 0) - 0 == self == abs(self). + // + // For negative self, self ^ sign == self ^ all_ones. + // But all_ones ^ self == all_ones - self == -1 - self. + // So for negative numbers, (self ^ sign) - sign is + // (-1 - self) - -1 == -self == abs(self). + // + // The subtraction overflows when self is min_value(), because + // (-1 - min_value()) - -1 is max_value() - -1 which overflows. + // This is exactly when we want self.abs() to overflow. + (self ^ sign) - sign } } From 146cb8eda667e5d76bebdef3acc61adaeaa025b0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 7 Sep 2019 15:49:58 +0200 Subject: [PATCH 03/41] or-patterns: remove hack from lowering. --- src/librustc/hir/lowering.rs | 29 ------------------ src/librustc/hir/lowering/expr.rs | 51 ++++++++++++------------------- src/libsyntax/visit.rs | 2 -- 3 files changed, 19 insertions(+), 63 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 58789a10609b7..a5f08cd96061f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -434,35 +434,6 @@ impl<'a> LoweringContext<'a> { visit::walk_pat(self, p) } - // HACK(or_patterns; Centril | dlrobertson): Avoid creating - // HIR nodes for `PatKind::Or` for the top level of a `ast::Arm`. - // This is a temporary hack that should go away once we push down - // `arm.pats: HirVec>` -> `arm.pat: P` to HIR. // Centril - fn visit_arm(&mut self, arm: &'tcx Arm) { - match &arm.pat.node { - PatKind::Or(pats) => pats.iter().for_each(|p| self.visit_pat(p)), - _ => self.visit_pat(&arm.pat), - } - walk_list!(self, visit_expr, &arm.guard); - self.visit_expr(&arm.body); - walk_list!(self, visit_attribute, &arm.attrs); - } - - // HACK(or_patterns; Centril | dlrobertson): Same as above. // Centril - fn visit_expr(&mut self, e: &'tcx Expr) { - if let ExprKind::Let(pat, scrutinee) = &e.node { - walk_list!(self, visit_attribute, e.attrs.iter()); - match &pat.node { - PatKind::Or(pats) => pats.iter().for_each(|p| self.visit_pat(p)), - _ => self.visit_pat(&pat), - } - self.visit_expr(scrutinee); - self.visit_expr_post(e); - return; - } - visit::walk_expr(self, e) - } - fn visit_item(&mut self, item: &'tcx Item) { let hir_id = self.lctx.allocate_hir_id_counter(item.id); diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs index a46cdabbb518f..d71dc53d104af 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc/hir/lowering/expr.rs @@ -250,14 +250,14 @@ impl LoweringContext<'_> { // 4. The return type of the block is `bool` which seems like what the user wanted. let scrutinee = self.lower_expr(scrutinee); let then_arm = { - let pat = self.lower_pat_top_hack(pat); + let pat = self.lower_pat(pat); let expr = self.expr_bool(span, true); self.arm(pat, P(expr)) }; let else_arm = { let pat = self.pat_wild(span); let expr = self.expr_bool(span, false); - self.arm(hir_vec![pat], P(expr)) + self.arm(pat, P(expr)) }; hir::ExprKind::Match( P(scrutinee), @@ -281,7 +281,7 @@ impl LoweringContext<'_> { None => (self.expr_block_empty(span), false), Some(els) => (self.lower_expr(els), true), }; - let else_arm = self.arm(hir_vec![else_pat], P(else_expr)); + let else_arm = self.arm(else_pat, P(else_expr)); // Handle then + scrutinee: let then_blk = self.lower_block(then, false); @@ -290,7 +290,7 @@ impl LoweringContext<'_> { // ` => `: ExprKind::Let(ref pat, ref scrutinee) => { let scrutinee = self.lower_expr(scrutinee); - let pat = self.lower_pat_top_hack(pat); + let pat = self.lower_pat(pat); (pat, scrutinee, hir::MatchSource::IfLetDesugar { contains_else_clause }) } // `true => `: @@ -307,7 +307,7 @@ impl LoweringContext<'_> { // let temporaries live outside of `cond`. let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); let pat = self.pat_bool(span, true); - (hir_vec![pat], cond, hir::MatchSource::IfDesugar { contains_else_clause }) + (pat, cond, hir::MatchSource::IfDesugar { contains_else_clause }) } }; let then_arm = self.arm(then_pat, P(then_expr)); @@ -331,7 +331,7 @@ impl LoweringContext<'_> { let else_arm = { let else_pat = self.pat_wild(span); let else_expr = self.expr_break(span, ThinVec::new()); - self.arm(hir_vec![else_pat], else_expr) + self.arm(else_pat, else_expr) }; // Handle then + scrutinee: @@ -348,7 +348,7 @@ impl LoweringContext<'_> { // } // } let scrutinee = self.with_loop_condition_scope(|t| t.lower_expr(scrutinee)); - let pat = self.lower_pat_top_hack(pat); + let pat = self.lower_pat(pat); (pat, scrutinee, hir::MatchSource::WhileLetDesugar, hir::LoopSource::WhileLet) } _ => { @@ -376,7 +376,7 @@ impl LoweringContext<'_> { let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); // `true => `: let pat = self.pat_bool(span, true); - (hir_vec![pat], cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While) + (pat, cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While) } }; let then_arm = self.arm(then_pat, P(then_expr)); @@ -429,7 +429,7 @@ impl LoweringContext<'_> { hir::Arm { hir_id: self.next_id(), attrs: self.lower_attrs(&arm.attrs), - pats: self.lower_pat_top_hack(&arm.pat), + pat: self.lower_pat(&arm.pat), guard: match arm.guard { Some(ref x) => Some(hir::Guard::If(P(self.lower_expr(x)))), _ => None, @@ -439,16 +439,6 @@ impl LoweringContext<'_> { } } - /// HACK(or_patterns; Centril | dlrobertson): For now we don't push down top level or-patterns - /// `p | q` into `hir::PatKind::Or(...)` as post-lowering bits of the compiler are not ready - /// to deal with it. This should by fixed by pushing it down to HIR and then HAIR. - fn lower_pat_top_hack(&mut self, pat: &Pat) -> HirVec> { - match pat.node { - PatKind::Or(ref ps) => ps.iter().map(|x| self.lower_pat(x)).collect(), - _ => hir_vec![self.lower_pat(pat)], - } - } - pub(super) fn make_async_expr( &mut self, capture_clause: CaptureBy, @@ -597,7 +587,7 @@ impl LoweringContext<'_> { ); P(this.expr(await_span, expr_break, ThinVec::new())) }); - self.arm(hir_vec![ready_pat], break_x) + self.arm(ready_pat, break_x) }; // `::std::task::Poll::Pending => {}` @@ -608,7 +598,7 @@ impl LoweringContext<'_> { hir_vec![], ); let empty_block = P(self.expr_block_empty(span)); - self.arm(hir_vec![pending_pat], empty_block) + self.arm(pending_pat, empty_block) }; let inner_match_stmt = { @@ -650,7 +640,7 @@ impl LoweringContext<'_> { }); // mut pinned => loop { ... } - let pinned_arm = self.arm(hir_vec![pinned_pat], loop_expr); + let pinned_arm = self.arm(pinned_pat, loop_expr); // match { // mut pinned => loop { .. } @@ -1084,7 +1074,7 @@ impl LoweringContext<'_> { ThinVec::new(), )); let some_pat = self.pat_some(pat.span, val_pat); - self.arm(hir_vec![some_pat], assign) + self.arm(some_pat, assign) }; // `::std::option::Option::None => break` @@ -1092,7 +1082,7 @@ impl LoweringContext<'_> { let break_expr = self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new())); let pat = self.pat_none(e.span); - self.arm(hir_vec![pat], break_expr) + self.arm(pat, break_expr) }; // `mut iter` @@ -1163,7 +1153,7 @@ impl LoweringContext<'_> { }); // `mut iter => { ... }` - let iter_arm = self.arm(hir_vec![iter_pat], loop_expr); + let iter_arm = self.arm(iter_pat, loop_expr); // `match ::std::iter::IntoIterator::into_iter() { ... }` let into_iter_expr = { @@ -1249,7 +1239,7 @@ impl LoweringContext<'_> { ThinVec::from(attrs.clone()), )); let ok_pat = self.pat_ok(span, val_pat); - self.arm(hir_vec![ok_pat], val_expr) + self.arm(ok_pat, val_expr) }; // `Err(err) => #[allow(unreachable_code)] @@ -1284,7 +1274,7 @@ impl LoweringContext<'_> { }; let err_pat = self.pat_err(try_span, err_local); - self.arm(hir_vec![err_pat], ret_expr) + self.arm(err_pat, ret_expr) }; hir::ExprKind::Match( @@ -1479,14 +1469,11 @@ impl LoweringContext<'_> { } } - /// HACK(or_patterns; Centril | dlrobertson): For now we don't push down top level or-patterns - /// `p | q` into `hir::PatKind::Or(...)` as post-lowering bits of the compiler are not ready - /// to deal with it. This should by fixed by pushing it down to HIR and then HAIR. - fn arm(&mut self, pats: HirVec>, expr: P) -> hir::Arm { + fn arm(&mut self, pat: P, expr: P) -> hir::Arm { hir::Arm { hir_id: self.next_id(), attrs: hir_vec![], - pats, + pat, guard: None, span: expr.span, body: expr, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d7c537be89668..4fc29d70540fd 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -834,8 +834,6 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) { pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { visitor.visit_pat(&arm.pat); - // NOTE(or_patterns; Centril | dlrobertson): - // If you change this, also change the hack in `lowering.rs`. walk_list!(visitor, visit_expr, &arm.guard); visitor.visit_expr(&arm.body); walk_list!(visitor, visit_attribute, &arm.attrs); From b2f903c066185d32bdfc02ff6a35f4e50c54728d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 7 Sep 2019 16:00:09 +0200 Subject: [PATCH 04/41] or-patterns: `hir::Arm::pats` -> `::pat` + `Arm::top_pats_hack`. --- src/librustc/hir/mod.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 2c8590aa4e3fa..1b32979eda5f4 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1259,21 +1259,32 @@ pub struct Local { } /// Represents a single arm of a `match` expression, e.g. -/// ` (if ) => `. +/// ` (if ) => `. #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Arm { #[stable_hasher(ignore)] pub hir_id: HirId, pub span: Span, pub attrs: HirVec, - /// Multiple patterns can be combined with `|` - pub pats: HirVec>, + /// If this pattern and the optional guard matches, then `body` is evaluated. + pub pat: P, /// Optional guard clause. pub guard: Option, /// The expression the arm evaluates to if this arm matches. pub body: P, } +impl Arm { + // HACK(or_patterns; Centril | dlrobertson): Remove this and + // correctly handle each case in which this method is used. + pub fn top_pats_hack(&self) -> &[P] { + match &self.pat.node { + PatKind::Or(pats) => pats, + _ => std::slice::from_ref(&self.pat), + } + } +} + #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum Guard { If(P), From 6579d136b13d6b8a3ad14afe688a8c368a538b57 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 7 Sep 2019 16:00:39 +0200 Subject: [PATCH 05/41] or-patterns: normalize HIR pretty priting. --- src/librustc/hir/print.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index cfbfb5eceb550..3cbc9ebec0ad8 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1790,16 +1790,7 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::Arm(arm)); self.ibox(0); self.print_outer_attributes(&arm.attrs); - let mut first = true; - for p in &arm.pats { - if first { - first = false; - } else { - self.s.space(); - self.word_space("|"); - } - self.print_pat(&p); - } + self.print_pat(&arm.pat); self.s.space(); if let Some(ref g) = arm.guard { match g { From 75fb42a11fa91a323e2109a0d42230d96c73e3bb Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 7 Sep 2019 16:01:12 +0200 Subject: [PATCH 06/41] or-patterns: use `top_pats_hack` to make things compile. --- src/librustc/hir/intravisit.rs | 2 +- src/librustc/hir/pat_util.rs | 2 +- src/librustc/middle/dead.rs | 5 +++-- src/librustc/middle/expr_use_visitor.rs | 4 ++-- src/librustc/middle/liveness.rs | 6 +++--- src/librustc_ast_borrowck/cfg/construct.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/pattern/check_match.rs | 6 +++--- src/librustc_passes/rvalue_promotion.rs | 2 +- src/librustc_typeck/check/_match.rs | 8 +++----- src/librustc_typeck/check/regionck.rs | 4 ++-- 11 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 1f125de967216..91fc004b893ba 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1103,7 +1103,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { visitor.visit_id(arm.hir_id); - walk_list!(visitor, visit_pat, &arm.pats); + visitor.visit_pat(&arm.pat); if let Some(ref g) = arm.guard { match g { Guard::If(ref e) => visitor.visit_expr(e), diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 0d2c7d393bb89..3d82f37e1a9c3 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -170,7 +170,7 @@ impl hir::Arm { // for #42640 (default match binding modes). // // See #44848. - self.pats.iter() + self.top_pats_hack().iter() .filter_map(|pat| pat.contains_explicit_ref_binding()) .max_by_key(|m| match *m { hir::MutMutable => 1, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index d4805a7c78322..666c1cc96f2f7 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -259,8 +259,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_arm(&mut self, arm: &'tcx hir::Arm) { - if arm.pats.len() == 1 { - let variants = arm.pats[0].necessary_variants(); + let pats = arm.top_pats_hack(); + if pats.len() == 1 { + let variants = pats[0].necessary_variants(); // Inside the body, ignore constructions of variants // necessary for the pattern to match. Those construction sites diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index de6dadabcbf56..ef84c9bbad60d 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -779,14 +779,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm) -> TrackMatchMode { let mut mode = Unknown; - for pat in &arm.pats { + for pat in arm.top_pats_hack() { self.determine_pat_move_mode(discr_cmt.clone(), &pat, &mut mode); } mode } fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm, mode: MatchMode) { - for pat in &arm.pats { + for pat in arm.top_pats_hack() { self.walk_pat(discr_cmt.clone(), &pat, mode); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 00013bfc574f4..5e91c81dd4ded 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -456,7 +456,7 @@ fn visit_local<'tcx>(ir: &mut IrMaps<'tcx>, local: &'tcx hir::Local) { } fn visit_arm<'tcx>(ir: &mut IrMaps<'tcx>, arm: &'tcx hir::Arm) { - for pat in &arm.pats { + for pat in arm.top_pats_hack() { add_from_pat(ir, pat); } intravisit::walk_arm(ir, arm); @@ -1080,7 +1080,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // the same bindings, and we also consider the first pattern to be // the "authoritative" set of ids let arm_succ = - self.define_bindings_in_arm_pats(arm.pats.first().map(|p| &**p), + self.define_bindings_in_arm_pats(arm.top_pats_hack().first().map(|p| &**p), guard_succ); self.merge_from_succ(ln, arm_succ, first_merge); first_merge = false; @@ -1422,7 +1422,7 @@ fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) { // patterns so the suggestions to prefix with underscores will apply to those too. let mut vars: BTreeMap)> = Default::default(); - for pat in &arm.pats { + for pat in arm.top_pats_hack() { this.arm_pats_bindings(Some(&*pat), |this, ln, var, sp, id| { let name = this.ir.variable_name(var); vars.entry(name) diff --git a/src/librustc_ast_borrowck/cfg/construct.rs b/src/librustc_ast_borrowck/cfg/construct.rs index 0dc999083a91a..e2c5de648a276 100644 --- a/src/librustc_ast_borrowck/cfg/construct.rs +++ b/src/librustc_ast_borrowck/cfg/construct.rs @@ -390,7 +390,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // patterns and the guard (if there is one) in the arm. let bindings_exit = self.add_dummy_node(&[]); - for pat in &arm.pats { + for pat in arm.top_pats_hack() { // Visit the pattern, coming from the discriminant exit let mut pat_exit = self.pat(&pat, discr_exit); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index a33d7207ed4e1..f3d699fa4f008 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -862,7 +862,7 @@ impl ToBorrowKind for hir::Mutability { fn convert_arm<'a, 'tcx>(cx: &mut Cx<'a, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { Arm { - patterns: arm.pats.iter().map(|p| cx.pattern_from_hir(p)).collect(), + patterns: arm.top_pats_hack().iter().map(|p| cx.pattern_from_hir(p)).collect(), guard: match arm.guard { Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())), _ => None, diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 161c58a175579..c3542d4ab6c5f 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -137,7 +137,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { ) { for arm in arms { // First, check legality of move bindings. - self.check_patterns(arm.guard.is_some(), &arm.pats); + self.check_patterns(arm.guard.is_some(), &arm.top_pats_hack()); // Second, if there is a guard on each arm, make sure it isn't // assigning or borrowing anything mutably. @@ -146,7 +146,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { } // Third, perform some lints. - for pat in &arm.pats { + for pat in arm.top_pats_hack() { check_for_bindings_named_same_as_variants(self, pat); } } @@ -156,7 +156,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { let mut have_errors = false; let inlined_arms : Vec<(Vec<_>, _)> = arms.iter().map(|arm| ( - arm.pats.iter().map(|pat| { + arm.top_pats_hack().iter().map(|pat| { let mut patcx = PatternContext::new(self.tcx, self.param_env.and(self.identity_substs), self.tables); diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index f2461f7016131..7470f5b7a5f0f 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -503,7 +503,7 @@ fn check_expr_kind<'a, 'tcx>( // Compute the most demanding borrow from all the arms' // patterns and set that on the discriminator. let mut mut_borrow = false; - for pat in hirvec_arm.iter().flat_map(|arm| &arm.pats) { + for pat in hirvec_arm.iter().flat_map(|arm| arm.top_pats_hack()) { mut_borrow = v.remove_mut_rvalue_borrow(pat); } if mut_borrow { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 308a3d8ebc2cf..7b971803db599 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -58,11 +58,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // collection into `Vec`), so we get types for all bindings. let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| { let mut all_pats_diverge = Diverges::WarnedAlways; - for p in &arm.pats { - self.diverges.set(Diverges::Maybe); - self.check_pat_top(&p, discrim_ty, Some(discrim.span)); - all_pats_diverge &= self.diverges.get(); - } + self.diverges.set(Diverges::Maybe); + self.check_pat_top(&arm.pat, discrim_ty, Some(discrim.span)); + all_pats_diverge &= self.diverges.get(); // As discussed with @eddyb, this is for disabling unreachable_code // warnings on patterns (they're now subsumed by unreachable_patterns diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index fc01a820e2359..86ec477a6aae8 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -488,7 +488,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { fn visit_arm(&mut self, arm: &'tcx hir::Arm) { // see above - for p in &arm.pats { + for p in arm.top_pats_hack() { self.constrain_bindings_in_pat(p); } intravisit::walk_arm(self, arm); @@ -1069,7 +1069,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { let discr_cmt = Rc::new(ignore_err!(self.with_mc(|mc| mc.cat_expr(discr)))); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { - for root_pat in &arm.pats { + for root_pat in arm.top_pats_hack() { self.link_pattern(discr_cmt.clone(), &root_pat); } } From 89bbef302646c4b33148e2a34b69de7643a55ffa Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 02:48:53 +0200 Subject: [PATCH 07/41] check_match: misc cleanup. --- src/librustc_mir/hair/pattern/check_match.rs | 43 ++++++++------------ src/librustc_mir/lib.rs | 1 + 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index c3542d4ab6c5f..dc884d40ac157 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -563,40 +563,30 @@ fn check_legality_of_move_bindings( } }) } + let span_vec = &mut Vec::new(); - let check_move = | - cx: &mut MatchVisitor<'_, '_>, - p: &Pat, - sub: Option<&Pat>, - span_vec: &mut Vec, - | { - // check legality of moving out of the enum - - // x @ Foo(..) is legal, but x @ Foo(y) isn't. + let mut check_move = |p: &Pat, sub: Option<&Pat>| { + // Check legality of moving out of the enum. + // + // `x @ Foo(..)` is legal, but `x @ Foo(y)` isn't. if sub.map_or(false, |p| p.contains_bindings()) { - struct_span_err!(cx.tcx.sess, p.span, E0007, - "cannot bind by-move with sub-bindings") + struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings") .span_label(p.span, "binds an already bound by-move value by moving it") .emit(); - } else if !has_guard { - if let Some(_by_ref_span) = by_ref_span { - span_vec.push(p.span); - } + } else if !has_guard && by_ref_span.is_some() { + span_vec.push(p.span); } }; for pat in pats { pat.walk(|p| { - if let PatKind::Binding(_, _, _, ref sub) = p.node { + if let PatKind::Binding(.., sub) = &p.node { if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { - match bm { - ty::BindByValue(..) => { - let pat_ty = cx.tables.node_type(p.hir_id); - if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { - check_move(cx, p, sub.as_ref().map(|p| &**p), span_vec); - } + if let ty::BindByValue(..) = bm { + let pat_ty = cx.tables.node_type(p.hir_id); + if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { + check_move(p, sub.as_deref()); } - _ => {} } } else { cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); @@ -605,11 +595,10 @@ fn check_legality_of_move_bindings( true }); } - if !span_vec.is_empty(){ - let span = MultiSpan::from_spans(span_vec.clone()); + if !span_vec.is_empty() { let mut err = struct_span_err!( cx.tcx.sess, - span, + MultiSpan::from_spans(span_vec.clone()), E0009, "cannot bind by-move and by-ref in the same pattern", ); @@ -627,7 +616,7 @@ fn check_legality_of_move_bindings( /// because of the way rvalues are handled in the borrow check. (See issue /// #14587.) fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { - AtBindingPatternVisitor { cx: cx, bindings_allowed: true }.visit_pat(pat); + AtBindingPatternVisitor { cx, bindings_allowed: true }.visit_pat(pat); } struct AtBindingPatternVisitor<'a, 'b, 'tcx> { diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index f27db351b74db..ac756747aa326 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -6,6 +6,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nll)] #![feature(in_band_lifetimes)] +#![feature(inner_deref)] #![feature(slice_patterns)] #![feature(box_patterns)] #![feature(box_syntax)] From 4c346939b088cf07ece818b7dc093f993eae2578 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 02:49:37 +0200 Subject: [PATCH 08/41] or-patterns: fix problems in typeck. --- src/librustc_typeck/check/pat.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 8502b89de1469..c8869132fb654 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -97,11 +97,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_pat_struct(pat, qpath, fields, *etc, expected, def_bm, discrim_span) } PatKind::Or(pats) => { - let expected_ty = self.structurally_resolved_type(pat.span, expected); for pat in pats { self.check_pat(pat, expected, def_bm, discrim_span); } - expected_ty + expected } PatKind::Tuple(elements, ddpos) => { self.check_pat_tuple(pat.span, elements, *ddpos, expected, def_bm, discrim_span) @@ -208,7 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match pat.node { PatKind::Struct(..) | PatKind::TupleStruct(..) | - PatKind::Or(_) | PatKind::Tuple(..) | PatKind::Box(_) | PatKind::Range(..) | @@ -226,6 +224,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => true, } } + // FIXME(or_patterns; Centril | dlrobertson): To keep things compiling + // for or-patterns at the top level, we need to make `p_0 | ... | p_n` + // a "non reference pattern". For example the following currently compiles: + // ``` + // match &1 { + // e @ &(1...2) | e @ &(3...4) => {} + // _ => {} + // } + // ``` + // + // We should consider whether we should do something special in nested or-patterns. + PatKind::Or(_) | PatKind::Wild | PatKind::Binding(..) | PatKind::Ref(..) => false, @@ -426,12 +436,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the binding is like `ref x | ref const x | ref mut x` // then `x` is assigned a value of type `&M T` where M is the // mutability and T is the expected type. - let region_ty = self.new_ref_ty(pat.span, mutbl, expected); - + // // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` // is required. However, we use equality, which is stronger. // See (note_1) for an explanation. - region_ty + self.new_ref_ty(pat.span, mutbl, expected) } // Otherwise, the type of x is the expected type `T`. ty::BindByValue(_) => { From 9d1c3c96e7866d6f82b92fffa00fac59f418b601 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 03:26:51 +0200 Subject: [PATCH 09/41] simplify `hir::Pat::walk_`. --- src/librustc/hir/mod.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1b32979eda5f4..edb55ab3caaf4 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -889,19 +889,14 @@ impl Pat { return false; } - match self.node { - PatKind::Binding(.., Some(ref p)) => p.walk_(it), - PatKind::Struct(_, ref fields, _) => { - fields.iter().all(|field| field.pat.walk_(it)) - } - PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => { + match &self.node { + PatKind::Binding(.., Some(p)) => p.walk_(it), + PatKind::Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_(it)), + PatKind::TupleStruct(_, s, _) | PatKind::Tuple(s, _) | PatKind::Or(s) => { s.iter().all(|p| p.walk_(it)) } - PatKind::Or(ref pats) => pats.iter().all(|p| p.walk_(it)), - PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { - s.walk_(it) - } - PatKind::Slice(ref before, ref slice, ref after) => { + PatKind::Box(s) | PatKind::Ref(s, _) => s.walk_(it), + PatKind::Slice(before, slice, after) => { before.iter() .chain(slice.iter()) .chain(after.iter()) From cc5fe6d520683e847d1d5fd2a4544e2a5dba9ab4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 03:55:34 +0200 Subject: [PATCH 10/41] or-patterns: liveness/`visit_arm`: remove `top_pats_hack`. --- src/librustc/middle/liveness.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 5e91c81dd4ded..3c264f9ac6e6c 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -404,7 +404,7 @@ fn visit_fn<'tcx>( lsets.warn_about_unused_args(body, entry_ln); } -fn add_from_pat<'tcx>(ir: &mut IrMaps<'tcx>, pat: &P) { +fn add_from_pat(ir: &mut IrMaps<'_>, pat: &P) { // For struct patterns, take note of which fields used shorthand // (`x` rather than `x: x`). let mut shorthand_field_ids = HirIdSet::default(); @@ -412,26 +412,21 @@ fn add_from_pat<'tcx>(ir: &mut IrMaps<'tcx>, pat: &P) { pats.push_back(pat); while let Some(pat) = pats.pop_front() { use crate::hir::PatKind::*; - match pat.node { - Binding(_, _, _, ref inner_pat) => { + match &pat.node { + Binding(.., inner_pat) => { pats.extend(inner_pat.iter()); } - Struct(_, ref fields, _) => { - for field in fields { - if field.is_shorthand { - shorthand_field_ids.insert(field.pat.hir_id); - } - } + Struct(_, fields, _) => { + let ids = fields.iter().filter(|f| f.is_shorthand).map(|f| f.pat.hir_id); + shorthand_field_ids.extend(ids); } - Ref(ref inner_pat, _) | - Box(ref inner_pat) => { + Ref(inner_pat, _) | Box(inner_pat) => { pats.push_back(inner_pat); } - TupleStruct(_, ref inner_pats, _) | - Tuple(ref inner_pats, _) => { + TupleStruct(_, inner_pats, _) | Tuple(inner_pats, _) | Or(inner_pats) => { pats.extend(inner_pats.iter()); } - Slice(ref pre_pats, ref inner_pat, ref post_pats) => { + Slice(pre_pats, inner_pat, post_pats) => { pats.extend(pre_pats.iter()); pats.extend(inner_pat.iter()); pats.extend(post_pats.iter()); @@ -440,7 +435,7 @@ fn add_from_pat<'tcx>(ir: &mut IrMaps<'tcx>, pat: &P) { } } - pat.each_binding(|_bm, hir_id, _sp, ident| { + pat.each_binding(|_, hir_id, _, ident| { ir.add_live_node_for_node(hir_id, VarDefNode(ident.span)); ir.add_variable(Local(LocalInfo { id: hir_id, @@ -456,9 +451,7 @@ fn visit_local<'tcx>(ir: &mut IrMaps<'tcx>, local: &'tcx hir::Local) { } fn visit_arm<'tcx>(ir: &mut IrMaps<'tcx>, arm: &'tcx hir::Arm) { - for pat in arm.top_pats_hack() { - add_from_pat(ir, pat); - } + add_from_pat(ir, &arm.pat); intravisit::walk_arm(ir, arm); } From 9ca42a56000d261be74db41339beff06bc6088c9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 03:41:21 +0200 Subject: [PATCH 11/41] or-patterns: liveness: generalize + remove `top_pats_hack`. --- src/librustc/hir/pat_util.rs | 28 ++++ src/librustc/middle/liveness.rs | 288 +++++++++++++------------------- 2 files changed, 141 insertions(+), 175 deletions(-) diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 3d82f37e1a9c3..b68886ba62c2d 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -77,6 +77,34 @@ impl hir::Pat { }); } + /// Call `f` on every "binding" in a pattern, e.g., on `a` in + /// `match foo() { Some(a) => (), None => () }`. + /// + /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited. + pub fn each_binding_or_first(&self, c: &mut F) + where F: FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident), + { + match &self.node { + PatKind::Binding(bm, _, ident, sub) => { + c(*bm, self.hir_id, self.span, *ident); + sub.iter().for_each(|p| p.each_binding_or_first(c)); + } + PatKind::Or(ps) => ps[0].each_binding_or_first(c), + PatKind::Struct(_, fs, _) => fs.iter().for_each(|f| f.pat.each_binding_or_first(c)), + PatKind::TupleStruct(_, ps, _) | PatKind::Tuple(ps, _) => { + ps.iter().for_each(|p| p.each_binding_or_first(c)); + } + PatKind::Box(p) | PatKind::Ref(p, _) => p.each_binding_or_first(c), + PatKind::Slice(before, slice, after) => { + before.iter() + .chain(slice.iter()) + .chain(after.iter()) + .for_each(|p| p.each_binding_or_first(c)); + } + PatKind::Wild | PatKind::Lit(_) | PatKind::Range(..) | PatKind::Path(_) => {} + } + } + /// Checks if the pattern contains any patterns that bind something to /// an ident, e.g., `foo`, or `Foo(foo)` or `foo @ Bar(..)`. pub fn contains_bindings(&self) -> bool { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 3c264f9ac6e6c..9afd147ae34e2 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -96,7 +96,11 @@ use self::LiveNodeKind::*; use self::VarKind::*; +use crate::hir; +use crate::hir::{Expr, HirId}; use crate::hir::def::*; +use crate::hir::def_id::DefId; +use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use crate::hir::Node; use crate::hir::ptr::P; use crate::ty::{self, TyCtxt}; @@ -105,20 +109,16 @@ use crate::lint; use crate::util::nodemap::{HirIdMap, HirIdSet}; use errors::Applicability; -use std::collections::{BTreeMap, VecDeque}; +use rustc_data_structures::fx::FxIndexMap; +use std::collections::VecDeque; use std::{fmt, u32}; use std::io::prelude::*; use std::io; use std::rc::Rc; use syntax::ast; -use syntax::symbol::{kw, sym}; +use syntax::symbol::sym; use syntax_pos::Span; -use crate::hir; -use crate::hir::{Expr, HirId}; -use crate::hir::def_id::DefId; -use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; - #[derive(Copy, Clone, PartialEq)] struct Variable(u32); @@ -727,35 +727,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.variable(hir_id, span) } - fn pat_bindings(&mut self, pat: &hir::Pat, mut f: F) where - F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, HirId), - { - pat.each_binding(|_bm, hir_id, sp, n| { - let ln = self.live_node(hir_id, sp); - let var = self.variable(hir_id, n.span); - f(self, ln, var, n.span, hir_id); - }) - } - - fn arm_pats_bindings(&mut self, pat: Option<&hir::Pat>, f: F) where - F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, HirId), - { - if let Some(pat) = pat { - self.pat_bindings(pat, f); - } - } - - fn define_bindings_in_pat(&mut self, pat: &hir::Pat, succ: LiveNode) - -> LiveNode { - self.define_bindings_in_arm_pats(Some(pat), succ) - } - - fn define_bindings_in_arm_pats(&mut self, pat: Option<&hir::Pat>, succ: LiveNode) - -> LiveNode { - let mut succ = succ; - self.arm_pats_bindings(pat, |this, ln, var, _sp, _id| { - this.init_from_succ(ln, succ); - this.define(ln, var); + fn define_bindings_in_pat(&mut self, pat: &hir::Pat, mut succ: LiveNode) -> LiveNode { + // In an or-pattern, only consider the first pattern; any later patterns + // must have the same bindings, and we also consider the first pattern + // to be the "authoritative" set of ids. + pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| { + let ln = self.live_node(hir_id, pat_sp); + let var = self.variable(hir_id, ident.span); + self.init_from_succ(ln, succ); + self.define(ln, var); succ = ln; }); succ @@ -1069,12 +1049,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { arm.guard.as_ref().map(|hir::Guard::If(e)| &**e), body_succ ); - // only consider the first pattern; any later patterns must have - // the same bindings, and we also consider the first pattern to be - // the "authoritative" set of ids - let arm_succ = - self.define_bindings_in_arm_pats(arm.top_pats_hack().first().map(|p| &**p), - guard_succ); + let arm_succ = self.define_bindings_in_pat(&arm.pat, guard_succ); self.merge_from_succ(ln, arm_succ, first_merge); first_merge = false; }; @@ -1381,74 +1356,36 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> { NestedVisitorMap::None } - fn visit_local(&mut self, l: &'tcx hir::Local) { - check_local(self, l); - } - fn visit_expr(&mut self, ex: &'tcx Expr) { - check_expr(self, ex); - } - fn visit_arm(&mut self, a: &'tcx hir::Arm) { - check_arm(self, a); - } -} + fn visit_local(&mut self, local: &'tcx hir::Local) { + self.check_unused_vars_in_pat(&local.pat, None, |spans, hir_id, ln, var| { + if local.init.is_some() { + self.warn_about_dead_assign(spans, hir_id, ln, var); + } + }); -fn check_local<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, local: &'tcx hir::Local) { - match local.init { - Some(_) => { - this.warn_about_unused_or_dead_vars_in_pat(&local.pat); - }, - None => { - this.pat_bindings(&local.pat, |this, ln, var, sp, id| { - let span = local.pat.simple_ident().map_or(sp, |ident| ident.span); - this.warn_about_unused(vec![span], id, ln, var); - }) - } + intravisit::walk_local(self, local); } - intravisit::walk_local(this, local); -} - -fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) { - // Only consider the variable from the first pattern; any later patterns must have - // the same bindings, and we also consider the first pattern to be the "authoritative" set of - // ids. However, we should take the spans of variables with the same name from the later - // patterns so the suggestions to prefix with underscores will apply to those too. - let mut vars: BTreeMap)> = Default::default(); - - for pat in arm.top_pats_hack() { - this.arm_pats_bindings(Some(&*pat), |this, ln, var, sp, id| { - let name = this.ir.variable_name(var); - vars.entry(name) - .and_modify(|(.., spans)| { - spans.push(sp); - }) - .or_insert_with(|| { - (ln, var, id, vec![sp]) - }); - }); + fn visit_expr(&mut self, ex: &'tcx Expr) { + check_expr(self, ex); } - for (_, (ln, var, id, spans)) in vars { - this.warn_about_unused(spans, id, ln, var); + fn visit_arm(&mut self, arm: &'tcx hir::Arm) { + self.check_unused_vars_in_pat(&arm.pat, None, |_, _, _, _| {}); + intravisit::walk_arm(self, arm); } - - intravisit::walk_arm(this, arm); } -fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { +fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr) { match expr.node { hir::ExprKind::Assign(ref l, _) => { this.check_place(&l); - - intravisit::walk_expr(this, expr); } hir::ExprKind::AssignOp(_, ref l, _) => { if !this.tables.is_method_call(expr) { this.check_place(&l); } - - intravisit::walk_expr(this, expr); } hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => { @@ -1463,8 +1400,6 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { } this.visit_expr(output); } - - intravisit::walk_expr(this, expr); } // no correctness conditions related to liveness @@ -1477,13 +1412,13 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { hir::ExprKind::Lit(_) | hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::Closure(..) | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) | - hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err => { - intravisit::walk_expr(this, expr); - } + hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err => {} } + + intravisit::walk_expr(this, expr); } -impl<'a, 'tcx> Liveness<'a, 'tcx> { +impl<'tcx> Liveness<'_, 'tcx> { fn check_place(&mut self, expr: &'tcx Expr) { match expr.node { hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => { @@ -1496,7 +1431,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // as being used. let ln = self.live_node(expr.hir_id, expr.span); let var = self.variable(var_hid, expr.span); - self.warn_about_dead_assign(expr.span, expr.hir_id, ln, var); + self.warn_about_dead_assign(vec![expr.span], expr.hir_id, ln, var); } } } @@ -1518,109 +1453,112 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn warn_about_unused_args(&self, body: &hir::Body, entry_ln: LiveNode) { - for param in &body.params { - param.pat.each_binding(|_bm, hir_id, _, ident| { - let sp = ident.span; - let var = self.variable(hir_id, sp); - // Ignore unused self. - if ident.name != kw::SelfLower { - if !self.warn_about_unused(vec![sp], hir_id, entry_ln, var) { - if self.live_on_entry(entry_ln, var).is_none() { - self.report_dead_assign(hir_id, sp, var, true); - } - } + for p in &body.params { + self.check_unused_vars_in_pat(&p.pat, Some(entry_ln), |spans, hir_id, ln, var| { + if self.live_on_entry(ln, var).is_none() { + self.report_dead_assign(hir_id, spans, var, true); } - }) + }); } } - fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &hir::Pat) { - self.pat_bindings(pat, |this, ln, var, sp, id| { - if !this.warn_about_unused(vec![sp], id, ln, var) { - this.warn_about_dead_assign(sp, id, ln, var); + fn check_unused_vars_in_pat( + &self, + pat: &hir::Pat, + entry_ln: Option, + on_used_on_entry: impl Fn(Vec, HirId, LiveNode, Variable), + ) { + // In an or-pattern, only consider the variable; any later patterns must have the same + // bindings, and we also consider the first pattern to be the "authoritative" set of ids. + // However, we should take the spans of variables with the same name from the later + // patterns so the suggestions to prefix with underscores will apply to those too. + let mut vars: FxIndexMap)> = <_>::default(); + + pat.each_binding(|_, hir_id, pat_sp, ident| { + let ln = entry_ln.unwrap_or_else(|| self.live_node(hir_id, pat_sp)); + let var = self.variable(hir_id, ident.span); + vars.entry(self.ir.variable_name(var)) + .and_modify(|(.., spans)| spans.push(ident.span)) + .or_insert_with(|| (ln, var, hir_id, vec![ident.span])); + }); + + for (_, (ln, var, id, spans)) in vars { + if self.used_on_entry(ln, var) { + on_used_on_entry(spans, id, ln, var); + } else { + self.report_unused(spans, id, ln, var); } - }) + } } - fn warn_about_unused(&self, - spans: Vec, - hir_id: HirId, - ln: LiveNode, - var: Variable) - -> bool { - if !self.used_on_entry(ln, var) { - let r = self.should_warn(var); - if let Some(name) = r { - // annoying: for parameters in funcs like `fn(x: i32) - // {ret}`, there is only one node, so asking about - // assigned_on_exit() is not meaningful. - let is_assigned = if ln == self.s.exit_ln { - false - } else { - self.assigned_on_exit(ln, var).is_some() - }; + fn report_unused(&self, spans: Vec, hir_id: HirId, ln: LiveNode, var: Variable) { + if let Some(name) = self.should_warn(var).filter(|name| name != "self") { + // annoying: for parameters in funcs like `fn(x: i32) + // {ret}`, there is only one node, so asking about + // assigned_on_exit() is not meaningful. + let is_assigned = if ln == self.s.exit_ln { + false + } else { + self.assigned_on_exit(ln, var).is_some() + }; - if is_assigned { - self.ir.tcx.lint_hir_note( - lint::builtin::UNUSED_VARIABLES, - hir_id, - spans, - &format!("variable `{}` is assigned to, but never used", name), - &format!("consider using `_{}` instead", name), - ); - } else if name != "self" { - let mut err = self.ir.tcx.struct_span_lint_hir( - lint::builtin::UNUSED_VARIABLES, - hir_id, - spans.clone(), - &format!("unused variable: `{}`", name), - ); + if is_assigned { + self.ir.tcx.lint_hir_note( + lint::builtin::UNUSED_VARIABLES, + hir_id, + spans, + &format!("variable `{}` is assigned to, but never used", name), + &format!("consider using `_{}` instead", name), + ); + } else { + let mut err = self.ir.tcx.struct_span_lint_hir( + lint::builtin::UNUSED_VARIABLES, + hir_id, + spans.clone(), + &format!("unused variable: `{}`", name), + ); + + if self.ir.variable_is_shorthand(var) { + if let Node::Binding(pat) = self.ir.tcx.hir().get(hir_id) { + // Handle `ref` and `ref mut`. + let spans = spans.iter() + .map(|_span| (pat.span, format!("{}: _", name))) + .collect(); - if self.ir.variable_is_shorthand(var) { - if let Node::Binding(pat) = self.ir.tcx.hir().get(hir_id) { - // Handle `ref` and `ref mut`. - let spans = spans.iter() - .map(|_span| (pat.span, format!("{}: _", name))) - .collect(); - - err.multipart_suggestion( - "try ignoring the field", - spans, - Applicability::MachineApplicable, - ); - } - } else { err.multipart_suggestion( - "consider prefixing with an underscore", - spans.iter().map(|span| (*span, format!("_{}", name))).collect(), + "try ignoring the field", + spans, Applicability::MachineApplicable, ); } - - err.emit() + } else { + err.multipart_suggestion( + "consider prefixing with an underscore", + spans.iter().map(|span| (*span, format!("_{}", name))).collect(), + Applicability::MachineApplicable, + ); } + + err.emit() } - true - } else { - false } } - fn warn_about_dead_assign(&self, sp: Span, hir_id: HirId, ln: LiveNode, var: Variable) { + fn warn_about_dead_assign(&self, spans: Vec, hir_id: HirId, ln: LiveNode, var: Variable) { if self.live_on_exit(ln, var).is_none() { - self.report_dead_assign(hir_id, sp, var, false); + self.report_dead_assign(hir_id, spans, var, false); } } - fn report_dead_assign(&self, hir_id: HirId, sp: Span, var: Variable, is_argument: bool) { + fn report_dead_assign(&self, hir_id: HirId, spans: Vec, var: Variable, is_argument: bool) { if let Some(name) = self.should_warn(var) { if is_argument { - self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp, + self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, spans, &format!("value passed to `{}` is never read", name)) .help("maybe it is overwritten before being read?") .emit(); } else { - self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp, + self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, spans, &format!("value assigned to `{}` is never read", name)) .help("maybe it is overwritten before being read?") .emit(); From 57eeb61cc861f32351a9d45eed09b6b8ca3c9c5b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 04:07:56 +0200 Subject: [PATCH 12/41] or-patterns: remove `Arm::contains_explicit_ref_binding`. --- src/librustc/hir/pat_util.rs | 17 ----------------- src/librustc_typeck/check/_match.rs | 10 +++++----- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index b68886ba62c2d..ea35418bc1ba7 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -189,20 +189,3 @@ impl hir::Pat { result } } - -impl hir::Arm { - /// Checks if the patterns for this arm contain any `ref` or `ref mut` - /// bindings, and if yes whether its containing mutable ones or just immutables ones. - pub fn contains_explicit_ref_binding(&self) -> Option { - // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed - // for #42640 (default match binding modes). - // - // See #44848. - self.top_pats_hack().iter() - .filter_map(|pat| pat.contains_explicit_ref_binding()) - .max_by_key(|m| match *m { - hir::MutMutable => 1, - hir::MutImmutable => 0, - }) - } -} diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 7b971803db599..e0b53525dc90c 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -411,11 +411,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // See #44848. let contains_ref_bindings = arms.iter() - .filter_map(|a| a.contains_explicit_ref_binding()) - .max_by_key(|m| match *m { - hir::MutMutable => 1, - hir::MutImmutable => 0, - }); + .filter_map(|a| a.pat.contains_explicit_ref_binding()) + .max_by_key(|m| match *m { + hir::MutMutable => 1, + hir::MutImmutable => 0, + }); if let Some(m) = contains_ref_bindings { self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m)) From fb2cfec433421ada440a5dc83686f739dc1ab521 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 04:17:55 +0200 Subject: [PATCH 13/41] or-patterns: euv/`arm_move_mode`: remove `top_pats_hack`. --- src/librustc/middle/expr_use_visitor.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index ef84c9bbad60d..0e97a3b59d082 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -779,9 +779,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm) -> TrackMatchMode { let mut mode = Unknown; - for pat in arm.top_pats_hack() { - self.determine_pat_move_mode(discr_cmt.clone(), &pat, &mut mode); - } + self.determine_pat_move_mode(discr_cmt.clone(), &arm.pat, &mut mode); mode } From d7139f3e6d9dfa11d03f8529907d643bbfa8005a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 04:26:00 +0200 Subject: [PATCH 14/41] or-patterns: euv/`walk_arm`: remove `top_pats_hack`. --- src/librustc/middle/expr_use_visitor.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 0e97a3b59d082..a3110c000fb22 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -784,9 +784,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm, mode: MatchMode) { - for pat in arm.top_pats_hack() { - self.walk_pat(discr_cmt.clone(), &pat, mode); - } + self.walk_pat(discr_cmt.clone(), &arm.pat, mode); if let Some(hir::Guard::If(ref e)) = arm.guard { self.consume_expr(e) From 07deb93bb291917967d167fa6cdacc62b0186599 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 18:44:32 +0200 Subject: [PATCH 15/41] or-patterns: middle/dead: make a hack less hacky. --- src/librustc/middle/dead.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 666c1cc96f2f7..1818dede3e229 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -260,8 +260,8 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { fn visit_arm(&mut self, arm: &'tcx hir::Arm) { let pats = arm.top_pats_hack(); - if pats.len() == 1 { - let variants = pats[0].necessary_variants(); + if let [pat] = pats { + let variants = pat.necessary_variants(); // Inside the body, ignore constructions of variants // necessary for the pattern to match. Those construction sites From 0dfd706257326cf826cca0a1029cf5bc0c2aee97 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 19:17:21 +0200 Subject: [PATCH 16/41] or-patterns: rvalue_promotion: remove `top_pats_hack`. --- src/librustc_passes/rvalue_promotion.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 7470f5b7a5f0f..12978cd117b52 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -499,19 +499,15 @@ fn check_expr_kind<'a, 'tcx>( } // Conditional control flow (possible to implement). - hir::ExprKind::Match(ref expr, ref hirvec_arm, ref _match_source) => { + hir::ExprKind::Match(ref expr, ref arms, ref _match_source) => { // Compute the most demanding borrow from all the arms' // patterns and set that on the discriminator. - let mut mut_borrow = false; - for pat in hirvec_arm.iter().flat_map(|arm| arm.top_pats_hack()) { - mut_borrow = v.remove_mut_rvalue_borrow(pat); - } - if mut_borrow { + if arms.iter().fold(false, |_, arm| v.remove_mut_rvalue_borrow(&arm.pat)) { v.mut_rvalue_borrows.insert(expr.hir_id); } let _ = v.check_expr(expr); - for index in hirvec_arm.iter() { + for index in arms.iter() { let _ = v.check_expr(&*index.body); if let Some(hir::Guard::If(ref expr)) = index.guard { let _ = v.check_expr(&expr); From 38a5ae9cc1bc2c4fb25a4be639b0eafaeb51426a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 19:24:40 +0200 Subject: [PATCH 17/41] or-patterns: regionck/visit_arm: remove `top_pats_hack`. --- src/librustc_typeck/check/regionck.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 86ec477a6aae8..698b49515fb66 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -488,9 +488,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { fn visit_arm(&mut self, arm: &'tcx hir::Arm) { // see above - for p in arm.top_pats_hack() { - self.constrain_bindings_in_pat(p); - } + self.constrain_bindings_in_pat(&arm.pat); intravisit::walk_arm(self, arm); } From 9b406f1069852ed2fb6c51e4abb8f51b947c0955 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 19:38:03 +0200 Subject: [PATCH 18/41] or-patterns: regionck/`link_match`: remove `top_pats_hack`. --- src/librustc_typeck/check/regionck.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 698b49515fb66..6fa8a016b5458 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1067,9 +1067,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { let discr_cmt = Rc::new(ignore_err!(self.with_mc(|mc| mc.cat_expr(discr)))); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { - for root_pat in arm.top_pats_hack() { - self.link_pattern(discr_cmt.clone(), &root_pat); - } + self.link_pattern(discr_cmt.clone(), &arm.pat); } } From 6bd8c6d4f44884a756471dda6ff3e5c66dbbd042 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 19:53:59 +0200 Subject: [PATCH 19/41] or-patterns: check_match: remove `top_pats_hack` for `check_for_bindings_named_same_as_variants`. --- src/librustc_mir/hair/pattern/check_match.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index dc884d40ac157..eb3698957157b 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -146,9 +146,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { } // Third, perform some lints. - for pat in arm.top_pats_hack() { - check_for_bindings_named_same_as_variants(self, pat); - } + check_for_bindings_named_same_as_variants(self, &arm.pat); } let module = self.tcx.hir().get_module_parent(scrut.hir_id); From 549756bef89fa7f9e39cf5e3d04553076ca952ae Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Sep 2019 20:54:38 +0200 Subject: [PATCH 20/41] or-patterns: check_match: nix `top_pats_hack` passed to `check_patterns`. --- src/librustc_mir/hair/pattern/check_match.rs | 70 +++++++++----------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index eb3698957157b..6301d9c390b02 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -14,7 +14,6 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc::hir::def::*; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::hir::ptr::P; use rustc::hir::{self, Pat, PatKind}; use smallvec::smallvec; @@ -76,7 +75,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { }); // Check legality of move bindings and `@` patterns. - self.check_patterns(false, slice::from_ref(&loc.pat)); + self.check_patterns(false, &loc.pat); } fn visit_body(&mut self, body: &'tcx hir::Body) { @@ -84,7 +83,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { for param in &body.params { self.check_irrefutable(¶m.pat, "function argument"); - self.check_patterns(false, slice::from_ref(¶m.pat)); + self.check_patterns(false, ¶m.pat); } } } @@ -122,11 +121,9 @@ impl PatternContext<'_, '_> { } impl<'tcx> MatchVisitor<'_, 'tcx> { - fn check_patterns(&mut self, has_guard: bool, pats: &[P]) { - check_legality_of_move_bindings(self, has_guard, pats); - for pat in pats { - check_legality_of_bindings_in_at_patterns(self, pat); - } + fn check_patterns(&mut self, has_guard: bool, pat: &Pat) { + check_legality_of_move_bindings(self, has_guard, pat); + check_legality_of_bindings_in_at_patterns(self, pat); } fn check_match( @@ -137,7 +134,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { ) { for arm in arms { // First, check legality of move bindings. - self.check_patterns(arm.guard.is_some(), &arm.top_pats_hack()); + self.check_patterns(arm.guard.is_some(), &arm.pat); // Second, if there is a guard on each arm, make sure it isn't // assigning or borrowing anything mutably. @@ -543,24 +540,18 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[Pattern<'_>]) -> Vec { covered } -// Legality of move bindings checking -fn check_legality_of_move_bindings( - cx: &mut MatchVisitor<'_, '_>, - has_guard: bool, - pats: &[P], -) { +// Check the legality of legality of by-move bindings. +fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat) { let mut by_ref_span = None; - for pat in pats { - pat.each_binding(|_, hir_id, span, _path| { - if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) { - if let ty::BindByReference(..) = bm { - by_ref_span = Some(span); - } - } else { - cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); + pat.each_binding(|_, hir_id, span, _| { + if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) { + if let ty::BindByReference(..) = bm { + by_ref_span = Some(span); } - }) - } + } else { + cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); + } + }); let span_vec = &mut Vec::new(); let mut check_move = |p: &Pat, sub: Option<&Pat>| { @@ -576,23 +567,22 @@ fn check_legality_of_move_bindings( } }; - for pat in pats { - pat.walk(|p| { - if let PatKind::Binding(.., sub) = &p.node { - if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { - if let ty::BindByValue(..) = bm { - let pat_ty = cx.tables.node_type(p.hir_id); - if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { - check_move(p, sub.as_deref()); - } + pat.walk(|p| { + if let PatKind::Binding(.., sub) = &p.node { + if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { + if let ty::BindByValue(..) = bm { + let pat_ty = cx.tables.node_type(p.hir_id); + if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { + check_move(p, sub.as_deref()); } - } else { - cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } + } else { + cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } - true - }); - } + } + true + }); + if !span_vec.is_empty() { let mut err = struct_span_err!( cx.tcx.sess, @@ -603,7 +593,7 @@ fn check_legality_of_move_bindings( if let Some(by_ref_span) = by_ref_span { err.span_label(by_ref_span, "both by-ref and by-move used"); } - for span in span_vec.iter(){ + for span in span_vec.iter() { err.span_label(*span, "by-move pattern here"); } err.emit(); From 56b055a6abf5f3cf0d4ae13026154eb82298b21b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 16 Sep 2019 03:32:44 +0200 Subject: [PATCH 21/41] or-patterns: HAIR: `Arm.patterns: Vec>` -> `.pattern: Pattern<'_>`. --- src/librustc_mir/build/matches/mod.rs | 6 +++--- src/librustc_mir/hair/cx/expr.rs | 4 ++-- src/librustc_mir/hair/mod.rs | 13 ++++++++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index aa261f8eb6fb2..f23abf86bcfc8 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -142,7 +142,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Step 2. Create the otherwise and prebinding blocks. // create binding start block for link them by false edges - let candidate_count = arms.iter().map(|c| c.patterns.len()).sum::(); + let candidate_count = arms.iter().map(|c| c.top_pats_hack().len()).sum::(); let pre_binding_blocks: Vec<_> = (0..candidate_count) .map(|_| self.cfg.start_new_block()) .collect(); @@ -159,7 +159,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .map(|arm| { let arm_has_guard = arm.guard.is_some(); match_has_guard |= arm_has_guard; - let arm_candidates: Vec<_> = arm.patterns + let arm_candidates: Vec<_> = arm.top_pats_hack() .iter() .zip(candidate_pre_binding_blocks.by_ref()) .map( @@ -238,7 +238,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scope = this.declare_bindings( None, arm.span, - &arm.patterns[0], + &arm.top_pats_hack()[0], ArmHasGuard(arm.guard.is_some()), Some((Some(&scrutinee_place), scrutinee_span)), ); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index f3d699fa4f008..bdfcacd0f4629 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -860,9 +860,9 @@ impl ToBorrowKind for hir::Mutability { } } -fn convert_arm<'a, 'tcx>(cx: &mut Cx<'a, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { +fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { Arm { - patterns: arm.top_pats_hack().iter().map(|p| cx.pattern_from_hir(p)).collect(), + pattern: cx.pattern_from_hir(&arm.pat), guard: match arm.guard { Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())), _ => None, diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 0638cb462f73b..63a9a83154b4f 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -293,7 +293,7 @@ pub struct FruInfo<'tcx> { #[derive(Clone, Debug)] pub struct Arm<'tcx> { - pub patterns: Vec>, + pub pattern: Pattern<'tcx>, pub guard: Option>, pub body: ExprRef<'tcx>, pub lint_level: LintLevel, @@ -301,6 +301,17 @@ pub struct Arm<'tcx> { pub span: Span, } +impl Arm<'tcx> { + // HACK(or_patterns; Centril | dlrobertson): Remove this and + // correctly handle each case in which this method is used. + pub fn top_pats_hack(&self) -> &[Pattern<'tcx>] { + match &*self.pattern.kind { + PatternKind::Or { pats } => pats, + _ => std::slice::from_ref(&self.pattern), + } + } +} + #[derive(Clone, Debug)] pub enum Guard<'tcx> { If(ExprRef<'tcx>), From 05cc3c0a83fc7faab20a10f2e0eca61dc34a6394 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 16 Sep 2019 16:35:36 +0200 Subject: [PATCH 22/41] or-patterns: liveness: `is_argument` -> `is_param`. Pacify `tidy`. It's also more correct in this context. --- src/librustc/middle/liveness.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 9afd147ae34e2..9f6611712a8aa 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1550,9 +1550,9 @@ impl<'tcx> Liveness<'_, 'tcx> { } } - fn report_dead_assign(&self, hir_id: HirId, spans: Vec, var: Variable, is_argument: bool) { + fn report_dead_assign(&self, hir_id: HirId, spans: Vec, var: Variable, is_param: bool) { if let Some(name) = self.should_warn(var) { - if is_argument { + if is_param { self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, spans, &format!("value passed to `{}` is never read", name)) .help("maybe it is overwritten before being read?") From 370fbcc0225a226096773fc8641c59eb5e635f7a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 16 Sep 2019 20:49:48 +0200 Subject: [PATCH 23/41] or-patterns: #47390: we rely on names to exercise `IndexMap`. --- ...47390-unused-variable-in-struct-pattern.rs | 3 +++ ...0-unused-variable-in-struct-pattern.stderr | 20 +++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index 4cb35e907c8f9..7870d394c8bfb 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -33,6 +33,9 @@ fn main() { let mut mut_unused_var = 1; let (mut var, unused_var) = (1, 2); + // NOTE: `var` comes after `unused_var` lexicographically yet the warning + // for `var` will be emitted before the one for `unused_var`. We use an + // `IndexMap` to ensure this is the case instead of a `BTreeMap`. if let SoulHistory { corridors_of_light, mut hours_are_suns, diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index a0b34d220c8d9..74bbef8adad05 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -30,13 +30,13 @@ LL | let (mut var, unused_var) = (1, 2); | ^^^^^^^^^^ help: consider prefixing with an underscore: `_unused_var` warning: unused variable: `corridors_of_light` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:26 | LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:30 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:30 | LL | mut hours_are_suns, | ^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | mut hours_are_suns, = note: consider using `_hours_are_suns` instead warning: value assigned to `hours_are_suns` is never read - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:9 | LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ @@ -58,43 +58,43 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) = help: maybe it is overwritten before being read? warning: unused variable: `fire` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:44:32 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:47:32 | LL | let LovelyAmbition { lips, fire } = the_spirit; | ^^^^ help: try ignoring the field: `fire: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:53:23 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:56:23 | LL | Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:58:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:61:24 | LL | &Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:63:27 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:66:27 | LL | box Large::Suit { case } => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:68:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:71:24 | LL | (Large::Suit { case },) => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:73:24 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:76:24 | LL | [Large::Suit { case }] => {} | ^^^^ help: try ignoring the field: `case: _` warning: unused variable: `case` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:78:29 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:81:29 | LL | Tuple(Large::Suit { case }, ()) => {} | ^^^^ help: try ignoring the field: `case: _` From 0918dc4e5990592c28484d1d64bec41cb9a4a301 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 21 Sep 2019 15:49:15 +0200 Subject: [PATCH 24/41] or-patterns: middle/dead: remove `top_pats_hack`. Also tweak walkers on `Pat`. --- src/librustc/hir/mod.rs | 62 ++++++++++++------- src/librustc/hir/pat_util.rs | 112 ++++++++++++++++------------------- src/librustc/middle/dead.rs | 21 +++---- 3 files changed, 100 insertions(+), 95 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index edb55ab3caaf4..87fc385acd64d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -882,39 +882,61 @@ impl fmt::Debug for Pat { impl Pat { // FIXME(#19596) this is a workaround, but there should be a better way - fn walk_(&self, it: &mut G) -> bool - where G: FnMut(&Pat) -> bool - { + fn walk_short_(&self, it: &mut impl FnMut(&Pat) -> bool) -> bool { if !it(self) { return false; } + use PatKind::*; match &self.node { - PatKind::Binding(.., Some(p)) => p.walk_(it), - PatKind::Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_(it)), - PatKind::TupleStruct(_, s, _) | PatKind::Tuple(s, _) | PatKind::Or(s) => { - s.iter().all(|p| p.walk_(it)) - } - PatKind::Box(s) | PatKind::Ref(s, _) => s.walk_(it), - PatKind::Slice(before, slice, after) => { + Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true, + Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it), + Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)), + TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)), + Slice(before, slice, after) => { before.iter() .chain(slice.iter()) .chain(after.iter()) - .all(|p| p.walk_(it)) + .all(|p| p.walk_short_(it)) } - PatKind::Wild | - PatKind::Lit(_) | - PatKind::Range(..) | - PatKind::Binding(..) | - PatKind::Path(_) => { - true + } + } + + /// Walk the pattern in left-to-right order, + /// short circuiting (with `.all(..)`) if `false` is returned. + /// + /// Note that when visiting e.g. `Tuple(ps)`, + /// if visiting `ps[0]` returns `false`, + /// then `ps[1]` will not be visited. + pub fn walk_short(&self, mut it: impl FnMut(&Pat) -> bool) -> bool { + self.walk_short_(&mut it) + } + + // FIXME(#19596) this is a workaround, but there should be a better way + fn walk_(&self, it: &mut impl FnMut(&Pat) -> bool) { + if !it(self) { + return; + } + + use PatKind::*; + match &self.node { + Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}, + Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it), + Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)), + TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)), + Slice(before, slice, after) => { + before.iter() + .chain(slice.iter()) + .chain(after.iter()) + .for_each(|p| p.walk_(it)) } } } - pub fn walk(&self, mut it: F) -> bool - where F: FnMut(&Pat) -> bool - { + /// Walk the pattern in left-to-right order. + /// + /// If `it(pat)` returns `false`, the children are not visited. + pub fn walk(&self, mut it: impl FnMut(&Pat) -> bool) { self.walk_(&mut it) } } diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index ea35418bc1ba7..118e168f87767 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -66,9 +66,7 @@ impl hir::Pat { /// Call `f` on every "binding" in a pattern, e.g., on `a` in /// `match foo() { Some(a) => (), None => () }` - pub fn each_binding(&self, mut f: F) - where F: FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident), - { + pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident)) { self.walk(|p| { if let PatKind::Binding(binding_mode, _, ident, _) = p.node { f(binding_mode, p.hir_id, p.span, ident); @@ -81,59 +79,53 @@ impl hir::Pat { /// `match foo() { Some(a) => (), None => () }`. /// /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited. - pub fn each_binding_or_first(&self, c: &mut F) - where F: FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident), - { - match &self.node { - PatKind::Binding(bm, _, ident, sub) => { - c(*bm, self.hir_id, self.span, *ident); - sub.iter().for_each(|p| p.each_binding_or_first(c)); - } - PatKind::Or(ps) => ps[0].each_binding_or_first(c), - PatKind::Struct(_, fs, _) => fs.iter().for_each(|f| f.pat.each_binding_or_first(c)), - PatKind::TupleStruct(_, ps, _) | PatKind::Tuple(ps, _) => { - ps.iter().for_each(|p| p.each_binding_or_first(c)); - } - PatKind::Box(p) | PatKind::Ref(p, _) => p.each_binding_or_first(c), - PatKind::Slice(before, slice, after) => { - before.iter() - .chain(slice.iter()) - .chain(after.iter()) - .for_each(|p| p.each_binding_or_first(c)); + pub fn each_binding_or_first( + &self, + f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident), + ) { + self.walk(|p| match &p.node { + PatKind::Or(ps) => { + ps[0].each_binding_or_first(f); + false + }, + PatKind::Binding(bm, _, ident, _) => { + f(*bm, p.hir_id, p.span, *ident); + true } - PatKind::Wild | PatKind::Lit(_) | PatKind::Range(..) | PatKind::Path(_) => {} - } + _ => true, + }) } /// Checks if the pattern contains any patterns that bind something to /// an ident, e.g., `foo`, or `Foo(foo)` or `foo @ Bar(..)`. pub fn contains_bindings(&self) -> bool { - let mut contains_bindings = false; - self.walk(|p| { - if let PatKind::Binding(..) = p.node { - contains_bindings = true; - false // there's at least one binding, can short circuit now. - } else { - true - } - }); - contains_bindings + self.satisfies(|p| match p.node { + PatKind::Binding(..) => true, + _ => false, + }) } /// Checks if the pattern contains any patterns that bind something to /// an ident or wildcard, e.g., `foo`, or `Foo(_)`, `foo @ Bar(..)`, pub fn contains_bindings_or_wild(&self) -> bool { - let mut contains_bindings = false; - self.walk(|p| { - match p.node { - PatKind::Binding(..) | PatKind::Wild => { - contains_bindings = true; - false // there's at least one binding/wildcard, can short circuit now. - } - _ => true + self.satisfies(|p| match p.node { + PatKind::Binding(..) | PatKind::Wild => true, + _ => false, + }) + } + + /// Checks if the pattern satisfies the given predicate on some sub-pattern. + fn satisfies(&self, pred: impl Fn(&Self) -> bool) -> bool { + let mut satisfies = false; + self.walk_short(|p| { + if pred(p) { + satisfies = true; + false // Found one, can short circuit now. + } else { + true } }); - contains_bindings + satisfies } pub fn simple_ident(&self) -> Option { @@ -147,20 +139,20 @@ impl hir::Pat { /// Returns variants that are necessary to exist for the pattern to match. pub fn necessary_variants(&self) -> Vec { let mut variants = vec![]; - self.walk(|p| { - match p.node { - PatKind::Path(hir::QPath::Resolved(_, ref path)) | - PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) | - PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => { - match path.res { - Res::Def(DefKind::Variant, id) => variants.push(id), - Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) => variants.push(id), - _ => () - } + self.walk(|p| match &p.node { + PatKind::Or(_) => false, + PatKind::Path(hir::QPath::Resolved(_, path)) | + PatKind::TupleStruct(hir::QPath::Resolved(_, path), ..) | + PatKind::Struct(hir::QPath::Resolved(_, path), ..) => { + if let Res::Def(DefKind::Variant, id) + | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) + = path.res + { + variants.push(id); } - _ => () + true } - true + _ => true, }); variants.sort(); variants.dedup(); @@ -176,14 +168,12 @@ impl hir::Pat { let mut result = None; self.each_binding(|annotation, _, _, _| { match annotation { - hir::BindingAnnotation::Ref => { - match result { - None | Some(hir::MutImmutable) => result = Some(hir::MutImmutable), - _ => (), - } + hir::BindingAnnotation::Ref => match result { + None | Some(hir::MutImmutable) => result = Some(hir::MutImmutable), + _ => {} } hir::BindingAnnotation::RefMut => result = Some(hir::MutMutable), - _ => (), + _ => {} } }); result diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 1818dede3e229..2746794e2a2c1 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -259,20 +259,13 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_arm(&mut self, arm: &'tcx hir::Arm) { - let pats = arm.top_pats_hack(); - if let [pat] = pats { - let variants = pat.necessary_variants(); - - // Inside the body, ignore constructions of variants - // necessary for the pattern to match. Those construction sites - // can't be reached unless the variant is constructed elsewhere. - let len = self.ignore_variant_stack.len(); - self.ignore_variant_stack.extend_from_slice(&variants); - intravisit::walk_arm(self, arm); - self.ignore_variant_stack.truncate(len); - } else { - intravisit::walk_arm(self, arm); - } + // Inside the body, ignore constructions of variants + // necessary for the pattern to match. Those construction sites + // can't be reached unless the variant is constructed elsewhere. + let len = self.ignore_variant_stack.len(); + self.ignore_variant_stack.extend(arm.pat.necessary_variants()); + intravisit::walk_arm(self, arm); + self.ignore_variant_stack.truncate(len); } fn visit_pat(&mut self, pat: &'tcx hir::Pat) { From 03ac54aed6f728ab4e5e18a10b5c3887782924cf Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 24 Sep 2019 16:14:43 +0200 Subject: [PATCH 25/41] Add const-eval support for SIMD types, insert, and extract --- src/librustc_mir/interpret/intrinsics.rs | 20 +++++++- src/librustc_mir/interpret/operand.rs | 15 ++++++ src/librustc_mir/interpret/place.rs | 34 +++++++++++++ src/librustc_mir/interpret/terminator.rs | 4 +- .../ui/consts/const-eval/const_eval-simd.rs | 24 ++++++++++ .../consts/const-eval/const_eval-simd.stderr | 48 +++++++++++++++++++ 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/consts/const-eval/const_eval-simd.rs create mode 100644 src/test/ui/consts/const-eval/const_eval-simd.stderr diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index ec09e69ec8537..0ede068190597 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -239,7 +239,25 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { "transmute" => { self.copy_op_transmute(args[0], dest)?; } - + "simd_insert" => { + let mut vector = self.read_vector(args[0])?; + let index = self.read_scalar(args[1])?.to_u32()? as usize; + let scalar = self.read_immediate(args[2])?; + if vector[index].layout.size == scalar.layout.size { + vector[index] = scalar; + } else { + throw_ub_format!( + "Inserting `{:?}` with size `{}` to a vector element place of size `{}`", + scalar, scalar.layout.size.bytes(), vector[index].layout.size.bytes() + ); + } + self.write_vector(vector, dest)?; + } + "simd_extract" => { + let index = self.read_scalar(args[1])?.to_u32()? as _; + let scalar = self.read_immediate(self.operand_field(args[0], index)?)?; + self.write_immediate(*scalar, dest)?; + } _ => return Ok(false), } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index dd214c4a031f7..184e2ee9516fc 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -335,6 +335,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } + /// Read vector from operand `op` + pub fn read_vector(&self, op: OpTy<'tcx, M::PointerTag>) + -> InterpResult<'tcx, Vec>> { + if let layout::Abi::Vector { count, .. } = op.layout.abi { + assert_ne!(count, 0); + let mut scalars = Vec::new(); + for index in 0..count { + scalars.push(self.read_immediate(self.operand_field(op, index as _)?)?); + } + Ok(scalars) + } else { + bug!("type is not a vector: {:?}, abi: {:?}", op.layout.ty, op.layout.abi); + } + } + /// Read a scalar from a place pub fn read_scalar( &self, diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index c3660fb7a2e28..9154e2666c598 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -696,6 +696,40 @@ where Ok(()) } + /// Writes the `scalar` to the `index`-th element of the `vector`. + pub fn write_scalar_to_vector( + &mut self, + scalar: ImmTy<'tcx, M::PointerTag>, + vector: PlaceTy<'tcx, M::PointerTag>, + index: usize, + ) -> InterpResult<'tcx> { + let index = index as u64; + let place = self.place_field(vector, index)?; + self.write_immediate(*scalar, place)?; + Ok(()) + } + + /// Writes the `scalars` to the `vector`. + pub fn write_vector( + &mut self, + scalars: Vec>, + vector: PlaceTy<'tcx, M::PointerTag>, + ) -> InterpResult<'tcx> { + assert_ne!(scalars.len(), 0); + match vector.layout.ty.sty { + ty::Adt(def, ..) if def.repr.simd() => { + let tcx = &*self.tcx; + let count = vector.layout.ty.simd_size(*tcx); + assert_eq!(count, scalars.len()); + for index in 0..scalars.len() { + self.write_scalar_to_vector(scalars[index], vector, index)?; + } + } + _ => bug!("not a vector"), + } + Ok(()) + } + /// Write an `Immediate` to memory. #[inline(always)] pub fn write_immediate_to_mplace( diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 8310ef02f9669..a324c58512406 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -249,7 +249,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { - if caller_abi != Abi::RustIntrinsic { + if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = caller_abi { + // ok + } else { throw_unsup!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)) } // The intrinsic itself cannot diverge, so if we got here without a return diff --git a/src/test/ui/consts/const-eval/const_eval-simd.rs b/src/test/ui/consts/const-eval/const_eval-simd.rs new file mode 100644 index 0000000000000..a0f088cc636fc --- /dev/null +++ b/src/test/ui/consts/const-eval/const_eval-simd.rs @@ -0,0 +1,24 @@ +// run-pass +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, val: U) -> T; + fn simd_extract(x: T, idx: u32) -> U; +} + +const fn foo(x: i8x1) -> i8 { + unsafe { simd_insert(x, 0_u32, 42_i8) }.0 +} + +fn main() { + const V: i8x1 = i8x1(13); + const X: i8 = foo(V); + const Y: i8 = unsafe { simd_extract(V, 0) }; + assert_eq!(X, 42); + assert_eq!(Y, 13); +} diff --git a/src/test/ui/consts/const-eval/const_eval-simd.stderr b/src/test/ui/consts/const-eval/const_eval-simd.stderr new file mode 100644 index 0000000000000..7fc068718b0be --- /dev/null +++ b/src/test/ui/consts/const-eval/const_eval-simd.stderr @@ -0,0 +1,48 @@ +warning: skipping const checks + --> $DIR/const_eval-simd.rs:22:5 + | +LL | assert_eq!(X, 42); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_eval-simd.rs:22:5 + | +LL | assert_eq!(X, 42); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_eval-simd.rs:22:5 + | +LL | assert_eq!(X, 42); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_eval-simd.rs:23:5 + | +LL | assert_eq!(Y, 13); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_eval-simd.rs:23:5 + | +LL | assert_eq!(Y, 13); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/const_eval-simd.rs:23:5 + | +LL | assert_eq!(Y, 13); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + From 75d8199ab1f41be3f58b5f5331eb642714f42732 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 24 Sep 2019 16:48:17 +0200 Subject: [PATCH 26/41] Add a fail test --- .../consts/const-eval/const_eval-simd_fail.rs | 20 +++++++++++++++++++ .../const-eval/const_eval-simd_fail.stderr | 16 +++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/test/ui/consts/const-eval/const_eval-simd_fail.rs create mode 100644 src/test/ui/consts/const-eval/const_eval-simd_fail.stderr diff --git a/src/test/ui/consts/const-eval/const_eval-simd_fail.rs b/src/test/ui/consts/const-eval/const_eval-simd_fail.rs new file mode 100644 index 0000000000000..20c839a81a04e --- /dev/null +++ b/src/test/ui/consts/const-eval/const_eval-simd_fail.rs @@ -0,0 +1,20 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, val: U) -> T; +} + +const fn foo(x: i8x1) -> i8 { + // 42 is a i16 that does not fit in a i8 + unsafe { simd_insert(x, 0_u32, 42_i16) }.0 //~ ERROR +} + +fn main() { + const V: i8x1 = i8x1(13); + const X: i8 = foo(V); +} diff --git a/src/test/ui/consts/const-eval/const_eval-simd_fail.stderr b/src/test/ui/consts/const-eval/const_eval-simd_fail.stderr new file mode 100644 index 0000000000000..9f76287979a60 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_eval-simd_fail.stderr @@ -0,0 +1,16 @@ +error: any use of this value will cause an error + --> $DIR/const_eval-simd_fail.rs:14:14 + | +LL | unsafe { simd_insert(x, 0_u32, 42_i16) }.0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | Inserting `i16` with size `2` to a vector element place of size `1` + | inside call to `foo` at $DIR/const_eval-simd_fail.rs:19:19 +... +LL | const X: i8 = foo(V); + | --------------------- + | + = note: `#[deny(const_err)]` on by default + +error: aborting due to previous error + From f0bbd2b71c4861efc11599fe763f80b5de4490cd Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 24 Sep 2019 16:52:03 +0200 Subject: [PATCH 27/41] Move tests to SIMD subdirectory --- src/librustc_mir/interpret/intrinsics.rs | 4 ++-- .../insert_extract-fail.rs} | 0 .../insert_extract-fail.stderr} | 4 ++-- .../{const_eval-simd.rs => simd/insert_extract.rs} | 0 .../insert_extract.stderr} | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) rename src/test/ui/consts/const-eval/{const_eval-simd_fail.rs => simd/insert_extract-fail.rs} (100%) rename src/test/ui/consts/const-eval/{const_eval-simd_fail.stderr => simd/insert_extract-fail.stderr} (77%) rename src/test/ui/consts/const-eval/{const_eval-simd.rs => simd/insert_extract.rs} (100%) rename src/test/ui/consts/const-eval/{const_eval-simd.stderr => simd/insert_extract.stderr} (87%) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 0ede068190597..630f5010b8598 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -247,8 +247,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { vector[index] = scalar; } else { throw_ub_format!( - "Inserting `{:?}` with size `{}` to a vector element place of size `{}`", - scalar, scalar.layout.size.bytes(), vector[index].layout.size.bytes() + "Inserting `{}` with size `{}` to a vector element place of size `{}`", + scalar.layout.ty, scalar.layout.size.bytes(), vector[index].layout.size.bytes() ); } self.write_vector(vector, dest)?; diff --git a/src/test/ui/consts/const-eval/const_eval-simd_fail.rs b/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs similarity index 100% rename from src/test/ui/consts/const-eval/const_eval-simd_fail.rs rename to src/test/ui/consts/const-eval/simd/insert_extract-fail.rs diff --git a/src/test/ui/consts/const-eval/const_eval-simd_fail.stderr b/src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr similarity index 77% rename from src/test/ui/consts/const-eval/const_eval-simd_fail.stderr rename to src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr index 9f76287979a60..cf4e6887f16d5 100644 --- a/src/test/ui/consts/const-eval/const_eval-simd_fail.stderr +++ b/src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr @@ -1,11 +1,11 @@ error: any use of this value will cause an error - --> $DIR/const_eval-simd_fail.rs:14:14 + --> $DIR/insert_extract-fail.rs:14:14 | LL | unsafe { simd_insert(x, 0_u32, 42_i16) }.0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | Inserting `i16` with size `2` to a vector element place of size `1` - | inside call to `foo` at $DIR/const_eval-simd_fail.rs:19:19 + | inside call to `foo` at $DIR/insert_extract-fail.rs:19:19 ... LL | const X: i8 = foo(V); | --------------------- diff --git a/src/test/ui/consts/const-eval/const_eval-simd.rs b/src/test/ui/consts/const-eval/simd/insert_extract.rs similarity index 100% rename from src/test/ui/consts/const-eval/const_eval-simd.rs rename to src/test/ui/consts/const-eval/simd/insert_extract.rs diff --git a/src/test/ui/consts/const-eval/const_eval-simd.stderr b/src/test/ui/consts/const-eval/simd/insert_extract.stderr similarity index 87% rename from src/test/ui/consts/const-eval/const_eval-simd.stderr rename to src/test/ui/consts/const-eval/simd/insert_extract.stderr index 7fc068718b0be..51510273a791b 100644 --- a/src/test/ui/consts/const-eval/const_eval-simd.stderr +++ b/src/test/ui/consts/const-eval/simd/insert_extract.stderr @@ -1,5 +1,5 @@ warning: skipping const checks - --> $DIR/const_eval-simd.rs:22:5 + --> $DIR/insert_extract.rs:22:5 | LL | assert_eq!(X, 42); | ^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | assert_eq!(X, 42); = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/const_eval-simd.rs:22:5 + --> $DIR/insert_extract.rs:22:5 | LL | assert_eq!(X, 42); | ^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | assert_eq!(X, 42); = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/const_eval-simd.rs:22:5 + --> $DIR/insert_extract.rs:22:5 | LL | assert_eq!(X, 42); | ^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | assert_eq!(X, 42); = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/const_eval-simd.rs:23:5 + --> $DIR/insert_extract.rs:23:5 | LL | assert_eq!(Y, 13); | ^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | assert_eq!(Y, 13); = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/const_eval-simd.rs:23:5 + --> $DIR/insert_extract.rs:23:5 | LL | assert_eq!(Y, 13); | ^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | assert_eq!(Y, 13); = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/const_eval-simd.rs:23:5 + --> $DIR/insert_extract.rs:23:5 | LL | assert_eq!(Y, 13); | ^^^^^^^^^^^^^^^^^^ From e6239bb81796715f66ec468b70d8779f8ccac6bd Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 24 Sep 2019 17:02:01 +0200 Subject: [PATCH 28/41] Add some more tests --- .../consts/const-eval/simd/insert_extract.rs | 47 ++- .../const-eval/simd/insert_extract.stderr | 276 ++++++++++++++++-- 2 files changed, 296 insertions(+), 27 deletions(-) diff --git a/src/test/ui/consts/const-eval/simd/insert_extract.rs b/src/test/ui/consts/const-eval/simd/insert_extract.rs index a0f088cc636fc..136965bf68abf 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract.rs +++ b/src/test/ui/consts/const-eval/simd/insert_extract.rs @@ -5,20 +5,49 @@ #![allow(non_camel_case_types)] #[repr(simd)] struct i8x1(i8); +#[repr(simd)] struct u16x2(u16, u16); +#[repr(simd)] struct f32x3(f32, f32, f32); extern "platform-intrinsic" { fn simd_insert(x: T, idx: u32, val: U) -> T; fn simd_extract(x: T, idx: u32) -> U; } -const fn foo(x: i8x1) -> i8 { - unsafe { simd_insert(x, 0_u32, 42_i8) }.0 -} - fn main() { - const V: i8x1 = i8x1(13); - const X: i8 = foo(V); - const Y: i8 = unsafe { simd_extract(V, 0) }; - assert_eq!(X, 42); - assert_eq!(Y, 13); + { + const U: i8x1 = i8x1(13); + const V: i8x1 = unsafe { simd_insert(U, 0_u32, 42_i8) }; + const X0: i8 = V.0; + const Y0: i8 = unsafe { simd_extract(V, 0) }; + assert_eq!(X0, 42); + assert_eq!(Y0, 42); + } + { + const U: u16x2 = u16x2(13, 14); + const V: u16x2 = unsafe { simd_insert(U, 1_u32, 42_u16) }; + const X0: u16 = V.0; + const X1: u16 = V.1; + const Y0: u16 = unsafe { simd_extract(V, 0) }; + const Y1: u16 = unsafe { simd_extract(V, 1) }; + assert_eq!(X0, 13); + assert_eq!(X1, 42); + assert_eq!(Y0, 13); + assert_eq!(Y1, 42); + } + { + const U: f32x3 = f32x3(13., 14., 15.); + const V: f32x3 = unsafe { simd_insert(U, 1_u32, 42_f32) }; + const X0: f32 = V.0; + const X1: f32 = V.1; + const X2: f32 = V.2; + const Y0: f32 = unsafe { simd_extract(V, 0) }; + const Y1: f32 = unsafe { simd_extract(V, 1) }; + const Y2: f32 = unsafe { simd_extract(V, 2) }; + assert_eq!(X0, 13.); + assert_eq!(X1, 42.); + assert_eq!(X2, 15.); + assert_eq!(Y0, 13.); + assert_eq!(Y1, 42.); + assert_eq!(Y2, 15.); + } } diff --git a/src/test/ui/consts/const-eval/simd/insert_extract.stderr b/src/test/ui/consts/const-eval/simd/insert_extract.stderr index 51510273a791b..8975241403e74 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract.stderr +++ b/src/test/ui/consts/const-eval/simd/insert_extract.stderr @@ -1,48 +1,288 @@ warning: skipping const checks - --> $DIR/insert_extract.rs:22:5 + --> $DIR/insert_extract.rs:22:9 | -LL | assert_eq!(X, 42); - | ^^^^^^^^^^^^^^^^^^ +LL | assert_eq!(X0, 42); + | ^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/insert_extract.rs:22:5 + --> $DIR/insert_extract.rs:22:9 | -LL | assert_eq!(X, 42); - | ^^^^^^^^^^^^^^^^^^ +LL | assert_eq!(X0, 42); + | ^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/insert_extract.rs:22:5 + --> $DIR/insert_extract.rs:22:9 | -LL | assert_eq!(X, 42); - | ^^^^^^^^^^^^^^^^^^ +LL | assert_eq!(X0, 42); + | ^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/insert_extract.rs:23:5 + --> $DIR/insert_extract.rs:23:9 | -LL | assert_eq!(Y, 13); - | ^^^^^^^^^^^^^^^^^^ +LL | assert_eq!(Y0, 42); + | ^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/insert_extract.rs:23:5 + --> $DIR/insert_extract.rs:23:9 | -LL | assert_eq!(Y, 13); - | ^^^^^^^^^^^^^^^^^^ +LL | assert_eq!(Y0, 42); + | ^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) warning: skipping const checks - --> $DIR/insert_extract.rs:23:5 + --> $DIR/insert_extract.rs:23:9 | -LL | assert_eq!(Y, 13); - | ^^^^^^^^^^^^^^^^^^ +LL | assert_eq!(Y0, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:32:9 + | +LL | assert_eq!(X0, 13); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:32:9 + | +LL | assert_eq!(X0, 13); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:32:9 + | +LL | assert_eq!(X0, 13); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:33:9 + | +LL | assert_eq!(X1, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:33:9 + | +LL | assert_eq!(X1, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:33:9 + | +LL | assert_eq!(X1, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:34:9 + | +LL | assert_eq!(Y0, 13); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:34:9 + | +LL | assert_eq!(Y0, 13); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:34:9 + | +LL | assert_eq!(Y0, 13); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:35:9 + | +LL | assert_eq!(Y1, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:35:9 + | +LL | assert_eq!(Y1, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:35:9 + | +LL | assert_eq!(Y1, 42); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:46:9 + | +LL | assert_eq!(X0, 13.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:46:9 + | +LL | assert_eq!(X0, 13.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:46:9 + | +LL | assert_eq!(X0, 13.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:47:9 + | +LL | assert_eq!(X1, 42.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:47:9 + | +LL | assert_eq!(X1, 42.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:47:9 + | +LL | assert_eq!(X1, 42.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:48:9 + | +LL | assert_eq!(X2, 15.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:48:9 + | +LL | assert_eq!(X2, 15.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:48:9 + | +LL | assert_eq!(X2, 15.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:49:9 + | +LL | assert_eq!(Y0, 13.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:49:9 + | +LL | assert_eq!(Y0, 13.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:49:9 + | +LL | assert_eq!(Y0, 13.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:50:9 + | +LL | assert_eq!(Y1, 42.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:50:9 + | +LL | assert_eq!(Y1, 42.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:50:9 + | +LL | assert_eq!(Y1, 42.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:51:9 + | +LL | assert_eq!(Y2, 15.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:51:9 + | +LL | assert_eq!(Y2, 15.); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +warning: skipping const checks + --> $DIR/insert_extract.rs:51:9 + | +LL | assert_eq!(Y2, 15.); + | ^^^^^^^^^^^^^^^^^^^^ | = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) From 9a020186f8d4411a9820c4e3378f86ea2ca72af5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 25 Sep 2019 10:14:47 +0300 Subject: [PATCH 29/41] remove unused parameters --- src/libsyntax/ext/mbe/macro_rules.rs | 8 -------- src/libsyntax/ext/mbe/quoted.rs | 24 +----------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/src/libsyntax/ext/mbe/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs index 816baadb12fbb..87bb26c709e5e 100644 --- a/src/libsyntax/ext/mbe/macro_rules.rs +++ b/src/libsyntax/ext/mbe/macro_rules.rs @@ -371,10 +371,6 @@ pub fn compile_declarative_macro( tt.clone().into(), true, sess, - features, - &def.attrs, - edition, - def.id, ) .pop() .unwrap(); @@ -398,10 +394,6 @@ pub fn compile_declarative_macro( tt.clone().into(), false, sess, - features, - &def.attrs, - edition, - def.id, ) .pop() .unwrap(); diff --git a/src/libsyntax/ext/mbe/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs index 3952e29a5f0d1..c881350fec3f8 100644 --- a/src/libsyntax/ext/mbe/quoted.rs +++ b/src/libsyntax/ext/mbe/quoted.rs @@ -1,15 +1,13 @@ use crate::ast; -use crate::ast::NodeId; use crate::ext::mbe::macro_parser; use crate::ext::mbe::{TokenTree, KleeneOp, KleeneToken, SequenceRepetition, Delimited}; -use crate::feature_gate::Features; use crate::parse::token::{self, Token}; use crate::parse::ParseSess; use crate::print::pprust; use crate::symbol::kw; use crate::tokenstream; -use syntax_pos::{edition::Edition, Span}; +use syntax_pos::Span; use rustc_data_structures::sync::Lrc; use std::iter::Peekable; @@ -39,10 +37,6 @@ pub(super) fn parse( input: tokenstream::TokenStream, expect_matchers: bool, sess: &ParseSess, - features: &Features, - attrs: &[ast::Attribute], - edition: Edition, - macro_node_id: NodeId, ) -> Vec { // Will contain the final collection of `self::TokenTree` let mut result = Vec::new(); @@ -58,10 +52,6 @@ pub(super) fn parse( &mut trees, expect_matchers, sess, - features, - attrs, - edition, - macro_node_id, ); match tree { TokenTree::MetaVar(start_sp, ident) if expect_matchers => { @@ -112,10 +102,6 @@ fn parse_tree( trees: &mut Peekable>, expect_matchers: bool, sess: &ParseSess, - features: &Features, - attrs: &[ast::Attribute], - edition: Edition, - macro_node_id: NodeId, ) -> TokenTree { // Depending on what `tree` is, we could be parsing different parts of a macro match tree { @@ -135,10 +121,6 @@ fn parse_tree( tts.into(), expect_matchers, sess, - features, - attrs, - edition, - macro_node_id, ); // Get the Kleene operator and optional separator let (separator, kleene) = parse_sep_and_kleene_op(trees, span.entire(), sess); @@ -192,10 +174,6 @@ fn parse_tree( tts.into(), expect_matchers, sess, - features, - attrs, - edition, - macro_node_id, ), }), ), From 538437e829fd1bdaaf5104f7750327cfdeed29bf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 25 Sep 2019 10:17:59 +0300 Subject: [PATCH 30/41] move function closer to its usage --- src/libsyntax/ext/mbe/macro_parser.rs | 12 ------------ src/libsyntax/ext/mbe/macro_rules.rs | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/ext/mbe/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs index b51384d3b15e1..8f49ba9572d77 100644 --- a/src/libsyntax/ext/mbe/macro_parser.rs +++ b/src/libsyntax/ext/mbe/macro_parser.rs @@ -413,18 +413,6 @@ fn nameize>( Success(ret_val) } -/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For -/// other tokens, this is "unexpected token...". -crate fn parse_failure_msg(tok: &Token) -> String { - match tok.kind { - token::Eof => "unexpected end of macro invocation".to_string(), - _ => format!( - "no rules expected the token `{}`", - pprust::token_to_string(tok) - ), - } -} - /// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison) fn token_name_eq(t1: &Token, t2: &Token) -> bool { if let (Some((ident1, is_raw1)), Some((ident2, is_raw2))) = (t1.ident(), t2.ident()) { diff --git a/src/libsyntax/ext/mbe/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs index 87bb26c709e5e..c24f6a666039f 100644 --- a/src/libsyntax/ext/mbe/macro_rules.rs +++ b/src/libsyntax/ext/mbe/macro_rules.rs @@ -6,7 +6,7 @@ use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::ext::expand::{AstFragment, AstFragmentKind}; use crate::ext::mbe; use crate::ext::mbe::macro_check; -use crate::ext::mbe::macro_parser::{parse, parse_failure_msg}; +use crate::ext::mbe::macro_parser::parse; use crate::ext::mbe::macro_parser::{Error, Failure, Success}; use crate::ext::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult}; use crate::ext::mbe::transcribe::transcribe; @@ -15,6 +15,7 @@ use crate::parse::parser::Parser; use crate::parse::token::TokenKind::*; use crate::parse::token::{self, NtTT, Token}; use crate::parse::{Directory, ParseSess}; +use crate::print::pprust; use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; @@ -1176,3 +1177,15 @@ impl TokenTree { parse(cx.parse_sess(), tts, mtch, Some(directory), true) } } + +/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For +/// other tokens, this is "unexpected token...". +fn parse_failure_msg(tok: &Token) -> String { + match tok.kind { + token::Eof => "unexpected end of macro invocation".to_string(), + _ => format!( + "no rules expected the token `{}`", + pprust::token_to_string(tok), + ), + } +} From f60a8734e088f3383512b0ffc12a9a909d2163b4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 25 Sep 2019 10:41:43 +0300 Subject: [PATCH 31/41] remove unused peekable --- src/libsyntax/ext/mbe/quoted.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/mbe/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs index c881350fec3f8..8cb85bdef762f 100644 --- a/src/libsyntax/ext/mbe/quoted.rs +++ b/src/libsyntax/ext/mbe/quoted.rs @@ -10,7 +10,6 @@ use crate::tokenstream; use syntax_pos::Span; use rustc_data_structures::sync::Lrc; -use std::iter::Peekable; /// Takes a `tokenstream::TokenStream` and returns a `Vec`. Specifically, this /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a @@ -43,7 +42,7 @@ pub(super) fn parse( // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming // additional trees if need be. - let mut trees = input.trees().peekable(); + let mut trees = input.trees(); while let Some(tree) = trees.next() { // Given the parsed tree, if there is a metavar and we are expecting matchers, actually // parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`). @@ -99,7 +98,7 @@ pub(super) fn parse( /// unstable features or not. fn parse_tree( tree: tokenstream::TokenTree, - trees: &mut Peekable>, + trees: &mut impl Iterator, expect_matchers: bool, sess: &ParseSess, ) -> TokenTree { @@ -222,7 +221,7 @@ fn parse_kleene_op( /// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an /// error with the appropriate span is emitted to `sess` and a dummy value is returned. fn parse_sep_and_kleene_op( - input: &mut Peekable>, + input: &mut impl Iterator, span: Span, sess: &ParseSess, ) -> (Option, KleeneToken) { From 3a6e96e8bc8b7285c5a9b357d0e5e8dd9c191edf Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 10:28:53 +0200 Subject: [PATCH 32/41] Allow simd_insert and simd_extract in const_fn --- src/librustc_mir/transform/qualify_consts.rs | 2 + .../const-eval/simd/insert_extract-fail.rs | 2 +- .../consts/const-eval/simd/insert_extract.rs | 2 +- .../const-eval/simd/insert_extract.stderr | 288 ------------------ 4 files changed, 4 insertions(+), 290 deletions(-) delete mode 100644 src/test/ui/consts/const-eval/simd/insert_extract.stderr diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 795721f3b3f28..8a6dcd1d2b476 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -557,6 +557,8 @@ impl Qualif for IsNotPromotable { | "saturating_add" | "saturating_sub" | "transmute" + | "simd_insert" + | "simd_extract" => return true, _ => {} diff --git a/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs b/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs index 20c839a81a04e..bbfae997e7241 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs +++ b/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs @@ -1,4 +1,4 @@ -// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/consts/const-eval/simd/insert_extract.rs b/src/test/ui/consts/const-eval/simd/insert_extract.rs index 136965bf68abf..d3462d802ea4e 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract.rs +++ b/src/test/ui/consts/const-eval/simd/insert_extract.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/consts/const-eval/simd/insert_extract.stderr b/src/test/ui/consts/const-eval/simd/insert_extract.stderr deleted file mode 100644 index 8975241403e74..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert_extract.stderr +++ /dev/null @@ -1,288 +0,0 @@ -warning: skipping const checks - --> $DIR/insert_extract.rs:22:9 - | -LL | assert_eq!(X0, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:22:9 - | -LL | assert_eq!(X0, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:22:9 - | -LL | assert_eq!(X0, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:23:9 - | -LL | assert_eq!(Y0, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:23:9 - | -LL | assert_eq!(Y0, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:23:9 - | -LL | assert_eq!(Y0, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:32:9 - | -LL | assert_eq!(X0, 13); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:32:9 - | -LL | assert_eq!(X0, 13); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:32:9 - | -LL | assert_eq!(X0, 13); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:33:9 - | -LL | assert_eq!(X1, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:33:9 - | -LL | assert_eq!(X1, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:33:9 - | -LL | assert_eq!(X1, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:34:9 - | -LL | assert_eq!(Y0, 13); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:34:9 - | -LL | assert_eq!(Y0, 13); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:34:9 - | -LL | assert_eq!(Y0, 13); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:35:9 - | -LL | assert_eq!(Y1, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:35:9 - | -LL | assert_eq!(Y1, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:35:9 - | -LL | assert_eq!(Y1, 42); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:46:9 - | -LL | assert_eq!(X0, 13.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:46:9 - | -LL | assert_eq!(X0, 13.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:46:9 - | -LL | assert_eq!(X0, 13.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:47:9 - | -LL | assert_eq!(X1, 42.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:47:9 - | -LL | assert_eq!(X1, 42.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:47:9 - | -LL | assert_eq!(X1, 42.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:48:9 - | -LL | assert_eq!(X2, 15.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:48:9 - | -LL | assert_eq!(X2, 15.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:48:9 - | -LL | assert_eq!(X2, 15.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:49:9 - | -LL | assert_eq!(Y0, 13.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:49:9 - | -LL | assert_eq!(Y0, 13.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:49:9 - | -LL | assert_eq!(Y0, 13.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:50:9 - | -LL | assert_eq!(Y1, 42.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:50:9 - | -LL | assert_eq!(Y1, 42.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:50:9 - | -LL | assert_eq!(Y1, 42.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:51:9 - | -LL | assert_eq!(Y2, 15.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:51:9 - | -LL | assert_eq!(Y2, 15.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -warning: skipping const checks - --> $DIR/insert_extract.rs:51:9 - | -LL | assert_eq!(Y2, 15.); - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - From 97ce904340f416b47c2b9790d550346bef5d7f7f Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 10:33:12 +0200 Subject: [PATCH 33/41] Remove unreachable code --- src/librustc_mir/interpret/terminator.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index a324c58512406..8666c937ce4c2 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -249,11 +249,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { - if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = caller_abi { - // ok - } else { - throw_unsup!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)) - } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) let dest = match dest { From 02b3234a7766694616e3396c17e9ff08859a785d Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 10:34:44 +0200 Subject: [PATCH 34/41] Tidy --- src/librustc_mir/interpret/intrinsics.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 630f5010b8598..fc1ec61c9629e 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -248,7 +248,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { throw_ub_format!( "Inserting `{}` with size `{}` to a vector element place of size `{}`", - scalar.layout.ty, scalar.layout.size.bytes(), vector[index].layout.size.bytes() + scalar.layout.ty, + scalar.layout.size.bytes(), vector[index].layout.size.bytes() ); } self.write_vector(vector, dest)?; From 5976674a717f61167a930df0c1fa1fe4106a439e Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 12:54:23 +0200 Subject: [PATCH 35/41] Refactor --- src/librustc_mir/interpret/intrinsics.rs | 57 ++++++++++++++----- src/librustc_mir/interpret/operand.rs | 19 +++---- src/librustc_mir/interpret/place.rs | 34 ----------- .../const-eval/simd/insert_extract-fail.rs | 7 +++ .../ui/consts/const-eval/simd/read_fail.rs | 17 ++++++ 5 files changed, 76 insertions(+), 58 deletions(-) create mode 100644 src/test/ui/consts/const-eval/simd/read_fail.rs diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index fc1ec61c9629e..586611397e344 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -240,24 +240,55 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.copy_op_transmute(args[0], dest)?; } "simd_insert" => { - let mut vector = self.read_vector(args[0])?; - let index = self.read_scalar(args[1])?.to_u32()? as usize; + let index = self.read_scalar(args[1])?.to_u32()? as u64; let scalar = self.read_immediate(args[2])?; - if vector[index].layout.size == scalar.layout.size { - vector[index] = scalar; - } else { - throw_ub_format!( - "Inserting `{}` with size `{}` to a vector element place of size `{}`", - scalar.layout.ty, - scalar.layout.size.bytes(), vector[index].layout.size.bytes() - ); + let input = args[0]; + let (len, e_ty) = self.read_vector_ty(input); + assert!( + index < len, + "index `{}` must be in bounds of vector type `{}`: `[0, {})`", + index, e_ty, len + ); + assert_eq!( + args[0].layout, dest.layout, + "Return type `{}` must match vector type `{}`", + dest.layout.ty, input.layout.ty + ); + assert_eq!( + scalar.layout.ty, e_ty, + "Scalar type `{}` must match vector element type `{}`", + scalar.layout.ty, e_ty + ); + + for i in 0..len { + let place = self.place_field(dest, index)?; + if i == index { + self.write_immediate(*scalar, place)?; + } else { + self.write_immediate( + *self.read_immediate(self.operand_field(input, index)?)?, + place + )?; + }; } - self.write_vector(vector, dest)?; } "simd_extract" => { let index = self.read_scalar(args[1])?.to_u32()? as _; - let scalar = self.read_immediate(self.operand_field(args[0], index)?)?; - self.write_immediate(*scalar, dest)?; + let (len, e_ty) = self.read_vector_ty(args[0]); + assert!( + index < len, + "index `{}` must be in bounds of vector type `{}`: `[0, {})`", + index, e_ty, len + ); + assert_eq!( + e_ty, dest.layout.ty, + "Return type `{}` must match vector element type `{}`", + dest.layout.ty, e_ty + ); + self.write_immediate( + *self.read_immediate(self.operand_field(args[0], index)?)?, + dest + )?; } _ => return Ok(false), } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 184e2ee9516fc..c5771e4f34378 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -335,18 +335,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - /// Read vector from operand `op` - pub fn read_vector(&self, op: OpTy<'tcx, M::PointerTag>) - -> InterpResult<'tcx, Vec>> { - if let layout::Abi::Vector { count, .. } = op.layout.abi { - assert_ne!(count, 0); - let mut scalars = Vec::new(); - for index in 0..count { - scalars.push(self.read_immediate(self.operand_field(op, index as _)?)?); - } - Ok(scalars) + /// Read vector length and element type + pub fn read_vector_ty( + &self, op: OpTy<'tcx, M::PointerTag> + ) + -> (u64, &rustc::ty::TyS<'tcx>) { + if let layout::Abi::Vector { .. } = op.layout.abi { + (op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx)) } else { - bug!("type is not a vector: {:?}, abi: {:?}", op.layout.ty, op.layout.abi); + bug!("Type `{}` is not a SIMD vector type", op.layout.ty) } } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 9154e2666c598..c3660fb7a2e28 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -696,40 +696,6 @@ where Ok(()) } - /// Writes the `scalar` to the `index`-th element of the `vector`. - pub fn write_scalar_to_vector( - &mut self, - scalar: ImmTy<'tcx, M::PointerTag>, - vector: PlaceTy<'tcx, M::PointerTag>, - index: usize, - ) -> InterpResult<'tcx> { - let index = index as u64; - let place = self.place_field(vector, index)?; - self.write_immediate(*scalar, place)?; - Ok(()) - } - - /// Writes the `scalars` to the `vector`. - pub fn write_vector( - &mut self, - scalars: Vec>, - vector: PlaceTy<'tcx, M::PointerTag>, - ) -> InterpResult<'tcx> { - assert_ne!(scalars.len(), 0); - match vector.layout.ty.sty { - ty::Adt(def, ..) if def.repr.simd() => { - let tcx = &*self.tcx; - let count = vector.layout.ty.simd_size(*tcx); - assert_eq!(count, scalars.len()); - for index in 0..scalars.len() { - self.write_scalar_to_vector(scalars[index], vector, index)?; - } - } - _ => bug!("not a vector"), - } - Ok(()) - } - /// Write an `Immediate` to memory. #[inline(always)] pub fn write_immediate_to_mplace( diff --git a/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs b/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs index bbfae997e7241..1d1df8d25a406 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs +++ b/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs @@ -7,6 +7,7 @@ extern "platform-intrinsic" { fn simd_insert(x: T, idx: u32, val: U) -> T; + fn simd_extract(x: T, idx: u32) -> U; } const fn foo(x: i8x1) -> i8 { @@ -14,7 +15,13 @@ const fn foo(x: i8x1) -> i8 { unsafe { simd_insert(x, 0_u32, 42_i16) }.0 //~ ERROR } +const fn bar(x: i8x1) -> i16 { + // the i8 is not a i16: + unsafe { simd_extract(x, 0_u32) } //~ ERROR +} + fn main() { const V: i8x1 = i8x1(13); const X: i8 = foo(V); + const Y: i16 = bar(V); } diff --git a/src/test/ui/consts/const-eval/simd/read_fail.rs b/src/test/ui/consts/const-eval/simd/read_fail.rs new file mode 100644 index 0000000000000..c5109c16e4c6d --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/read_fail.rs @@ -0,0 +1,17 @@ +#![feature(const_fn)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +extern "platform-intrinsic" { + fn simd_extract(x: T, idx: u32) -> U; +} + +const fn foo(x: i8) -> i8 { + // i8 is not a vector type: + unsafe { simd_extract(x, 0_u32) } //~ ERROR +} + +fn main() { + const V: i8 = 13; + const X: i8 = foo(V); +} From e74a268db511d4f124425c981300ebfaea0d64ee Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 13:39:20 +0200 Subject: [PATCH 36/41] Test errors --- src/librustc_mir/interpret/intrinsics.rs | 25 +++++++---------- .../consts/const-eval/simd/extract-fail0.rs | 22 +++++++++++++++ .../const-eval/simd/extract-fail0.stderr | 15 +++++++++++ .../consts/const-eval/simd/extract-fail1.rs | 22 +++++++++++++++ .../const-eval/simd/extract-fail1.stderr | 15 +++++++++++ .../consts/const-eval/simd/extract-fail2.rs | 22 +++++++++++++++ .../const-eval/simd/extract-fail2.stderr | 13 +++++++++ .../ui/consts/const-eval/simd/insert-fail0.rs | 22 +++++++++++++++ .../const-eval/simd/insert-fail0.stderr | 15 +++++++++++ .../ui/consts/const-eval/simd/insert-fail1.rs | 22 +++++++++++++++ .../const-eval/simd/insert-fail1.stderr | 13 +++++++++ .../const-eval/simd/insert_extract-fail.rs | 27 ------------------- .../simd/insert_extract-fail.stderr | 16 ----------- .../ui/consts/const-eval/simd/read_fail.rs | 17 ------------ 14 files changed, 191 insertions(+), 75 deletions(-) create mode 100644 src/test/ui/consts/const-eval/simd/extract-fail0.rs create mode 100644 src/test/ui/consts/const-eval/simd/extract-fail0.stderr create mode 100644 src/test/ui/consts/const-eval/simd/extract-fail1.rs create mode 100644 src/test/ui/consts/const-eval/simd/extract-fail1.stderr create mode 100644 src/test/ui/consts/const-eval/simd/extract-fail2.rs create mode 100644 src/test/ui/consts/const-eval/simd/extract-fail2.stderr create mode 100644 src/test/ui/consts/const-eval/simd/insert-fail0.rs create mode 100644 src/test/ui/consts/const-eval/simd/insert-fail0.stderr create mode 100644 src/test/ui/consts/const-eval/simd/insert-fail1.rs create mode 100644 src/test/ui/consts/const-eval/simd/insert-fail1.stderr delete mode 100644 src/test/ui/consts/const-eval/simd/insert_extract-fail.rs delete mode 100644 src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr delete mode 100644 src/test/ui/consts/const-eval/simd/read_fail.rs diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 586611397e344..5fc23b4a69ec5 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -241,16 +241,16 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } "simd_insert" => { let index = self.read_scalar(args[1])?.to_u32()? as u64; - let scalar = self.read_immediate(args[2])?; + let scalar = args[2]; let input = args[0]; let (len, e_ty) = self.read_vector_ty(input); assert!( index < len, - "index `{}` must be in bounds of vector type `{}`: `[0, {})`", + "Index `{}` must be in bounds of vector type `{}`: `[0, {})`", index, e_ty, len ); assert_eq!( - args[0].layout, dest.layout, + input.layout, dest.layout, "Return type `{}` must match vector type `{}`", dest.layout.ty, input.layout.ty ); @@ -261,15 +261,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ); for i in 0..len { - let place = self.place_field(dest, index)?; - if i == index { - self.write_immediate(*scalar, place)?; + let place = self.place_field(dest, i)?; + let value = if i == index { + scalar } else { - self.write_immediate( - *self.read_immediate(self.operand_field(input, index)?)?, - place - )?; + self.operand_field(input, i)? }; + self.copy_op(value, place)?; } } "simd_extract" => { @@ -277,7 +275,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (len, e_ty) = self.read_vector_ty(args[0]); assert!( index < len, - "index `{}` must be in bounds of vector type `{}`: `[0, {})`", + "index `{}` is out-of-bounds of vector type `{}` with length `{}`", index, e_ty, len ); assert_eq!( @@ -285,10 +283,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { "Return type `{}` must match vector element type `{}`", dest.layout.ty, e_ty ); - self.write_immediate( - *self.read_immediate(self.operand_field(args[0], index)?)?, - dest - )?; + self.copy_op(self.operand_field(args[0], index)?, dest)?; } _ => return Ok(false), } diff --git a/src/test/ui/consts/const-eval/simd/extract-fail0.rs b/src/test/ui/consts/const-eval/simd/extract-fail0.rs new file mode 100644 index 0000000000000..d2c313ddd0cd4 --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/extract-fail0.rs @@ -0,0 +1,22 @@ +// failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 +#![feature(const_fn)] +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_extract(x: T, idx: u32) -> U; +} + +const X: i8x1 = i8x1(42); + +const fn extract_wrong_ret() -> i16 { + unsafe { simd_extract(X, 0_u32) } +} + +const A: i16 = extract_wrong_ret(); + +fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/extract-fail0.stderr b/src/test/ui/consts/const-eval/simd/extract-fail0.stderr new file mode 100644 index 0000000000000..51518481941df --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/extract-fail0.stderr @@ -0,0 +1,15 @@ +thread 'rustc' panicked at 'assertion failed: `(left == right)` + left: `i8`, + right: `i16`: Return type `i16` must match vector element type `i8`', src/librustc_mir/interpret/intrinsics.rs:281:17 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + +error: internal compiler error: unexpected panic + +note: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports + +note: rustc 1.39.0-dev running on x86_64-apple-darwin + +note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 + diff --git a/src/test/ui/consts/const-eval/simd/extract-fail1.rs b/src/test/ui/consts/const-eval/simd/extract-fail1.rs new file mode 100644 index 0000000000000..ddff608181e93 --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/extract-fail1.rs @@ -0,0 +1,22 @@ +// failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 +#![feature(const_fn)] +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_extract(x: T, idx: u32) -> U; +} + +const X: i8x1 = i8x1(42); + +const fn extract_wrong_vec() -> i8 { + unsafe { simd_extract(42_i8, 0_u32) } +} + +const B: i8 = extract_wrong_vec(); + +fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/extract-fail1.stderr b/src/test/ui/consts/const-eval/simd/extract-fail1.stderr new file mode 100644 index 0000000000000..a00d98bf7fd9b --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/extract-fail1.stderr @@ -0,0 +1,15 @@ +error: internal compiler error: src/librustc_mir/interpret/operand.rs:346: Type `i8` is not a SIMD vector type + +thread 'rustc' panicked at 'Box', src/librustc_errors/lib.rs:643:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + +note: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports + +note: rustc 1.39.0-dev running on x86_64-apple-darwin + +note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-eval/simd/extract-fail2.rs b/src/test/ui/consts/const-eval/simd/extract-fail2.rs new file mode 100644 index 0000000000000..e2eb449f977ce --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/extract-fail2.rs @@ -0,0 +1,22 @@ +// failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 +#![feature(const_fn)] +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_extract(x: T, idx: u32) -> U; +} + +const X: i8x1 = i8x1(42); + +const fn extract_wrong_idx() -> i8 { + unsafe { simd_extract(X, 1_u32) } +} + +const C: i8 = extract_wrong_idx(); + +fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/extract-fail2.stderr b/src/test/ui/consts/const-eval/simd/extract-fail2.stderr new file mode 100644 index 0000000000000..5d74e115ef87f --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/extract-fail2.stderr @@ -0,0 +1,13 @@ +thread 'rustc' panicked at 'index `1` is out-of-bounds of vector type `i8` with length `1`', src/librustc_mir/interpret/intrinsics.rs:276:17 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + +error: internal compiler error: unexpected panic + +note: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports + +note: rustc 1.39.0-dev running on x86_64-apple-darwin + +note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 + diff --git a/src/test/ui/consts/const-eval/simd/insert-fail0.rs b/src/test/ui/consts/const-eval/simd/insert-fail0.rs new file mode 100644 index 0000000000000..dca58fb2555a8 --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/insert-fail0.rs @@ -0,0 +1,22 @@ +// failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 +#![feature(const_fn)] +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, val: U) -> T; +} + +const X: i8x1 = i8x1(42); + +const fn insert_wrong_scalar() -> i8x1 { + unsafe { simd_insert(X, 0_u32, 42_i16) } +} + +const D: i8x1 = insert_wrong_scalar(); + +fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/insert-fail0.stderr b/src/test/ui/consts/const-eval/simd/insert-fail0.stderr new file mode 100644 index 0000000000000..1ea31ec8deb6a --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/insert-fail0.stderr @@ -0,0 +1,15 @@ +thread 'rustc' panicked at 'assertion failed: `(left == right)` + left: `i16`, + right: `i8`: Scalar type `i16` must match vector element type `i8`', src/librustc_mir/interpret/intrinsics.rs:257:17 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + +error: internal compiler error: unexpected panic + +note: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports + +note: rustc 1.39.0-dev running on x86_64-apple-darwin + +note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 + diff --git a/src/test/ui/consts/const-eval/simd/insert-fail1.rs b/src/test/ui/consts/const-eval/simd/insert-fail1.rs new file mode 100644 index 0000000000000..2a3d79b76c306 --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/insert-fail1.rs @@ -0,0 +1,22 @@ +// failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 +#![feature(const_fn)] +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, val: U) -> T; +} + +const X: i8x1 = i8x1(42); + +const fn insert_wrong_idx() -> i8x1 { + unsafe { simd_insert(X, 1_u32, 42_i8) } +} + +const E: i8x1 = insert_wrong_idx(); + +fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/insert-fail1.stderr b/src/test/ui/consts/const-eval/simd/insert-fail1.stderr new file mode 100644 index 0000000000000..38d3782263010 --- /dev/null +++ b/src/test/ui/consts/const-eval/simd/insert-fail1.stderr @@ -0,0 +1,13 @@ +thread 'rustc' panicked at 'Index `1` must be in bounds of vector type `i8`: `[0, 1)`', src/librustc_mir/interpret/intrinsics.rs:247:17 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + +error: internal compiler error: unexpected panic + +note: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports + +note: rustc 1.39.0-dev running on x86_64-apple-darwin + +note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 + diff --git a/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs b/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs deleted file mode 100644 index 1d1df8d25a406..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert_extract-fail.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![feature(const_fn)] -#![feature(repr_simd)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] struct i8x1(i8); - -extern "platform-intrinsic" { - fn simd_insert(x: T, idx: u32, val: U) -> T; - fn simd_extract(x: T, idx: u32) -> U; -} - -const fn foo(x: i8x1) -> i8 { - // 42 is a i16 that does not fit in a i8 - unsafe { simd_insert(x, 0_u32, 42_i16) }.0 //~ ERROR -} - -const fn bar(x: i8x1) -> i16 { - // the i8 is not a i16: - unsafe { simd_extract(x, 0_u32) } //~ ERROR -} - -fn main() { - const V: i8x1 = i8x1(13); - const X: i8 = foo(V); - const Y: i16 = bar(V); -} diff --git a/src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr b/src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr deleted file mode 100644 index cf4e6887f16d5..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert_extract-fail.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: any use of this value will cause an error - --> $DIR/insert_extract-fail.rs:14:14 - | -LL | unsafe { simd_insert(x, 0_u32, 42_i16) }.0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | Inserting `i16` with size `2` to a vector element place of size `1` - | inside call to `foo` at $DIR/insert_extract-fail.rs:19:19 -... -LL | const X: i8 = foo(V); - | --------------------- - | - = note: `#[deny(const_err)]` on by default - -error: aborting due to previous error - diff --git a/src/test/ui/consts/const-eval/simd/read_fail.rs b/src/test/ui/consts/const-eval/simd/read_fail.rs deleted file mode 100644 index c5109c16e4c6d..0000000000000 --- a/src/test/ui/consts/const-eval/simd/read_fail.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(const_fn)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -extern "platform-intrinsic" { - fn simd_extract(x: T, idx: u32) -> U; -} - -const fn foo(x: i8) -> i8 { - // i8 is not a vector type: - unsafe { simd_extract(x, 0_u32) } //~ ERROR -} - -fn main() { - const V: i8 = 13; - const X: i8 = foo(V); -} From e1cf0a1d677a6f583baf96b14dccf61ec5e4cfeb Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 13:39:28 +0200 Subject: [PATCH 37/41] Format --- src/librustc_mir/interpret/operand.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c5771e4f34378..afaf9d7ed9d67 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -338,8 +338,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Read vector length and element type pub fn read_vector_ty( &self, op: OpTy<'tcx, M::PointerTag> - ) - -> (u64, &rustc::ty::TyS<'tcx>) { + ) -> (u64, &rustc::ty::TyS<'tcx>) { if let layout::Abi::Vector { .. } = op.layout.abi { (op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx)) } else { From 02bfbf96c7c241146957a75128ad63276fa0b671 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 14:05:39 +0200 Subject: [PATCH 38/41] Clean tests --- src/test/ui/consts/const-eval/simd/extract-fail0.rs | 4 ++++ src/test/ui/consts/const-eval/simd/extract-fail0.stderr | 4 ++-- src/test/ui/consts/const-eval/simd/extract-fail1.rs | 4 ++++ src/test/ui/consts/const-eval/simd/extract-fail1.stderr | 6 +++--- src/test/ui/consts/const-eval/simd/extract-fail2.rs | 4 ++++ src/test/ui/consts/const-eval/simd/extract-fail2.stderr | 4 ++-- src/test/ui/consts/const-eval/simd/insert-fail0.rs | 4 ++++ src/test/ui/consts/const-eval/simd/insert-fail0.stderr | 4 ++-- src/test/ui/consts/const-eval/simd/insert-fail1.rs | 4 ++++ src/test/ui/consts/const-eval/simd/insert-fail1.stderr | 4 ++-- 10 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/test/ui/consts/const-eval/simd/extract-fail0.rs b/src/test/ui/consts/const-eval/simd/extract-fail0.rs index d2c313ddd0cd4..4a046e424c528 100644 --- a/src/test/ui/consts/const-eval/simd/extract-fail0.rs +++ b/src/test/ui/consts/const-eval/simd/extract-fail0.rs @@ -1,5 +1,9 @@ // failure-status: 101 // rustc-env:RUST_BACKTRACE=0 +// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" +// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" +// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" + #![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] diff --git a/src/test/ui/consts/const-eval/simd/extract-fail0.stderr b/src/test/ui/consts/const-eval/simd/extract-fail0.stderr index 51518481941df..be2c2607002e0 100644 --- a/src/test/ui/consts/const-eval/simd/extract-fail0.stderr +++ b/src/test/ui/consts/const-eval/simd/extract-fail0.stderr @@ -9,7 +9,7 @@ note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports -note: rustc 1.39.0-dev running on x86_64-apple-darwin +note: rustc VERSION running on TARGET -note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 +note: compiler flags: FLAGS diff --git a/src/test/ui/consts/const-eval/simd/extract-fail1.rs b/src/test/ui/consts/const-eval/simd/extract-fail1.rs index ddff608181e93..ec281a19b17d0 100644 --- a/src/test/ui/consts/const-eval/simd/extract-fail1.rs +++ b/src/test/ui/consts/const-eval/simd/extract-fail1.rs @@ -1,5 +1,9 @@ // failure-status: 101 // rustc-env:RUST_BACKTRACE=0 +// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" +// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" +// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" + #![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] diff --git a/src/test/ui/consts/const-eval/simd/extract-fail1.stderr b/src/test/ui/consts/const-eval/simd/extract-fail1.stderr index a00d98bf7fd9b..8c53ee874c466 100644 --- a/src/test/ui/consts/const-eval/simd/extract-fail1.stderr +++ b/src/test/ui/consts/const-eval/simd/extract-fail1.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: src/librustc_mir/interpret/operand.rs:346: Type `i8` is not a SIMD vector type +error: internal compiler error: src/librustc_mir/interpret/operand.rs:345: Type `i8` is not a SIMD vector type thread 'rustc' panicked at 'Box', src/librustc_errors/lib.rs:643:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. @@ -7,9 +7,9 @@ note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports -note: rustc 1.39.0-dev running on x86_64-apple-darwin +note: rustc VERSION running on TARGET -note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 +note: compiler flags: FLAGS error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/simd/extract-fail2.rs b/src/test/ui/consts/const-eval/simd/extract-fail2.rs index e2eb449f977ce..d1970877574f8 100644 --- a/src/test/ui/consts/const-eval/simd/extract-fail2.rs +++ b/src/test/ui/consts/const-eval/simd/extract-fail2.rs @@ -1,5 +1,9 @@ // failure-status: 101 // rustc-env:RUST_BACKTRACE=0 +// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" +// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" +// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" + #![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] diff --git a/src/test/ui/consts/const-eval/simd/extract-fail2.stderr b/src/test/ui/consts/const-eval/simd/extract-fail2.stderr index 5d74e115ef87f..1885c930e9a2b 100644 --- a/src/test/ui/consts/const-eval/simd/extract-fail2.stderr +++ b/src/test/ui/consts/const-eval/simd/extract-fail2.stderr @@ -7,7 +7,7 @@ note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports -note: rustc 1.39.0-dev running on x86_64-apple-darwin +note: rustc VERSION running on TARGET -note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 +note: compiler flags: FLAGS diff --git a/src/test/ui/consts/const-eval/simd/insert-fail0.rs b/src/test/ui/consts/const-eval/simd/insert-fail0.rs index dca58fb2555a8..2ee0fdfc1ec6b 100644 --- a/src/test/ui/consts/const-eval/simd/insert-fail0.rs +++ b/src/test/ui/consts/const-eval/simd/insert-fail0.rs @@ -1,5 +1,9 @@ // failure-status: 101 // rustc-env:RUST_BACKTRACE=0 +// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" +// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" +// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" + #![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] diff --git a/src/test/ui/consts/const-eval/simd/insert-fail0.stderr b/src/test/ui/consts/const-eval/simd/insert-fail0.stderr index 1ea31ec8deb6a..1d0173ed33272 100644 --- a/src/test/ui/consts/const-eval/simd/insert-fail0.stderr +++ b/src/test/ui/consts/const-eval/simd/insert-fail0.stderr @@ -9,7 +9,7 @@ note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports -note: rustc 1.39.0-dev running on x86_64-apple-darwin +note: rustc VERSION running on TARGET -note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 +note: compiler flags: FLAGS diff --git a/src/test/ui/consts/const-eval/simd/insert-fail1.rs b/src/test/ui/consts/const-eval/simd/insert-fail1.rs index 2a3d79b76c306..146b8ce6a130a 100644 --- a/src/test/ui/consts/const-eval/simd/insert-fail1.rs +++ b/src/test/ui/consts/const-eval/simd/insert-fail1.rs @@ -1,5 +1,9 @@ // failure-status: 101 // rustc-env:RUST_BACKTRACE=0 +// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" +// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" +// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" + #![feature(const_fn)] #![feature(repr_simd)] #![feature(platform_intrinsics)] diff --git a/src/test/ui/consts/const-eval/simd/insert-fail1.stderr b/src/test/ui/consts/const-eval/simd/insert-fail1.stderr index 38d3782263010..6223f308c2f35 100644 --- a/src/test/ui/consts/const-eval/simd/insert-fail1.stderr +++ b/src/test/ui/consts/const-eval/simd/insert-fail1.stderr @@ -7,7 +7,7 @@ note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports -note: rustc 1.39.0-dev running on x86_64-apple-darwin +note: rustc VERSION running on TARGET -note: compiler flags: -Z threads=1 -Z ui-testing -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 +note: compiler flags: FLAGS From 1a4e4d937e9a5ffb907063fc0837799a87cd1508 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 25 Sep 2019 08:20:32 -0400 Subject: [PATCH 39/41] Switch version to 1.40 --- src/bootstrap/channel.rs | 2 +- src/stage0.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index caa4843da4d36..ef1b6e217a24f 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -13,7 +13,7 @@ use build_helper::output; use crate::Build; // The version number -pub const CFG_RELEASE_NUM: &str = "1.39.0"; +pub const CFG_RELEASE_NUM: &str = "1.40.0"; pub struct GitInfo { inner: Option, diff --git a/src/stage0.txt b/src/stage0.txt index 1a9e64a1862c9..9509d3e99612f 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2019-08-13 +date: 2019-09-25 rustc: beta cargo: beta From 5ecb7eb161e75ab33ca015e7f717424f32af3d59 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 25 Sep 2019 14:32:57 +0200 Subject: [PATCH 40/41] Remove fail tests --- .../consts/const-eval/simd/extract-fail0.rs | 26 ------------------- .../const-eval/simd/extract-fail0.stderr | 15 ----------- .../consts/const-eval/simd/extract-fail1.rs | 26 ------------------- .../const-eval/simd/extract-fail1.stderr | 15 ----------- .../consts/const-eval/simd/extract-fail2.rs | 26 ------------------- .../const-eval/simd/extract-fail2.stderr | 13 ---------- .../ui/consts/const-eval/simd/insert-fail0.rs | 26 ------------------- .../const-eval/simd/insert-fail0.stderr | 15 ----------- .../ui/consts/const-eval/simd/insert-fail1.rs | 26 ------------------- .../const-eval/simd/insert-fail1.stderr | 13 ---------- 10 files changed, 201 deletions(-) delete mode 100644 src/test/ui/consts/const-eval/simd/extract-fail0.rs delete mode 100644 src/test/ui/consts/const-eval/simd/extract-fail0.stderr delete mode 100644 src/test/ui/consts/const-eval/simd/extract-fail1.rs delete mode 100644 src/test/ui/consts/const-eval/simd/extract-fail1.stderr delete mode 100644 src/test/ui/consts/const-eval/simd/extract-fail2.rs delete mode 100644 src/test/ui/consts/const-eval/simd/extract-fail2.stderr delete mode 100644 src/test/ui/consts/const-eval/simd/insert-fail0.rs delete mode 100644 src/test/ui/consts/const-eval/simd/insert-fail0.stderr delete mode 100644 src/test/ui/consts/const-eval/simd/insert-fail1.rs delete mode 100644 src/test/ui/consts/const-eval/simd/insert-fail1.stderr diff --git a/src/test/ui/consts/const-eval/simd/extract-fail0.rs b/src/test/ui/consts/const-eval/simd/extract-fail0.rs deleted file mode 100644 index 4a046e424c528..0000000000000 --- a/src/test/ui/consts/const-eval/simd/extract-fail0.rs +++ /dev/null @@ -1,26 +0,0 @@ -// failure-status: 101 -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" -// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" -// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" - -#![feature(const_fn)] -#![feature(repr_simd)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] struct i8x1(i8); - -extern "platform-intrinsic" { - fn simd_extract(x: T, idx: u32) -> U; -} - -const X: i8x1 = i8x1(42); - -const fn extract_wrong_ret() -> i16 { - unsafe { simd_extract(X, 0_u32) } -} - -const A: i16 = extract_wrong_ret(); - -fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/extract-fail0.stderr b/src/test/ui/consts/const-eval/simd/extract-fail0.stderr deleted file mode 100644 index be2c2607002e0..0000000000000 --- a/src/test/ui/consts/const-eval/simd/extract-fail0.stderr +++ /dev/null @@ -1,15 +0,0 @@ -thread 'rustc' panicked at 'assertion failed: `(left == right)` - left: `i8`, - right: `i16`: Return type `i16` must match vector element type `i8`', src/librustc_mir/interpret/intrinsics.rs:281:17 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. - -error: internal compiler error: unexpected panic - -note: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports - -note: rustc VERSION running on TARGET - -note: compiler flags: FLAGS - diff --git a/src/test/ui/consts/const-eval/simd/extract-fail1.rs b/src/test/ui/consts/const-eval/simd/extract-fail1.rs deleted file mode 100644 index ec281a19b17d0..0000000000000 --- a/src/test/ui/consts/const-eval/simd/extract-fail1.rs +++ /dev/null @@ -1,26 +0,0 @@ -// failure-status: 101 -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" -// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" -// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" - -#![feature(const_fn)] -#![feature(repr_simd)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] struct i8x1(i8); - -extern "platform-intrinsic" { - fn simd_extract(x: T, idx: u32) -> U; -} - -const X: i8x1 = i8x1(42); - -const fn extract_wrong_vec() -> i8 { - unsafe { simd_extract(42_i8, 0_u32) } -} - -const B: i8 = extract_wrong_vec(); - -fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/extract-fail1.stderr b/src/test/ui/consts/const-eval/simd/extract-fail1.stderr deleted file mode 100644 index 8c53ee874c466..0000000000000 --- a/src/test/ui/consts/const-eval/simd/extract-fail1.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: internal compiler error: src/librustc_mir/interpret/operand.rs:345: Type `i8` is not a SIMD vector type - -thread 'rustc' panicked at 'Box', src/librustc_errors/lib.rs:643:9 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. - -note: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports - -note: rustc VERSION running on TARGET - -note: compiler flags: FLAGS - -error: aborting due to previous error - diff --git a/src/test/ui/consts/const-eval/simd/extract-fail2.rs b/src/test/ui/consts/const-eval/simd/extract-fail2.rs deleted file mode 100644 index d1970877574f8..0000000000000 --- a/src/test/ui/consts/const-eval/simd/extract-fail2.rs +++ /dev/null @@ -1,26 +0,0 @@ -// failure-status: 101 -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" -// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" -// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" - -#![feature(const_fn)] -#![feature(repr_simd)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] struct i8x1(i8); - -extern "platform-intrinsic" { - fn simd_extract(x: T, idx: u32) -> U; -} - -const X: i8x1 = i8x1(42); - -const fn extract_wrong_idx() -> i8 { - unsafe { simd_extract(X, 1_u32) } -} - -const C: i8 = extract_wrong_idx(); - -fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/extract-fail2.stderr b/src/test/ui/consts/const-eval/simd/extract-fail2.stderr deleted file mode 100644 index 1885c930e9a2b..0000000000000 --- a/src/test/ui/consts/const-eval/simd/extract-fail2.stderr +++ /dev/null @@ -1,13 +0,0 @@ -thread 'rustc' panicked at 'index `1` is out-of-bounds of vector type `i8` with length `1`', src/librustc_mir/interpret/intrinsics.rs:276:17 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. - -error: internal compiler error: unexpected panic - -note: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports - -note: rustc VERSION running on TARGET - -note: compiler flags: FLAGS - diff --git a/src/test/ui/consts/const-eval/simd/insert-fail0.rs b/src/test/ui/consts/const-eval/simd/insert-fail0.rs deleted file mode 100644 index 2ee0fdfc1ec6b..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert-fail0.rs +++ /dev/null @@ -1,26 +0,0 @@ -// failure-status: 101 -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" -// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" -// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" - -#![feature(const_fn)] -#![feature(repr_simd)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] struct i8x1(i8); - -extern "platform-intrinsic" { - fn simd_insert(x: T, idx: u32, val: U) -> T; -} - -const X: i8x1 = i8x1(42); - -const fn insert_wrong_scalar() -> i8x1 { - unsafe { simd_insert(X, 0_u32, 42_i16) } -} - -const D: i8x1 = insert_wrong_scalar(); - -fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/insert-fail0.stderr b/src/test/ui/consts/const-eval/simd/insert-fail0.stderr deleted file mode 100644 index 1d0173ed33272..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert-fail0.stderr +++ /dev/null @@ -1,15 +0,0 @@ -thread 'rustc' panicked at 'assertion failed: `(left == right)` - left: `i16`, - right: `i8`: Scalar type `i16` must match vector element type `i8`', src/librustc_mir/interpret/intrinsics.rs:257:17 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. - -error: internal compiler error: unexpected panic - -note: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports - -note: rustc VERSION running on TARGET - -note: compiler flags: FLAGS - diff --git a/src/test/ui/consts/const-eval/simd/insert-fail1.rs b/src/test/ui/consts/const-eval/simd/insert-fail1.rs deleted file mode 100644 index 146b8ce6a130a..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert-fail1.rs +++ /dev/null @@ -1,26 +0,0 @@ -// failure-status: 101 -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" -// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" -// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" - -#![feature(const_fn)] -#![feature(repr_simd)] -#![feature(platform_intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] struct i8x1(i8); - -extern "platform-intrinsic" { - fn simd_insert(x: T, idx: u32, val: U) -> T; -} - -const X: i8x1 = i8x1(42); - -const fn insert_wrong_idx() -> i8x1 { - unsafe { simd_insert(X, 1_u32, 42_i8) } -} - -const E: i8x1 = insert_wrong_idx(); - -fn main() {} diff --git a/src/test/ui/consts/const-eval/simd/insert-fail1.stderr b/src/test/ui/consts/const-eval/simd/insert-fail1.stderr deleted file mode 100644 index 6223f308c2f35..0000000000000 --- a/src/test/ui/consts/const-eval/simd/insert-fail1.stderr +++ /dev/null @@ -1,13 +0,0 @@ -thread 'rustc' panicked at 'Index `1` must be in bounds of vector type `i8`: `[0, 1)`', src/librustc_mir/interpret/intrinsics.rs:247:17 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. - -error: internal compiler error: unexpected panic - -note: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports - -note: rustc VERSION running on TARGET - -note: compiler flags: FLAGS - From f359a94849f5a66be4e5058ad9f5a480623a4627 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 25 Sep 2019 08:42:46 -0400 Subject: [PATCH 41/41] Snap cfgs to new beta --- src/liballoc/alloc.rs | 1 - src/liballoc/lib.rs | 1 - src/liballoc/string.rs | 1 - src/liballoc/vec.rs | 3 +-- src/libcore/bool.rs | 1 - src/libcore/clone.rs | 1 - src/libcore/cmp.rs | 4 ---- src/libcore/default.rs | 1 - src/libcore/fmt/mod.rs | 4 +--- src/libcore/hash/mod.rs | 1 - src/libcore/intrinsics.rs | 22 ----------------- src/libcore/lib.rs | 4 ---- src/libcore/macros.rs | 6 ++--- src/libcore/marker.rs | 1 - src/libcore/num/mod.rs | 48 +++++--------------------------------- src/libcore/panicking.rs | 1 - src/libcore/slice/mod.rs | 4 +--- src/libcore/str/mod.rs | 5 +--- src/libproc_macro/lib.rs | 2 +- src/librustc/ty/context.rs | 2 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/sty.rs | 2 +- src/librustc_passes/lib.rs | 1 - src/librustdoc/lib.rs | 1 - src/libstd/lib.rs | 1 - src/libsyntax/lib.rs | 1 - 26 files changed, 16 insertions(+), 105 deletions(-) diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index a39fcd5ad4c58..9bc76f51570e1 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -240,7 +240,6 @@ pub(crate) unsafe fn box_free(ptr: Unique) { #[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_allocator_nounwind] pub fn handle_alloc_error(layout: Layout) -> ! { - #[cfg_attr(bootstrap, allow(improper_ctypes))] extern "Rust" { #[lang = "oom"] fn oom_impl(layout: Layout) -> !; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 9e6ed92ffb567..247cd9a020161 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -117,7 +117,6 @@ #![feature(allocator_internals)] #![feature(on_unimplemented)] #![feature(rustc_const_unstable)] -#![cfg_attr(bootstrap, feature(const_vec_new))] #![feature(slice_partition_dedup)] #![feature(maybe_uninit_extra, maybe_uninit_slice)] #![feature(alloc_layout_extra)] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index e5f96ada6d5ee..abe50fdb7a396 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -369,7 +369,6 @@ impl String { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))] pub const fn new() -> String { String { vec: Vec::new() } } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 405969a550b88..e5672f8542ff6 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -291,7 +291,7 @@ use crate::raw_vec::RawVec; /// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve /// [owned slice]: ../../std/boxed/struct.Box.html #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(all(not(bootstrap), not(test)), rustc_diagnostic_item = "vec_type")] +#[cfg_attr(not(test), rustc_diagnostic_item = "vec_type")] pub struct Vec { buf: RawVec, len: usize, @@ -314,7 +314,6 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_vec_new"))] pub const fn new() -> Vec { Vec { buf: RawVec::NEW, diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index f751ccb428030..617bdd238f4c6 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -1,6 +1,5 @@ //! impl bool {} -#[cfg(not(bootstrap))] #[lang = "bool"] impl bool { /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise. diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 6bdae1b557d61..14d947ccf2402 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -135,7 +135,6 @@ pub trait Clone : Sized { /// Derive macro generating an impl of the trait `Clone`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_clone_copy)] pub macro Clone($item:item) { /* compiler built-in */ } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index fc7329f57d45e..d0ea75c7623f4 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -210,7 +210,6 @@ pub trait PartialEq { /// Derive macro generating an impl of the trait `PartialEq`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] pub macro PartialEq($item:item) { /* compiler built-in */ } @@ -273,7 +272,6 @@ pub trait Eq: PartialEq { /// Derive macro generating an impl of the trait `Eq`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq)] pub macro Eq($item:item) { /* compiler built-in */ } @@ -624,7 +622,6 @@ pub trait Ord: Eq + PartialOrd { /// Derive macro generating an impl of the trait `Ord`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] pub macro Ord($item:item) { /* compiler built-in */ } @@ -873,7 +870,6 @@ pub trait PartialOrd: PartialEq { /// Derive macro generating an impl of the trait `PartialOrd`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] pub macro PartialOrd($item:item) { /* compiler built-in */ } diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 806d478310760..1aadc77cfb8da 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -117,7 +117,6 @@ pub trait Default: Sized { /// Derive macro generating an impl of the trait `Default`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] pub macro Default($item:item) { /* compiler built-in */ } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 65e2f8b9be63f..aafa35873bb65 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -518,8 +518,7 @@ impl Display for Arguments<'_> { label="`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`", )] #[doc(alias = "{:?}")] -#[cfg_attr(bootstrap, lang = "debug_trait")] -#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "debug_trait")] +#[rustc_diagnostic_item = "debug_trait"] pub trait Debug { /// Formats the value using the given formatter. /// @@ -550,7 +549,6 @@ pub trait Debug { pub(crate) mod macros { /// Derive macro generating an impl of the trait `Debug`. #[rustc_builtin_macro] - #[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] pub macro Debug($item:item) { /* compiler built-in */ } diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index aaaa6f9c575fd..020e085abf8a8 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -202,7 +202,6 @@ pub trait Hash { pub(crate) mod macros { /// Derive macro generating an impl of the trait `Hash`. #[rustc_builtin_macro] - #[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] pub macro Hash($item:item) { /* compiler built-in */ } diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 905375eb60fe4..b240d059114eb 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1299,38 +1299,16 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_add` method. For example, /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add) - #[cfg(bootstrap)] - pub fn overflowing_add(a: T, b: T) -> T; - /// Returns (a - b) mod 2N, where N is the width of T in bits. - /// The stabilized versions of this intrinsic are available on the integer - /// primitives via the `wrapping_sub` method. For example, - /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub) - #[cfg(bootstrap)] - pub fn overflowing_sub(a: T, b: T) -> T; - /// Returns (a * b) mod 2N, where N is the width of T in bits. - /// The stabilized versions of this intrinsic are available on the integer - /// primitives via the `wrapping_mul` method. For example, - /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul) - #[cfg(bootstrap)] - pub fn overflowing_mul(a: T, b: T) -> T; - - /// Returns (a + b) mod 2N, where N is the width of T in bits. - /// The stabilized versions of this intrinsic are available on the integer - /// primitives via the `wrapping_add` method. For example, - /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add) - #[cfg(not(bootstrap))] pub fn wrapping_add(a: T, b: T) -> T; /// Returns (a - b) mod 2N, where N is the width of T in bits. /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_sub` method. For example, /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub) - #[cfg(not(bootstrap))] pub fn wrapping_sub(a: T, b: T) -> T; /// Returns (a * b) mod 2N, where N is the width of T in bits. /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_mul` method. For example, /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul) - #[cfg(not(bootstrap))] pub fn wrapping_mul(a: T, b: T) -> T; /// Computes `a + b`, while saturating at numeric bounds. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 8221df56a5142..e8c76b49a8e56 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -87,7 +87,6 @@ #![feature(link_llvm_intrinsics)] #![feature(never_type)] #![feature(nll)] -#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))] #![feature(exhaustive_patterns)] #![feature(no_core)] #![feature(on_unimplemented)] @@ -120,9 +119,6 @@ #![feature(rtm_target_feature)] #![feature(f16c_target_feature)] #![feature(hexagon_target_feature)] -#![cfg_attr(bootstrap, feature(const_slice_len))] -#![cfg_attr(bootstrap, feature(const_str_as_bytes))] -#![cfg_attr(bootstrap, feature(const_str_len))] #![feature(const_int_conversion)] #![feature(const_transmute)] #![feature(non_exhaustive)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index c6f5fb0b16350..ef91c3559d8be 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -1236,10 +1236,8 @@ pub(crate) mod builtin { pub macro test($item:item) { /* compiler built-in */ } /// Attribute macro applied to a function to turn it into a benchmark test. - #[cfg_attr(not(bootstrap), unstable(soft, feature = "test", issue = "50297", - reason = "`bench` is a part of custom test frameworks which are unstable"))] - #[cfg_attr(bootstrap, unstable(feature = "test", issue = "50297", - reason = "`bench` is a part of custom test frameworks which are unstable"))] + #[unstable(soft, feature = "test", issue = "50297", + reason = "`bench` is a part of custom test frameworks which are unstable")] #[allow_internal_unstable(test, rustc_attrs)] #[rustc_builtin_macro] pub macro bench($item:item) { /* compiler built-in */ } diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index a2cfb320e7698..7f3d958f5dc80 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -290,7 +290,6 @@ pub trait Copy : Clone { /// Derive macro generating an impl of the trait `Copy`. #[rustc_builtin_macro] -#[cfg_attr(bootstrap, rustc_macro_transparency = "semitransparent")] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_clone_copy)] pub macro Copy($item:item) { /* compiler built-in */ } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 5d99c10e73815..e9b4efd9c2173 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1112,13 +1112,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_add(self, rhs: Self) -> Self { - #[cfg(bootstrap)] { - intrinsics::overflowing_add(self, rhs) - } - - #[cfg(not(bootstrap))] { - intrinsics::wrapping_add(self, rhs) - } + intrinsics::wrapping_add(self, rhs) } } @@ -1141,13 +1135,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_sub(self, rhs: Self) -> Self { - #[cfg(bootstrap)] { - intrinsics::overflowing_sub(self, rhs) - } - - #[cfg(not(bootstrap))] { - intrinsics::wrapping_sub(self, rhs) - } + intrinsics::wrapping_sub(self, rhs) } } @@ -1169,13 +1157,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { - #[cfg(bootstrap)] { - intrinsics::overflowing_mul(self, rhs) - } - - #[cfg(not(bootstrap))] { - intrinsics::wrapping_mul(self, rhs) - } + intrinsics::wrapping_mul(self, rhs) } } @@ -3040,13 +3022,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_add(self, rhs: Self) -> Self { - #[cfg(bootstrap)] { - intrinsics::overflowing_add(self, rhs) - } - - #[cfg(not(bootstrap))] { - intrinsics::wrapping_add(self, rhs) - } + intrinsics::wrapping_add(self, rhs) } } @@ -3068,13 +3044,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_sub(self, rhs: Self) -> Self { - #[cfg(bootstrap)] { - intrinsics::overflowing_sub(self, rhs) - } - - #[cfg(not(bootstrap))] { - intrinsics::wrapping_sub(self, rhs) - } + intrinsics::wrapping_sub(self, rhs) } } @@ -3097,13 +3067,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { - #[cfg(bootstrap)] { - intrinsics::overflowing_mul(self, rhs) - } - - #[cfg(not(bootstrap))] { - intrinsics::wrapping_mul(self, rhs) - } + intrinsics::wrapping_mul(self, rhs) } doc_comment! { diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 7b7253419b1bd..e8f0561604aec 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -71,7 +71,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3 } // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - #[cfg_attr(bootstrap, allow(improper_ctypes))] extern "Rust" { #[lang = "panic_impl"] fn panic_impl(pi: &PanicInfo<'_>) -> !; diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 0c2a4e086727b..5ec21e6d92862 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -62,9 +62,8 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_slice_len"))] // SAFETY: const sound because we transmute out the length field as a usize (which it must be) - #[cfg_attr(not(bootstrap), allow_internal_unstable(const_fn_union))] + #[allow_internal_unstable(const_fn_union)] pub const fn len(&self) -> usize { unsafe { crate::ptr::Repr { rust: self }.raw.len @@ -81,7 +80,6 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_slice_len"))] pub const fn is_empty(&self) -> bool { self.len() == 0 } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index a6ec757faf1d6..ece61dde490fd 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2090,7 +2090,6 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_str_len"))] pub const fn len(&self) -> usize { self.as_bytes().len() } @@ -2110,7 +2109,6 @@ impl str { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_str_len"))] pub const fn is_empty(&self) -> bool { self.len() == 0 } @@ -2168,9 +2166,8 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline(always)] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_str_as_bytes"))] // SAFETY: const sound because we transmute two types with the same layout - #[cfg_attr(not(bootstrap), allow_internal_unstable(const_fn_union))] + #[allow_internal_unstable(const_fn_union)] pub const fn as_bytes(&self) -> &[u8] { #[repr(C)] union Slices<'a> { diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index d408fef75153e..d5cdc266acb6a 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -227,7 +227,7 @@ pub mod token_stream { /// To quote `$` itself, use `$$`. #[unstable(feature = "proc_macro_quote", issue = "54722")] #[allow_internal_unstable(proc_macro_def_site)] -#[cfg_attr(not(bootstrap), rustc_builtin_macro)] +#[rustc_builtin_macro] pub macro quote ($($t:tt)*) { /* compiler built-in */ } #[unstable(feature = "proc_macro_internals", issue = "27812")] diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c03dbb2b1ed0e..a25ef21d6978f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -974,7 +974,7 @@ pub struct FreeRegionInfo { /// /// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html #[derive(Copy, Clone)] -#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "TyCtxt")] +#[rustc_diagnostic_item = "TyCtxt"] pub struct TyCtxt<'tcx> { gcx: &'tcx GlobalCtxt<'tcx>, } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ef8bdfb583edf..61483fa8a498e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -581,7 +581,7 @@ impl<'a, 'tcx> HashStable> for ty::TyS<'tcx> { } } -#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "Ty")] +#[rustc_diagnostic_item = "Ty"] pub type Ty<'tcx> = &'tcx TyS<'tcx>; impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {} diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index e73a51e6f78e5..036f41a4043d4 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -86,7 +86,7 @@ impl BoundRegion { /// AST structure in `libsyntax/ast.rs` as well. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, Debug)] -#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "TyKind")] +#[rustc_diagnostic_item = "TyKind"] pub enum TyKind<'tcx> { /// The primitive boolean type. Written as `bool`. Bool, diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index a5a8315a1e73f..4e29706714f3d 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -8,7 +8,6 @@ #![feature(in_band_lifetimes)] #![feature(nll)] -#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))] #![recursion_limit="256"] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0b9e717221f2d..2985e7f70b52f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,7 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/")] -#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))] #![feature(rustc_private)] #![feature(arbitrary_self_types)] #![feature(box_patterns)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 21aeb9c26f83c..5d9683f8deda9 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -238,7 +238,6 @@ #![feature(array_error_internals)] #![feature(asm)] #![feature(associated_type_bounds)] -#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))] #![feature(box_syntax)] #![feature(c_variadic)] #![feature(cfg_target_has_atomic)] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index b0833010fe071..2c10220c766a8 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -7,7 +7,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] -#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))] #![feature(box_syntax)] #![feature(const_fn)] #![feature(const_transmute)]