diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_error_messages/locales/en-US/parse.ftl index 2ef3dba557e..581bb9a766e 100644 --- a/compiler/rustc_error_messages/locales/en-US/parse.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parse.ftl @@ -475,6 +475,9 @@ parse_unexpected_token_after_struct_name_found_other = expected `where`, `{"{"}` parse_unexpected_self_in_generic_parameters = unexpected keyword `Self` in generic parameters .note = you cannot use `Self` as a generic parameter because it is reserved for associated items +parse_unexpected_default_value_for_lifetime_in_generic_parameters = unexpected default lifetime parameter + .label = lifetime parameters cannot have default values + parse_multiple_where_clauses = cannot define duplicate `where` clauses on an item .label = previous `where` clause starts here .suggestion = consider joining the two `where` clauses into one diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 19b8fb96cde..c4905a934cb 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -60,6 +60,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_clone_for_ref(err, expr, expr_ty, expected) || self.suggest_into(err, expr, expr_ty, expected) || self.suggest_floating_point_literal(err, expr, expected) + || self.suggest_null_ptr_for_literal_zero_given_to_ptr_arg(err, expr, expected) || self.note_result_coercion(err, expr, expected, expr_ty); if !suggested { self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected, expr.span); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 237142acca6..e84b3de124c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -921,6 +921,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: hir::ImplItemKind::Fn(ref sig, ..), .. }) => Some((&sig.decl, ident, false)), + Node::Expr(&hir::Expr { + hir_id, + kind: hir::ExprKind::Closure(..), + .. + }) if let Some(Node::Expr(&hir::Expr { + hir_id, + kind: hir::ExprKind::Call(..), + .. + })) = self.tcx.hir().find_parent(hir_id) && + let Some(Node::Item(&hir::Item { + ident, + kind: hir::ItemKind::Fn(ref sig, ..), + .. + })) = self.tcx.hir().find_parent(hir_id) => { + Some((&sig.decl, ident, ident.name != sym::main)) + }, _ => None, } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 11d47053ade..51e3e3ec73d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -13,6 +13,7 @@ use rustc_hir::{ use rustc_hir_analysis::astconv::AstConv; use rustc_infer::traits::{self, StatementAsExpression}; use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty, TypeVisitable, @@ -704,10 +705,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } hir::FnRetTy::Return(ty) => { + let span = ty.span; + + if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind + && let hir::Node::Item(hir::Item { + kind: hir::ItemKind::OpaqueTy(op_ty), + .. + }) = self.tcx.hir().get(item_id.hir_id()) + && let hir::OpaqueTy { + bounds: [bound], .. + } = op_ty + && let hir::GenericBound::LangItemTrait( + hir::LangItem::Future, _, _, generic_args) = bound + && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args + && let hir::TypeBinding { kind, .. } = ty_binding + && let hir::TypeBindingKind::Equality { term } = kind + && let hir::Term::Ty(term_ty) = term { + // Check if async function's return type was omitted. + // Don't emit suggestions if the found type is `impl Future<...>`. + debug!("suggest_missing_return_type: found = {:?}", found); + if found.is_suggestable(self.tcx, false) { + if term_ty.span.is_empty() { + err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() }); + return true; + } else { + err.subdiagnostic(ExpectedReturnTypeLabel::Other { span, expected }); + } + } + } + // Only point to return type if the expected type is the return type, as if they // are not, the expectation must have been caused by something else. debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind); - let span = ty.span; let ty = self.astconv().ast_ty_to_ty(ty); debug!("suggest_missing_return_type: return type {:?}", ty); debug!("suggest_missing_return_type: expected type {:?}", ty); @@ -1244,6 +1273,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Suggest providing `std::ptr::null()` or `std::ptr::null_mut()` if they + /// pass in a literal 0 to an raw pointer. + #[instrument(skip(self, err))] + pub(crate) fn suggest_null_ptr_for_literal_zero_given_to_ptr_arg( + &self, + err: &mut Diagnostic, + expr: &hir::Expr<'_>, + expected_ty: Ty<'tcx>, + ) -> bool { + // Expected type needs to be a raw pointer. + let ty::RawPtr(ty::TypeAndMut { mutbl, .. }) = expected_ty.kind() else { + return false; + }; + + // Provided expression needs to be a literal `0`. + let ExprKind::Lit(Spanned { + node: rustc_ast::LitKind::Int(0, _), + span, + }) = expr.kind else { + return false; + }; + + // We need to find a null pointer symbol to suggest + let null_sym = match mutbl { + hir::Mutability::Not => sym::ptr_null, + hir::Mutability::Mut => sym::ptr_null_mut, + }; + let Some(null_did) = self.tcx.get_diagnostic_item(null_sym) else { + return false; + }; + let null_path_str = with_no_trimmed_paths!(self.tcx.def_path_str(null_did)); + + // We have satisfied all requirements to provide a suggestion. Emit it. + err.span_suggestion( + span, + format!("if you meant to create a null pointer, use `{null_path_str}()`"), + null_path_str + "()", + Applicability::MachineApplicable, + ); + + true + } + pub(crate) fn suggest_associated_const( &self, err: &mut Diagnostic, diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 6bdbda909d7..8bf6493be4b 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -790,7 +790,7 @@ impl TryFrom> for TrackElem { } /// Invokes `f` on all direct fields of `ty`. -fn iter_fields<'tcx>( +pub fn iter_fields<'tcx>( ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, mut f: impl FnMut(Option, Field, Ty<'tcx>), @@ -824,7 +824,7 @@ fn iter_fields<'tcx>( } /// Returns all locals with projections that have their reference or address taken. -fn excluded_locals(body: &Body<'_>) -> IndexVec { +pub fn excluded_locals(body: &Body<'_>) -> IndexVec { struct Collector { result: IndexVec, } diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 42124f5a480..26acd406ed8 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -1,10 +1,11 @@ use crate::MirPass; -use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; +use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields}; pub struct ScalarReplacementOfAggregates; @@ -13,27 +14,41 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates { sess.mir_opt_level() >= 3 } + #[instrument(level = "debug", skip(self, tcx, body))] fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let escaping = escaping_locals(&*body); - debug!(?escaping); - let replacements = compute_flattening(tcx, body, escaping); - debug!(?replacements); - replace_flattened_locals(tcx, body, replacements); + debug!(def_id = ?body.source.def_id()); + let mut excluded = excluded_locals(body); + loop { + debug!(?excluded); + let escaping = escaping_locals(&excluded, body); + debug!(?escaping); + let replacements = compute_flattening(tcx, body, escaping); + debug!(?replacements); + let all_dead_locals = replace_flattened_locals(tcx, body, replacements); + if !all_dead_locals.is_empty() { + for local in excluded.indices() { + excluded[local] |= all_dead_locals.contains(local); + } + excluded.raw.resize(body.local_decls.len(), false); + } else { + break; + } + } } } /// Identify all locals that are not eligible for SROA. /// /// There are 3 cases: -/// - the aggegated local is used or passed to other code (function parameters and arguments); +/// - the aggregated local is used or passed to other code (function parameters and arguments); /// - the locals is a union or an enum; /// - the local's address is taken, and thus the relative addresses of the fields are observable to /// client code. -fn escaping_locals(body: &Body<'_>) -> BitSet { +fn escaping_locals(excluded: &IndexVec, body: &Body<'_>) -> BitSet { let mut set = BitSet::new_empty(body.local_decls.len()); set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count)); for (local, decl) in body.local_decls().iter_enumerated() { - if decl.ty.is_union() || decl.ty.is_enum() { + if decl.ty.is_union() || decl.ty.is_enum() || excluded[local] { set.insert(local); } } @@ -58,41 +73,33 @@ fn escaping_locals(body: &Body<'_>) -> BitSet { self.super_place(place, context, location); } - fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - if let Rvalue::AddressOf(.., place) | Rvalue::Ref(.., place) = rvalue { - if !place.is_indirect() { - // Raw pointers may be used to access anything inside the enclosing place. - self.set.insert(place.local); - return; + fn visit_assign( + &mut self, + lvalue: &Place<'tcx>, + rvalue: &Rvalue<'tcx>, + location: Location, + ) { + if lvalue.as_local().is_some() { + match rvalue { + // Aggregate assignments are expanded in run_pass. + Rvalue::Aggregate(..) | Rvalue::Use(..) => { + self.visit_rvalue(rvalue, location); + return; + } + _ => {} } } - self.super_rvalue(rvalue, location) + self.super_assign(lvalue, rvalue, location) } fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { - if let StatementKind::StorageLive(..) - | StatementKind::StorageDead(..) - | StatementKind::Deinit(..) = statement.kind - { + match statement.kind { // Storage statements are expanded in run_pass. - return; + StatementKind::StorageLive(..) + | StatementKind::StorageDead(..) + | StatementKind::Deinit(..) => return, + _ => self.super_statement(statement, location), } - self.super_statement(statement, location) - } - - fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { - // Drop implicitly calls `drop_in_place`, which takes a `&mut`. - // This implies that `Drop` implicitly takes the address of the place. - if let TerminatorKind::Drop { place, .. } - | TerminatorKind::DropAndReplace { place, .. } = terminator.kind - { - if !place.is_indirect() { - // Raw pointers may be used to access anything inside the enclosing place. - self.set.insert(place.local); - return; - } - } - self.super_terminator(terminator, location); } // We ignore anything that happens in debuginfo, since we expand it using @@ -103,7 +110,30 @@ fn escaping_locals(body: &Body<'_>) -> BitSet { #[derive(Default, Debug)] struct ReplacementMap<'tcx> { - fields: FxIndexMap, Local>, + /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage + /// and deinit statement and debuginfo. + fragments: IndexVec, Local)>>>>, +} + +impl<'tcx> ReplacementMap<'tcx> { + fn replace_place(&self, tcx: TyCtxt<'tcx>, place: PlaceRef<'tcx>) -> Option> { + let &[PlaceElem::Field(f, _), ref rest @ ..] = place.projection else { return None; }; + let fields = self.fragments[place.local].as_ref()?; + let (_, new_local) = fields[f]?; + Some(Place { local: new_local, projection: tcx.intern_place_elems(&rest) }) + } + + fn place_fragments( + &self, + place: Place<'tcx>, + ) -> Option, Local)> + '_> { + let local = place.as_local()?; + let fields = self.fragments[local].as_ref()?; + Some(fields.iter_enumerated().filter_map(|(field, &opt_ty_local)| { + let (ty, local) = opt_ty_local?; + Some((field, ty, local)) + })) + } } /// Compute the replacement of flattened places into locals. @@ -115,53 +145,25 @@ fn compute_flattening<'tcx>( body: &mut Body<'tcx>, escaping: BitSet, ) -> ReplacementMap<'tcx> { - let mut visitor = PreFlattenVisitor { - tcx, - escaping, - local_decls: &mut body.local_decls, - map: Default::default(), - }; - for (block, bbdata) in body.basic_blocks.iter_enumerated() { - visitor.visit_basic_block_data(block, bbdata); - } - return visitor.map; + let mut fragments = IndexVec::from_elem(None, &body.local_decls); - struct PreFlattenVisitor<'tcx, 'll> { - tcx: TyCtxt<'tcx>, - local_decls: &'ll mut LocalDecls<'tcx>, - escaping: BitSet, - map: ReplacementMap<'tcx>, - } - - impl<'tcx, 'll> PreFlattenVisitor<'tcx, 'll> { - fn create_place(&mut self, place: PlaceRef<'tcx>) { - if self.escaping.contains(place.local) { + for local in body.local_decls.indices() { + if escaping.contains(local) { + continue; + } + let decl = body.local_decls[local].clone(); + let ty = decl.ty; + iter_fields(ty, tcx, |variant, field, field_ty| { + if variant.is_some() { + // Downcasts are currently not supported. return; - } - - match self.map.fields.entry(place) { - IndexEntry::Occupied(_) => {} - IndexEntry::Vacant(v) => { - let ty = place.ty(&*self.local_decls, self.tcx).ty; - let local = self.local_decls.push(LocalDecl { - ty, - user_ty: None, - ..self.local_decls[place.local].clone() - }); - v.insert(local); - } - } - } - } - - impl<'tcx, 'll> Visitor<'tcx> for PreFlattenVisitor<'tcx, 'll> { - fn visit_place(&mut self, place: &Place<'tcx>, _: PlaceContext, _: Location) { - if let &[PlaceElem::Field(..), ..] = &place.projection[..] { - let pr = PlaceRef { local: place.local, projection: &place.projection[..1] }; - self.create_place(pr) - } - } + }; + let new_local = + body.local_decls.push(LocalDecl { ty: field_ty, user_ty: None, ..decl.clone() }); + fragments.get_or_insert_with(local, IndexVec::new).insert(field, (field_ty, new_local)); + }); } + ReplacementMap { fragments } } /// Perform the replacement computed by `compute_flattening`. @@ -169,29 +171,24 @@ fn replace_flattened_locals<'tcx>( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, replacements: ReplacementMap<'tcx>, -) { +) -> BitSet { let mut all_dead_locals = BitSet::new_empty(body.local_decls.len()); - for p in replacements.fields.keys() { - all_dead_locals.insert(p.local); + for (local, replacements) in replacements.fragments.iter_enumerated() { + if replacements.is_some() { + all_dead_locals.insert(local); + } } debug!(?all_dead_locals); if all_dead_locals.is_empty() { - return; + return all_dead_locals; } - let mut fragments = IndexVec::new(); - for (k, v) in &replacements.fields { - fragments.ensure_contains_elem(k.local, || Vec::new()); - fragments[k.local].push((k.projection, *v)); - } - debug!(?fragments); - let mut visitor = ReplacementVisitor { tcx, local_decls: &body.local_decls, - replacements, + replacements: &replacements, all_dead_locals, - fragments, + patch: MirPatch::new(body), }; for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { visitor.visit_basic_block_data(bb, data); @@ -205,6 +202,9 @@ fn replace_flattened_locals<'tcx>( for var_debug_info in &mut body.var_debug_info { visitor.visit_var_debug_info(var_debug_info); } + let ReplacementVisitor { patch, all_dead_locals, .. } = visitor; + patch.apply(body); + all_dead_locals } struct ReplacementVisitor<'tcx, 'll> { @@ -212,40 +212,23 @@ struct ReplacementVisitor<'tcx, 'll> { /// This is only used to compute the type for `VarDebugInfoContents::Composite`. local_decls: &'ll LocalDecls<'tcx>, /// Work to do. - replacements: ReplacementMap<'tcx>, + replacements: &'ll ReplacementMap<'tcx>, /// This is used to check that we are not leaving references to replaced locals behind. all_dead_locals: BitSet, - /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage - /// and deinit statement and debuginfo. - fragments: IndexVec], Local)>>, + patch: MirPatch<'tcx>, } -impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> { - fn gather_debug_info_fragments( - &self, - place: PlaceRef<'tcx>, - ) -> Vec> { +impl<'tcx> ReplacementVisitor<'tcx, '_> { + fn gather_debug_info_fragments(&self, local: Local) -> Option>> { let mut fragments = Vec::new(); - let parts = &self.fragments[place.local]; - for (proj, replacement_local) in parts { - if proj.starts_with(place.projection) { - fragments.push(VarDebugInfoFragment { - projection: proj[place.projection.len()..].to_vec(), - contents: Place::from(*replacement_local), - }); - } - } - fragments - } - - fn replace_place(&self, place: PlaceRef<'tcx>) -> Option> { - if let &[PlaceElem::Field(..), ref rest @ ..] = place.projection { - let pr = PlaceRef { local: place.local, projection: &place.projection[..1] }; - let local = self.replacements.fields.get(&pr)?; - Some(Place { local: *local, projection: self.tcx.intern_place_elems(&rest) }) - } else { - None + let parts = self.replacements.place_fragments(local.into())?; + for (field, ty, replacement_local) in parts { + fragments.push(VarDebugInfoFragment { + projection: vec![PlaceElem::Field(field, ty)], + contents: Place::from(replacement_local), + }); } + Some(fragments) } } @@ -254,94 +237,186 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { self.tcx } - fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { - if let StatementKind::StorageLive(..) - | StatementKind::StorageDead(..) - | StatementKind::Deinit(..) = statement.kind - { - // Storage statements are expanded in run_pass. - return; - } - self.super_statement(statement, location) - } - fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if let Some(repl) = self.replace_place(place.as_ref()) { + if let Some(repl) = self.replacements.replace_place(self.tcx, place.as_ref()) { *place = repl } else { self.super_place(place, context, location) } } + #[instrument(level = "trace", skip(self))] + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { + match statement.kind { + // Duplicate storage and deinit statements, as they pretty much apply to all fields. + StatementKind::StorageLive(l) => { + if let Some(final_locals) = self.replacements.place_fragments(l.into()) { + for (_, _, fl) in final_locals { + self.patch.add_statement(location, StatementKind::StorageLive(fl)); + } + statement.make_nop(); + } + return; + } + StatementKind::StorageDead(l) => { + if let Some(final_locals) = self.replacements.place_fragments(l.into()) { + for (_, _, fl) in final_locals { + self.patch.add_statement(location, StatementKind::StorageDead(fl)); + } + statement.make_nop(); + } + return; + } + StatementKind::Deinit(box place) => { + if let Some(final_locals) = self.replacements.place_fragments(place) { + for (_, _, fl) in final_locals { + self.patch + .add_statement(location, StatementKind::Deinit(Box::new(fl.into()))); + } + statement.make_nop(); + return; + } + } + + // We have `a = Struct { 0: x, 1: y, .. }`. + // We replace it by + // ``` + // a_0 = x + // a_1 = y + // ... + // ``` + StatementKind::Assign(box (place, Rvalue::Aggregate(_, ref mut operands))) => { + if let Some(local) = place.as_local() + && let Some(final_locals) = &self.replacements.fragments[local] + { + // This is ok as we delete the statement later. + let operands = std::mem::take(operands); + for (&opt_ty_local, mut operand) in final_locals.iter().zip(operands) { + if let Some((_, new_local)) = opt_ty_local { + // Replace mentions of SROA'd locals that appear in the operand. + self.visit_operand(&mut operand, location); + + let rvalue = Rvalue::Use(operand); + self.patch.add_statement( + location, + StatementKind::Assign(Box::new((new_local.into(), rvalue))), + ); + } + } + statement.make_nop(); + return; + } + } + + // We have `a = some constant` + // We add the projections. + // ``` + // a_0 = a.0 + // a_1 = a.1 + // ... + // ``` + // ConstProp will pick up the pieces and replace them by actual constants. + StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => { + if let Some(final_locals) = self.replacements.place_fragments(place) { + for (field, ty, new_local) in final_locals { + let rplace = self.tcx.mk_place_field(place, field, ty); + let rvalue = Rvalue::Use(Operand::Move(rplace)); + self.patch.add_statement( + location, + StatementKind::Assign(Box::new((new_local.into(), rvalue))), + ); + } + // We still need `place.local` to exist, so don't make it nop. + return; + } + } + + // We have `a = move? place` + // We replace it by + // ``` + // a_0 = move? place.0 + // a_1 = move? place.1 + // ... + // ``` + StatementKind::Assign(box (lhs, Rvalue::Use(ref op))) => { + let (rplace, copy) = match *op { + Operand::Copy(rplace) => (rplace, true), + Operand::Move(rplace) => (rplace, false), + Operand::Constant(_) => bug!(), + }; + if let Some(final_locals) = self.replacements.place_fragments(lhs) { + for (field, ty, new_local) in final_locals { + let rplace = self.tcx.mk_place_field(rplace, field, ty); + debug!(?rplace); + let rplace = self + .replacements + .replace_place(self.tcx, rplace.as_ref()) + .unwrap_or(rplace); + debug!(?rplace); + let rvalue = if copy { + Rvalue::Use(Operand::Copy(rplace)) + } else { + Rvalue::Use(Operand::Move(rplace)) + }; + self.patch.add_statement( + location, + StatementKind::Assign(Box::new((new_local.into(), rvalue))), + ); + } + statement.make_nop(); + return; + } + } + + _ => {} + } + self.super_statement(statement, location) + } + + #[instrument(level = "trace", skip(self))] fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) { match &mut var_debug_info.value { VarDebugInfoContents::Place(ref mut place) => { - if let Some(repl) = self.replace_place(place.as_ref()) { + if let Some(repl) = self.replacements.replace_place(self.tcx, place.as_ref()) { *place = repl; - } else if self.all_dead_locals.contains(place.local) { + } else if let Some(local) = place.as_local() + && let Some(fragments) = self.gather_debug_info_fragments(local) + { let ty = place.ty(self.local_decls, self.tcx).ty; - let fragments = self.gather_debug_info_fragments(place.as_ref()); var_debug_info.value = VarDebugInfoContents::Composite { ty, fragments }; } } VarDebugInfoContents::Composite { ty: _, ref mut fragments } => { let mut new_fragments = Vec::new(); + debug!(?fragments); fragments .drain_filter(|fragment| { - if let Some(repl) = self.replace_place(fragment.contents.as_ref()) { + if let Some(repl) = + self.replacements.replace_place(self.tcx, fragment.contents.as_ref()) + { fragment.contents = repl; - true - } else if self.all_dead_locals.contains(fragment.contents.local) { - let frg = self.gather_debug_info_fragments(fragment.contents.as_ref()); + false + } else if let Some(local) = fragment.contents.as_local() + && let Some(frg) = self.gather_debug_info_fragments(local) + { new_fragments.extend(frg.into_iter().map(|mut f| { f.projection.splice(0..0, fragment.projection.iter().copied()); f })); - false - } else { true + } else { + false } }) .for_each(drop); + debug!(?fragments); + debug!(?new_fragments); fragments.extend(new_fragments); } VarDebugInfoContents::Const(_) => {} } } - fn visit_basic_block_data(&mut self, bb: BasicBlock, bbdata: &mut BasicBlockData<'tcx>) { - self.super_basic_block_data(bb, bbdata); - - #[derive(Debug)] - enum Stmt { - StorageLive, - StorageDead, - Deinit, - } - - bbdata.expand_statements(|stmt| { - let source_info = stmt.source_info; - let (stmt, origin_local) = match &stmt.kind { - StatementKind::StorageLive(l) => (Stmt::StorageLive, *l), - StatementKind::StorageDead(l) => (Stmt::StorageDead, *l), - StatementKind::Deinit(p) if let Some(l) = p.as_local() => (Stmt::Deinit, l), - _ => return None, - }; - if !self.all_dead_locals.contains(origin_local) { - return None; - } - let final_locals = self.fragments.get(origin_local)?; - Some(final_locals.iter().map(move |&(_, l)| { - let kind = match stmt { - Stmt::StorageLive => StatementKind::StorageLive(l), - Stmt::StorageDead => StatementKind::StorageDead(l), - Stmt::Deinit => StatementKind::Deinit(Box::new(l.into())), - }; - Statement { source_info, kind } - })) - }); - } - fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { assert!(!self.all_dead_locals.contains(*local)); } diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index fc7c839f1c4..0c11e002690 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1601,6 +1601,14 @@ pub(crate) struct UnexpectedSelfInGenericParameters { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_unexpected_default_value_for_lifetime_in_generic_parameters)] +pub(crate) struct UnexpectedDefaultValueForLifetimeInGenericParameters { + #[primary_span] + #[label] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_multiple_where_clauses)] pub(crate) struct MultipleWhereClauses { diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 585dfc518b3..23f49ec55a1 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -1,5 +1,6 @@ use crate::errors::{ - MultipleWhereClauses, UnexpectedSelfInGenericParameters, WhereClauseBeforeTupleStructBody, + MultipleWhereClauses, UnexpectedDefaultValueForLifetimeInGenericParameters, + UnexpectedSelfInGenericParameters, WhereClauseBeforeTupleStructBody, WhereClauseBeforeTupleStructBodySugg, }; @@ -145,6 +146,20 @@ impl<'a> Parser<'a> { } else { (None, Vec::new()) }; + + if this.check_noexpect(&token::Eq) + && this.look_ahead(1, |t| t.is_lifetime()) + { + let lo = this.token.span; + // Parse `= 'lifetime`. + this.bump(); // `=` + this.bump(); // `'lifetime` + let span = lo.to(this.prev_token.span); + this.sess.emit_err( + UnexpectedDefaultValueForLifetimeInGenericParameters { span }, + ); + } + Some(ast::GenericParam { ident: lifetime.ident, id: lifetime.id, diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index d20d13ab36d..b5a2cf7f28b 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -105,10 +105,9 @@ Original by Dempfi (https://github.com/dempfi/ayu) --scrape-example-code-wrapper-background-end: rgba(15, 20, 25, 0); } -h1, h2, h3, h4 { - color: white; -} -h1 a { +h1, h2, h3, h4, +h1 a, .sidebar h2 a, .sidebar h3 a, +#source-sidebar > .title { color: #fff; } h4 { @@ -118,24 +117,22 @@ h4 { .docblock code { color: #ffb454; } -.code-header { - color: #e6e1cf; -} -.docblock pre > code, pre > code { - color: #e6e1cf; -} -.item-info code { - color: #e6e1cf; -} .docblock a > code { color: #39AFD7 !important; } -pre, .rustdoc.source .example-wrap { +.code-header, +.docblock pre > code, +pre, pre > code, +.item-info code, +.rustdoc.source .example-wrap { color: #e6e1cf; } .sidebar .current, -.sidebar a:hover { +.sidebar a:hover, +#source-sidebar div.files > a:hover, details.dir-entry summary:hover, +#source-sidebar div.files > a:focus, details.dir-entry summary:focus, +#source-sidebar div.files > a.selected { color: #ffb44c; } @@ -149,15 +146,12 @@ pre, .rustdoc.source .example-wrap { border-right: 1px solid #ffb44c; } -.search-results a:hover { - color: #fff !important; - background-color: #3c3c3c; -} - +.search-results a:hover, .search-results a:focus { color: #fff !important; background-color: #3c3c3c; } + .search-results a { color: #0096cf; } @@ -165,11 +159,6 @@ pre, .rustdoc.source .example-wrap { color: #c5c5c5; } -.sidebar h2 a, -.sidebar h3 a { - color: white; -} - .result-name .primitive > i, .result-name .keyword > i { color: #788797; } @@ -189,12 +178,3 @@ pre, .rustdoc.source .example-wrap { #settings-menu > a img { filter: invert(100); } - -#source-sidebar > .title { - color: #fff; -} -#source-sidebar div.files > a:hover, details.dir-entry summary:hover, -#source-sidebar div.files > a:focus, details.dir-entry summary:focus, -#source-sidebar div.files > a.selected { - color: #ffb44c; -} diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff index 49e8b020dfb..f1f53a48165 100644 --- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -8,8 +8,8 @@ let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16 let mut _7: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:19: +4:20 let mut _8: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:23: +4:24 - let mut _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 - let mut _15: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 + let mut _12: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 + let mut _13: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 scope 1 { - debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 + debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 @@ -29,18 +29,21 @@ scope 5 { - debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 + debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 - let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _14: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _15: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _16: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 scope 6 { - debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 - let _11: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + debug f => (bool, bool, u32){ .0 => _14, .1 => _15, .2 => _16, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _10: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 scope 7 { - debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 - let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + debug o => _10; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 + let _17: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 scope 8 { - debug p => _12; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 - let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + debug p => Point{ .0 => _17, .1 => _18, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 scope 9 { -- debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 +- debug a => _11; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 + debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 } } @@ -66,24 +69,23 @@ // mir::Constant // + span: $DIR/const_debuginfo.rs:14:13: 14:28 // + literal: Const { ty: &str, val: Value(Slice(..)) } - StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - _10 = (const true, const false, const 123_u32); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 - _11 = Option::::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 - StorageLive(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 - _12 = Point { x: const 32_u32, y: const 32_u32 }; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 - StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 - _14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 - StorageLive(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 - _15 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 - _13 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 - StorageDead(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 - StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 - StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_12); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageLive(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + _14 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _15 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _16 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + StorageLive(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + _10 = Option::::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + _17 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + _18 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + StorageLive(_11); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + _11 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 + StorageDead(_11); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_10); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_14); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_15); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_16); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2 return; // scope 0 at $DIR/const_debuginfo.rs:+14:2: +14:2 diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index 0eb47087c9c..d088c4f662b 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -3,25 +3,27 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +0:11 - let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + let mut _3: i32; // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + let mut _4: i32; // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 scope 1 { - debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 - let _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + debug x => (i32, i32){ .0 => _3, .1 => _4, }; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + let _1: i32; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + let _2: i32; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + debug y => (i32, i32){ .0 => _3, .1 => _2, }; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 -- _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 -+ _1 = const (42_i32, 43_i32); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 - (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13 + StorageLive(_4); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + _3 = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 + _4 = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 + _4 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13 StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 -- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 -+ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 +- _2 = _4; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 ++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 + StorageDead(_4); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff index 26a1c3c1aa9..134f0c080bf 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff @@ -9,9 +9,10 @@ let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 scope 2 { debug z => _2; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 - let _3: (i32, i32); // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + let _3: i32; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + let _4: i32; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 scope 3 { - debug y => _3; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + debug y => (i32, i32){ .0 => _3, .1 => _4, }; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 } } } @@ -23,8 +24,11 @@ _2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:13: +2:19 ((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13 StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 - _3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 + StorageLive(_4); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + _3 = (_1.0: i32); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 + _4 = (_1.1: i32); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 StorageDead(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 + StorageDead(_4); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 return; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2 diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff index a2e4890c6a6..4010dd6c6d0 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff @@ -4,16 +4,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11 let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 - let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + let mut _2: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 scope 1 { debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 - let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let mut _5: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 scope 2 { - debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 - let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + debug x => (i32, i32){ .0 => _5, .1 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let _3: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 scope 3 { - debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 - let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + debug y => _3; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + let _4: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 scope 4 { debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 } @@ -30,21 +31,17 @@ } bb1: { - StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 -- _2 = (const 1_i32, const 2_i32); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 -+ _2 = const (1_i32, 2_i32); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 - StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - _3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - (_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 - StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 - _4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 - StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 -- _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 -+ _5 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 - StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 - StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 - StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageLive(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + _5 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + _6 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + StorageLive(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _2 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _6 = move _2; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 + StorageDead(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + _3 = _6; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2 } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff index 1368b114658..691aa01a564 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff @@ -9,7 +9,7 @@ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 - let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + let mut _9: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -17,7 +17,7 @@ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 scope 3 { - debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => _9; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } @@ -50,13 +50,7 @@ + _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 - StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 -- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 -+ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 - StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + _9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff index 1368b114658..691aa01a564 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff @@ -9,7 +9,7 @@ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 - let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + let mut _9: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -17,7 +17,7 @@ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 scope 3 { - debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => _9; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } @@ -50,13 +50,7 @@ + _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 - StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 -- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 -+ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 - StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + _9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir index 9db87cfc879..81cfd22db6c 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir @@ -3,12 +3,12 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 2 { debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 scope 3 { debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } @@ -18,8 +18,6 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir index 9db87cfc879..81cfd22db6c 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir @@ -3,12 +3,12 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 2 { debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 scope 3 { debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } @@ -18,8 +18,6 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff index de1d57ed401..98cd020dade 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff @@ -10,6 +10,8 @@ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -45,10 +47,20 @@ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 +- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 +- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff index de1d57ed401..98cd020dade 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff @@ -10,6 +10,8 @@ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -45,10 +47,20 @@ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 +- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 +- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir index d926b9df733..002e914e8fa 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir @@ -3,12 +3,12 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 2 { debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 scope 3 { debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } @@ -18,8 +18,6 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir index d926b9df733..002e914e8fa 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir @@ -3,12 +3,12 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 2 { debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 scope 3 { debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } @@ -18,8 +18,6 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 diff --git a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir index 5c898d798ff..e338f15b485 100644 --- a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir +++ b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir @@ -4,25 +4,22 @@ fn ezmap(_1: Option) -> Option { debug x => _1; // in scope 0 at $DIR/simple_option_map_e2e.rs:+0:14: +0:15 let mut _0: std::option::Option; // return place in scope 0 at $DIR/simple_option_map_e2e.rs:+0:33: +0:44 let mut _2: [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]; // in scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21 - let mut _7: i32; // in scope 0 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 scope 1 (inlined map::) { // at $DIR/simple_option_map_e2e.rs:14:5: 14:22 debug slf => _1; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:17: 2:20 debug f => _2; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:33: 2:34 let mut _3: isize; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:9: 7:16 let _4: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 let mut _5: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - let mut _6: (i32,); // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 scope 2 { debug x => _4; // in scope 2 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - debug n => _7; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14 + debug n => _4; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14 } } } bb0: { StorageLive(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21 - StorageLive(_4); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:5: +1:22 _3 = discriminant(_1); // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14 switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map_e2e.rs:6:5: 6:14 } @@ -39,20 +36,13 @@ fn ezmap(_1: Option) -> Option { bb3: { _4 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 StorageLive(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - StorageLive(_6); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - _6 = (move _4,); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - StorageLive(_7); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - _7 = move (_6.0: i32); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - _5 = Add(_7, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21 - StorageDead(_7); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - StorageDead(_6); // scope 2 at $DIR/simple_option_map_e2e.rs:7:28: 7:29 + _5 = Add(_4, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21 _0 = Option::::Some(move _5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30 StorageDead(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:29: 7:30 goto -> bb4; // scope 1 at $DIR/simple_option_map_e2e.rs:10:1: 10:2 } bb4: { - StorageDead(_4); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:5: +1:22 StorageDead(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:21: +1:22 return; // scope 0 at $DIR/simple_option_map_e2e.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff new file mode 100644 index 00000000000..976f6d44b75 --- /dev/null +++ b/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff @@ -0,0 +1,91 @@ +- // MIR for `copies` before ScalarReplacementOfAggregates ++ // MIR for `copies` after ScalarReplacementOfAggregates + + fn copies(_1: Foo) -> () { + debug x => _1; // in scope 0 at $DIR/sroa.rs:+0:11: +0:12 + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19 + let _2: Foo; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _11: u8; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _12: (); // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _13: &str; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _14: std::option::Option; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 ++ debug y => Foo{ .0 => _11, .1 => _12, .2 => _13, .3 => _14, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 + let _3: u8; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 + scope 2 { + debug t => _3; // in scope 2 at $DIR/sroa.rs:+2:9: +2:10 + let _4: &str; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10 + scope 3 { + debug u => _4; // in scope 3 at $DIR/sroa.rs:+3:9: +3:10 + let _5: Foo; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _7: u8; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _8: (); // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _9: &str; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _10: std::option::Option; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 + scope 4 { +- debug z => _5; // in scope 4 at $DIR/sroa.rs:+4:9: +4:10 ++ debug z => Foo{ .0 => _7, .1 => _8, .2 => _9, .3 => _10, }; // in scope 4 at $DIR/sroa.rs:+4:9: +4:10 + let _6: (); // in scope 4 at $DIR/sroa.rs:+5:9: +5:10 + scope 5 { + debug a => _6; // in scope 5 at $DIR/sroa.rs:+5:9: +5:10 + } + } + } + } + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/sroa.rs:+1:13: +1:14 ++ StorageLive(_11); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_12); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_13); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_14); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ nop; // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ _11 = (_1.0: u8); // scope 0 at $DIR/sroa.rs:+1:13: +1:14 ++ _12 = (_1.1: ()); // scope 0 at $DIR/sroa.rs:+1:13: +1:14 ++ _13 = (_1.2: &str); // scope 0 at $DIR/sroa.rs:+1:13: +1:14 ++ _14 = (_1.3: std::option::Option); // scope 0 at $DIR/sroa.rs:+1:13: +1:14 ++ nop; // scope 0 at $DIR/sroa.rs:+1:13: +1:14 + StorageLive(_3); // scope 1 at $DIR/sroa.rs:+2:9: +2:10 +- _3 = (_2.0: u8); // scope 1 at $DIR/sroa.rs:+2:13: +2:16 ++ _3 = _11; // scope 1 at $DIR/sroa.rs:+2:13: +2:16 + StorageLive(_4); // scope 2 at $DIR/sroa.rs:+3:9: +3:10 +- _4 = (_2.2: &str); // scope 2 at $DIR/sroa.rs:+3:13: +3:16 +- StorageLive(_5); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 +- _5 = _2; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _4 = _13; // scope 2 at $DIR/sroa.rs:+3:13: +3:16 ++ StorageLive(_7); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ StorageLive(_8); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ StorageLive(_9); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ StorageLive(_10); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ nop; // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ _7 = _11; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _8 = _12; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _9 = _13; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _10 = _14; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ nop; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 + StorageLive(_6); // scope 4 at $DIR/sroa.rs:+5:9: +5:10 +- _6 = (_5.1: ()); // scope 4 at $DIR/sroa.rs:+5:13: +5:16 ++ _6 = _8; // scope 4 at $DIR/sroa.rs:+5:13: +5:16 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +6:2 + StorageDead(_6); // scope 4 at $DIR/sroa.rs:+6:1: +6:2 +- StorageDead(_5); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_7); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_8); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_9); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_10); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ nop; // scope 3 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_4); // scope 2 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_3); // scope 1 at $DIR/sroa.rs:+6:1: +6:2 +- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_12); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_13); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_14); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 ++ nop; // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff index b01fb6fc915..ea7f5007224 100644 --- a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff @@ -17,7 +17,7 @@ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37 _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37 // mir::Constant - // + span: $DIR/sroa.rs:78:34: 78:35 + // + span: $DIR/sroa.rs:73:34: 73:35 // + literal: Const { ty: fn() -> u32 {g}, val: Value() } } @@ -28,7 +28,7 @@ _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42 // mir::Constant - // + span: $DIR/sroa.rs:78:5: 78:6 + // + span: $DIR/sroa.rs:73:5: 73:6 // + literal: Const { ty: fn(*const u32) {f}, val: Value() } } diff --git a/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff index 749c22c26e0..69631fc0213 100644 --- a/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff @@ -10,6 +10,10 @@ let mut _5: Foo; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 let mut _6: (); // in scope 0 at $DIR/sroa.rs:+1:45: +1:47 let mut _7: std::option::Option; // in scope 0 at $DIR/sroa.rs:+1:60: +1:68 ++ let mut _8: u8; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ let mut _9: (); // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ let mut _10: &str; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ let mut _11: std::option::Option; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 scope 1 { debug a => _1; // in scope 1 at $DIR/sroa.rs:+1:15: +1:16 debug b => _2; // in scope 1 at $DIR/sroa.rs:+1:18: +1:19 @@ -26,26 +30,45 @@ } bb0: { - StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 +- StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ nop; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47 _6 = (); // scope 0 at $DIR/sroa.rs:+1:45: +1:47 StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68 _7 = Option::::Some(const -4_isize); // scope 0 at $DIR/sroa.rs:+1:60: +1:68 - _5 = Foo { a: const 5_u8, b: move _6, c: const "a", d: move _7 }; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 +- _5 = Foo { a: const 5_u8, b: move _6, c: const "a", d: move _7 }; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _8 = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _9 = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _10 = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 // mir::Constant - // + span: $DIR/sroa.rs:57:52: 57:55 + // + span: $DIR/sroa.rs:53:52: 53:55 // + literal: Const { ty: &str, val: Value(Slice(..)) } ++ _11 = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ nop; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 StorageDead(_7); // scope 0 at $DIR/sroa.rs:+1:69: +1:70 StorageDead(_6); // scope 0 at $DIR/sroa.rs:+1:69: +1:70 StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:15: +1:16 - _1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16 +- _1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16 ++ _1 = _8; // scope 0 at $DIR/sroa.rs:+1:15: +1:16 StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:18: +1:19 - _2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19 +- _2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19 ++ _2 = _9; // scope 0 at $DIR/sroa.rs:+1:18: +1:19 StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:21: +1:22 - _3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22 +- _3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22 ++ _3 = _10; // scope 0 at $DIR/sroa.rs:+1:21: +1:22 StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:24: +1:25 - _4 = (_5.3: std::option::Option); // scope 0 at $DIR/sroa.rs:+1:24: +1:25 - StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 +- _4 = (_5.3: std::option::Option); // scope 0 at $DIR/sroa.rs:+1:24: +1:25 +- StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ _4 = _11; // scope 0 at $DIR/sroa.rs:+1:24: +1:25 ++ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ StorageDead(_9); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ StorageDead(_10); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ nop; // scope 0 at $DIR/sroa.rs:+1:70: +1:71 _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +6:2 StorageDead(_4); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 diff --git a/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff new file mode 100644 index 00000000000..f0d62220dd6 --- /dev/null +++ b/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff @@ -0,0 +1,56 @@ +- // MIR for `ref_copies` before ScalarReplacementOfAggregates ++ // MIR for `ref_copies` after ScalarReplacementOfAggregates + + fn ref_copies(_1: &Foo) -> () { + debug x => _1; // in scope 0 at $DIR/sroa.rs:+0:15: +0:16 + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:24: +0:24 + let _2: Foo; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _5: u8; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _6: (); // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _7: &str; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _8: std::option::Option; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 ++ debug y => Foo{ .0 => _5, .1 => _6, .2 => _7, .3 => _8, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 + let _3: u8; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 + scope 2 { + debug t => _3; // in scope 2 at $DIR/sroa.rs:+2:9: +2:10 + let _4: &str; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10 + scope 3 { + debug u => _4; // in scope 3 at $DIR/sroa.rs:+3:9: +3:10 + } + } + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 +- _2 = (*_1); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ nop; // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ _5 = ((*_1).0: u8); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ _6 = ((*_1).1: ()); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ _7 = ((*_1).2: &str); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ _8 = ((*_1).3: std::option::Option); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ nop; // scope 0 at $DIR/sroa.rs:+1:13: +1:15 + StorageLive(_3); // scope 1 at $DIR/sroa.rs:+2:9: +2:10 +- _3 = (_2.0: u8); // scope 1 at $DIR/sroa.rs:+2:13: +2:16 ++ _3 = _5; // scope 1 at $DIR/sroa.rs:+2:13: +2:16 + StorageLive(_4); // scope 2 at $DIR/sroa.rs:+3:9: +3:10 +- _4 = (_2.2: &str); // scope 2 at $DIR/sroa.rs:+3:13: +3:16 ++ _4 = _7; // scope 2 at $DIR/sroa.rs:+3:13: +3:16 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:24: +4:2 + StorageDead(_4); // scope 2 at $DIR/sroa.rs:+4:1: +4:2 + StorageDead(_3); // scope 1 at $DIR/sroa.rs:+4:1: +4:2 +- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ StorageDead(_6); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ StorageDead(_7); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ nop; // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + return; // scope 0 at $DIR/sroa.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index ff8deb40d7d..471aac9f9d8 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -12,17 +12,14 @@ impl Drop for Tag { fn drop(&mut self) {} } -// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff pub fn dropping() { S(Tag(0), Tag(1), Tag(2)).1; } -// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff pub fn enums(a: usize) -> usize { if let Some(a) = Some(a) { a } else { 0 } } -// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff pub fn structs(a: f32) -> f32 { struct U { _foo: usize, @@ -32,7 +29,6 @@ pub fn structs(a: f32) -> f32 { U { _foo: 0, a }.a } -// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff pub fn unions(a: f32) -> u32 { union Repr { f: f32, @@ -41,6 +37,7 @@ pub fn unions(a: f32) -> u32 { unsafe { Repr { f: a }.u } } +#[derive(Copy, Clone)] struct Foo { a: u8, b: (), @@ -52,7 +49,6 @@ fn g() -> u32 { 3 } -// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff pub fn flat() { let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) }; let _ = a; @@ -72,12 +68,25 @@ fn f(a: *const u32) { println!("{}", unsafe { *a.add(2) }); } -// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff pub fn escaping() { // Verify this struct is not flattened. f(&Escaping { a: 1, b: 2, c: g() }.a); } +fn copies(x: Foo) { + let y = x; + let t = y.a; + let u = y.c; + let z = y; + let a = z.b; +} + +fn ref_copies(x: &Foo) { + let y = *x; + let t = y.a; + let u = y.c; +} + fn main() { dropping(); enums(5); @@ -85,4 +94,15 @@ fn main() { unions(5.); flat(); escaping(); + copies(Foo { a: 5, b: (), c: "a", d: Some(-4) }); + ref_copies(&Foo { a: 5, b: (), c: "a", d: Some(-4) }); } + +// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.copies.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.ref_copies.ScalarReplacementOfAggregates.diff diff --git a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff index dc4945104f4..2c63d8b266d 100644 --- a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff @@ -6,15 +6,27 @@ let mut _0: f32; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30 let mut _2: structs::U; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+6:18: +6:19 ++ let mut _4: usize; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ let mut _5: f32; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 bb0: { - StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 +- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ nop; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19 _3 = _1; // scope 0 at $DIR/sroa.rs:+6:18: +6:19 - _2 = U { _foo: const 0_usize, a: move _3 }; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 +- _2 = U { _foo: const 0_usize, a: move _3 }; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ _4 = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ _5 = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ nop; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:20: +6:21 - _0 = (_2.1: f32); // scope 0 at $DIR/sroa.rs:+6:5: +6:23 - StorageDead(_2); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 +- _0 = (_2.1: f32); // scope 0 at $DIR/sroa.rs:+6:5: +6:23 +- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 ++ _0 = _5; // scope 0 at $DIR/sroa.rs:+6:5: +6:23 ++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 ++ nop; // scope 0 at $DIR/sroa.rs:+7:1: +7:2 return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2 } } diff --git a/tests/ui/lifetimes/issue-107492-default-value-for-lifetime.rs b/tests/ui/lifetimes/issue-107492-default-value-for-lifetime.rs new file mode 100644 index 00000000000..f129035d040 --- /dev/null +++ b/tests/ui/lifetimes/issue-107492-default-value-for-lifetime.rs @@ -0,0 +1,6 @@ +pub struct DefaultLifetime<'a, 'b = 'static> { + //~^ ERROR unexpected default lifetime parameter + _marker: std::marker::PhantomData<&'a &'b ()>, +} + +fn main(){} diff --git a/tests/ui/lifetimes/issue-107492-default-value-for-lifetime.stderr b/tests/ui/lifetimes/issue-107492-default-value-for-lifetime.stderr new file mode 100644 index 00000000000..c235c31809f --- /dev/null +++ b/tests/ui/lifetimes/issue-107492-default-value-for-lifetime.stderr @@ -0,0 +1,8 @@ +error: unexpected default lifetime parameter + --> $DIR/issue-107492-default-value-for-lifetime.rs:1:35 + | +LL | pub struct DefaultLifetime<'a, 'b = 'static> { + | ^^^^^^^^^ lifetime parameters cannot have default values + +error: aborting due to previous error + diff --git a/tests/ui/suggest-null-ptr.fixed b/tests/ui/suggest-null-ptr.fixed new file mode 100644 index 00000000000..40f900c7d30 --- /dev/null +++ b/tests/ui/suggest-null-ptr.fixed @@ -0,0 +1,31 @@ +// run-rustfix + +// Suggest providing a std::ptr::null{,_mut}() to a function that takes in a raw +// pointer if a literal 0 was provided by the user. + +extern "C" { + fn foo(ptr: *const u8); + + fn foo_mut(ptr: *mut u8); + + fn usize(ptr: *const usize); + + fn usize_mut(ptr: *mut usize); +} + +fn main() { + unsafe { + foo(std::ptr::null()); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null()` + foo_mut(std::ptr::null_mut()); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null_mut()` + usize(std::ptr::null()); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null()` + usize_mut(std::ptr::null_mut()); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null_mut()` + } +} diff --git a/tests/ui/suggest-null-ptr.rs b/tests/ui/suggest-null-ptr.rs new file mode 100644 index 00000000000..19b595bf769 --- /dev/null +++ b/tests/ui/suggest-null-ptr.rs @@ -0,0 +1,31 @@ +// run-rustfix + +// Suggest providing a std::ptr::null{,_mut}() to a function that takes in a raw +// pointer if a literal 0 was provided by the user. + +extern "C" { + fn foo(ptr: *const u8); + + fn foo_mut(ptr: *mut u8); + + fn usize(ptr: *const usize); + + fn usize_mut(ptr: *mut usize); +} + +fn main() { + unsafe { + foo(0); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null()` + foo_mut(0); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null_mut()` + usize(0); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null()` + usize_mut(0); + //~^ mismatched types [E0308] + //~| if you meant to create a null pointer, use `std::ptr::null_mut()` + } +} diff --git a/tests/ui/suggest-null-ptr.stderr b/tests/ui/suggest-null-ptr.stderr new file mode 100644 index 00000000000..66a79d0749e --- /dev/null +++ b/tests/ui/suggest-null-ptr.stderr @@ -0,0 +1,83 @@ +error[E0308]: mismatched types + --> $DIR/suggest-null-ptr.rs:18:13 + | +LL | foo(0); + | --- ^ expected `*const u8`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*const u8` + found type `usize` +note: function defined here + --> $DIR/suggest-null-ptr.rs:7:8 + | +LL | fn foo(ptr: *const u8); + | ^^^ +help: if you meant to create a null pointer, use `std::ptr::null()` + | +LL | foo(std::ptr::null()); + | ~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/suggest-null-ptr.rs:21:17 + | +LL | foo_mut(0); + | ------- ^ expected `*mut u8`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*mut u8` + found type `usize` +note: function defined here + --> $DIR/suggest-null-ptr.rs:9:8 + | +LL | fn foo_mut(ptr: *mut u8); + | ^^^^^^^ +help: if you meant to create a null pointer, use `std::ptr::null_mut()` + | +LL | foo_mut(std::ptr::null_mut()); + | ~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/suggest-null-ptr.rs:24:15 + | +LL | usize(0); + | ----- ^ expected `*const usize`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*const usize` + found type `usize` +note: function defined here + --> $DIR/suggest-null-ptr.rs:11:8 + | +LL | fn usize(ptr: *const usize); + | ^^^^^ +help: if you meant to create a null pointer, use `std::ptr::null()` + | +LL | usize(std::ptr::null()); + | ~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/suggest-null-ptr.rs:27:19 + | +LL | usize_mut(0); + | --------- ^ expected `*mut usize`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*mut usize` + found type `usize` +note: function defined here + --> $DIR/suggest-null-ptr.rs:13:8 + | +LL | fn usize_mut(ptr: *mut usize); + | ^^^^^^^^^ +help: if you meant to create a null pointer, use `std::ptr::null_mut()` + | +LL | usize_mut(std::ptr::null_mut()); + | ~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.rs b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.rs new file mode 100644 index 00000000000..8ccb15ca48a --- /dev/null +++ b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.rs @@ -0,0 +1,21 @@ +// edition:2018 + +async fn hello() { //~ HELP try adding a return type + 0 + //~^ ERROR [E0308] +} + +async fn world() -> () { + 0 + //~^ ERROR [E0308] +} + +async fn suggest_await_in_async_fn_return() { + hello() + //~^ ERROR mismatched types [E0308] + //~| HELP consider `await`ing on the `Future` + //~| HELP consider using a semicolon here + //~| SUGGESTION .await +} + +fn main() {} diff --git a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr new file mode 100644 index 00000000000..6a1a9f45bc6 --- /dev/null +++ b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr @@ -0,0 +1,36 @@ +error[E0308]: mismatched types + --> $DIR/issue-90027-async-fn-return-suggestion.rs:4:5 + | +LL | async fn hello() { + | - help: try adding a return type: `-> i32` +LL | 0 + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/issue-90027-async-fn-return-suggestion.rs:9:5 + | +LL | async fn world() -> () { + | -- expected `()` because of return type +LL | 0 + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5 + | +LL | hello() + | ^^^^^^^ expected `()`, found opaque type + | + = note: expected unit type `()` + found opaque type `impl Future` +help: consider `await`ing on the `Future` + | +LL | hello().await + | ++++++ +help: consider using a semicolon here + | +LL | hello(); + | + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`.