diff options
| author | bors <bors@rust-lang.org> | 2022-06-08 08:05:47 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-06-08 08:05:47 +0000 |
| commit | e45d9973b2665897a768312e971b82cc62633103 (patch) | |
| tree | 7010049e4a0bd89610767791bb05b7696aa27d8f /compiler | |
| parent | 64a7aa7016de32f4d991c30bfa40d3911e18a213 (diff) | |
| parent | 1660b4b70cfb43a03680f12d61dd89fb50e6a54e (diff) | |
Auto merge of #97860 - Dylan-DPC:rollup-t3vxos8, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #97595 (Remove unwrap from get_vtable) - #97597 (Preserve unused pointer to address casts) - #97819 (Recover `import` instead of `use` in item) - #97823 (Recover missing comma after match arm) - #97851 (Use repr(C) when depending on struct layout in ptr tests) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_mir_dataflow/src/impls/liveness.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/dead_store_elimination.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/simplify.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 51 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 69 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/util.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 14 |
8 files changed, 141 insertions, 55 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 07ba3ce0408..4fe81a91d1a 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2605,9 +2605,34 @@ pub enum Rvalue<'tcx> { static_assert_size!(Rvalue<'_>, 40); impl<'tcx> Rvalue<'tcx> { + /// Returns true if rvalue can be safely removed when the result is unused. #[inline] - pub fn is_pointer_int_cast(&self) -> bool { - matches!(self, Rvalue::Cast(CastKind::PointerExposeAddress, _, _)) + pub fn is_safe_to_remove(&self) -> bool { + match self { + // Pointer to int casts may be side-effects due to exposing the provenance. + // While the model is undecided, we should be conservative. See + // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html> + Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false, + + Rvalue::Use(_) + | Rvalue::Repeat(_, _) + | Rvalue::Ref(_, _, _) + | Rvalue::ThreadLocalRef(_) + | Rvalue::AddressOf(_, _) + | Rvalue::Len(_) + | Rvalue::Cast( + CastKind::Misc | CastKind::Pointer(_) | CastKind::PointerFromExposedAddress, + _, + _, + ) + | Rvalue::BinaryOp(_, _) + | Rvalue::CheckedBinaryOp(_, _) + | Rvalue::NullaryOp(_, _) + | Rvalue::UnaryOp(_, _) + | Rvalue::Discriminant(_) + | Rvalue::Aggregate(_, _) + | Rvalue::ShallowInitBox(_, _) => true, + } } } diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 7076fbe1bdb..9b62ee5473c 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -244,13 +244,10 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { // Compute the place that we are storing to, if any let destination = match &statement.kind { StatementKind::Assign(assign) => { - if assign.1.is_pointer_int_cast() { - // Pointer to int casts may be side-effects due to exposing the provenance. - // While the model is undecided, we should be conservative. See - // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html> - None - } else { + if assign.1.is_safe_to_remove() { Some(assign.0) + } else { + None } } StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 8becac34ed7..779f3c77815 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -34,7 +34,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS for (statement_index, statement) in bb_data.statements.iter().enumerate().rev() { let loc = Location { block: bb, statement_index }; if let StatementKind::Assign(assign) = &statement.kind { - if assign.1.is_pointer_int_cast() { + if !assign.1.is_safe_to_remove() { continue; } } diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 72e08343925..8a78ea5c82b 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -494,8 +494,12 @@ impl<'tcx> Visitor<'tcx> for UsedLocals { StatementKind::StorageLive(_local) | StatementKind::StorageDead(_local) => {} StatementKind::Assign(box (ref place, ref rvalue)) => { - self.visit_lhs(place, location); - self.visit_rvalue(rvalue, location); + if rvalue.is_safe_to_remove() { + self.visit_lhs(place, location); + self.visit_rvalue(rvalue, location); + } else { + self.super_statement(statement, location); + } } StatementKind::SetDiscriminant { ref place, variant_index: _ } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b786c52e688..324e04b1981 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2718,13 +2718,12 @@ impl<'a> Parser<'a> { )); } this.expect_one_of(&[token::Comma], &[token::CloseDelim(Delimiter::Brace)]) - .map_err(|mut err| { - match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) { - (Ok(ref expr_lines), Ok(ref arm_start_lines)) - if arm_start_lines.lines[0].end_col - == expr_lines.lines[0].end_col - && expr_lines.lines.len() == 2 - && this.token == token::FatArrow => + .or_else(|mut err| { + if this.token == token::FatArrow { + if let Ok(expr_lines) = sm.span_to_lines(expr.span) + && let Ok(arm_start_lines) = sm.span_to_lines(arm_start_span) + && arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col + && expr_lines.lines.len() == 2 { // We check whether there's any trailing code in the parse span, // if there isn't, we very likely have the following: @@ -2743,15 +2742,41 @@ impl<'a> Parser<'a> { ",".to_owned(), Applicability::MachineApplicable, ); + return Err(err); } - _ => { - err.span_label( - arrow_span, - "while parsing the `match` arm starting here", - ); + } else { + // FIXME(compiler-errors): We could also recover `; PAT =>` here + + // Try to parse a following `PAT =>`, if successful + // then we should recover. + let mut snapshot = this.create_snapshot_for_diagnostic(); + let pattern_follows = snapshot + .parse_pat_allow_top_alt( + None, + RecoverComma::Yes, + RecoverColon::Yes, + CommaRecoveryMode::EitherTupleOrPipe, + ) + .map_err(|err| err.cancel()) + .is_ok(); + if pattern_follows && snapshot.check(&TokenKind::FatArrow) { + err.cancel(); + this.struct_span_err( + hi.shrink_to_hi(), + "expected `,` following `match` arm", + ) + .span_suggestion( + hi.shrink_to_hi(), + "missing a comma here to end this `match` arm", + ",".to_owned(), + Applicability::MachineApplicable, + ) + .emit(); + return Ok(true); } } - err + err.span_label(arrow_span, "while parsing the `match` arm starting here"); + Err(err) })?; } else { this.eat(&token::Comma); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6720399aacb..48c3c467bec 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -204,25 +204,7 @@ impl<'a> Parser<'a> { let mut def = || mem::replace(def, Defaultness::Final); let info = if self.eat_keyword(kw::Use) { - // USE ITEM - let tree = self.parse_use_tree()?; - - // If wildcard or glob-like brace syntax doesn't have `;`, - // the user may not know `*` or `{}` should be the last. - if let Err(mut e) = self.expect_semi() { - match tree.kind { - UseTreeKind::Glob => { - e.note("the wildcard token must be last on the path"); - } - UseTreeKind::Nested(..) => { - e.note("glob-like brace syntax must be last on the path"); - } - _ => (), - } - return Err(e); - } - - (Ident::empty(), ItemKind::Use(tree)) + self.parse_use_item()? } else if self.check_fn_front_matter(def_final) { // FUNCTION ITEM let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis)?; @@ -288,7 +270,12 @@ impl<'a> Parser<'a> { } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() { // MACRO_RULES ITEM self.parse_item_macro_rules(vis, has_bang)? - } else if vis.kind.is_pub() && self.isnt_macro_invocation() { + } else if self.isnt_macro_invocation() + && (self.token.is_ident_named(Symbol::intern("import")) + || self.token.is_ident_named(Symbol::intern("using"))) + { + return self.recover_import_as_use(); + } else if self.isnt_macro_invocation() && vis.kind.is_pub() { self.recover_missing_kw_before_item()?; return Ok(None); } else if macros_allowed && self.check_path() { @@ -300,6 +287,48 @@ impl<'a> Parser<'a> { Ok(Some(info)) } + fn recover_import_as_use(&mut self) -> PResult<'a, Option<(Ident, ItemKind)>> { + let span = self.token.span; + let token_name = super::token_descr(&self.token); + let snapshot = self.create_snapshot_for_diagnostic(); + self.bump(); + match self.parse_use_item() { + Ok(u) => { + self.struct_span_err(span, format!("expected item, found {token_name}")) + .span_suggestion_short( + span, + "items are imported using the `use` keyword", + "use".to_owned(), + Applicability::MachineApplicable, + ) + .emit(); + Ok(Some(u)) + } + Err(e) => { + e.cancel(); + self.restore_snapshot(snapshot); + Ok(None) + } + } + } + + fn parse_use_item(&mut self) -> PResult<'a, (Ident, ItemKind)> { + let tree = self.parse_use_tree()?; + if let Err(mut e) = self.expect_semi() { + match tree.kind { + UseTreeKind::Glob => { + e.note("the wildcard token must be last on the path"); + } + UseTreeKind::Nested(..) => { + e.note("glob-like brace syntax must be last on the path"); + } + _ => (), + } + return Err(e); + } + Ok((Ident::empty(), ItemKind::Use(tree))) + } + /// When parsing a statement, would the start of a path be an item? pub(super) fn is_path_start_item(&mut self) -> bool { self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }` diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index f2e31c068a0..3a00c41d90a 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -304,22 +304,24 @@ pub fn get_vtable_index_of_object_method<'tcx, N>( tcx: TyCtxt<'tcx>, object: &super::ImplSourceObjectData<'tcx, N>, method_def_id: DefId, -) -> usize { +) -> Option<usize> { let existential_trait_ref = object .upcast_trait_ref .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); let existential_trait_ref = tcx.erase_regions(existential_trait_ref); + // Count number of methods preceding the one we are selecting and // add them to the total offset. - let index = tcx + if let Some(index) = tcx .own_existential_vtable_entries(existential_trait_ref) .iter() .copied() .position(|def_id| def_id == method_def_id) - .unwrap_or_else(|| { - bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id); - }); - object.vtable_base + index + { + Some(object.vtable_base + index) + } else { + None + } } pub fn closure_trait_ref_and_return_type<'tcx>( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 9c450fe1e32..7c89ce125e0 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -349,11 +349,15 @@ fn resolve_associated_item<'tcx>( _ => None, }, traits::ImplSource::Object(ref data) => { - let index = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id); - Some(Instance { - def: ty::InstanceDef::Virtual(trait_item_id, index), - substs: rcvr_substs, - }) + if let Some(index) = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id) + { + Some(Instance { + def: ty::InstanceDef::Virtual(trait_item_id, index), + substs: rcvr_substs, + }) + } else { + None + } } traits::ImplSource::Builtin(..) => { if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() { |
