diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 274665ccd9836..4a02e0595376b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -801,7 +801,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> { if let Some(trait_id) = tcx.trait_of_item(callee) { trace!("attempting to call a trait method"); if !self.tcx.features().const_trait_impl { - self.check_op(ops::FnCallNonConst); + self.check_op(ops::FnCallNonConst(Some((callee, substs)))); return; } @@ -857,7 +857,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> { } if !nonconst_call_permission { - self.check_op(ops::FnCallNonConst); + self.check_op(ops::FnCallNonConst(None)); return; } } @@ -926,7 +926,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> { } if !nonconst_call_permission { - self.check_op(ops::FnCallNonConst); + self.check_op(ops::FnCallNonConst(None)); return; } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 6391c88600936..421c559474a97 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -1,12 +1,14 @@ //! Concrete error types for all operations which may be invalid in a certain const context. -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_middle::mir; +use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; +use rustc_middle::{mir, ty::AssocKind}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; -use rustc_span::{Span, Symbol}; +use rustc_span::{symbol::Ident, Span, Symbol}; +use rustc_span::{BytePos, Pos}; use super::ConstCx; @@ -72,17 +74,71 @@ impl NonConstOp for FnCallIndirect { /// A function call where the callee is not marked as `const`. #[derive(Debug)] -pub struct FnCallNonConst; -impl NonConstOp for FnCallNonConst { +pub struct FnCallNonConst<'tcx>(pub Option<(DefId, SubstsRef<'tcx>)>); +impl<'a> NonConstOp for FnCallNonConst<'a> { fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + let mut err = struct_span_err!( ccx.tcx.sess, span, E0015, "calls in {}s are limited to constant functions, \ tuple structs and tuple variants", ccx.const_kind(), - ) + ); + + if let FnCallNonConst(Some((callee, substs))) = *self { + if let Some(trait_def_id) = ccx.tcx.lang_items().eq_trait() { + if let Some(eq_item) = ccx.tcx.associated_items(trait_def_id).find_by_name_and_kind( + ccx.tcx, + Ident::with_dummy_span(sym::eq), + AssocKind::Fn, + trait_def_id, + ) { + if callee == eq_item.def_id && substs.len() == 2 { + match (substs[0].unpack(), substs[1].unpack()) { + (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) + if self_ty == rhs_ty + && self_ty.is_ref() + && self_ty.peel_refs().is_primitive() => + { + let mut num_refs = 0; + let mut tmp_ty = self_ty; + while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() { + num_refs += 1; + tmp_ty = inner_ty; + } + let deref = "*".repeat(num_refs); + + if let Ok(call_str) = + ccx.tcx.sess.source_map().span_to_snippet(span) + { + if let Some(eq_idx) = call_str.find("==") { + if let Some(rhs_idx) = call_str[(eq_idx + 2)..] + .find(|c: char| !c.is_whitespace()) + { + let rhs_pos = span.lo() + + BytePos::from_usize(eq_idx + 2 + rhs_idx); + let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos); + err.multipart_suggestion( + "consider dereferencing here", + vec![ + (span.shrink_to_lo(), deref.clone()), + (rhs_span, deref), + ], + Applicability::MachineApplicable, + ); + } + } + } + } + _ => {} + } + } + } + } + } + + err } } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 1b123520961a6..5221ab4b6133a 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -402,7 +402,24 @@ impl<'a> StripUnconfigured<'a> { ); trees.push((bracket_group, Spacing::Alone)); let tokens = Some(LazyTokenStream::new(AttrAnnotatedTokenStream::new(trees))); - self.process_cfg_attr(attr::mk_attr_from_item(item, tokens, attr.style, span)) + let attr = attr::mk_attr_from_item(item, tokens, attr.style, span); + if attr.has_name(sym::crate_type) { + self.sess.parse_sess.buffer_lint( + rustc_lint_defs::builtin::DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, + attr.span, + ast::CRATE_NODE_ID, + "`crate_type` within an `#![cfg_attr] attribute is deprecated`", + ); + } + if attr.has_name(sym::crate_name) { + self.sess.parse_sess.buffer_lint( + rustc_lint_defs::builtin::DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, + attr.span, + ast::CRATE_NODE_ID, + "`crate_name` within an `#![cfg_attr] attribute is deprecated`", + ); + } + self.process_cfg_attr(attr) }) .collect() } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c1a53c34b7a24..c9294c68a7dc9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2960,6 +2960,41 @@ declare_lint! { "detects large moves or copies", } +declare_lint! { + /// The `deprecated_cfg_attr_crate_type_name` lint detects uses of the + /// `#![cfg_attr(..., crate_type = "...")]` and + /// `#![cfg_attr(..., crate_name = "...")]` attributes to conditionally + /// specify the crate type and name in the source code. + /// + /// ### Example + /// + /// ```rust + /// #![cfg_attr(debug_assertions, crate_type = "lib")] + /// ``` + /// + /// {{produces}} + /// + /// + /// ### Explanation + /// + /// The `#![crate_type]` and `#![crate_name]` attributes require a hack in + /// the compiler to be able to change the used crate type and crate name + /// after macros have been expanded. Neither attribute works in combination + /// with Cargo as it explicitly passes `--crate-type` and `--crate-name` on + /// the commandline. These values must match the value used in the source + /// code to prevent an error. + /// + /// To fix the warning use `--crate-type` on the commandline when running + /// rustc instead of `#![cfg_attr(..., crate_type = "...")]` and + /// `--crate-name` instead of `#![cfg_attr(..., crate_name = "...")]`. + pub DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, + Warn, + "detects usage of `#![cfg_attr(..., crate_type/crate_name = \"...\")]`", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #91632 ", + }; +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -3056,6 +3091,7 @@ declare_lint_pass! { NON_EXHAUSTIVE_OMITTED_PATTERNS, TEXT_DIRECTION_CODEPOINT_IN_COMMENT, DEREF_INTO_DYN_SUPERTRAIT, + DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, ] } diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 84ae2a2fbd094..28a5a22dd9d5d 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -34,7 +34,7 @@ fn is_stable(place: PlaceRef<'_>) -> bool { } /// Determine whether this type may be a reference (or box), and thus needs retagging. -fn may_be_reference(ty: Ty<'tcx>) -> bool { +fn may_be_reference(ty: Ty<'_>) -> bool { match ty.kind() { // Primitive types that are not references ty::Bool diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 6f0d03068f566..a19a3c8b1d506 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -23,7 +23,7 @@ struct ConstMutationChecker<'a, 'tcx> { target_local: Option, } -impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { +impl<'tcx> ConstMutationChecker<'_, 'tcx> { fn is_const_item(&self, local: Local) -> Option { if let Some(box LocalInfo::ConstRef { def_id }) = self.body.local_decls[local].local_info { Some(def_id) @@ -95,7 +95,7 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { } } -impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { fn visit_statement(&mut self, stmt: &Statement<'tcx>, loc: Location) { if let StatementKind::Assign(box (lhs, _)) = &stmt.kind { // Check for assignment to fields of a constant diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 31d547103095f..c6661e9c74e9b 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -66,7 +66,7 @@ fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { } } -impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { // Make sure we know where in the MIR we are. self.source_info = terminator.source_info; diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index cdfeb957df9b1..2dda19badd7c1 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } } -impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { self.source_info = terminator.source_info; match terminator.kind { @@ -244,7 +244,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } } -impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { +impl<'tcx> UnsafetyChecker<'_, 'tcx> { fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) { // Violations can turn out to be `UnsafeFn` during analysis, but they should not start out as such. assert_ne!(kind, UnsafetyViolationKind::UnsafeFn); @@ -397,7 +397,7 @@ struct UnusedUnsafeVisitor<'a> { unsafe_blocks: &'a mut Vec<(hir::HirId, bool)>, } -impl<'a, 'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'a> { +impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_> { type Map = intravisit::ErasedMap<'tcx>; fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index 3613fa4560d6c..839d94167fecd 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -89,7 +89,7 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta eligable_locals } -impl<'tcx> Visitor<'tcx> for LocalUseVisitor { +impl Visitor<'_> for LocalUseVisitor { fn visit_local(&mut self, local: &Local, context: PlaceContext, location: Location) { if context.is_mutating_use() { self.local_mutating_uses[*local] = self.local_mutating_uses[*local].saturating_add(1); diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs index 0b5b911e9a5c8..905173b045719 100644 --- a/compiler/rustc_mir_transform/src/const_goto.rs +++ b/compiler/rustc_mir_transform/src/const_goto.rs @@ -54,7 +54,7 @@ impl<'tcx> MirPass<'tcx> for ConstGoto { } } -impl<'a, 'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { let _: Option<_> = try { let target = terminator.kind.as_goto()?; diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index e3377f5953aad..e897e89982c0d 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -171,7 +171,7 @@ struct ConstPropMachine<'mir, 'tcx> { can_const_prop: IndexVec, } -impl<'mir, 'tcx> ConstPropMachine<'mir, 'tcx> { +impl ConstPropMachine<'_, '_> { fn new( only_propagate_inside_block_locals: BitSet, can_const_prop: IndexVec, @@ -308,14 +308,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> } #[inline(always)] - fn stack( + fn stack<'a>( ecx: &'a InterpCx<'mir, 'tcx, Self>, ) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>] { &ecx.machine.stack } #[inline(always)] - fn stack_mut( + fn stack_mut<'a>( ecx: &'a mut InterpCx<'mir, 'tcx, Self>, ) -> &'a mut Vec> { &mut ecx.machine.stack @@ -336,7 +336,7 @@ struct ConstPropagator<'mir, 'tcx> { source_info: Option, } -impl<'mir, 'tcx> LayoutOfHelpers<'tcx> for ConstPropagator<'mir, 'tcx> { +impl<'tcx> LayoutOfHelpers<'tcx> for ConstPropagator<'_, 'tcx> { type LayoutOfResult = Result, LayoutError<'tcx>>; #[inline] @@ -345,21 +345,21 @@ impl<'mir, 'tcx> LayoutOfHelpers<'tcx> for ConstPropagator<'mir, 'tcx> { } } -impl<'mir, 'tcx> HasDataLayout for ConstPropagator<'mir, 'tcx> { +impl HasDataLayout for ConstPropagator<'_, '_> { #[inline] fn data_layout(&self) -> &TargetDataLayout { &self.tcx.data_layout } } -impl<'mir, 'tcx> ty::layout::HasTyCtxt<'tcx> for ConstPropagator<'mir, 'tcx> { +impl<'tcx> ty::layout::HasTyCtxt<'tcx> for ConstPropagator<'_, 'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } } -impl<'mir, 'tcx> ty::layout::HasParamEnv<'tcx> for ConstPropagator<'mir, 'tcx> { +impl<'tcx> ty::layout::HasParamEnv<'tcx> for ConstPropagator<'_, 'tcx> { #[inline] fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env @@ -971,7 +971,7 @@ struct CanConstProp { impl CanConstProp { /// Returns true if `local` can be propagated - fn check( + fn check<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, body: &Body<'tcx>, @@ -1019,7 +1019,7 @@ impl CanConstProp { } } -impl<'tcx> Visitor<'tcx> for CanConstProp { +impl Visitor<'_> for CanConstProp { fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) { use rustc_middle::mir::visit::PlaceContext::*; match context { @@ -1079,7 +1079,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { } } -impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { +impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs index 513a85b591306..588103ca43dd0 100644 --- a/compiler/rustc_mir_transform/src/coverage/debug.rs +++ b/compiler/rustc_mir_transform/src/coverage/debug.rs @@ -629,7 +629,7 @@ impl UsedExpressions { } /// Generates the MIR pass `CoverageSpan`-specific spanview dump file. -pub(super) fn dump_coverage_spanview( +pub(super) fn dump_coverage_spanview<'tcx>( tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>, basic_coverage_blocks: &CoverageGraph, @@ -651,7 +651,7 @@ pub(super) fn dump_coverage_spanview( } /// Converts the computed `BasicCoverageBlockData`s into `SpanViewable`s. -fn span_viewables( +fn span_viewables<'tcx>( tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>, basic_coverage_blocks: &CoverageGraph, @@ -670,7 +670,7 @@ fn span_viewables( } /// Generates the MIR pass coverage-specific graphviz dump file. -pub(super) fn dump_coverage_graphviz( +pub(super) fn dump_coverage_graphviz<'tcx>( tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>, pass_name: &str, @@ -750,7 +750,7 @@ pub(super) fn dump_coverage_graphviz( .expect("Unexpected error writing BasicCoverageBlock graphviz DOT file"); } -fn bcb_to_string_sections( +fn bcb_to_string_sections<'tcx>( tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>, debug_counters: &DebugCounters, @@ -817,7 +817,7 @@ fn bcb_to_string_sections( /// Returns a simple string representation of a `TerminatorKind` variant, independent of any /// values it might hold. -pub(super) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { +pub(super) fn term_type(kind: &TerminatorKind<'_>) -> &'static str { match kind { TerminatorKind::Goto { .. } => "Goto", TerminatorKind::SwitchInt { .. } => "SwitchInt", diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index d78ad6ce97fa2..a25402a1ff9f5 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -27,7 +27,7 @@ pub(super) struct CoverageGraph { } impl CoverageGraph { - pub fn from_mir(mir_body: &mir::Body<'tcx>) -> Self { + pub fn from_mir(mir_body: &mir::Body<'_>) -> Self { let (bcbs, bb_to_bcb) = Self::compute_basic_coverage_blocks(mir_body); // Pre-transform MIR `BasicBlock` successors and predecessors into the BasicCoverageBlock @@ -74,7 +74,7 @@ impl CoverageGraph { } fn compute_basic_coverage_blocks( - mir_body: &mir::Body<'tcx>, + mir_body: &mir::Body<'_>, ) -> ( IndexVec, IndexVec>, @@ -267,7 +267,7 @@ impl graph::WithSuccessors for CoverageGraph { } } -impl graph::GraphPredecessors<'graph> for CoverageGraph { +impl<'graph> graph::GraphPredecessors<'graph> for CoverageGraph { type Item = BasicCoverageBlock; type Iter = std::iter::Copied>; } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index bba188bd39350..b009e2fd0e4ad 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -443,7 +443,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } fn inject_edge_counter_basic_block( - mir_body: &mut mir::Body<'tcx>, + mir_body: &mut mir::Body<'_>, from_bb: BasicBlock, to_bb: BasicBlock, ) -> BasicBlock { @@ -466,7 +466,7 @@ fn inject_edge_counter_basic_block( } fn inject_statement( - mir_body: &mut mir::Body<'tcx>, + mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb: BasicBlock, some_code_region: Option, @@ -488,7 +488,7 @@ fn inject_statement( } // Non-code expressions are injected into the coverage map, without generating executable code. -fn inject_intermediate_expression(mir_body: &mut mir::Body<'tcx>, expression: CoverageKind) { +fn inject_intermediate_expression(mir_body: &mut mir::Body<'_>, expression: CoverageKind) { debug_assert!(matches!(expression, CoverageKind::Expression { .. })); debug!(" injecting non-code expression {:?}", expression); let inject_in_bb = mir::START_BLOCK; diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 760f16eae6b1f..1721fb5cde0e8 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -137,7 +137,7 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> coverage_visitor.info } -fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { +fn covered_file_name(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if tcx.is_mir_available(def_id) { let body = mir_body(tcx, def_id); for bb_data in body.basic_blocks().iter() { diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index d13fa0729cd95..146cabf350880 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -21,7 +21,7 @@ pub(super) enum CoverageStatement { } impl CoverageStatement { - pub fn format(&self, tcx: TyCtxt<'tcx>, mir_body: &'a mir::Body<'tcx>) -> String { + pub fn format<'tcx>(&self, tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>) -> String { match *self { Self::Statement(bb, span, stmt_index) => { let stmt = &mir_body[bb].statements[stmt_index]; @@ -86,7 +86,7 @@ impl CoverageSpan { } pub fn for_statement( - statement: &Statement<'tcx>, + statement: &Statement<'_>, span: Span, expn_span: Span, bcb: BasicCoverageBlock, @@ -151,7 +151,7 @@ impl CoverageSpan { self.bcb == other.bcb } - pub fn format(&self, tcx: TyCtxt<'tcx>, mir_body: &'a mir::Body<'tcx>) -> String { + pub fn format<'tcx>(&self, tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>) -> String { format!( "{}\n {}", source_range_no_file(tcx, &self.span), @@ -159,10 +159,10 @@ impl CoverageSpan { ) } - pub fn format_coverage_statements( + pub fn format_coverage_statements<'tcx>( &self, tcx: TyCtxt<'tcx>, - mir_body: &'a mir::Body<'tcx>, + mir_body: &mir::Body<'tcx>, ) -> String { let mut sorted_coverage_statements = self.coverage_statements.clone(); sorted_coverage_statements.sort_unstable_by_key(|covstmt| match *covstmt { @@ -803,7 +803,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { /// If the MIR `Statement` has a span contributive to computing coverage spans, /// return it; otherwise return `None`. -pub(super) fn filtered_statement_span(statement: &'a Statement<'tcx>) -> Option { +pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option { match statement.kind { // These statements have spans that are often outside the scope of the executed source code // for their parent `BasicBlock`. @@ -847,7 +847,7 @@ pub(super) fn filtered_statement_span(statement: &'a Statement<'tcx>) -> Option< /// If the MIR `Terminator` has a span contributive to computing coverage spans, /// return it; otherwise return `None`. -pub(super) fn filtered_terminator_span(terminator: &'a Terminator<'tcx>) -> Option { +pub(super) fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { match terminator.kind { // These terminators have spans that don't positively contribute to computing a reasonable // span of actually executed source code. (For example, SwitchInt terminators extracted from diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 14dd0a8b9245b..b9c79d4cf2db8 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -180,7 +180,7 @@ impl<'tcx> MockBlocks<'tcx> { } } -fn debug_basic_blocks(mir_body: &Body<'tcx>) -> String { +fn debug_basic_blocks<'tcx>(mir_body: &Body<'tcx>) -> String { format!( "{:?}", mir_body @@ -273,7 +273,7 @@ fn print_coverage_graphviz( } /// Create a mock `Body` with a simple flow. -fn goto_switchint() -> Body<'a> { +fn goto_switchint<'a>() -> Body<'a> { let mut blocks = MockBlocks::new(); let start = blocks.call(None); let goto = blocks.goto(Some(start)); @@ -363,7 +363,7 @@ fn test_covgraph_goto_switchint() { } /// Create a mock `Body` with a loop. -fn switchint_then_loop_else_return() -> Body<'a> { +fn switchint_then_loop_else_return<'a>() -> Body<'a> { let mut blocks = MockBlocks::new(); let start = blocks.call(None); let switchint = blocks.switchint(Some(start)); @@ -449,7 +449,7 @@ fn test_covgraph_switchint_then_loop_else_return() { } /// Create a mock `Body` with nested loops. -fn switchint_loop_then_inner_loop_else_break() -> Body<'a> { +fn switchint_loop_then_inner_loop_else_break<'a>() -> Body<'a> { let mut blocks = MockBlocks::new(); let start = blocks.call(None); let switchint = blocks.switchint(Some(start)); diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs index 993c8eef711ce..d1977ed49fe15 100644 --- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs +++ b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs @@ -54,7 +54,7 @@ impl<'tcx> MutVisitor<'tcx> for OptApplier<'tcx> { } } -fn find_duplicates<'a, 'tcx>(body: &'a Body<'tcx>) -> FxHashMap { +fn find_duplicates(body: &Body<'_>) -> FxHashMap { let mut duplicates = FxHashMap::default(); let bbs_to_go_through = @@ -102,7 +102,7 @@ struct BasicBlockHashable<'tcx, 'a> { basic_block_data: &'a BasicBlockData<'tcx>, } -impl<'tcx, 'a> Hash for BasicBlockHashable<'tcx, 'a> { +impl Hash for BasicBlockHashable<'_, '_> { fn hash(&self, state: &mut H) { hash_statements(state, self.basic_block_data.statements.iter()); // Note that since we only hash the kind, we lose span information if we deduplicate the blocks @@ -110,9 +110,9 @@ impl<'tcx, 'a> Hash for BasicBlockHashable<'tcx, 'a> { } } -impl<'tcx, 'a> Eq for BasicBlockHashable<'tcx, 'a> {} +impl Eq for BasicBlockHashable<'_, '_> {} -impl<'tcx, 'a> PartialEq for BasicBlockHashable<'tcx, 'a> { +impl PartialEq for BasicBlockHashable<'_, '_> { fn eq(&self, other: &Self) -> bool { self.basic_block_data.statements.len() == other.basic_block_data.statements.len() && &self.basic_block_data.terminator().kind == &other.basic_block_data.terminator().kind @@ -132,7 +132,7 @@ fn hash_statements<'a, 'tcx, H: Hasher>( } } -fn statement_hash<'tcx, H: Hasher>(hasher: &mut H, stmt: &StatementKind<'tcx>) { +fn statement_hash(hasher: &mut H, stmt: &StatementKind<'_>) { match stmt { StatementKind::Assign(box (place, rvalue)) => { place.hash(hasher); @@ -142,14 +142,14 @@ fn statement_hash<'tcx, H: Hasher>(hasher: &mut H, stmt: &StatementKind<'tcx>) { }; } -fn rvalue_hash(hasher: &mut H, rvalue: &Rvalue<'tcx>) { +fn rvalue_hash(hasher: &mut H, rvalue: &Rvalue<'_>) { match rvalue { Rvalue::Use(op) => operand_hash(hasher, op), x => x.hash(hasher), }; } -fn operand_hash(hasher: &mut H, operand: &Operand<'tcx>) { +fn operand_hash(hasher: &mut H, operand: &Operand<'_>) { match operand { Operand::Constant(box Constant { user_ty: _, literal, span: _ }) => literal.hash(hasher), x => x.hash(hasher), @@ -168,7 +168,7 @@ fn statement_eq<'tcx>(lhs: &StatementKind<'tcx>, rhs: &StatementKind<'tcx>) -> b res } -fn rvalue_eq(lhs: &Rvalue<'tcx>, rhs: &Rvalue<'tcx>) -> bool { +fn rvalue_eq<'tcx>(lhs: &Rvalue<'tcx>, rhs: &Rvalue<'tcx>) -> bool { let res = match (lhs, rhs) { (Rvalue::Use(op1), Rvalue::Use(op2)) => operand_eq(op1, op2), (x, y) => x == y, @@ -177,7 +177,7 @@ fn rvalue_eq(lhs: &Rvalue<'tcx>, rhs: &Rvalue<'tcx>) -> bool { res } -fn operand_eq(lhs: &Operand<'tcx>, rhs: &Operand<'tcx>) -> bool { +fn operand_eq<'tcx>(lhs: &Operand<'tcx>, rhs: &Operand<'tcx>) -> bool { let res = match (lhs, rhs) { ( Operand::Constant(box Constant { user_ty: _, literal, span: _ }), diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 256f7fbd75923..2b382468be0f5 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -241,7 +241,7 @@ struct Replacements<'tcx> { kill: BitSet, } -impl Replacements<'tcx> { +impl<'tcx> Replacements<'tcx> { fn new(locals: usize) -> Self { Self { map: IndexVec::from_elem_n(None, locals), kill: BitSet::new_empty(locals) } } @@ -298,7 +298,7 @@ struct Replacer<'tcx> { } impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -372,7 +372,7 @@ struct Conflicts<'a> { unified_locals: InPlaceUnificationTable, } -impl Conflicts<'a> { +impl<'a> Conflicts<'a> { fn build<'tcx>( tcx: TyCtxt<'tcx>, body: &'_ Body<'tcx>, @@ -820,10 +820,7 @@ struct CandidateAssignment<'tcx> { /// comment) and also throw out assignments that involve a local that has its address taken or is /// otherwise ineligible (eg. locals used as array indices are ignored because we cannot propagate /// arbitrary places into array indices). -fn find_candidates<'a, 'tcx>( - tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, -) -> Vec> { +fn find_candidates<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> Vec> { let mut visitor = FindAssignments { tcx, body, @@ -843,7 +840,7 @@ struct FindAssignments<'a, 'tcx> { locals_used_as_array_index: BitSet, } -impl<'a, 'tcx> Visitor<'tcx> for FindAssignments<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { if let StatementKind::Assign(box ( dest, diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 62e82aca26207..ac88060f0d349 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -167,7 +167,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { } } -fn is_switch<'tcx>(terminator: &Terminator<'tcx>) -> bool { +fn is_switch(terminator: &Terminator<'_>) -> bool { matches!(terminator.kind, TerminatorKind::SwitchInt { .. }) } @@ -208,7 +208,7 @@ struct OptimizationInfo<'tcx> { second_switch_info: SwitchDiscriminantInfo<'tcx>, } -impl<'a, 'tcx> Helper<'a, 'tcx> { +impl<'tcx> Helper<'_, 'tcx> { pub fn go( &self, bb: &BasicBlockData<'tcx>, diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index af13c734e5b9a..d346dfb177219 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -149,13 +149,13 @@ struct Elaborator<'a, 'b, 'tcx> { ctxt: &'a mut ElaborateDropsCtxt<'b, 'tcx>, } -impl<'a, 'b, 'tcx> fmt::Debug for Elaborator<'a, 'b, 'tcx> { +impl fmt::Debug for Elaborator<'_, '_, '_> { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } } -impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { +impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { type Path = MovePathIndex; fn patch(&mut self) -> &mut MirPatch<'tcx> { diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index c05dc39afc47e..05834b443d0d9 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -27,7 +27,7 @@ struct FunctionItemRefChecker<'a, 'tcx> { body: &'a Body<'tcx>, } -impl<'a, 'tcx> Visitor<'tcx> for FunctionItemRefChecker<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { /// Emits a lint for function reference arguments bound by `fmt::Pointer` or passed to /// `transmute`. This only handles arguments in calls outside macro expansions to avoid double /// counting function references formatted as pointers by macros. @@ -92,7 +92,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FunctionItemRefChecker<'a, 'tcx> { } } -impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> { +impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { /// Emits a lint for function reference arguments bound by `fmt::Pointer` in calls to the /// function defined by `def_id` with the substitutions `substs_ref`. fn check_bound_args( diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 5376855035e71..6220cee8d2162 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -233,7 +233,7 @@ struct TransformVisitor<'tcx> { new_ret_local: Local, } -impl TransformVisitor<'tcx> { +impl<'tcx> TransformVisitor<'tcx> { // Make a GeneratorState variant assignment. `core::ops::GeneratorState` only has single // element tuple variants, so we can just write to the downcasted first field and then set the // discriminant to the appropriate variant. @@ -295,7 +295,7 @@ impl TransformVisitor<'tcx> { } } -impl MutVisitor<'tcx> for TransformVisitor<'tcx> { +impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -446,7 +446,7 @@ struct LivenessInfo { storage_liveness: IndexVec>>, } -fn locals_live_across_suspend_points( +fn locals_live_across_suspend_points<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, always_live_locals: &storage::AlwaysLiveLocals, @@ -613,7 +613,7 @@ impl ops::Deref for GeneratorSavedLocals { /// time. Generates a bitset for every local of all the other locals that may be /// StorageLive simultaneously with that local. This is used in the layout /// computation; see `GeneratorLayout` for more. -fn compute_storage_conflicts( +fn compute_storage_conflicts<'mir, 'tcx>( body: &'mir Body<'tcx>, saved_locals: &GeneratorSavedLocals, always_live_locals: storage::AlwaysLiveLocals, @@ -672,7 +672,9 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> { local_conflicts: BitMatrix, } -impl rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx> for StorageConflictVisitor<'mir, 'tcx, '_> { +impl<'mir, 'tcx> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx> + for StorageConflictVisitor<'mir, 'tcx, '_> +{ type FlowState = BitSet; fn visit_statement_before_primary_effect( @@ -694,7 +696,7 @@ impl rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx> for StorageConflictVisitor<' } } -impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> { +impl StorageConflictVisitor<'_, '_, '_> { fn apply_state(&mut self, flow_state: &BitSet, loc: Location) { // Ignore unreachable blocks. if self.body.basic_blocks()[loc.block].terminator().kind == TerminatorKind::Unreachable { @@ -1398,7 +1400,7 @@ impl EnsureGeneratorFieldAssignmentsNeverAlias<'_> { self.saved_locals.get(place.local) } - fn check_assigned_place(&mut self, place: Place<'tcx>, f: impl FnOnce(&mut Self)) { + fn check_assigned_place(&mut self, place: Place<'_>, f: impl FnOnce(&mut Self)) { if let Some(assigned_local) = self.saved_local_for_direct_place(place) { assert!(self.assigned_local.is_none(), "`check_assigned_place` must not recurse"); @@ -1409,7 +1411,7 @@ impl EnsureGeneratorFieldAssignmentsNeverAlias<'_> { } } -impl Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { +impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { let lhs = match self.assigned_local { Some(l) => l, diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 81454cc4070bd..558b1ce082e40 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -57,7 +57,7 @@ impl<'tcx> MirPass<'tcx> for Inline { } } -fn inline(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { +fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { let def_id = body.source.def_id(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); @@ -95,7 +95,7 @@ struct Inliner<'tcx> { changed: bool, } -impl Inliner<'tcx> { +impl<'tcx> Inliner<'tcx> { fn process_blocks(&mut self, caller_body: &mut Body<'tcx>, blocks: Range) { for bb in blocks { let bb_data = &caller_body[bb]; @@ -786,7 +786,7 @@ struct Integrator<'a, 'tcx> { always_live_locals: BitSet, } -impl<'a, 'tcx> Integrator<'a, 'tcx> { +impl Integrator<'_, '_> { fn map_local(&self, local: Local) -> Local { let new = if local == RETURN_PLACE { self.destination.local @@ -815,7 +815,7 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { } } -impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { +impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 385394ba67d4d..747e760a18b92 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -10,7 +10,7 @@ use rustc_session::Limit; // FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking // this query riddiculously often. #[instrument(level = "debug", skip(tcx, root, target))] -crate fn mir_callgraph_reachable( +crate fn mir_callgraph_reachable<'tcx>( tcx: TyCtxt<'tcx>, (root, target): (ty::Instance<'tcx>, LocalDefId), ) -> bool { @@ -33,7 +33,7 @@ crate fn mir_callgraph_reachable( level = "debug", skip(tcx, param_env, target, stack, seen, recursion_limiter, caller, recursion_limit) )] - fn process( + fn process<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, caller: ty::Instance<'tcx>, diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index c5adc241664d2..792ac68671efb 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -38,7 +38,7 @@ struct InstCombineContext<'tcx, 'a> { local_decls: &'a LocalDecls<'tcx>, } -impl<'tcx, 'a> InstCombineContext<'tcx, 'a> { +impl<'tcx> InstCombineContext<'tcx, '_> { fn should_combine(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { self.tcx.consider_optimizing(|| { format!("InstCombine - Rvalue: {:?} SourceInfo: {:?}", rvalue, source_info) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index a7e003a55b400..0e7488aa98eee 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,7 +1,6 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(in_band_lifetimes)] #![feature(iter_zip)] #![feature(let_else)] #![feature(map_try_insert)] @@ -150,7 +149,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxHashSet { tcx: TyCtxt<'tcx>, set: &'a mut FxHashSet, } - impl<'a, 'tcx> Visitor<'tcx> for GatherCtors<'a, 'tcx> { + impl<'tcx> Visitor<'tcx> for GatherCtors<'_, 'tcx> { fn visit_variant_data( &mut self, v: &'tcx hir::VariantData<'tcx>, @@ -243,7 +242,7 @@ fn mir_const<'tcx>( } /// Compute the main MIR body and the list of MIR bodies of the promoteds. -fn mir_promoted( +fn mir_promoted<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, ) -> (&'tcx Steal>, &'tcx Steal>>) { @@ -480,8 +479,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // FIXME(#70073): This pass is responsible for both optimization as well as some lints. &const_prop::ConstProp, // - // FIXME: The old pass manager ran this only at mir-opt-level >= 1, but - // const-prop runs unconditionally. Should this run unconditionally as well? + // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0. &o1(simplify_branches::SimplifyConstCondition::new("after-const-prop")), &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 5848163af72fc..4c4497ad629da 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -135,7 +135,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } -fn resolve_rust_intrinsic( +fn resolve_rust_intrinsic<'tcx>( tcx: TyCtxt<'tcx>, func_ty: Ty<'tcx>, ) -> Option<(Symbol, SubstsRef<'tcx>)> { @@ -148,7 +148,7 @@ fn resolve_rust_intrinsic( None } -fn validate_simd_shuffle(tcx: TyCtxt<'tcx>, args: &[Operand<'tcx>], span: Span) { +fn validate_simd_shuffle<'tcx>(tcx: TyCtxt<'tcx>, args: &[Operand<'tcx>], span: Span) { match &args[2] { Operand::Constant(_) => {} // all good _ => { diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index 0fd9e0352a249..e4ac57ac92508 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -85,7 +85,7 @@ struct Patcher<'a, 'tcx> { statement_idx: usize, } -impl<'a, 'tcx> Patcher<'a, 'tcx> { +impl<'tcx> Patcher<'_, 'tcx> { fn patch_expand_statement( &mut self, statement: &mut Statement<'tcx>, diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 88ec34b73ec40..797f7ee2685b8 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -165,7 +165,7 @@ struct RenameToReturnPlace<'tcx> { } /// Replaces all uses of `self.to_rename` with `_0`. -impl MutVisitor<'tcx> for RenameToReturnPlace<'tcx> { +impl<'tcx> MutVisitor<'tcx> for RenameToReturnPlace<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -221,7 +221,7 @@ impl IsReturnPlaceRead { } } -impl Visitor<'tcx> for IsReturnPlaceRead { +impl<'tcx> Visitor<'tcx> for IsReturnPlaceRead { fn visit_local(&mut self, &l: &Local, ctxt: PlaceContext, _: Location) { if l == mir::RETURN_PLACE && ctxt.is_use() && !ctxt.is_place_assignment() { self.0 = true; diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 729b8cae5e47a..8725eae870917 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -28,7 +28,7 @@ pub trait MirLint<'tcx> { #[derive(Debug, Clone)] pub struct Lint(pub T); -impl MirPass<'tcx> for Lint +impl<'tcx, T> MirPass<'tcx> for Lint where T: MirLint<'tcx>, { @@ -51,7 +51,7 @@ where pub struct WithMinOptLevel(pub u32, pub T); -impl MirPass<'tcx> for WithMinOptLevel +impl<'tcx, T> MirPass<'tcx> for WithMinOptLevel where T: MirPass<'tcx>, { @@ -72,7 +72,7 @@ where } } -pub fn run_passes(tcx: TyCtxt<'tcx>, body: &'mir mut Body<'tcx>, passes: &[&dyn MirPass<'tcx>]) { +pub fn run_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, passes: &[&dyn MirPass<'tcx>]) { let start_phase = body.phase; let mut cnt = 0; @@ -119,11 +119,11 @@ pub fn run_passes(tcx: TyCtxt<'tcx>, body: &'mir mut Body<'tcx>, passes: &[&dyn } } -pub fn validate_body(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) { +pub fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) { validate::Validator { when, mir_phase: body.phase }.run_pass(tcx, body); } -pub fn dump_mir( +pub fn dump_mir<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, phase: MirPhase, diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index c219f26732441..fc5ac97e3e1dc 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -86,7 +86,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { } } -fn is_needs_drop_and_init( +fn is_needs_drop_and_init<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, maybe_inits: &BitSet, @@ -158,7 +158,7 @@ fn is_needs_drop_and_init( } } -fn variant_needs_drop( +fn variant_needs_drop<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, substs: SubstsRef<'tcx>, diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index 8b64ad65ab35c..80c87cafea101 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -12,7 +12,7 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { } } -impl<'a, 'tcx> Visitor<'tcx> for RequiredConstsVisitor<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) { if let Some(ct) = constant.literal.const_for_ty() { if let ConstKind::Unevaluated(_) = ct.val { diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index 7450d53ba717e..612fce71f9167 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -59,7 +59,7 @@ impl<'tcx> MirPass<'tcx> for SeparateConstSwitch { } /// Returns the amount of blocks that were duplicated -pub fn separate_const_switch<'tcx>(body: &mut Body<'tcx>) -> usize { +pub fn separate_const_switch(body: &mut Body<'_>) -> usize { let mut new_blocks: SmallVec<[(BasicBlock, BasicBlock); 6]> = SmallVec::new(); let predecessors = body.predecessors(); 'block_iter: for (block_id, block) in body.basic_blocks().iter_enumerated() { diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 193a9e6ad291f..d003938036144 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -64,7 +64,19 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) } - ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty), + + ty::InstanceDef::DropGlue(def_id, ty) => { + // FIXME(#91576): Drop shims for generators aren't subject to the MIR passes at the end + // of this function. Is this intentional? + if let Some(ty::Generator(gen_def_id, substs, _)) = ty.map(ty::TyS::kind) { + let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap(); + let body = body.clone().subst(tcx, substs); + debug!("make_shim({:?}) = {:?}", instance, body); + return body; + } + + build_drop_shim(tcx, def_id, ty) + } ty::InstanceDef::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), ty::InstanceDef::Virtual(..) => { bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance) @@ -75,14 +87,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' }; debug!("make_shim({:?}) = untransformed {:?}", instance, result); - // In some of the above cases, we seem to be invoking the passes for non-shim MIR bodies. - // If that happens, there's no need to run them again. - // - // FIXME: Is this intentional? - if result.phase >= MirPhase::Const { - return result; - } - pm::run_passes( tcx, &mut result, @@ -140,11 +144,7 @@ fn local_decls_for_sig<'tcx>( fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) -> Body<'tcx> { debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty); - // Check if this is a generator, if so, return the drop glue for it - if let Some(&ty::Generator(gen_def_id, substs, _)) = ty.map(|ty| ty.kind()) { - let body = tcx.optimized_mir(gen_def_id).generator_drop().unwrap(); - return body.clone().subst(tcx, substs); - } + assert!(!matches!(ty, Some(ty) if ty.is_generator())); let substs = if let Some(ty) = ty { tcx.intern_substs(&[ty.into()]) @@ -247,7 +247,7 @@ pub struct DropShimElaborator<'a, 'tcx> { pub param_env: ty::ParamEnv<'tcx>, } -impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> { +impl fmt::Debug for DropShimElaborator<'_, '_> { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { Ok(()) } @@ -337,7 +337,7 @@ struct CloneShimBuilder<'tcx> { sig: ty::FnSig<'tcx>, } -impl CloneShimBuilder<'tcx> { +impl<'tcx> CloneShimBuilder<'tcx> { fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Self { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 677869a0bdb6a..7992124bacd43 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -47,7 +47,7 @@ impl SimplifyCfg { } } -pub fn simplify_cfg(tcx: TyCtxt<'tcx>, body: &mut Body<'_>) { +pub fn simplify_cfg<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { CfgSimplifier::new(body).simplify(); remove_dead_blocks(tcx, body); @@ -262,7 +262,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } -pub fn remove_dead_blocks(tcx: TyCtxt<'tcx>, body: &mut Body<'_>) { +pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let reachable = traversal::reachable_as_bitset(body); let num_blocks = body.basic_blocks().len(); if num_blocks == reachable.count() { @@ -454,7 +454,7 @@ impl UsedLocals { } /// Updates the use counts to reflect the removal of given statement. - fn statement_removed(&mut self, statement: &Statement<'tcx>) { + fn statement_removed(&mut self, statement: &Statement<'_>) { self.increment = false; // The location of the statement is irrelevant. @@ -463,7 +463,7 @@ impl UsedLocals { } /// Visits a left-hand side of an assignment. - fn visit_lhs(&mut self, place: &Place<'tcx>, location: Location) { + fn visit_lhs(&mut self, place: &Place<'_>, location: Location) { if place.is_indirect() { // A use, not a definition. self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), location); @@ -480,7 +480,7 @@ impl UsedLocals { } } -impl Visitor<'_> for UsedLocals { +impl<'tcx> Visitor<'tcx> for UsedLocals { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { match statement.kind { StatementKind::LlvmInlineAsm(..) @@ -518,7 +518,7 @@ impl Visitor<'_> for UsedLocals { } /// Removes unused definitions. Updates the used locals to reflect the changes made. -fn remove_unused_definitions<'a, 'tcx>(used_locals: &'a mut UsedLocals, body: &mut Body<'tcx>) { +fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>) { // The use counts are updated as we remove the statements. A local might become unused // during the retain operation, leading to a temporary inconsistency (storage statements or // definitions referencing the local might remain). For correctness it is crucial that this diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 3bd68e8210d5b..da683a33651d6 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -148,7 +148,7 @@ struct OptimizationFinder<'a, 'tcx> { body: &'a Body<'tcx>, } -impl<'a, 'tcx> OptimizationFinder<'a, 'tcx> { +impl<'tcx> OptimizationFinder<'_, 'tcx> { fn find_optimizations(&self) -> Vec> { self.body .basic_blocks() diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs index e436d73226a55..7761d4006d3db 100644 --- a/compiler/rustc_mir_transform/src/simplify_try.rs +++ b/compiler/rustc_mir_transform/src/simplify_try.rs @@ -102,7 +102,7 @@ fn get_arm_identity_info<'a, 'tcx>( type StmtIter<'a, 'tcx> = Peekable>>>; - fn is_storage_stmt<'tcx>(stmt: &Statement<'tcx>) -> bool { + fn is_storage_stmt(stmt: &Statement<'_>) -> bool { matches!(stmt.kind, StatementKind::StorageLive(_) | StatementKind::StorageDead(_)) } @@ -122,8 +122,8 @@ fn get_arm_identity_info<'a, 'tcx>( /// Eats consecutive `StorageLive` and `StorageDead` Statements. /// The iterator `stmt_iter` is not advanced if none were found. - fn try_eat_storage_stmts<'a, 'tcx>( - stmt_iter: &mut StmtIter<'a, 'tcx>, + fn try_eat_storage_stmts( + stmt_iter: &mut StmtIter<'_, '_>, storage_live_stmts: &mut Vec<(usize, Local)>, storage_dead_stmts: &mut Vec<(usize, Local)>, ) { @@ -136,7 +136,7 @@ fn get_arm_identity_info<'a, 'tcx>( }) } - fn is_tmp_storage_stmt<'tcx>(stmt: &Statement<'tcx>) -> bool { + fn is_tmp_storage_stmt(stmt: &Statement<'_>) -> bool { use rustc_middle::mir::StatementKind::Assign; if let Assign(box (place, Rvalue::Use(Operand::Copy(p) | Operand::Move(p)))) = &stmt.kind { place.as_local().is_some() && p.as_local().is_some() @@ -147,8 +147,8 @@ fn get_arm_identity_info<'a, 'tcx>( /// Eats consecutive `Assign` Statements. // The iterator `stmt_iter` is not advanced if none were found. - fn try_eat_assign_tmp_stmts<'a, 'tcx>( - stmt_iter: &mut StmtIter<'a, 'tcx>, + fn try_eat_assign_tmp_stmts( + stmt_iter: &mut StmtIter<'_, '_>, tmp_assigns: &mut Vec<(Local, Local)>, nop_stmts: &mut Vec, ) { @@ -163,9 +163,9 @@ fn get_arm_identity_info<'a, 'tcx>( }) } - fn find_storage_live_dead_stmts_for_local<'tcx>( + fn find_storage_live_dead_stmts_for_local( local: Local, - stmts: &[Statement<'tcx>], + stmts: &[Statement<'_>], ) -> Option<(usize, usize)> { trace!("looking for {:?}", local); let mut storage_live_stmt = None; @@ -452,14 +452,14 @@ struct LocalUseCounter { } impl LocalUseCounter { - fn get_local_uses<'tcx>(body: &Body<'tcx>) -> IndexVec { + fn get_local_uses(body: &Body<'_>) -> IndexVec { let mut counter = LocalUseCounter { local_uses: IndexVec::from_elem(0, &body.local_decls) }; counter.visit_body(body); counter.local_uses } } -impl<'tcx> Visitor<'tcx> for LocalUseCounter { +impl Visitor<'_> for LocalUseCounter { fn visit_local(&mut self, local: &Local, context: PlaceContext, _location: Location) { if context.is_storage_marker() || context == PlaceContext::NonUse(NonUseContext::VarDebugInfo) @@ -510,7 +510,7 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local /// ```rust /// discriminant(_LOCAL_TO_SET) = VAR_IDX; /// ``` -fn match_set_discr<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, VariantIdx)> { +fn match_set_discr(stmt: &Statement<'_>) -> Option<(Local, VariantIdx)> { match &stmt.kind { StatementKind::SetDiscriminant { place, variant_index } => { Some((place.as_local()?, *variant_index)) @@ -588,7 +588,7 @@ struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> { tcx: TyCtxt<'tcx>, } -impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> { +impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> { fn find(&self) -> Vec { self.body .basic_blocks() diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 37071ba611708..9e755ab141a48 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -64,7 +64,7 @@ impl MirPass<'_> for UnreachablePropagation { } } -fn remove_successors( +fn remove_successors<'tcx, F>( terminator_kind: &TerminatorKind<'tcx>, predicate: F, ) -> Option> diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index b402b8ba53ada..ca92d6b7fd04d 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,4 +1,4 @@ -use super::{AttrWrapper, Capturing, ForceCollect, Parser, PathStyle}; +use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle}; use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Nonterminal}; @@ -177,7 +177,7 @@ impl<'a> Parser<'a> { AttrWrapper::empty(), true, false, - |_| true, + FnParseMode { req_name: |_| true, req_body: true }, ForceCollect::No, ) { Ok(Some(item)) => { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 55af2c9ddd32f..8e2e6eaee58ef 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1129,7 +1129,8 @@ impl<'a> Parser<'a> { } pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { - if self.eat(&token::Semi) { + if self.token.kind == TokenKind::Semi { + self.bump(); let mut err = self.struct_span_err(self.prev_token.span, "expected item, found `;`"); err.span_suggestion_short( self.prev_token.span, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index cbeaf675be4e5..831c64e3faf03 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -78,16 +78,17 @@ pub(super) type ItemInfo = (Ident, ItemKind); impl<'a> Parser<'a> { pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option>> { - self.parse_item_(|_| true, force_collect).map(|i| i.map(P)) + let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; + self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(P)) } fn parse_item_( &mut self, - req_name: ReqName, + fn_parse_mode: FnParseMode, force_collect: ForceCollect, ) -> PResult<'a, Option> { let attrs = self.parse_outer_attributes()?; - self.parse_item_common(attrs, true, false, req_name, force_collect) + self.parse_item_common(attrs, true, false, fn_parse_mode, force_collect) } pub(super) fn parse_item_common( @@ -95,7 +96,7 @@ impl<'a> Parser<'a> { attrs: AttrWrapper, mac_allowed: bool, attrs_allowed: bool, - req_name: ReqName, + fn_parse_mode: FnParseMode, force_collect: ForceCollect, ) -> PResult<'a, Option> { // Don't use `maybe_whole` so that we have precise control @@ -113,7 +114,8 @@ impl<'a> Parser<'a> { let mut unclosed_delims = vec![]; let item = self.collect_tokens_trailing_token(attrs, force_collect, |this: &mut Self, attrs| { - let item = this.parse_item_common_(attrs, mac_allowed, attrs_allowed, req_name); + let item = + this.parse_item_common_(attrs, mac_allowed, attrs_allowed, fn_parse_mode); unclosed_delims.append(&mut this.unclosed_delims); Ok((item?, TrailingToken::None)) })?; @@ -127,12 +129,13 @@ impl<'a> Parser<'a> { mut attrs: Vec, mac_allowed: bool, attrs_allowed: bool, - req_name: ReqName, + fn_parse_mode: FnParseMode, ) -> PResult<'a, Option> { let lo = self.token.span; let vis = self.parse_visibility(FollowedByType::No)?; let mut def = self.parse_defaultness(); - let kind = self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, req_name)?; + let kind = + self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, fn_parse_mode)?; if let Some((ident, kind)) = kind { self.error_on_unconsumed_default(def, &kind); let span = lo.to(self.prev_token.span); @@ -192,7 +195,7 @@ impl<'a> Parser<'a> { lo: Span, vis: &Visibility, def: &mut Defaultness, - req_name: ReqName, + fn_parse_mode: FnParseMode, ) -> PResult<'a, Option> { let def_final = def == &Defaultness::Final; let mut def = || mem::replace(def, Defaultness::Final); @@ -219,7 +222,7 @@ impl<'a> Parser<'a> { (Ident::empty(), ItemKind::Use(tree)) } else if self.check_fn_front_matter(def_final) { // FUNCTION ITEM - let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?; + let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo)?; (ident, ItemKind::Fn(Box::new(Fn { defaultness: def(), sig, generics, body }))) } else if self.eat_keyword(kw::Extern) { if self.eat_keyword(kw::Crate) { @@ -733,23 +736,26 @@ impl<'a> Parser<'a> { &mut self, force_collect: ForceCollect, ) -> PResult<'a, Option>>> { - self.parse_assoc_item(|_| true, force_collect) + let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; + self.parse_assoc_item(fn_parse_mode, force_collect) } pub fn parse_trait_item( &mut self, force_collect: ForceCollect, ) -> PResult<'a, Option>>> { - self.parse_assoc_item(|edition| edition >= Edition::Edition2018, force_collect) + let fn_parse_mode = + FnParseMode { req_name: |edition| edition >= Edition::Edition2018, req_body: false }; + self.parse_assoc_item(fn_parse_mode, force_collect) } /// Parses associated items. fn parse_assoc_item( &mut self, - req_name: ReqName, + fn_parse_mode: FnParseMode, force_collect: ForceCollect, ) -> PResult<'a, Option>>> { - Ok(self.parse_item_(req_name, force_collect)?.map( + Ok(self.parse_item_(fn_parse_mode, force_collect)?.map( |Item { attrs, id, span, vis, ident, kind, tokens }| { let kind = match AssocItemKind::try_from(kind) { Ok(kind) => kind, @@ -944,7 +950,8 @@ impl<'a> Parser<'a> { &mut self, force_collect: ForceCollect, ) -> PResult<'a, Option>>> { - Ok(self.parse_item_(|_| true, force_collect)?.map( + let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false }; + Ok(self.parse_item_(fn_parse_mode, force_collect)?.map( |Item { attrs, id, span, vis, ident, kind, tokens }| { let kind = match ForeignItemKind::try_from(kind) { Ok(kind) => kind, @@ -1484,7 +1491,8 @@ impl<'a> Parser<'a> { if !is_raw && ident.is_reserved() { let err = if self.check_fn_front_matter(false) { // We use `parse_fn` to get a span for the function - if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) { + let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; + if let Err(mut db) = self.parse_fn(&mut Vec::new(), fn_parse_mode, lo) { db.delay_as_bug(); } let mut err = self.struct_span_err( @@ -1698,25 +1706,82 @@ impl<'a> Parser<'a> { /// The parsing configuration used to parse a parameter list (see `parse_fn_params`). /// /// The function decides if, per-parameter `p`, `p` must have a pattern or just a type. +/// +/// This function pointer accepts an edition, because in edition 2015, trait declarations +/// were allowed to omit parameter names. In 2018, they became required. type ReqName = fn(Edition) -> bool; +/// Parsing configuration for functions. +/// +/// The syntax of function items is slightly different within trait definitions, +/// impl blocks, and modules. It is still parsed using the same code, just with +/// different flags set, so that even when the input is wrong and produces a parse +/// error, it still gets into the AST and the rest of the parser and +/// type checker can run. +#[derive(Clone, Copy)] +pub(crate) struct FnParseMode { + /// A function pointer that decides if, per-parameter `p`, `p` must have a + /// pattern or just a type. This field affects parsing of the parameters list. + /// + /// ```text + /// fn foo(alef: A) -> X { X::new() } + /// -----^^ affects parsing this part of the function signature + /// | + /// if req_name returns false, then this name is optional + /// + /// fn bar(A) -> X; + /// ^ + /// | + /// if req_name returns true, this is an error + /// ``` + /// + /// Calling this function pointer should only return false if: + /// + /// * The item is being parsed inside of a trait definition. + /// Within an impl block or a module, it should always evaluate + /// to true. + /// * The span is from Edition 2015. In particular, you can get a + /// 2015 span inside a 2021 crate using macros. + pub req_name: ReqName, + /// If this flag is set to `true`, then plain, semicolon-terminated function + /// prototypes are not allowed here. + /// + /// ```text + /// fn foo(alef: A) -> X { X::new() } + /// ^^^^^^^^^^^^ + /// | + /// this is always allowed + /// + /// fn bar(alef: A, bet: B) -> X; + /// ^ + /// | + /// if req_body is set to true, this is an error + /// ``` + /// + /// This field should only be set to false if the item is inside of a trait + /// definition or extern block. Within an impl block or a module, it should + /// always be set to true. + pub req_body: bool, +} + /// Parsing of functions and methods. impl<'a> Parser<'a> { /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`. fn parse_fn( &mut self, attrs: &mut Vec, - req_name: ReqName, + fn_parse_mode: FnParseMode, sig_lo: Span, ) -> PResult<'a, (Ident, FnSig, Generics, Option>)> { let header = self.parse_fn_front_matter()?; // `const ... fn` let ident = self.parse_ident()?; // `foo` let mut generics = self.parse_generics()?; // `<'a, T, ...>` - let decl = self.parse_fn_decl(req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)` + let decl = + self.parse_fn_decl(fn_parse_mode.req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)` generics.where_clause = self.parse_where_clause()?; // `where T: Ord` let mut sig_hi = self.prev_token.span; - let body = self.parse_fn_body(attrs, &ident, &mut sig_hi)?; // `;` or `{ ... }`. + let body = self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body)?; // `;` or `{ ... }`. let fn_sig_span = sig_lo.to(sig_hi); Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, body)) } @@ -1729,9 +1794,17 @@ impl<'a> Parser<'a> { attrs: &mut Vec, ident: &Ident, sig_hi: &mut Span, + req_body: bool, ) -> PResult<'a, Option>> { - let (inner_attrs, body) = if self.eat(&token::Semi) { + let has_semi = if req_body { + self.token.kind == TokenKind::Semi + } else { + // Only include `;` in list of expected tokens if body is not required + self.check(&TokenKind::Semi) + }; + let (inner_attrs, body) = if has_semi { // Include the trailing semicolon in the span of the signature + self.expect_semi()?; *sig_hi = self.prev_token.span; (Vec::new(), None) } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() { @@ -1752,9 +1825,12 @@ impl<'a> Parser<'a> { .emit(); (Vec::new(), Some(self.mk_block_err(span))) } else { - if let Err(mut err) = - self.expected_one_of_not_found(&[], &[token::Semi, token::OpenDelim(token::Brace)]) - { + let expected = if req_body { + &[token::OpenDelim(token::Brace)][..] + } else { + &[token::Semi, token::OpenDelim(token::Brace)] + }; + if let Err(mut err) = self.expected_one_of_not_found(&[], &expected) { if self.token.kind == token::CloseDelim(token::Brace) { // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in // the AST for typechecking. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 9212aaa87d194..6d534bece463e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -14,6 +14,7 @@ use crate::lexer::UnmatchedBrace; pub use attr_wrapper::AttrWrapper; pub use diagnostics::AttemptLocalParseRecovery; use diagnostics::Error; +pub(crate) use item::FnParseMode; pub use pat::{RecoverColon, RecoverComma}; pub use path::PathStyle; diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 01e751ea8b5bf..d3e7d1690ccf6 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -4,7 +4,9 @@ use super::expr::LhsExpr; use super::pat::RecoverComma; use super::path::PathStyle; use super::TrailingToken; -use super::{AttrWrapper, BlockMode, ForceCollect, Parser, Restrictions, SemiColonMode}; +use super::{ + AttrWrapper, BlockMode, FnParseMode, ForceCollect, Parser, Restrictions, SemiColonMode, +}; use crate::maybe_whole; use rustc_ast as ast; @@ -79,9 +81,13 @@ impl<'a> Parser<'a> { } else { self.parse_stmt_path_start(lo, attrs) }? - } else if let Some(item) = - self.parse_item_common(attrs.clone(), false, true, |_| true, force_collect)? - { + } else if let Some(item) = self.parse_item_common( + attrs.clone(), + false, + true, + FnParseMode { req_name: |_| true, req_body: true }, + force_collect, + )? { // FIXME: Bad copy of attrs self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))) } else if self.eat(&token::Semi) { diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 7f3bb836754ed..019b64c395eda 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -81,9 +81,9 @@ //! [`OsStr`] and Rust strings work similarly to those for [`CString`] //! and [`CStr`]. //! -//! * [`OsString`] represents an owned string in whatever -//! representation the operating system prefers. In the Rust standard -//! library, various APIs that transfer strings to/from the operating +//! * [`OsString`] losslessly represents an owned platform string. However, this +//! representation is not necessarily in a form native to the platform. +//! In the Rust standard library, various APIs that transfer strings to/from the operating //! system use [`OsString`] instead of plain strings. For example, //! [`env::var_os()`] is used to query environment variables; it //! returns an [Option]<[OsString]>. If the environment variable @@ -92,9 +92,9 @@ //! your code can detect errors in case the environment variable did //! not in fact contain valid Unicode data. //! -//! * [`OsStr`] represents a borrowed reference to a string in a -//! format that can be passed to the operating system. It can be -//! converted into a UTF-8 Rust string slice in a similar way to +//! * [`OsStr`] losslessly represents a borrowed reference to a platform string. +//! However, this representation is not necessarily in a form native to the platform. +//! It can be converted into a UTF-8 Rust string slice in a similar way to //! [`OsString`]. //! //! # Conversions @@ -113,16 +113,19 @@ //! //! ## On Windows //! +//! An [`OsStr`] can be losslessly converted to a native Windows string. And +//! a native Windows string can be losslessly converted to an [`OsString`]. +//! //! On Windows, [`OsStr`] implements the //! std::os::windows::ffi::[OsStrExt][windows.OsStrExt] trait, //! which provides an [`encode_wide`] method. This provides an -//! iterator that can be [`collect`]ed into a vector of [`u16`]. +//! iterator that can be [`collect`]ed into a vector of [`u16`]. After a nul +//! characters is appended, this is the same as a native Windows string. //! //! Additionally, on Windows [`OsString`] implements the //! std::os::windows:ffi::[OsStringExt][windows.OsStringExt] -//! trait, which provides a [`from_wide`] method. The result of this -//! method is an [`OsString`] which can be round-tripped to a Windows -//! string losslessly. +//! trait, which provides a [`from_wide`] method to convert a native Windows +//! string (without the terminating nul character) to an [`OsString`]. //! //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value //! [Unicode code point]: https://www.unicode.org/glossary/#code_point diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile index e6b6b6e53b99d..ab588ccc24999 100644 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile @@ -1,5 +1,18 @@ +FROM ubuntu:20.04 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + ca-certificates +WORKDIR /tmp +RUN curl -f https://curl.se/ca/cacert.pem -o cacert.pem + FROM ubuntu:16.04 +# The ca-certificates in ubuntu-16 is too old, so update the certificates +# with something more recent. +COPY --from=0 /tmp/cacert.pem /tmp/cacert.pem +ENV CURL_CA_BUNDLE /tmp/cacert.pem + COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile index 61cc000dca555..ee4fd759b469b 100644 --- a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile @@ -1,5 +1,18 @@ +FROM ubuntu:20.04 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + ca-certificates +WORKDIR /tmp +RUN curl -f https://curl.se/ca/cacert.pem -o cacert.pem + FROM ubuntu:16.04 +# The ca-certificates in ubuntu-16 is too old, so update the certificates +# with something more recent. +COPY --from=0 /tmp/cacert.pem /tmp/cacert.pem +ENV CURL_CA_BUNDLE /tmp/cacert.pem + COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile index 66eb4137a87ca..b11a1d3feb2ee 100644 --- a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile @@ -1,5 +1,18 @@ +FROM ubuntu:20.04 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + ca-certificates +WORKDIR /tmp +RUN curl -f https://curl.se/ca/cacert.pem -o cacert.pem + FROM ubuntu:16.04 +# The ca-certificates in ubuntu-16 is too old, so update the certificates +# with something more recent. +COPY --from=0 /tmp/cacert.pem /tmp/cacert.pem +ENV CURL_CA_BUNDLE /tmp/cacert.pem + COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile index c13f63911f8fa..55ca23b293d5e 100644 --- a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile @@ -1,5 +1,18 @@ +FROM ubuntu:20.04 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + ca-certificates +WORKDIR /tmp +RUN curl -f https://curl.se/ca/cacert.pem -o cacert.pem + FROM ubuntu:16.04 +# The ca-certificates in ubuntu-16 is too old, so update the certificates +# with something more recent. +COPY --from=0 /tmp/cacert.pem /tmp/cacert.pem +ENV CURL_CA_BUNDLE /tmp/cacert.pem + COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh diff --git a/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs deleted file mode 100644 index 1e0f5d79c0b42..0000000000000 --- a/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs +++ /dev/null @@ -1,6 +0,0 @@ -// no-prefer-dynamic -// compile-flags: --cfg foo - -#![cfg_attr(foo, crate_type="lib")] - -pub fn foo() {} diff --git a/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs deleted file mode 100644 index 43b266b778f0e..0000000000000 --- a/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// aux-build:crate-attributes-using-cfg_attr.rs - -extern crate crate_attributes_using_cfg_attr; - -pub fn main() {} diff --git a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs new file mode 100644 index 0000000000000..ef12b05fab237 --- /dev/null +++ b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.rs @@ -0,0 +1,12 @@ +// check-fail +// compile-flags:--cfg foo + +#![deny(warnings)] +#![cfg_attr(foo, crate_type="bin")] +//~^ERROR `crate_type` within +//~| WARN this was previously accepted +#![cfg_attr(foo, crate_name="bar")] +//~^ERROR `crate_name` within +//~| WARN this was previously accepted + +fn main() {} diff --git a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr new file mode 100644 index 0000000000000..5df2eacc96e1e --- /dev/null +++ b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr @@ -0,0 +1,26 @@ +error: `crate_type` within an `#![cfg_attr] attribute is deprecated` + --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:5:18 + | +LL | #![cfg_attr(foo, crate_type="bin")] + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:4:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` implied by `#[deny(warnings)]` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #91632 + +error: `crate_name` within an `#![cfg_attr] attribute is deprecated` + --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:8:18 + | +LL | #![cfg_attr(foo, crate_name="bar")] + | ^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #91632 + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/consts/issue-90870.fixed b/src/test/ui/consts/issue-90870.fixed new file mode 100644 index 0000000000000..e767effcdd06f --- /dev/null +++ b/src/test/ui/consts/issue-90870.fixed @@ -0,0 +1,34 @@ +// Regression test for issue #90870. + +// run-rustfix + +#![allow(dead_code)] + +const fn f(a: &u8, b: &u8) -> bool { + *a == *b + //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants [E0015] + //~| HELP: consider dereferencing here +} + +const fn g(a: &&&&i64, b: &&&&i64) -> bool { + ****a == ****b + //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants [E0015] + //~| HELP: consider dereferencing here +} + +const fn h(mut a: &[u8], mut b: &[u8]) -> bool { + while let ([l, at @ ..], [r, bt @ ..]) = (a, b) { + if *l == *r { + //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants [E0015] + //~| HELP: consider dereferencing here + a = at; + b = bt; + } else { + return false; + } + } + + a.is_empty() && b.is_empty() +} + +fn main() {} diff --git a/src/test/ui/consts/issue-90870.rs b/src/test/ui/consts/issue-90870.rs new file mode 100644 index 0000000000000..35b3c8242aa0c --- /dev/null +++ b/src/test/ui/consts/issue-90870.rs @@ -0,0 +1,34 @@ +// Regression test for issue #90870. + +// run-rustfix + +#![allow(dead_code)] + +const fn f(a: &u8, b: &u8) -> bool { + a == b + //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants [E0015] + //~| HELP: consider dereferencing here +} + +const fn g(a: &&&&i64, b: &&&&i64) -> bool { + a == b + //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants [E0015] + //~| HELP: consider dereferencing here +} + +const fn h(mut a: &[u8], mut b: &[u8]) -> bool { + while let ([l, at @ ..], [r, bt @ ..]) = (a, b) { + if l == r { + //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants [E0015] + //~| HELP: consider dereferencing here + a = at; + b = bt; + } else { + return false; + } + } + + a.is_empty() && b.is_empty() +} + +fn main() {} diff --git a/src/test/ui/consts/issue-90870.stderr b/src/test/ui/consts/issue-90870.stderr new file mode 100644 index 0000000000000..0e33e6ebe5a59 --- /dev/null +++ b/src/test/ui/consts/issue-90870.stderr @@ -0,0 +1,36 @@ +error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants + --> $DIR/issue-90870.rs:8:5 + | +LL | a == b + | ^^^^^^ + | +help: consider dereferencing here + | +LL | *a == *b + | + + + +error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants + --> $DIR/issue-90870.rs:14:5 + | +LL | a == b + | ^^^^^^ + | +help: consider dereferencing here + | +LL | ****a == ****b + | ++++ ++++ + +error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants + --> $DIR/issue-90870.rs:21:12 + | +LL | if l == r { + | ^^^^^^ + | +help: consider dereferencing here + | +LL | if *l == *r { + | + + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/fn/fn-recover-return-sign2.rs b/src/test/ui/fn/fn-recover-return-sign2.rs index b6a6a1ec2a6ed..31f56565c49a6 100644 --- a/src/test/ui/fn/fn-recover-return-sign2.rs +++ b/src/test/ui/fn/fn-recover-return-sign2.rs @@ -3,6 +3,6 @@ fn foo() => impl Fn() => bool { //~^ ERROR return types are denoted using `->` - //~| ERROR expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>` + //~| ERROR expected one of `+`, `->`, `::`, `where`, or `{`, found `=>` unimplemented!() } diff --git a/src/test/ui/fn/fn-recover-return-sign2.stderr b/src/test/ui/fn/fn-recover-return-sign2.stderr index d62cacd4bf531..25ee8dd0c5dcd 100644 --- a/src/test/ui/fn/fn-recover-return-sign2.stderr +++ b/src/test/ui/fn/fn-recover-return-sign2.stderr @@ -4,11 +4,11 @@ error: return types are denoted using `->` LL | fn foo() => impl Fn() => bool { | ^^ help: use `->` instead -error: expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>` +error: expected one of `+`, `->`, `::`, `where`, or `{`, found `=>` --> $DIR/fn-recover-return-sign2.rs:4:23 | LL | fn foo() => impl Fn() => bool { - | ^^ expected one of `+`, `->`, `::`, `;`, `where`, or `{` + | ^^ expected one of `+`, `->`, `::`, `where`, or `{` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/issues/issue-24780.rs b/src/test/ui/parser/issues/issue-24780.rs index 480d9bc2bade0..017521f570c82 100644 --- a/src/test/ui/parser/issues/issue-24780.rs +++ b/src/test/ui/parser/issues/issue-24780.rs @@ -2,7 +2,7 @@ // to happen in #24780. For example, following should be an error: // expected one of ..., `>`, ... found `>`. -fn foo() -> Vec> { //~ ERROR expected one of `!`, `+`, `::`, `;`, `where`, or `{`, found `>` +fn foo() -> Vec> { //~ ERROR expected one of `!`, `+`, `::`, `where`, or `{`, found `>` Vec::new() } diff --git a/src/test/ui/parser/issues/issue-24780.stderr b/src/test/ui/parser/issues/issue-24780.stderr index bdd089bb7a139..d9470191b25a4 100644 --- a/src/test/ui/parser/issues/issue-24780.stderr +++ b/src/test/ui/parser/issues/issue-24780.stderr @@ -1,8 +1,8 @@ -error: expected one of `!`, `+`, `::`, `;`, `where`, or `{`, found `>` +error: expected one of `!`, `+`, `::`, `where`, or `{`, found `>` --> $DIR/issue-24780.rs:5:23 | LL | fn foo() -> Vec> { - | ^ expected one of `!`, `+`, `::`, `;`, `where`, or `{` + | ^ expected one of `!`, `+`, `::`, `where`, or `{` error: aborting due to previous error diff --git a/src/test/ui/parser/issues/issue-58856-1.rs b/src/test/ui/parser/issues/issue-58856-1.rs index 332a3014416b5..ea80eb8714f96 100644 --- a/src/test/ui/parser/issues/issue-58856-1.rs +++ b/src/test/ui/parser/issues/issue-58856-1.rs @@ -2,7 +2,7 @@ impl A { //~^ ERROR cannot find type `A` in this scope fn b(self> //~^ ERROR expected one of `)`, `,`, or `:`, found `>` - //~| ERROR expected one of `->`, `;`, `where`, or `{`, found `>` + //~| ERROR expected one of `->`, `where`, or `{`, found `>` } fn main() {} diff --git a/src/test/ui/parser/issues/issue-58856-1.stderr b/src/test/ui/parser/issues/issue-58856-1.stderr index 2afb26d175834..96151f3fe07fd 100644 --- a/src/test/ui/parser/issues/issue-58856-1.stderr +++ b/src/test/ui/parser/issues/issue-58856-1.stderr @@ -6,14 +6,14 @@ LL | fn b(self> | | | unclosed delimiter -error: expected one of `->`, `;`, `where`, or `{`, found `>` +error: expected one of `->`, `where`, or `{`, found `>` --> $DIR/issue-58856-1.rs:3:14 | LL | impl A { | - while parsing this item list starting here LL | LL | fn b(self> - | ^ expected one of `->`, `;`, `where`, or `{` + | ^ expected one of `->`, `where`, or `{` ... LL | } | - the item list ends here diff --git a/src/test/ui/parser/issues/issue-84148-1.stderr b/src/test/ui/parser/issues/issue-84148-1.stderr index 98506568d82c2..77f0896e9c155 100644 --- a/src/test/ui/parser/issues/issue-84148-1.stderr +++ b/src/test/ui/parser/issues/issue-84148-1.stderr @@ -13,11 +13,11 @@ LL | fn f(t:for<>t?) | expected one of `(`, `)`, `+`, `,`, `::`, or `<` | help: missing `,` -error: expected one of `->`, `;`, `where`, or `{`, found `` +error: expected one of `->`, `where`, or `{`, found `` --> $DIR/issue-84148-1.rs:1:15 | LL | fn f(t:for<>t?) - | ^ expected one of `->`, `;`, `where`, or `{` + | ^ expected one of `->`, `where`, or `{` error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/issues/issue-84148-2.stderr b/src/test/ui/parser/issues/issue-84148-2.stderr index 6f314da436070..396208316df67 100644 --- a/src/test/ui/parser/issues/issue-84148-2.stderr +++ b/src/test/ui/parser/issues/issue-84148-2.stderr @@ -21,11 +21,11 @@ LL | fn f(t:for<>t? | expected one of `(`, `)`, `+`, `,`, `::`, or `<` | help: missing `,` -error: expected one of `->`, `;`, `where`, or `{`, found `` +error: expected one of `->`, `where`, or `{`, found `` --> $DIR/issue-84148-2.rs:4:16 | LL | fn f(t:for<>t? - | ^ expected one of `->`, `;`, `where`, or `{` + | ^ expected one of `->`, `where`, or `{` error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/issues/issue-87635.rs b/src/test/ui/parser/issues/issue-87635.rs index da74c1877b165..f70a87fb0e8fb 100644 --- a/src/test/ui/parser/issues/issue-87635.rs +++ b/src/test/ui/parser/issues/issue-87635.rs @@ -2,8 +2,8 @@ struct Foo {} impl Foo { pub fn bar() - //~^ ERROR: expected `;`, found `}` - //~| ERROR: associated function in `impl` without body + //~^ ERROR: associated function in `impl` without body } +//~^ERROR expected one of `->`, `where`, or `{`, found `}` fn main() {} diff --git a/src/test/ui/parser/issues/issue-87635.stderr b/src/test/ui/parser/issues/issue-87635.stderr index 920a9f937dd6b..0a52d0687b22b 100644 --- a/src/test/ui/parser/issues/issue-87635.stderr +++ b/src/test/ui/parser/issues/issue-87635.stderr @@ -1,11 +1,13 @@ -error: expected `;`, found `}` - --> $DIR/issue-87635.rs:4:17 +error: expected one of `->`, `where`, or `{`, found `}` + --> $DIR/issue-87635.rs:6:1 | LL | pub fn bar() - | ^ help: add `;` here -... + | --- - expected one of `->`, `where`, or `{` + | | + | while parsing this `fn` +LL | LL | } - | - unexpected token + | ^ unexpected token error: associated function in `impl` without body --> $DIR/issue-87635.rs:4:5 diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr index 22e1c2f97e769..3fe0d0f4273de 100644 --- a/src/test/ui/parser/missing_right_paren.stderr +++ b/src/test/ui/parser/missing_right_paren.stderr @@ -22,11 +22,11 @@ error: expected one of `:` or `|`, found `)` LL | fn main((ؼ | ^ expected one of `:` or `|` -error: expected one of `->`, `;`, `where`, or `{`, found `` +error: expected one of `->`, `where`, or `{`, found `` --> $DIR/missing_right_paren.rs:3:11 | LL | fn main((ؼ - | ^ expected one of `->`, `;`, `where`, or `{` + | ^ expected one of `->`, `where`, or `{` error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.fixed b/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.fixed new file mode 100644 index 0000000000000..5c55566ffe92f --- /dev/null +++ b/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +#[allow(dead_code)] + +extern "C" { + fn foo(); //~ERROR expected `;` +} + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.rs b/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.rs new file mode 100644 index 0000000000000..91971cba3e863 --- /dev/null +++ b/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.rs @@ -0,0 +1,9 @@ +// run-rustfix + +#[allow(dead_code)] + +extern "C" { + fn foo() //~ERROR expected `;` +} + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.stderr b/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.stderr new file mode 100644 index 0000000000000..c5df72c4a477f --- /dev/null +++ b/src/test/ui/suggestions/suggest-semicolon-for-fn-in-extern-block.stderr @@ -0,0 +1,10 @@ +error: expected `;`, found `}` + --> $DIR/suggest-semicolon-for-fn-in-extern-block.rs:6:11 + | +LL | fn foo() + | ^ help: add `;` here +LL | } + | - unexpected token + +error: aborting due to previous error +