diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index a283bf1de763a..f1fe495282abc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -9,11 +9,8 @@ use super::FunctionCx; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage, scope: SourceScope) { // Determine the instance that coverage data was originally generated for. - let scope_data = &self.mir.source_scopes[scope]; - let instance = if let Some((inlined_instance, _)) = scope_data.inlined { - self.monomorphize(inlined_instance) - } else if let Some(inlined_scope) = scope_data.inlined_parent_scope { - self.monomorphize(self.mir.source_scopes[inlined_scope].inlined.unwrap().0) + let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) { + self.monomorphize(inlined) } else { self.instance }; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 48a41c8bd245a..18ffc227fed86 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -954,6 +954,16 @@ pub struct Block<'hir> { pub targeted_by_break: bool, } +impl<'hir> Block<'hir> { + pub fn innermost_block(&self) -> &Block<'hir> { + let mut block = self; + while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr { + block = inner_block; + } + block + } +} + #[derive(Debug, HashStable_Generic)] pub struct Pat<'hir> { #[stable_hasher(ignore)] diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index d7505717bf3d2..4e87ec86658f8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -316,37 +316,6 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( err } -/// Structurally compares two types, modulo any inference variables. -/// -/// Returns `true` if two types are equal, or if one type is an inference variable compatible -/// with the other type. A TyVar inference type is compatible with any type, and an IntVar or -/// FloatVar inference type are compatible with themselves or their concrete types (Int and -/// Float types, respectively). When comparing two ADTs, these rules apply recursively. -pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { - match (&a.kind(), &b.kind()) { - (&ty::Adt(did_a, substs_a), &ty::Adt(did_b, substs_b)) => { - if did_a != did_b { - return false; - } - - substs_a.types().zip(substs_b.types()).all(|(a, b)| same_type_modulo_infer(a, b)) - } - (&ty::Int(_), &ty::Infer(ty::InferTy::IntVar(_))) - | (&ty::Infer(ty::InferTy::IntVar(_)), &ty::Int(_) | &ty::Infer(ty::InferTy::IntVar(_))) - | (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_))) - | ( - &ty::Infer(ty::InferTy::FloatVar(_)), - &ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)), - ) - | (&ty::Infer(ty::InferTy::TyVar(_)), _) - | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true, - (&ty::Ref(_, ty_a, mut_a), &ty::Ref(_, ty_b, mut_b)) => { - mut_a == mut_b && same_type_modulo_infer(*ty_a, *ty_b) - } - _ => a == b, - } -} - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_region_errors( &self, @@ -645,13 +614,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_label(span, "expected due to this"); } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { - semi_span, + arm_block_id, + arm_span, + arm_ty, + prior_arm_block_id, + prior_arm_span, + prior_arm_ty, source, ref prior_arms, - last_ty, scrut_hir_id, opt_suggest_box_span, - arm_span, scrut_span, .. }) => match source { @@ -682,10 +654,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } _ => { - // `last_ty` can be `!`, `expected` will have better info when present. + // `prior_arm_ty` can be `!`, `expected` will have better info when present. let t = self.resolve_vars_if_possible(match exp_found { Some(ty::error::ExpectedFound { expected, .. }) => expected, - _ => last_ty, + _ => prior_arm_ty, }); let source_map = self.tcx.sess.source_map(); let mut any_multiline_arm = source_map.is_multiline(arm_span); @@ -710,37 +682,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; let msg = "`match` arms have incompatible types"; err.span_label(outer_error_span, msg); - if let Some((sp, boxed)) = semi_span { - if let (StatementAsExpression::NeedsBoxing, [.., prior_arm]) = - (boxed, &prior_arms[..]) - { - err.multipart_suggestion( - "consider removing this semicolon and boxing the expressions", - vec![ - (prior_arm.shrink_to_lo(), "Box::new(".to_string()), - (prior_arm.shrink_to_hi(), ")".to_string()), - (arm_span.shrink_to_lo(), "Box::new(".to_string()), - (arm_span.shrink_to_hi(), ")".to_string()), - (sp, String::new()), - ], - Applicability::HasPlaceholders, - ); - } else if matches!(boxed, StatementAsExpression::NeedsBoxing) { - err.span_suggestion_short( - sp, - "consider removing this semicolon and boxing the expressions", - "", - Applicability::MachineApplicable, - ); - } else { - err.span_suggestion_short( - sp, - "consider removing this semicolon", - "", - Applicability::MachineApplicable, - ); - } - } + self.suggest_remove_semi_or_return_binding( + err, + prior_arm_block_id, + prior_arm_ty, + prior_arm_span, + arm_block_id, + arm_ty, + arm_span, + ); if let Some(ret_sp) = opt_suggest_box_span { // Get return type span and point to it. self.suggest_boxing_for_return_impl_trait( @@ -752,43 +702,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } }, ObligationCauseCode::IfExpression(box IfExpressionCause { - then, - else_sp, - outer, - semicolon, + then_id, + else_id, + then_ty, + else_ty, + outer_span, opt_suggest_box_span, }) => { - err.span_label(then, "expected because of this"); - if let Some(sp) = outer { + let then_span = self.find_block_span_from_hir_id(then_id); + let else_span = self.find_block_span_from_hir_id(then_id); + err.span_label(then_span, "expected because of this"); + if let Some(sp) = outer_span { err.span_label(sp, "`if` and `else` have incompatible types"); } - if let Some((sp, boxed)) = semicolon { - if matches!(boxed, StatementAsExpression::NeedsBoxing) { - err.multipart_suggestion( - "consider removing this semicolon and boxing the expression", - vec![ - (then.shrink_to_lo(), "Box::new(".to_string()), - (then.shrink_to_hi(), ")".to_string()), - (else_sp.shrink_to_lo(), "Box::new(".to_string()), - (else_sp.shrink_to_hi(), ")".to_string()), - (sp, String::new()), - ], - Applicability::MachineApplicable, - ); - } else { - err.span_suggestion_short( - sp, - "consider removing this semicolon", - "", - Applicability::MachineApplicable, - ); - } - } + self.suggest_remove_semi_or_return_binding( + err, + Some(then_id), + then_ty, + then_span, + Some(else_id), + else_ty, + else_span, + ); if let Some(ret_sp) = opt_suggest_box_span { self.suggest_boxing_for_return_impl_trait( err, ret_sp, - [then, else_sp].into_iter(), + [then_span, else_span].into_iter(), ); } } @@ -808,6 +748,56 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + fn suggest_remove_semi_or_return_binding( + &self, + err: &mut Diagnostic, + first_id: Option, + first_ty: Ty<'tcx>, + first_span: Span, + second_id: Option, + second_ty: Ty<'tcx>, + second_span: Span, + ) { + let remove_semicolon = + [(first_id, second_ty), (second_id, first_ty)].into_iter().find_map(|(id, ty)| { + let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None }; + self.could_remove_semicolon(blk, ty) + }); + match remove_semicolon { + Some((sp, StatementAsExpression::NeedsBoxing)) => { + err.multipart_suggestion( + "consider removing this semicolon and boxing the expressions", + vec![ + (first_span.shrink_to_lo(), "Box::new(".to_string()), + (first_span.shrink_to_hi(), ")".to_string()), + (second_span.shrink_to_lo(), "Box::new(".to_string()), + (second_span.shrink_to_hi(), ")".to_string()), + (sp, String::new()), + ], + Applicability::MachineApplicable, + ); + } + Some((sp, StatementAsExpression::CorrectType)) => { + err.span_suggestion_short( + sp, + "consider removing this semicolon", + "", + Applicability::MachineApplicable, + ); + } + None => { + for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] { + if let Some(id) = id + && let hir::Node::Block(blk) = self.tcx.hir().get(id) + && self.consider_returning_binding(blk, ty, err) + { + break; + } + } + } + } + } + fn suggest_boxing_for_return_impl_trait( &self, err: &mut Diagnostic, @@ -1723,15 +1713,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; debug!("exp_found {:?} terr {:?} cause.code {:?}", exp_found, terr, cause.code()); if let Some(exp_found) = exp_found { - let should_suggest_fixes = if let ObligationCauseCode::Pattern { root_ty, .. } = - cause.code() - { - // Skip if the root_ty of the pattern is not the same as the expected_ty. - // If these types aren't equal then we've probably peeled off a layer of arrays. - same_type_modulo_infer(self.resolve_vars_if_possible(*root_ty), exp_found.expected) - } else { - true - }; + let should_suggest_fixes = + if let ObligationCauseCode::Pattern { root_ty, .. } = cause.code() { + // Skip if the root_ty of the pattern is not the same as the expected_ty. + // If these types aren't equal then we've probably peeled off a layer of arrays. + self.same_type_modulo_infer(*root_ty, exp_found.expected) + } else { + true + }; if should_suggest_fixes { self.suggest_tuple_pattern(cause, &exp_found, diag); @@ -1786,7 +1775,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .filter_map(|variant| { let sole_field = &variant.fields[0]; let sole_field_ty = sole_field.ty(self.tcx, substs); - if same_type_modulo_infer(sole_field_ty, exp_found.found) { + if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { let variant_path = with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); // FIXME #56861: DRYer prelude filtering @@ -1902,12 +1891,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.get_impl_future_output_ty(exp_found.expected).map(Binder::skip_binder), self.get_impl_future_output_ty(exp_found.found).map(Binder::skip_binder), ) { - (Some(exp), Some(found)) if same_type_modulo_infer(exp, found) => match cause.code() { - ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => { + (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause + .code() + { + ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { + let then_span = self.find_block_span_from_hir_id(*then_id); diag.multipart_suggestion( "consider `await`ing on both `Future`s", vec![ - (then.shrink_to_hi(), ".await".to_string()), + (then_span.shrink_to_hi(), ".await".to_string()), (exp_span.shrink_to_hi(), ".await".to_string()), ], Applicability::MaybeIncorrect, @@ -1934,7 +1926,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { diag.help("consider `await`ing on both `Future`s"); } }, - (_, Some(ty)) if same_type_modulo_infer(exp_found.expected, ty) => { + (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { diag.span_suggestion_verbose( exp_span.shrink_to_hi(), "consider `await`ing on the `Future`", @@ -1942,11 +1934,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - (Some(ty), _) if same_type_modulo_infer(ty, exp_found.found) => match cause.code() { - ObligationCauseCode::Pattern { span: Some(span), .. } - | ObligationCauseCode::IfExpression(box IfExpressionCause { then: span, .. }) => { + (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() + { + ObligationCauseCode::Pattern { span: Some(then_span), .. } => { diag.span_suggestion_verbose( - span.shrink_to_hi(), + then_span.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await", + Applicability::MaybeIncorrect, + ); + } + ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { + let then_span = self.find_block_span_from_hir_id(*then_id); + diag.span_suggestion_verbose( + then_span.shrink_to_hi(), "consider `await`ing on the `Future`", ".await", Applicability::MaybeIncorrect, @@ -1992,7 +1993,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .iter() .filter(|field| field.vis.is_accessible_from(field.did, self.tcx)) .map(|field| (field.name, field.ty(self.tcx, expected_substs))) - .find(|(_, ty)| same_type_modulo_infer(*ty, exp_found.found)) + .find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found)) { if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { @@ -2057,7 +2058,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { | (_, ty::Infer(_)) | (ty::Param(_), _) | (ty::Infer(_), _) => {} - _ if same_type_modulo_infer(exp_ty, found_ty) => {} + _ if self.same_type_modulo_infer(exp_ty, found_ty) => {} _ => show_suggestion = false, }; } @@ -2179,7 +2180,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { let [expected_tup_elem] = expected_fields[..] else { return }; - if !same_type_modulo_infer(expected_tup_elem, found) { + if !self.same_type_modulo_infer(expected_tup_elem, found) { return; } @@ -2647,6 +2648,76 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span.is_desugaring(DesugaringKind::QuestionMark) && self.tcx.is_diagnostic_item(sym::From, trait_def_id) } + + /// Structurally compares two types, modulo any inference variables. + /// + /// Returns `true` if two types are equal, or if one type is an inference variable compatible + /// with the other type. A TyVar inference type is compatible with any type, and an IntVar or + /// FloatVar inference type are compatible with themselves or their concrete types (Int and + /// Float types, respectively). When comparing two ADTs, these rules apply recursively. + pub fn same_type_modulo_infer(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { + let (a, b) = self.resolve_vars_if_possible((a, b)); + match (a.kind(), b.kind()) { + (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) => { + if def_a != def_b { + return false; + } + + substs_a + .types() + .zip(substs_b.types()) + .all(|(a, b)| self.same_type_modulo_infer(a, b)) + } + (&ty::FnDef(did_a, substs_a), &ty::FnDef(did_b, substs_b)) => { + if did_a != did_b { + return false; + } + + substs_a + .types() + .zip(substs_b.types()) + .all(|(a, b)| self.same_type_modulo_infer(a, b)) + } + (&ty::Int(_) | &ty::Uint(_), &ty::Infer(ty::InferTy::IntVar(_))) + | ( + &ty::Infer(ty::InferTy::IntVar(_)), + &ty::Int(_) | &ty::Uint(_) | &ty::Infer(ty::InferTy::IntVar(_)), + ) + | (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_))) + | ( + &ty::Infer(ty::InferTy::FloatVar(_)), + &ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)), + ) + | (&ty::Infer(ty::InferTy::TyVar(_)), _) + | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true, + (&ty::Ref(_, ty_a, mut_a), &ty::Ref(_, ty_b, mut_b)) => { + mut_a == mut_b && self.same_type_modulo_infer(ty_a, ty_b) + } + (&ty::RawPtr(a), &ty::RawPtr(b)) => { + a.mutbl == b.mutbl && self.same_type_modulo_infer(a.ty, b.ty) + } + (&ty::Slice(a), &ty::Slice(b)) => self.same_type_modulo_infer(a, b), + (&ty::Array(a_ty, a_ct), &ty::Array(b_ty, b_ct)) => { + self.same_type_modulo_infer(a_ty, b_ty) && a_ct == b_ct + } + (&ty::Tuple(a), &ty::Tuple(b)) => { + if a.len() != b.len() { + return false; + } + std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b)) + } + (&ty::FnPtr(a), &ty::FnPtr(b)) => { + let a = a.skip_binder().inputs_and_output; + let b = b.skip_binder().inputs_and_output; + if a.len() != b.len() { + return false; + } + std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b)) + } + // FIXME(compiler-errors): This needs to be generalized more + _ => a == b, + } + } } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { @@ -2798,3 +2869,237 @@ impl TyCategory { } } } + +impl<'tcx> InferCtxt<'_, 'tcx> { + /// Given a [`hir::Block`], get the span of its last expression or + /// statement, peeling off any inner blocks. + pub fn find_block_span(&self, block: &'tcx hir::Block<'tcx>) -> Span { + let block = block.innermost_block(); + if let Some(expr) = &block.expr { + expr.span + } else if let Some(stmt) = block.stmts.last() { + // possibly incorrect trailing `;` in the else arm + stmt.span + } else { + // empty block; point at its entirety + block.span + } + } + + /// Given a [`hir::HirId`] for a block, get the span of its last expression + /// or statement, peeling off any inner blocks. + pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span { + match self.tcx.hir().get(hir_id) { + hir::Node::Block(blk) => self.find_block_span(blk), + // The parser was in a weird state if either of these happen, but + // it's better not to panic. + hir::Node::Expr(e) => e.span, + _ => rustc_span::DUMMY_SP, + } + } + + /// Be helpful when the user wrote `{... expr; }` and taking the `;` off + /// is enough to fix the error. + pub fn could_remove_semicolon( + &self, + blk: &'tcx hir::Block<'tcx>, + expected_ty: Ty<'tcx>, + ) -> Option<(Span, StatementAsExpression)> { + let blk = blk.innermost_block(); + // Do not suggest if we have a tail expr. + if blk.expr.is_some() { + return None; + } + let last_stmt = blk.stmts.last()?; + let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else { + return None; + }; + let last_expr_ty = self.in_progress_typeck_results?.borrow().expr_ty_opt(*last_expr)?; + let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { + _ if last_expr_ty.references_error() => return None, + _ if self.same_type_modulo_infer(last_expr_ty, expected_ty) => { + StatementAsExpression::CorrectType + } + (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) + if last_def_id == exp_def_id => + { + StatementAsExpression::CorrectType + } + (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { + debug!( + "both opaque, likely future {:?} {:?} {:?} {:?}", + last_def_id, last_bounds, exp_def_id, exp_bounds + ); + + let last_local_id = last_def_id.as_local()?; + let exp_local_id = exp_def_id.as_local()?; + + match ( + &self.tcx.hir().expect_item(last_local_id).kind, + &self.tcx.hir().expect_item(exp_local_id).kind, + ) { + ( + hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), + hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), + ) if iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { + match (left, right) { + ( + hir::GenericBound::Trait(tl, ml), + hir::GenericBound::Trait(tr, mr), + ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() + && ml == mr => + { + true + } + ( + hir::GenericBound::LangItemTrait(langl, _, _, argsl), + hir::GenericBound::LangItemTrait(langr, _, _, argsr), + ) if langl == langr => { + // FIXME: consider the bounds! + debug!("{:?} {:?}", argsl, argsr); + true + } + _ => false, + } + }) => + { + StatementAsExpression::NeedsBoxing + } + _ => StatementAsExpression::CorrectType, + } + } + _ => return None, + }; + let span = if last_stmt.span.from_expansion() { + let mac_call = rustc_span::source_map::original_sp(last_stmt.span, blk.span); + self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)? + } else { + last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1)) + }; + Some((span, needs_box)) + } + + /// Suggest returning a local binding with a compatible type if the block + /// has no return expression. + pub fn consider_returning_binding( + &self, + blk: &'tcx hir::Block<'tcx>, + expected_ty: Ty<'tcx>, + err: &mut Diagnostic, + ) -> bool { + let blk = blk.innermost_block(); + // Do not suggest if we have a tail expr. + if blk.expr.is_some() { + return false; + } + let mut shadowed = FxHashSet::default(); + let mut candidate_idents = vec![]; + let mut find_compatible_candidates = |pat: &hir::Pat<'_>| { + if let hir::PatKind::Binding(_, hir_id, ident, _) = &pat.kind + && let Some(pat_ty) = self + .in_progress_typeck_results + .and_then(|typeck_results| typeck_results.borrow().node_type_opt(*hir_id)) + { + let pat_ty = self.resolve_vars_if_possible(pat_ty); + if self.same_type_modulo_infer(pat_ty, expected_ty) + && !(pat_ty, expected_ty).references_error() + && shadowed.insert(ident.name) + { + candidate_idents.push((*ident, pat_ty)); + } + } + true + }; + + let hir = self.tcx.hir(); + for stmt in blk.stmts.iter().rev() { + let hir::StmtKind::Local(local) = &stmt.kind else { continue; }; + local.pat.walk(&mut find_compatible_candidates); + } + match hir.find(hir.get_parent_node(blk.hir_id)) { + Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => { + match hir.find(hir.get_parent_node(*hir_id)) { + Some(hir::Node::Arm(hir::Arm { pat, .. })) => { + pat.walk(&mut find_compatible_candidates); + } + Some( + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(_, body), + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, .. }), + .. + }), + ) => { + for param in hir.body(*body).params { + param.pat.walk(&mut find_compatible_candidates); + } + } + Some(hir::Node::Expr(hir::Expr { + kind: + hir::ExprKind::If( + hir::Expr { kind: hir::ExprKind::Let(let_), .. }, + then_block, + _, + ), + .. + })) if then_block.hir_id == *hir_id => { + let_.pat.walk(&mut find_compatible_candidates); + } + _ => {} + } + } + _ => {} + } + + match &candidate_idents[..] { + [(ident, _ty)] => { + let sm = self.tcx.sess.source_map(); + if let Some(stmt) = blk.stmts.last() { + let stmt_span = sm.stmt_span(stmt.span, blk.span); + let sugg = if sm.is_multiline(blk.span) + && let Some(spacing) = sm.indentation_before(stmt_span) + { + format!("\n{spacing}{ident}") + } else { + format!(" {ident}") + }; + err.span_suggestion_verbose( + stmt_span.shrink_to_hi(), + format!("consider returning the local binding `{ident}`"), + sugg, + Applicability::MaybeIncorrect, + ); + } else { + let sugg = if sm.is_multiline(blk.span) + && let Some(spacing) = sm.indentation_before(blk.span.shrink_to_lo()) + { + format!("\n{spacing} {ident}\n{spacing}") + } else { + format!(" {ident} ") + }; + let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi(); + err.span_suggestion_verbose( + sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span), + format!("consider returning the local binding `{ident}`"), + sugg, + Applicability::MaybeIncorrect, + ); + } + true + } + values if (1..3).contains(&values.len()) => { + let spans = values.iter().map(|(ident, _)| ident.span).collect::>(); + err.span_note(spans, "consider returning one of these bindings"); + true + } + _ => false, + } + } +} diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f61cb7e8c472e..702cc48ff7bb3 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1662,6 +1662,22 @@ impl SourceScope { ClearCrossCrate::Clear => None, } } + + /// The instance this source scope was inlined from, if any. + #[inline] + pub fn inlined_instance<'tcx>( + self, + source_scopes: &IndexVec>, + ) -> Option> { + let scope_data = &source_scopes[self]; + if let Some((inlined_instance, _)) = scope_data.inlined { + Some(inlined_instance) + } else if let Some(inlined_scope) = scope_data.inlined_parent_scope { + Some(source_scopes[inlined_scope].inlined.unwrap().0) + } else { + None + } + } } #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 75559d4f8b843..c55971557fac1 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -351,7 +351,7 @@ pub enum ObligationCauseCode<'tcx> { ConstPatternStructural, /// Computing common supertype in an if expression - IfExpression(Box), + IfExpression(Box>), /// Computing common supertype of an if expression with no else counter-part IfExpressionWithNoElse, @@ -488,22 +488,27 @@ impl<'tcx> ty::Lift<'tcx> for StatementAsExpression { #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub struct MatchExpressionArmCause<'tcx> { + pub arm_block_id: Option, + pub arm_ty: Ty<'tcx>, pub arm_span: Span, + pub prior_arm_block_id: Option, + pub prior_arm_ty: Ty<'tcx>, + pub prior_arm_span: Span, pub scrut_span: Span, - pub semi_span: Option<(Span, StatementAsExpression)>, pub source: hir::MatchSource, pub prior_arms: Vec, - pub last_ty: Ty<'tcx>, pub scrut_hir_id: hir::HirId, pub opt_suggest_box_span: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct IfExpressionCause { - pub then: Span, - pub else_sp: Span, - pub outer: Option, - pub semicolon: Option<(Span, StatementAsExpression)>, +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Lift, TypeFoldable, TypeVisitable)] +pub struct IfExpressionCause<'tcx> { + pub then_id: hir::HirId, + pub else_id: hir::HirId, + pub then_ty: Ty<'tcx>, + pub else_ty: Ty<'tcx>, + pub outer_span: Option, pub opt_suggest_box_span: Option, } diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index 8f1a1564fc8e8..7fbd57ac7354a 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -130,7 +130,6 @@ impl fmt::Debug for traits::ImplSourceConstDestructData { // Lift implementations TrivialTypeTraversalAndLiftImpls! { - super::IfExpressionCause, super::ImplSourceDiscriminantKindData, super::ImplSourcePointeeData, } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 09b9c80669128..03bb515904cd0 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1729,7 +1729,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { } fn print_const(self, ct: ty::Const<'tcx>) -> Result { - self.pretty_print_const(ct, true) + self.pretty_print_const(ct, false) } fn path_crate(mut self, cnum: CrateNum) -> Result { diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 980af98436281..d305960b4856d 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -28,6 +28,7 @@ //! return. use crate::MirPass; +use rustc_data_structures::fx::FxHashSet; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; @@ -267,7 +268,8 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { return; } - let basic_blocks = body.basic_blocks_mut(); + let basic_blocks = body.basic_blocks.as_mut(); + let source_scopes = &body.source_scopes; let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); let mut used_blocks = 0; for alive_index in reachable.iter() { @@ -282,7 +284,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { } if tcx.sess.instrument_coverage() { - save_unreachable_coverage(basic_blocks, used_blocks); + save_unreachable_coverage(basic_blocks, source_scopes, used_blocks); } basic_blocks.raw.truncate(used_blocks); @@ -311,56 +313,62 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// `Unreachable` coverage statements. These are non-executable statements whose /// code regions are still recorded in the coverage map, representing regions /// with `0` executions. +/// +/// If there are no live `Counter` `Coverage` statements remaining, we remove +/// dead `Coverage` statements along with the dead blocks. Since at least one +/// counter per function is required by LLVM (and necessary, to add the +/// `function_hash` to the counter's call to the LLVM intrinsic +/// `instrprof.increment()`). +/// +/// The `generator::StateTransform` MIR pass and MIR inlining can create +/// atypical conditions, where all live `Counter`s are dropped from the MIR. +/// +/// With MIR inlining we can have coverage counters belonging to different +/// instances in a single body, so the strategy described above is applied to +/// coverage counters from each instance individually. fn save_unreachable_coverage( basic_blocks: &mut IndexVec>, + source_scopes: &IndexVec>, first_dead_block: usize, ) { - let has_live_counters = basic_blocks.raw[0..first_dead_block].iter().any(|live_block| { - live_block.statements.iter().any(|statement| { - if let StatementKind::Coverage(coverage) = &statement.kind { - matches!(coverage.kind, CoverageKind::Counter { .. }) - } else { - false - } - }) - }); - if !has_live_counters { - // If there are no live `Counter` `Coverage` statements anymore, don't - // move dead coverage to the `START_BLOCK`. Just allow the dead - // `Coverage` statements to be dropped with the dead blocks. - // - // The `generator::StateTransform` MIR pass can create atypical - // conditions, where all live `Counter`s are dropped from the MIR. - // - // At least one Counter per function is required by LLVM (and necessary, - // to add the `function_hash` to the counter's call to the LLVM - // intrinsic `instrprof.increment()`). + // Identify instances that still have some live coverage counters left. + let mut live = FxHashSet::default(); + for basic_block in &basic_blocks.raw[0..first_dead_block] { + for statement in &basic_block.statements { + let StatementKind::Coverage(coverage) = &statement.kind else { continue }; + let CoverageKind::Counter { .. } = coverage.kind else { continue }; + let instance = statement.source_info.scope.inlined_instance(source_scopes); + live.insert(instance); + } + } + + if live.is_empty() { return; } - // Retain coverage info for dead blocks, so coverage reports will still - // report `0` executions for the uncovered code regions. - let mut dropped_coverage = Vec::new(); - for dead_block in basic_blocks.raw[first_dead_block..].iter() { - for statement in dead_block.statements.iter() { - if let StatementKind::Coverage(coverage) = &statement.kind { - if let Some(code_region) = &coverage.code_region { - dropped_coverage.push((statement.source_info, code_region.clone())); - } + // Retain coverage for instances that still have some live counters left. + let mut retained_coverage = Vec::new(); + for dead_block in &basic_blocks.raw[first_dead_block..] { + for statement in &dead_block.statements { + let StatementKind::Coverage(coverage) = &statement.kind else { continue }; + let Some(code_region) = &coverage.code_region else { continue }; + let instance = statement.source_info.scope.inlined_instance(source_scopes); + if live.contains(&instance) { + retained_coverage.push((statement.source_info, code_region.clone())); } } } let start_block = &mut basic_blocks[START_BLOCK]; - for (source_info, code_region) in dropped_coverage { - start_block.statements.push(Statement { + start_block.statements.extend(retained_coverage.into_iter().map( + |(source_info, code_region)| Statement { source_info, kind: StatementKind::Coverage(Box::new(Coverage { kind: CoverageKind::Unreachable, code_region: Some(code_region), })), - }) - } + }, + )); } pub struct SimplifyLocals; diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 36243803f994e..ff2d386932858 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -98,6 +98,7 @@ mod merging; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync; use rustc_hir::def_id::DefIdSet; +use rustc_middle::mir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{CodegenUnit, Linkage}; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -479,9 +480,14 @@ fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx DefIdSe if !visited.insert(did) { continue; } - for scope in &tcx.instance_mir(instance.def).source_scopes { - if let Some((ref inlined, _)) = scope.inlined { - result.insert(inlined.def_id()); + let body = tcx.instance_mir(instance.def); + for block in body.basic_blocks() { + for statement in &block.statements { + let mir::StatementKind::Coverage(_) = statement.kind else { continue }; + let scope = statement.source_info.scope; + if let Some(inlined) = scope.inlined_instance(&body.source_scopes) { + result.insert(inlined.def_id()); + } } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index eb2c3c9601943..2f92a77a7957d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -22,7 +22,6 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::GenericParam; use rustc_hir::Item; use rustc_hir::Node; -use rustc_infer::infer::error_reporting::same_type_modulo_infer; use rustc_infer::traits::TraitEngine; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; @@ -640,7 +639,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if expected.len() == 1 { "" } else { "s" }, ) ); - } else if !same_type_modulo_infer(given_ty, expected_ty) { + } else if !self.same_type_modulo_infer(given_ty, expected_ty) { // Print type mismatch let (expected_args, given_args) = self.cmp(given_ty, expected_ty); diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index c733f0d3c86d0..f629f6a0099d7 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -9,7 +9,6 @@ use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, - StatementAsExpression, }; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -75,8 +74,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut other_arms = vec![]; // Used only for diagnostics. - let mut prior_arm_ty = None; - for (i, arm) in arms.iter().enumerate() { + let mut prior_arm = None; + for arm in arms { if let Some(g) = &arm.guard { self.diverges.set(Diverges::Maybe); match g { @@ -96,21 +95,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let opt_suggest_box_span = self.opt_suggest_box_span(arm_ty, orig_expected); - let (arm_span, semi_span) = - self.get_appropriate_arm_semicolon_removal_span(&arms, i, prior_arm_ty, arm_ty); - let (span, code) = match i { + let (arm_block_id, arm_span) = if let hir::ExprKind::Block(blk, _) = arm.body.kind { + (Some(blk.hir_id), self.find_block_span(blk)) + } else { + (None, arm.body.span) + }; + + let (span, code) = match prior_arm { // The reason for the first arm to fail is not that the match arms diverge, // but rather that there's a prior obligation that doesn't hold. - 0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)), - _ => ( + None => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)), + Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => ( expr.span, ObligationCauseCode::MatchExpressionArm(Box::new(MatchExpressionArmCause { + arm_block_id, arm_span, + arm_ty, + prior_arm_block_id, + prior_arm_ty, + prior_arm_span, scrut_span: scrut.span, - semi_span, source: match_src, prior_arms: other_arms.clone(), - last_ty: prior_arm_ty.unwrap(), scrut_hir_id: scrut.hir_id, opt_suggest_box_span, })), @@ -139,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ret_ty = ret_coercion.borrow().expected_ty(); let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); self.can_coerce(arm_ty, ret_ty) - && prior_arm_ty.map_or(true, |t| self.can_coerce(t, ret_ty)) + && prior_arm.map_or(true, |(_, t, _)| self.can_coerce(t, ret_ty)) // The match arms need to unify for the case of `impl Trait`. && !matches!(ret_ty.kind(), ty::Opaque(..)) } @@ -181,7 +187,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if other_arms.len() > 5 { other_arms.remove(0); } - prior_arm_ty = Some(arm_ty); + + prior_arm = Some((arm_block_id, arm_ty, arm_span)); } // If all of the arms in the `match` diverge, @@ -207,28 +214,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match_ty } - fn get_appropriate_arm_semicolon_removal_span( - &self, - arms: &'tcx [hir::Arm<'tcx>], - i: usize, - prior_arm_ty: Option>, - arm_ty: Ty<'tcx>, - ) -> (Span, Option<(Span, StatementAsExpression)>) { - let arm = &arms[i]; - let (arm_span, mut semi_span) = if let hir::ExprKind::Block(blk, _) = &arm.body.kind { - self.find_block_span(blk, prior_arm_ty) - } else { - (arm.body.span, None) - }; - if semi_span.is_none() && i > 0 { - if let hir::ExprKind::Block(blk, _) = &arms[i - 1].body.kind { - let (_, semi_span_prev) = self.find_block_span(blk, Some(arm_ty)); - semi_span = semi_span_prev; - } - } - (arm_span, semi_span) - } - /// When the previously checked expression (the scrutinee) diverges, /// warn the user about the match arms being unreachable. fn warn_arms_when_scrutinee_diverges(&self, arms: &'tcx [hir::Arm<'tcx>]) { @@ -313,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else_ty: Ty<'tcx>, opt_suggest_box_span: Option, ) -> ObligationCause<'tcx> { - let mut outer_sp = if self.tcx.sess.source_map().is_multiline(span) { + let mut outer_span = if self.tcx.sess.source_map().is_multiline(span) { // The `if`/`else` isn't in one line in the output, include some context to make it // clear it is an if/else expression: // ``` @@ -339,69 +324,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None }; - let mut remove_semicolon = None; - let error_sp = if let ExprKind::Block(block, _) = &else_expr.kind { - let (error_sp, semi_sp) = self.find_block_span(block, Some(then_ty)); - remove_semicolon = semi_sp; - if block.expr.is_none() && block.stmts.is_empty() { - // Avoid overlapping spans that aren't as readable: - // ``` - // 2 | let x = if true { - // | _____________- - // 3 | | 3 - // | | - expected because of this - // 4 | | } else { - // | |____________^ - // 5 | || - // 6 | || }; - // | || ^ - // | ||_____| - // | |______if and else have incompatible types - // | expected integer, found `()` - // ``` - // by not pointing at the entire expression: - // ``` - // 2 | let x = if true { - // | ------- `if` and `else` have incompatible types - // 3 | 3 - // | - expected because of this - // 4 | } else { - // | ____________^ - // 5 | | - // 6 | | }; - // | |_____^ expected integer, found `()` - // ``` - if outer_sp.is_some() { - outer_sp = Some(self.tcx.sess.source_map().guess_head_span(span)); - } + let (error_sp, else_id) = if let ExprKind::Block(block, _) = &else_expr.kind { + let block = block.innermost_block(); + + // Avoid overlapping spans that aren't as readable: + // ``` + // 2 | let x = if true { + // | _____________- + // 3 | | 3 + // | | - expected because of this + // 4 | | } else { + // | |____________^ + // 5 | || + // 6 | || }; + // | || ^ + // | ||_____| + // | |______if and else have incompatible types + // | expected integer, found `()` + // ``` + // by not pointing at the entire expression: + // ``` + // 2 | let x = if true { + // | ------- `if` and `else` have incompatible types + // 3 | 3 + // | - expected because of this + // 4 | } else { + // | ____________^ + // 5 | | + // 6 | | }; + // | |_____^ expected integer, found `()` + // ``` + if block.expr.is_none() && block.stmts.is_empty() + && let Some(outer_span) = &mut outer_span + { + *outer_span = self.tcx.sess.source_map().guess_head_span(*outer_span); } - error_sp + + (self.find_block_span(block), block.hir_id) } else { - // shouldn't happen unless the parser has done something weird - else_expr.span + (else_expr.span, else_expr.hir_id) }; - // Compute `Span` of `then` part of `if`-expression. - let then_sp = if let ExprKind::Block(block, _) = &then_expr.kind { - let (then_sp, semi_sp) = self.find_block_span(block, Some(else_ty)); - remove_semicolon = remove_semicolon.or(semi_sp); + let then_id = if let ExprKind::Block(block, _) = &then_expr.kind { + let block = block.innermost_block(); + // Exclude overlapping spans if block.expr.is_none() && block.stmts.is_empty() { - outer_sp = None; // same as in `error_sp`; cleanup output + outer_span = None; } - then_sp + block.hir_id } else { - // shouldn't happen unless the parser has done something weird - then_expr.span + then_expr.hir_id }; // Finally construct the cause: self.cause( error_sp, ObligationCauseCode::IfExpression(Box::new(IfExpressionCause { - then: then_sp, - else_sp: error_sp, - outer: outer_sp, - semicolon: remove_semicolon, + else_id, + then_id, + then_ty, + else_ty, + outer_span, opt_suggest_box_span, })), ) @@ -482,22 +465,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn find_block_span( - &self, - block: &'tcx hir::Block<'tcx>, - expected_ty: Option>, - ) -> (Span, Option<(Span, StatementAsExpression)>) { - if let Some(expr) = &block.expr { - (expr.span, None) - } else if let Some(stmt) = block.stmts.last() { - // possibly incorrect trailing `;` in the else arm - (stmt.span, expected_ty.and_then(|ty| self.could_remove_semicolon(block, ty))) - } else { - // empty block; point at its entirety - (block.span, None) - } - } - // When we have a `match` as a tail expression in a `fn` with a returned `impl Trait` // we check if the different arms would work with boxed trait objects instead and // provide a structured suggestion in that case. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index d079aeb4801ca..21b3c9063a78a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -30,17 +30,15 @@ use rustc_middle::ty::{ }; use rustc_session::lint; use rustc_span::hygiene::DesugaringKind; -use rustc_span::source_map::{original_sp, DUMMY_SP}; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{self, BytePos, Span}; +use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt, + self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt, }; use std::collections::hash_map::Entry; -use std::iter; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -1059,84 +1057,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); } - pub(in super::super) fn could_remove_semicolon( - &self, - blk: &'tcx hir::Block<'tcx>, - expected_ty: Ty<'tcx>, - ) -> Option<(Span, StatementAsExpression)> { - // Be helpful when the user wrote `{... expr;}` and - // taking the `;` off is enough to fix the error. - let last_stmt = blk.stmts.last()?; - let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else { - return None; - }; - let last_expr_ty = self.node_ty(last_expr.hir_id); - let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { - (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) - if last_def_id == exp_def_id => - { - StatementAsExpression::CorrectType - } - (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { - debug!( - "both opaque, likely future {:?} {:?} {:?} {:?}", - last_def_id, last_bounds, exp_def_id, exp_bounds - ); - - let last_local_id = last_def_id.as_local()?; - let exp_local_id = exp_def_id.as_local()?; - - match ( - &self.tcx.hir().expect_item(last_local_id).kind, - &self.tcx.hir().expect_item(exp_local_id).kind, - ) { - ( - hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), - hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), - ) if iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { - match (left, right) { - ( - hir::GenericBound::Trait(tl, ml), - hir::GenericBound::Trait(tr, mr), - ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() - && ml == mr => - { - true - } - ( - hir::GenericBound::LangItemTrait(langl, _, _, argsl), - hir::GenericBound::LangItemTrait(langr, _, _, argsr), - ) if langl == langr => { - // FIXME: consider the bounds! - debug!("{:?} {:?}", argsl, argsr); - true - } - _ => false, - } - }) => - { - StatementAsExpression::NeedsBoxing - } - _ => StatementAsExpression::CorrectType, - } - } - _ => StatementAsExpression::CorrectType, - }; - if (matches!(last_expr_ty.kind(), ty::Error(_)) - || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()) - && matches!(needs_box, StatementAsExpression::CorrectType) - { - return None; - } - let span = if last_stmt.span.from_expansion() { - let mac_call = original_sp(last_stmt.span, blk.span); - self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)? - } else { - last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1)) - }; - Some((span, needs_box)) - } - // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. #[instrument(skip(self, span), level = "debug")] diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 871fc4a21f2a7..3e6ff72204f4c 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -3,7 +3,6 @@ use crate::astconv::AstConv; use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel}; use rustc_ast::util::parser::ExprPrecedence; -use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind}; @@ -14,7 +13,7 @@ use rustc_hir::{ use rustc_infer::infer::{self, TyCtxtInferExt}; use rustc_infer::traits::{self, StatementAsExpression}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, Binder, IsSuggestable, Subst, ToPredicate, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Binder, IsSuggestable, Subst, ToPredicate, Ty}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -904,117 +903,4 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } } - - pub(crate) fn consider_returning_binding( - &self, - blk: &'tcx hir::Block<'tcx>, - expected_ty: Ty<'tcx>, - err: &mut Diagnostic, - ) { - let mut shadowed = FxHashSet::default(); - let mut candidate_idents = vec![]; - let mut find_compatible_candidates = |pat: &hir::Pat<'_>| { - if let hir::PatKind::Binding(_, hir_id, ident, _) = &pat.kind - && let Some(pat_ty) = self.typeck_results.borrow().node_type_opt(*hir_id) - { - let pat_ty = self.resolve_vars_if_possible(pat_ty); - if self.can_coerce(pat_ty, expected_ty) - && !(pat_ty, expected_ty).references_error() - && shadowed.insert(ident.name) - { - candidate_idents.push((*ident, pat_ty)); - } - } - true - }; - - let hir = self.tcx.hir(); - for stmt in blk.stmts.iter().rev() { - let StmtKind::Local(local) = &stmt.kind else { continue; }; - local.pat.walk(&mut find_compatible_candidates); - } - match hir.find(hir.get_parent_node(blk.hir_id)) { - Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => { - match hir.find(hir.get_parent_node(*hir_id)) { - Some(hir::Node::Arm(hir::Arm { pat, .. })) => { - pat.walk(&mut find_compatible_candidates); - } - Some( - hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(_, body), - .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), - .. - }) - | hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(hir::Closure { body, .. }), - .. - }), - ) => { - for param in hir.body(*body).params { - param.pat.walk(&mut find_compatible_candidates); - } - } - Some(hir::Node::Expr(hir::Expr { - kind: - hir::ExprKind::If( - hir::Expr { kind: hir::ExprKind::Let(let_), .. }, - then_block, - _, - ), - .. - })) if then_block.hir_id == *hir_id => { - let_.pat.walk(&mut find_compatible_candidates); - } - _ => {} - } - } - _ => {} - } - - match &candidate_idents[..] { - [(ident, _ty)] => { - let sm = self.tcx.sess.source_map(); - if let Some(stmt) = blk.stmts.last() { - let stmt_span = sm.stmt_span(stmt.span, blk.span); - let sugg = if sm.is_multiline(blk.span) - && let Some(spacing) = sm.indentation_before(stmt_span) - { - format!("\n{spacing}{ident}") - } else { - format!(" {ident}") - }; - err.span_suggestion_verbose( - stmt_span.shrink_to_hi(), - format!("consider returning the local binding `{ident}`"), - sugg, - Applicability::MachineApplicable, - ); - } else { - let sugg = if sm.is_multiline(blk.span) - && let Some(spacing) = sm.indentation_before(blk.span.shrink_to_lo()) - { - format!("\n{spacing} {ident}\n{spacing}") - } else { - format!(" {ident} ") - }; - let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi(); - err.span_suggestion_verbose( - sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span), - format!("consider returning the local binding `{ident}`"), - sugg, - Applicability::MachineApplicable, - ); - } - } - values if (1..3).contains(&values.len()) => { - let spans = values.iter().map(|(ident, _)| ident.span).collect::>(); - err.span_note(spans, "consider returning one of these bindings"); - } - _ => {} - } - } } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 74aa0d9c7bcb2..55f781ce0222a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -97,7 +97,7 @@ impl *const T { /// refactored. #[unstable(feature = "ptr_const_cast", issue = "92675")] #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")] - pub const fn as_mut(self) -> *mut T { + pub const fn cast_mut(self) -> *mut T { self as _ } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index b988090f4bc4c..27e8b20b3c52d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -96,11 +96,13 @@ impl *mut T { /// refactored. /// /// While not strictly required (`*mut T` coerces to `*const T`), this is provided for symmetry - /// with `as_mut()` on `*const T` and may have documentation value if used instead of implicit + /// with [`cast_mut`] on `*const T` and may have documentation value if used instead of implicit /// coercion. + /// + /// [`cast_mut`]: #method.cast_mut #[unstable(feature = "ptr_const_cast", issue = "92675")] #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")] - pub const fn as_const(self) -> *const T { + pub const fn cast_const(self) -> *const T { self as _ } @@ -289,7 +291,7 @@ impl *mut T { /// For the mutable counterpart see [`as_mut`]. /// /// [`as_uninit_ref`]: #method.as_uninit_ref-1 - /// [`as_mut`]: #method.as_mut-1 + /// [`as_mut`]: #method.as_mut /// /// # Safety /// diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 8a68cdf7d651b..45b052c824d31 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1009,6 +1009,15 @@ impl Result { /// Returns the contained [`Ok`] value, consuming the `self` value. /// + /// Because this function may panic, its use is generally discouraged. + /// Instead, prefer to use pattern matching and handle the [`Err`] + /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or + /// [`unwrap_or_default`]. + /// + /// [`unwrap_or`]: Result::unwrap_or + /// [`unwrap_or_else`]: Result::unwrap_or_else + /// [`unwrap_or_default`]: Result::unwrap_or_default + /// /// # Panics /// /// Panics if the value is an [`Err`], with a panic message including the diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 69409b77251cb..70b7a47bcd58b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -216,6 +216,15 @@ details.rustdoc-toggle > summary::before, div.impl-items > div:not(.docblock):not(.item-info), .content ul.crate a.crate, a.srclink, +#main-content > .since, +#help-button > button, +details.rustdoc-toggle.top-doc > summary, +details.rustdoc-toggle.top-doc > summary::before, +details.rustdoc-toggle.non-exhaustive > summary, +details.rustdoc-toggle.non-exhaustive > summary::before, +.scraped-example-title, +.more-examples-toggle summary, .more-examples-toggle .hide-more, +.example-links a, /* This selector is for the items listed in the "all items" page. */ #main-content > ul.docblock > li > a { font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; @@ -702,7 +711,6 @@ pre, .rustdoc.source .example-wrap { } #main-content > .since { top: inherit; - font-family: "Fira Sans", Arial, sans-serif; } .content table:not(.table-display) { @@ -1518,7 +1526,6 @@ input:checked + .slider { } #help-button > button { - font-family: "Fira Sans", Arial, sans-serif; text-align: center; /* Rare exception to specifying font sizes in rem. Since this is acting as an icon, it's okay to specify their sizes in pixels. */ @@ -1690,7 +1697,6 @@ details.rustdoc-toggle.top-doc > summary, details.rustdoc-toggle.top-doc > summary::before, details.rustdoc-toggle.non-exhaustive > summary, details.rustdoc-toggle.non-exhaustive > summary::before { - font-family: 'Fira Sans'; font-size: 1rem; } @@ -2176,10 +2182,6 @@ in storage.js plus the media query with (min-width: 701px) border-radius: 50px; } -.scraped-example-title { - font-family: 'Fira Sans'; -} - .scraped-example .code-wrapper { position: relative; display: flex; @@ -2283,10 +2285,6 @@ in storage.js plus the media query with (min-width: 701px) cursor: pointer; } -.more-examples-toggle summary, .more-examples-toggle .hide-more { - font-family: 'Fira Sans'; -} - .more-scraped-examples { margin-left: 5px; display: flex; @@ -2321,7 +2319,6 @@ in storage.js plus the media query with (min-width: 701px) .example-links a { margin-top: 20px; - font-family: 'Fira Sans'; } .example-links ul { diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline-dead.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline-dead.txt new file mode 100644 index 0000000000000..d102d9ecf7d14 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline-dead.txt @@ -0,0 +1,21 @@ + 1| |// Regression test for issue #98833. + 2| |// compile-flags: -Zinline-mir + 3| | + 4| 1|fn main() { + 5| 1| println!("{}", live::()); + 6| 1|} + 7| | + 8| |#[inline] + 9| 1|fn live() -> u32 { + 10| 1| if B { + 11| 0| dead() + 12| | } else { + 13| 1| 0 + 14| | } + 15| 1|} + 16| | + 17| |#[inline] + 18| 0|fn dead() -> u32 { + 19| 0| 42 + 20| 0|} + diff --git a/src/test/run-make-fulldeps/coverage/inline-dead.rs b/src/test/run-make-fulldeps/coverage/inline-dead.rs new file mode 100644 index 0000000000000..cd1ae911a5f7e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/inline-dead.rs @@ -0,0 +1,20 @@ +// Regression test for issue #98833. +// compile-flags: -Zinline-mir + +fn main() { + println!("{}", live::()); +} + +#[inline] +fn live() -> u32 { + if B { + dead() + } else { + 0 + } +} + +#[inline] +fn dead() -> u32 { + 42 +} diff --git a/src/test/rustdoc/const-generics/add-impl.rs b/src/test/rustdoc/const-generics/add-impl.rs index e54f9a57ae4ee..591139523456e 100644 --- a/src/test/rustdoc/const-generics/add-impl.rs +++ b/src/test/rustdoc/const-generics/add-impl.rs @@ -7,7 +7,7 @@ pub struct Simd { inner: T, } -// @has foo/struct.Simd.html '//div[@id="trait-implementations-list"]//h3[@class="code-header in-band"]' 'impl Add> for Simd' +// @has foo/struct.Simd.html '//div[@id="trait-implementations-list"]//h3[@class="code-header in-band"]' 'impl Add> for Simd' impl Add for Simd { type Output = Self; diff --git a/src/test/rustdoc/const-generics/const-generic-defaults.rs b/src/test/rustdoc/const-generics/const-generic-defaults.rs index 8035f826775ef..2693d9b596993 100644 --- a/src/test/rustdoc/const-generics/const-generic-defaults.rs +++ b/src/test/rustdoc/const-generics/const-generic-defaults.rs @@ -1,5 +1,5 @@ #![crate_name = "foo"] // @has foo/struct.Foo.html '//pre[@class="rust struct"]' \ -// 'pub struct Foo(_);' +// 'pub struct Foo(_);' pub struct Foo(T); diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs index 61af7de4794a6..352a8e646bb49 100644 --- a/src/test/rustdoc/const-generics/const-generics-docs.rs +++ b/src/test/rustdoc/const-generics/const-generics-docs.rs @@ -19,8 +19,8 @@ pub use extern_crate::WTrait; // @has foo/trait.Trait.html '//pre[@class="rust trait"]' \ // 'pub trait Trait' -// @has - '//*[@id="impl-Trait%3C1_usize%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<1_usize> for u8' -// @has - '//*[@id="impl-Trait%3C2_usize%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<2_usize> for u8' +// @has - '//*[@id="impl-Trait%3C1%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<1> for u8' +// @has - '//*[@id="impl-Trait%3C2%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<2> for u8' // @has - '//*[@id="impl-Trait%3C{1%20+%202}%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<{1 + 2}> for u8' // @has - '//*[@id="impl-Trait%3CN%3E-for-%5Bu8%3B%20N%5D"]//h3[@class="code-header in-band"]' \ // 'impl Trait for [u8; N]' diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs index 2868517774d46..6ce67dcaf1d9b 100644 --- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs +++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs @@ -44,11 +44,11 @@ struct WithParameters { } impl WithParameters { - fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference + fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference } impl WithParameters { - fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference + fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference } fn main() {} diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr index 54a7cf7cab757..fb39ed60b8235 100644 --- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr +++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr @@ -22,17 +22,17 @@ error: passing `Foo` by reference LL | fn with_ref(&self) {} | ^^^^^ help: try passing by value: `Foo` -error: passing `WithParameters` by reference +error: passing `WithParameters` by reference --> $DIR/rustc_pass_by_value_self.rs:47:17 | LL | fn with_ref(&self) {} - | ^^^^^ help: try passing by value: `WithParameters` + | ^^^^^ help: try passing by value: `WithParameters` -error: passing `WithParameters` by reference +error: passing `WithParameters` by reference --> $DIR/rustc_pass_by_value_self.rs:51:17 | LL | fn with_ref(&self) {} - | ^^^^^ help: try passing by value: `WithParameters` + | ^^^^^ help: try passing by value: `WithParameters` error: aborting due to 5 previous errors diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr index 1a14ab40b1f86..5e531a993c62c 100644 --- a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr +++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/match_arr_unknown_len.rs:3:9 | LL | [1, 2] => true, - | ^^^^^^ expected `2_usize`, found `N` + | ^^^^^^ expected `2`, found `N` | = note: expected array `[u32; 2]` found array `[u32; N]` diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr index ada6e357aea5e..e5887689690e7 100644 --- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -18,14 +18,6 @@ LL | | break 0u8; LL | | }; | |_________- enclosing `async` block -error[E0271]: type mismatch resolving ` as Future>::Output == ()` - --> $DIR/async-block-control-flow-static-semantics.rs:26:39 - | -LL | let _: &dyn Future = █ - | ^^^^^^ expected `()`, found `u8` - | - = note: required for the cast from `impl Future` to the object type `dyn Future` - error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:21:58 | @@ -40,7 +32,7 @@ LL | | } | |_^ expected `u8`, found `()` error[E0271]: type mismatch resolving ` as Future>::Output == ()` - --> $DIR/async-block-control-flow-static-semantics.rs:17:39 + --> $DIR/async-block-control-flow-static-semantics.rs:26:39 | LL | let _: &dyn Future = █ | ^^^^^^ expected `()`, found `u8` @@ -55,6 +47,14 @@ LL | fn return_targets_async_block_not_fn() -> u8 { | | | implicitly returns `()` as its body has no tail or `return` expression +error[E0271]: type mismatch resolving ` as Future>::Output == ()` + --> $DIR/async-block-control-flow-static-semantics.rs:17:39 + | +LL | let _: &dyn Future = █ + | ^^^^^^ expected `()`, found `u8` + | + = note: required for the cast from `impl Future` to the object type `dyn Future` + error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:47:44 | diff --git a/src/test/ui/const-generics/associated-type-bound-fail.stderr b/src/test/ui/const-generics/associated-type-bound-fail.stderr index da2558229a758..e5e7ee26e44bc 100644 --- a/src/test/ui/const-generics/associated-type-bound-fail.stderr +++ b/src/test/ui/const-generics/associated-type-bound-fail.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `u16: Bar` is not satisfied LL | type Assoc = u16; | ^^^ the trait `Bar` is not implemented for `u16` | - = help: the trait `Bar<3_usize>` is implemented for `u16` + = help: the trait `Bar<3>` is implemented for `u16` note: required by a bound in `Foo::Assoc` --> $DIR/associated-type-bound-fail.rs:4:17 | diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr index 905a285370a0d..e8826ce4335e7 100644 --- a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr +++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/generic-expr-default-concrete.rs:10:5 | LL | Foo::<10, 12> - | ^^^^^^^^^^^^^ expected `11_usize`, found `12_usize` + | ^^^^^^^^^^^^^ expected `11`, found `12` | - = note: expected type `11_usize` - found type `12_usize` + = note: expected type `11` + found type `12` error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs index fce4ec4edda08..ec131505ed755 100644 --- a/src/test/ui/const-generics/defaults/mismatch.rs +++ b/src/test/ui/const-generics/defaults/mismatch.rs @@ -1,22 +1,22 @@ -pub struct Example; -pub struct Example2(T); -pub struct Example3(T); -pub struct Example4; +pub struct Example; +pub struct Example2(T); +pub struct Example3(T); +pub struct Example4; fn main() { - let e: Example::<13> = (); + let e: Example<13> = (); //~^ Error: mismatched types //~| expected struct `Example` - let e: Example2:: = (); + let e: Example2 = (); //~^ Error: mismatched types //~| expected struct `Example2` - let e: Example3::<13, u32> = (); + let e: Example3<13, u32> = (); //~^ Error: mismatched types //~| expected struct `Example3` - let e: Example3::<7> = (); + let e: Example3<7> = (); //~^ Error: mismatched types - //~| expected struct `Example3<7_usize>` - let e: Example4::<7> = (); + //~| expected struct `Example3<7>` + let e: Example4<7> = (); //~^ Error: mismatched types - //~| expected struct `Example4<7_usize>` + //~| expected struct `Example4<7>` } diff --git a/src/test/ui/const-generics/defaults/mismatch.stderr b/src/test/ui/const-generics/defaults/mismatch.stderr index 369768191951b..52c54aace5f16 100644 --- a/src/test/ui/const-generics/defaults/mismatch.stderr +++ b/src/test/ui/const-generics/defaults/mismatch.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/mismatch.rs:7:28 + --> $DIR/mismatch.rs:7:26 | -LL | let e: Example::<13> = (); - | ------------- ^^ expected struct `Example`, found `()` +LL | let e: Example<13> = (); + | ----------- ^^ expected struct `Example`, found `()` | | | expected due to this | @@ -10,10 +10,10 @@ LL | let e: Example::<13> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:10:34 + --> $DIR/mismatch.rs:10:32 | -LL | let e: Example2:: = (); - | ------------------- ^^ expected struct `Example2`, found `()` +LL | let e: Example2 = (); + | ----------------- ^^ expected struct `Example2`, found `()` | | | expected due to this | @@ -21,10 +21,10 @@ LL | let e: Example2:: = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:13:34 + --> $DIR/mismatch.rs:13:32 | -LL | let e: Example3::<13, u32> = (); - | ------------------- ^^ expected struct `Example3`, found `()` +LL | let e: Example3<13, u32> = (); + | ----------------- ^^ expected struct `Example3`, found `()` | | | expected due to this | @@ -32,25 +32,25 @@ LL | let e: Example3::<13, u32> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:16:28 + --> $DIR/mismatch.rs:16:26 | -LL | let e: Example3::<7> = (); - | ------------- ^^ expected struct `Example3`, found `()` +LL | let e: Example3<7> = (); + | ----------- ^^ expected struct `Example3`, found `()` | | | expected due to this | - = note: expected struct `Example3<7_usize>` + = note: expected struct `Example3<7>` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:19:28 + --> $DIR/mismatch.rs:19:26 | -LL | let e: Example4::<7> = (); - | ------------- ^^ expected struct `Example4`, found `()` +LL | let e: Example4<7> = (); + | ----------- ^^ expected struct `Example4`, found `()` | | | expected due to this | - = note: expected struct `Example4<7_usize>` + = note: expected struct `Example4<7>` found unit type `()` error: aborting due to 5 previous errors diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs index f633e56b0ec1d..80013e7b4b230 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -4,16 +4,15 @@ trait Trait {} impl Trait for Uwu {} fn rawr() -> impl Trait { - //~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied + //~^ error: the trait bound `Uwu<10, 12>: Trait` is not satisfied Uwu::<10, 12> } -trait Traitor { } +trait Traitor {} impl Traitor for u32 {} impl Traitor<1, 2> for u64 {} - fn uwu() -> impl Traitor { //~^ error: the trait bound `u32: Traitor` is not satisfied 1_u32 diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr index cbc7b93f3a925..f2e7777ce6814 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -1,16 +1,16 @@ -error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied +error[E0277]: the trait bound `Uwu<10, 12>: Trait` is not satisfied --> $DIR/rp_impl_trait_fail.rs:6:14 | LL | fn rawr() -> impl Trait { - | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` + | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10, 12>` LL | LL | Uwu::<10, 12> - | ------------- return type was inferred to be `Uwu<10_u32, 12_u32>` here + | ------------- return type was inferred to be `Uwu<10, 12>` here | = help: the trait `Trait` is implemented for `Uwu` error[E0277]: the trait bound `u32: Traitor` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:17:26 + --> $DIR/rp_impl_trait_fail.rs:16:26 | LL | fn uwu() -> impl Traitor { | ^^^^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u32` @@ -19,11 +19,11 @@ LL | 1_u32 | ----- return type was inferred to be `u32` here | = help: the following other types implement trait `Traitor`: - > - > + > + > error[E0277]: the trait bound `u64: Traitor` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:22:13 + --> $DIR/rp_impl_trait_fail.rs:21:13 | LL | fn owo() -> impl Traitor { | ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64` @@ -32,8 +32,8 @@ LL | 1_u64 | ----- return type was inferred to be `u64` here | = help: the following other types implement trait `Traitor`: - > - > + > + > error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.rs b/src/test/ui/const-generics/defaults/trait_objects_fail.rs index 5e779d2e8de59..6ab803f990920 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.rs +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.rs @@ -16,7 +16,7 @@ trait Traitor { } } -impl Traitor<2, 3> for bool { } +impl Traitor<2, 3> for bool {} fn bar(arg: &dyn Traitor) -> u8 { arg.owo() @@ -26,5 +26,5 @@ fn main() { foo(&10_u32); //~^ error: the trait bound `u32: Trait` is not satisfied bar(&true); - //~^ error: the trait bound `bool: Traitor<{_: u8}>` is not satisfied + //~^ error: the trait bound `bool: Traitor<_>` is not satisfied } diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr index da85b2059f0a3..a9c185e5fcbd1 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr @@ -6,19 +6,19 @@ LL | foo(&10_u32); | | | required by a bound introduced by this call | - = help: the trait `Trait<2_u8>` is implemented for `u32` + = help: the trait `Trait<2>` is implemented for `u32` = note: required for the cast from `u32` to the object type `dyn Trait` -error[E0277]: the trait bound `bool: Traitor<{_: u8}>` is not satisfied +error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 | LL | bar(&true); - | --- ^^^^^ the trait `Traitor<{_: u8}>` is not implemented for `bool` + | --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | | | required by a bound introduced by this call | - = help: the trait `Traitor<2_u8, 3_u8>` is implemented for `bool` - = note: required for the cast from `bool` to the object type `dyn Traitor<{_: u8}>` + = help: the trait `Traitor<2, 3>` is implemented for `bool` + = note: required for the cast from `bool` to the object type `dyn Traitor<_>` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/defaults/wfness.rs b/src/test/ui/const-generics/defaults/wfness.rs index d366040ba3ea6..a93f670815a03 100644 --- a/src/test/ui/const-generics/defaults/wfness.rs +++ b/src/test/ui/const-generics/defaults/wfness.rs @@ -3,16 +3,20 @@ struct Ooopsies; trait Trait {} impl Trait<3> for () {} -struct WhereClause where (): Trait; -//~^ error: the trait bound `(): Trait<2_u8>` is not satisfied +struct WhereClause +where + (): Trait; +//~^ error: the trait bound `(): Trait<2>` is not satisfied trait Traitor {} -struct WhereClauseTooGeneric(T) where (): Traitor; +struct WhereClauseTooGeneric(T) +where + (): Traitor; // no error on struct def struct DependentDefaultWfness>(T); fn foo() -> DependentDefaultWfness { - //~^ error: the trait bound `(): Trait<1_u8>` is not satisfied + //~^ error: the trait bound `(): Trait<1>` is not satisfied loop {} } diff --git a/src/test/ui/const-generics/defaults/wfness.stderr b/src/test/ui/const-generics/defaults/wfness.stderr index 8b405d6753e56..25038f830befc 100644 --- a/src/test/ui/const-generics/defaults/wfness.stderr +++ b/src/test/ui/const-generics/defaults/wfness.stderr @@ -4,26 +4,29 @@ error[E0080]: evaluation of constant value failed LL | struct Ooopsies; | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow -error[E0277]: the trait bound `(): Trait<2_u8>` is not satisfied - --> $DIR/wfness.rs:6:47 +error[E0277]: the trait bound `(): Trait<2>` is not satisfied + --> $DIR/wfness.rs:8:9 | -LL | struct WhereClause where (): Trait; - | ^^^^^^^^ the trait `Trait<2_u8>` is not implemented for `()` +LL | (): Trait; + | ^^^^^^^^ the trait `Trait<2>` is not implemented for `()` | - = help: the trait `Trait<3_u8>` is implemented for `()` + = help: the trait `Trait<3>` is implemented for `()` -error[E0277]: the trait bound `(): Trait<1_u8>` is not satisfied - --> $DIR/wfness.rs:14:13 +error[E0277]: the trait bound `(): Trait<1>` is not satisfied + --> $DIR/wfness.rs:18:13 | LL | fn foo() -> DependentDefaultWfness { - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1_u8>` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1>` is not implemented for `()` | - = help: the trait `Trait<3_u8>` is implemented for `()` + = help: the trait `Trait<3>` is implemented for `()` note: required by a bound in `WhereClause` - --> $DIR/wfness.rs:6:47 + --> $DIR/wfness.rs:8:9 | -LL | struct WhereClause where (): Trait; - | ^^^^^^^^ required by this bound in `WhereClause` +LL | struct WhereClause + | ----------- required by a bound in this +LL | where +LL | (): Trait; + | ^^^^^^^^ required by this bound in `WhereClause` error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/different_generic_args.full.stderr b/src/test/ui/const-generics/different_generic_args.full.stderr index a2dcc033627c6..eba1768f7dda3 100644 --- a/src/test/ui/const-generics/different_generic_args.full.stderr +++ b/src/test/ui/const-generics/different_generic_args.full.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/different_generic_args.rs:11:9 | LL | u = ConstUsize::<4> {}; - | ^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize` + | ^^^^^^^^^^^^^^^^^^ expected `3`, found `4` | - = note: expected struct `ConstUsize<3_usize>` - found struct `ConstUsize<4_usize>` + = note: expected struct `ConstUsize<3>` + found struct `ConstUsize<4>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/different_generic_args.min.stderr b/src/test/ui/const-generics/different_generic_args.min.stderr index a2dcc033627c6..eba1768f7dda3 100644 --- a/src/test/ui/const-generics/different_generic_args.min.stderr +++ b/src/test/ui/const-generics/different_generic_args.min.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/different_generic_args.rs:11:9 | LL | u = ConstUsize::<4> {}; - | ^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize` + | ^^^^^^^^^^^^^^^^^^ expected `3`, found `4` | - = note: expected struct `ConstUsize<3_usize>` - found struct `ConstUsize<4_usize>` + = note: expected struct `ConstUsize<3>` + found struct `ConstUsize<4>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/different_generic_args_array.stderr b/src/test/ui/const-generics/different_generic_args_array.stderr index f0b9035357d82..4c5b5ada4f132 100644 --- a/src/test/ui/const-generics/different_generic_args_array.stderr +++ b/src/test/ui/const-generics/different_generic_args_array.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/different_generic_args_array.rs:9:9 | LL | x = Const::<{ [4] }> {}; - | ^^^^^^^^^^^^^^^^^^^ expected `[3_usize]`, found `[4_usize]` + | ^^^^^^^^^^^^^^^^^^^ expected `[3]`, found `[4]` | - = note: expected struct `Const<[3_usize]>` - found struct `Const<[4_usize]>` + = note: expected struct `Const<[3]>` + found struct `Const<[4]>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/exhaustive-value.stderr b/src/test/ui/const-generics/exhaustive-value.stderr index 9c1b086f4da9a..76a83ba67ce79 100644 --- a/src/test/ui/const-generics/exhaustive-value.stderr +++ b/src/test/ui/const-generics/exhaustive-value.stderr @@ -5,14 +5,14 @@ LL | <() as Foo>::test() | ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` | = help: the following other types implement trait `Foo`: - <() as Foo<0_u8>> - <() as Foo<100_u8>> - <() as Foo<101_u8>> - <() as Foo<102_u8>> - <() as Foo<103_u8>> - <() as Foo<104_u8>> - <() as Foo<105_u8>> - <() as Foo<106_u8>> + <() as Foo<0>> + <() as Foo<100>> + <() as Foo<101>> + <() as Foo<102>> + <() as Foo<103>> + <() as Foo<104>> + <() as Foo<105>> + <() as Foo<106>> and 248 others error: aborting due to previous error diff --git a/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr b/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr index 7581cf4120ecf..52d1b29f93222 100644 --- a/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr +++ b/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr @@ -14,7 +14,7 @@ LL | fn ty_fn() -> Bar { | ---------^- | | | | | not allowed in type signatures - | help: replace with the correct return type: `Bar` + | help: replace with the correct return type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/in-signature.rs:17:25 @@ -24,7 +24,7 @@ LL | fn ty_fn_mixed() -> Bar<_, _> { | | | | | | | not allowed in type signatures | | not allowed in type signatures - | help: replace with the correct return type: `Bar` + | help: replace with the correct return type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:22:15 @@ -45,7 +45,7 @@ LL | const TY_CT: Bar = Bar::(0); | ^^^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/in-signature.rs:28:19 @@ -54,7 +54,7 @@ LL | static TY_STATIC: Bar = Bar::(0); | ^^^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:30:20 @@ -63,7 +63,7 @@ LL | const TY_CT_MIXED: Bar<_, _> = Bar::(0); | ^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/in-signature.rs:32:25 @@ -72,7 +72,7 @@ LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::(0); | ^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:35:21 diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr index f235eb443b829..ababb27a869d6 100644 --- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr @@ -56,19 +56,19 @@ error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:23:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13` | - = note: expected type `12_u128` - found type `13_u128` + = note: expected type `12` + found type `13` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:25:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14` | - = note: expected type `13_u128` - found type `14_u128` + = note: expected type `13` + found type `14` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:35:5 @@ -128,19 +128,19 @@ error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:41:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13` | - = note: expected type `12_u128` - found type `13_u128` + = note: expected type `12` + found type `13` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:43:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14` | - = note: expected type `13_u128` - found type `14_u128` + = note: expected type `13` + found type `14` error: aborting due to 12 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs index 90953145944fe..b8f9827ec9187 100644 --- a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs +++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] fn test() -> [u8; N - 1] { - //~^ ERROR evaluation of `test::<0_usize>::{constant#0}` failed + //~^ ERROR evaluation of `test::<0>::{constant#0}` failed todo!() } diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr index 31ccf97969472..bd71b49ee238b 100644 --- a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr @@ -1,4 +1,4 @@ -error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed +error[E0080]: evaluation of `test::<0>::{constant#0}` failed --> $DIR/from-sig-fail.rs:4:35 | LL | fn test() -> [u8; N - 1] { diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr index 77a3b77ad428b..7a083733a2cd1 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -4,14 +4,14 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: usize}>`, but its trait bounds were not satisfied +error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 | LL | struct Foo {} | -------------------------- function or associated item `foo` not found for this struct ... LL | Foo::foo(); - | ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds + | ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `[u8; _]: Bar<[(); _]>` diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index 41afaec86b6e4..4d0d0253f1b6d 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -34,21 +34,21 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: const parameters may only be used as standalone arguments, i.e. `J` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` +error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, | ^^^^ | - = note: cannot satisfy `IsLessOrEqual: True` + = note: cannot satisfy `IsLessOrEqual: True` -error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` +error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, | ^^^^ | - = note: cannot satisfy `IsLessOrEqual: True` + = note: cannot satisfy `IsLessOrEqual: True` error: aborting due to 6 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs index c47a350c7fb43..cae54df4c1210 100644 --- a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs +++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs @@ -2,10 +2,13 @@ #![allow(incomplete_features)] type Arr = [u8; N - 1]; -//~^ ERROR evaluation of `Arr::<0_usize>::{constant#0}` failed +//~^ ERROR evaluation of `Arr::<0>::{constant#0}` failed -fn test() -> Arr where [u8; N - 1]: Sized { -//~^ ERROR evaluation of `test::<0_usize>::{constant#0}` failed +fn test() -> Arr +where + [u8; N - 1]: Sized, + //~^ ERROR evaluation of `test::<0>::{constant#0}` failed +{ todo!() } diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr index 99fc92fb4f0ad..a25fa56b7d498 100644 --- a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr @@ -1,10 +1,10 @@ -error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed - --> $DIR/simple_fail.rs:7:48 +error[E0080]: evaluation of `test::<0>::{constant#0}` failed + --> $DIR/simple_fail.rs:9:10 | -LL | fn test() -> Arr where [u8; N - 1]: Sized { - | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow +LL | [u8; N - 1]: Sized, + | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow -error[E0080]: evaluation of `Arr::<0_usize>::{constant#0}` failed +error[E0080]: evaluation of `Arr::<0>::{constant#0}` failed --> $DIR/simple_fail.rs:4:33 | LL | type Arr = [u8; N - 1]; diff --git a/src/test/ui/const-generics/infer/one-param-uninferred.stderr b/src/test/ui/const-generics/infer/one-param-uninferred.stderr index 98ea8df825265..cf70c21813950 100644 --- a/src/test/ui/const-generics/infer/one-param-uninferred.stderr +++ b/src/test/ui/const-generics/infer/one-param-uninferred.stderr @@ -6,8 +6,8 @@ LL | let _: [u8; 17] = foo(); | help: consider specifying the generic arguments | -LL | let _: [u8; 17] = foo::<17_usize, M>(); - | +++++++++++++++ +LL | let _: [u8; 17] = foo::<17, M>(); + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/const-generics/issue-66451.stderr b/src/test/ui/const-generics/issue-66451.stderr index b691eac4f2d0e..e0cb0b661ff65 100644 --- a/src/test/ui/const-generics/issue-66451.stderr +++ b/src/test/ui/const-generics/issue-66451.stderr @@ -8,12 +8,12 @@ LL | | value: 3, LL | | nested: &Bar(5), LL | | } LL | | }> = x; - | | - ^ expected `Foo { value: 3_i32, nested: &Bar::(5_i32) }`, found `Foo { value: 3_i32, nested: &Bar::(4_i32) }` + | | - ^ expected `Foo { value: 3, nested: &Bar::(5) }`, found `Foo { value: 3, nested: &Bar::(4) }` | |______| | expected due to this | - = note: expected struct `Test(5_i32) }>` - found struct `Test(4_i32) }>` + = note: expected struct `Test(5) }>` + found struct `Test(4) }>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/nested-type.full.stderr b/src/test/ui/const-generics/nested-type.full.stderr index 52f1c58825823..6d9f4406504ee 100644 --- a/src/test/ui/const-generics/nested-type.full.stderr +++ b/src/test/ui/const-generics/nested-type.full.stderr @@ -1,4 +1,4 @@ -error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17_usize>::value` in constants +error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | LL | Foo::<17>::value() diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr index 48e12e903b86a..a3c011d927b5a 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied +error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied --> $DIR/unused-substs-1.rs:12:13 | LL | let _ = A; - | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>` + | ^ the trait `Bar<_>` is not implemented for `A<_>` | - = help: the trait `Bar` is implemented for `A<7_usize>` + = help: the trait `Bar` is implemented for `A<7>` note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr index 4d6b752867f1b..486506239ddfd 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:14:41 | LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | - = note: expected type `2_u32` - found type `4_u32` + = note: expected type `2` + found type `4` error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:16:41 @@ -26,8 +26,8 @@ LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data | | | expected due to this | - = note: expected struct `A<'a, u16, 4_u32, _>` - found struct `A<'b, u32, 2_u32, _>` + = note: expected struct `A<'a, u16, 4, _>` + found struct `A<'b, u32, 2, _>` error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr index 8b60238cb0c03..6ac93a08d5d68 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr @@ -2,12 +2,12 @@ error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:14:41 | LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData }; - | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32` + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | | | expected due to this | - = note: expected struct `A<'_, _, 2_u32, _>` - found struct `A<'_, _, 4_u32, _>` + = note: expected struct `A<'_, _, 2, _>` + found struct `A<'_, _, 4, _>` error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:16:41 @@ -28,8 +28,8 @@ LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data | | | expected due to this | - = note: expected struct `A<'a, u16, 4_u32, _>` - found struct `A<'b, u32, 2_u32, _>` + = note: expected struct `A<'a, u16, 4, _>` + found struct `A<'b, u32, 2, _>` error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/issue-85155.stderr b/src/test/ui/consts/const-eval/issue-85155.stderr index c36d7c1721526..3d2c76b7ed040 100644 --- a/src/test/ui/consts/const-eval/issue-85155.stderr +++ b/src/test/ui/consts/const-eval/issue-85155.stderr @@ -1,10 +1,10 @@ -error[E0080]: evaluation of `post_monomorphization_error::ValidateConstImm::<2_i32, 0_i32, 1_i32>::VALID` failed +error[E0080]: evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed --> $DIR/auxiliary/post_monomorphization_error.rs:7:17 | LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero -note: the above error was encountered while instantiating `fn post_monomorphization_error::stdarch_intrinsic::<2_i32>` +note: the above error was encountered while instantiating `fn post_monomorphization_error::stdarch_intrinsic::<2>` --> $DIR/issue-85155.rs:19:5 | LL | post_monomorphization_error::stdarch_intrinsic::<2>(); diff --git a/src/test/ui/dropck/reject-specialized-drops-8142.stderr b/src/test/ui/dropck/reject-specialized-drops-8142.stderr index ebd484b880001..cb48221c67a82 100644 --- a/src/test/ui/dropck/reject-specialized-drops-8142.stderr +++ b/src/test/ui/dropck/reject-specialized-drops-8142.stderr @@ -104,7 +104,7 @@ error[E0366]: `Drop` impls cannot be specialized LL | impl Drop for X<3> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `3_usize` is not a generic parameter + = note: `3` is not a generic parameter note: use the same sequence of generic lifetime, type and const parameters as the struct definition --> $DIR/reject-specialized-drops-8142.rs:17:1 | diff --git a/src/test/ui/inline-const/const-expr-generic-err.stderr b/src/test/ui/inline-const/const-expr-generic-err.stderr index db0d85a2d4e74..fc0b6cc445164 100644 --- a/src/test/ui/inline-const/const-expr-generic-err.stderr +++ b/src/test/ui/inline-const/const-expr-generic-err.stderr @@ -12,13 +12,13 @@ note: the above error was encountered while instantiating `fn foo::` LL | foo::(); | ^^^^^^^^^^^^ -error[E0080]: evaluation of `bar::<0_usize>::{constant#0}` failed +error[E0080]: evaluation of `bar::<0>::{constant#0}` failed --> $DIR/const-expr-generic-err.rs:9:13 | LL | const { N - 1 } | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow -note: the above error was encountered while instantiating `fn bar::<0_usize>` +note: the above error was encountered while instantiating `fn bar::<0>` --> $DIR/const-expr-generic-err.rs:14:5 | LL | bar::<0>(); diff --git a/src/test/ui/issues/issue-59494.stderr b/src/test/ui/issues/issue-59494.stderr index 8b542bb69de2e..a9284535e4dc4 100644 --- a/src/test/ui/issues/issue-59494.stderr +++ b/src/test/ui/issues/issue-59494.stderr @@ -7,8 +7,6 @@ LL | let t8 = t8n(t7, t7p(f, g)); | required by a bound introduced by this call | = help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))` - = note: expected a closure with arguments `(((_, _), _),)` - found a closure with arguments `(_,)` note: required by a bound in `t8n` --> $DIR/issue-59494.rs:5:45 | diff --git a/src/test/ui/lint/function-item-references.stderr b/src/test/ui/lint/function-item-references.stderr index 33db687df31d2..a9d18bb6a4743 100644 --- a/src/test/ui/lint/function-item-references.stderr +++ b/src/test/ui/lint/function-item-references.stderr @@ -116,7 +116,7 @@ warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:118:22 | LL | println!("{:p}", &take_generic_array::); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_array` to obtain a function pointer: `take_generic_array:: as fn(_)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_array` to obtain a function pointer: `take_generic_array:: as fn(_)` warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:120:22 @@ -128,7 +128,7 @@ warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:122:22 | LL | println!("{:p}", &multiple_generic_arrays::); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays:: as fn(_, _)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays:: as fn(_, _)` warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:124:22 diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 3df928b5d804d..799ced5e9c460 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -61,13 +61,13 @@ impl Other { fn other(&self) {} } -struct Struct{ - _phatom: PhantomData +struct Struct { + _phatom: PhantomData, } impl Default for Struct { fn default() -> Self { - Self{ _phatom: PhantomData } + Self { _phatom: PhantomData } } } @@ -76,9 +76,9 @@ impl Struct { } fn main() { - let point_f64 = Point{ x: 1_f64, y: 1_f64}; + let point_f64 = Point { x: 1_f64, y: 1_f64 }; let d = point_f64.distance(); - let point_i32 = Point{ x: 1_i32, y: 1_i32}; + let point_i32 = Point { x: 1_i32, y: 1_i32 }; let d = point_i32.distance(); //~^ ERROR no method named `distance` found for struct `Point let d = point_i32.other(); @@ -92,9 +92,9 @@ fn main() { wrapper.other(); //~^ ERROR no method named `other` found for struct `Wrapper let boolean = true; - let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; + let wrapper = Wrapper2::<'_, _, 3> { x: &boolean }; wrapper.method(); - //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> + //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3> wrapper.other(); //~^ ERROR no method named `other` found for struct `Wrapper2 let a = vec![1, 2, 3]; diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 56e1b5a0f4473..fc42d1a4dcd08 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -50,14 +50,14 @@ LL | struct Wrapper(T); LL | wrapper.other(); | ^^^^^ method not found in `Wrapper` -error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope +error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3>` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:96:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `method` not found for this struct ... LL | wrapper.method(); - | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | ^^^^^^ method not found in `Wrapper2<'_, bool, 3>` | = note: the method was found for - `Wrapper2<'a, i8, C>` @@ -71,7 +71,7 @@ LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `other` not found for this struct ... LL | wrapper.other(); - | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | ^^^^^ method not found in `Wrapper2<'_, bool, 3>` error[E0599]: no method named `not_found` found for struct `Vec<{integer}>` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:101:7 @@ -82,7 +82,7 @@ LL | a.not_found(); error[E0599]: the method `method` exists for struct `Struct`, but its trait bounds were not satisfied --> $DIR/method-not-found-generic-arg-elision.rs:104:7 | -LL | struct Struct{ +LL | struct Struct { | ---------------- method `method` not found for this struct ... LL | s.method(); diff --git a/src/test/ui/simd/intrinsic/generic-shuffle.stderr b/src/test/ui/simd/intrinsic/generic-shuffle.stderr index 44c57cd7c47bc..81e641612ce00 100644 --- a/src/test/ui/simd/intrinsic/generic-shuffle.stderr +++ b/src/test/ui/simd/intrinsic/generic-shuffle.stderr @@ -1,10 +1,10 @@ -error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 --> $DIR/generic-shuffle.rs:24:31 | LL | let _: Simd = simd_shuffle(v, v, I); | ^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` --> $DIR/generic-shuffle.rs:27:31 | LL | let _: Simd = simd_shuffle(v, v, I); diff --git a/src/test/ui/simd/libm_no_std_cant_float.stderr b/src/test/ui/simd/libm_no_std_cant_float.stderr index dc8638f6ab72d..7249914256cd9 100644 --- a/src/test/ui/simd/libm_no_std_cant_float.stderr +++ b/src/test/ui/simd/libm_no_std_cant_float.stderr @@ -2,37 +2,37 @@ error[E0599]: no method named `ceil` found for struct `Simd` in the current scop --> $DIR/libm_no_std_cant_float.rs:14:17 | LL | let _xc = x.ceil(); - | ^^^^ method not found in `Simd` + | ^^^^ method not found in `Simd` error[E0599]: no method named `floor` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:15:17 | LL | let _xf = x.floor(); - | ^^^^^ method not found in `Simd` + | ^^^^^ method not found in `Simd` error[E0599]: no method named `round` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:16:17 | LL | let _xr = x.round(); - | ^^^^^ method not found in `Simd` + | ^^^^^ method not found in `Simd` error[E0599]: no method named `trunc` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:17:17 | LL | let _xt = x.trunc(); - | ^^^^^ method not found in `Simd` + | ^^^^^ method not found in `Simd` error[E0599]: no method named `mul_add` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:18:19 | LL | let _xfma = x.mul_add(x, x); - | ^^^^^^^ method not found in `Simd` + | ^^^^^^^ method not found in `Simd` error[E0599]: no method named `sqrt` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:19:20 | LL | let _xsqrt = x.sqrt(); - | ^^^^ method not found in `Simd` + | ^^^^ method not found in `Simd` error: aborting due to 6 previous errors diff --git a/src/test/ui/simd/type-generic-monomorphisation-empty.rs b/src/test/ui/simd/type-generic-monomorphisation-empty.rs index 0121404c74935..2bf6641e9c91c 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-empty.rs +++ b/src/test/ui/simd/type-generic-monomorphisation-empty.rs @@ -2,7 +2,7 @@ #![feature(repr_simd, platform_intrinsics)] -// error-pattern:monomorphising SIMD type `Simd<0_usize>` of zero length +// error-pattern:monomorphising SIMD type `Simd<0>` of zero length #[repr(simd)] struct Simd([f32; N]); diff --git a/src/test/ui/simd/type-generic-monomorphisation-empty.stderr b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr index 00fde199b12a2..b334b1f4b5893 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-empty.stderr +++ b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr @@ -1,4 +1,4 @@ -error: monomorphising SIMD type `Simd<0_usize>` of zero length +error: monomorphising SIMD type `Simd<0>` of zero length error: aborting due to previous error diff --git a/src/test/ui/simd/type-generic-monomorphisation-oversized.rs b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs index bd0d457b35e27..a7dc482f3cb1d 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-oversized.rs +++ b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs @@ -2,7 +2,7 @@ #![feature(repr_simd, platform_intrinsics)] -// error-pattern:monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768 +// error-pattern:monomorphising SIMD type `Simd<65536>` of length greater than 32768 #[repr(simd)] struct Simd([f32; N]); diff --git a/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr index f441835011532..a2dba1222eecd 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr +++ b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr @@ -1,4 +1,4 @@ -error: monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768 +error: monomorphising SIMD type `Simd<65536>` of length greater than 32768 error: aborting due to previous error diff --git a/src/test/ui/suggestions/return-bindings.fixed b/src/test/ui/suggestions/return-bindings.fixed deleted file mode 100644 index 4fabc411abcbe..0000000000000 --- a/src/test/ui/suggestions/return-bindings.fixed +++ /dev/null @@ -1,23 +0,0 @@ -// run-rustfix - -#![allow(unused)] - -fn a(i: i32) -> i32 { i } -//~^ ERROR mismatched types - -fn b(opt_str: Option) { - let s: String = if let Some(s) = opt_str { - s - //~^ ERROR mismatched types - } else { - String::new() - }; -} - -fn c() -> Option { - //~^ ERROR mismatched types - let x = Some(1); - x -} - -fn main() {} diff --git a/src/test/ui/suggestions/return-bindings.rs b/src/test/ui/suggestions/return-bindings.rs index d05b4ba27d6e8..fa1bad37699f3 100644 --- a/src/test/ui/suggestions/return-bindings.rs +++ b/src/test/ui/suggestions/return-bindings.rs @@ -1,5 +1,3 @@ -// run-rustfix - #![allow(unused)] fn a(i: i32) -> i32 {} @@ -18,4 +16,36 @@ fn c() -> Option { let x = Some(1); } +fn d(opt_str: Option) { + let s: String = if let Some(s) = opt_str { + //~^ ERROR mismatched types + } else { + String::new() + }; +} + +fn d2(opt_str: Option) { + let s = if let Some(s) = opt_str { + } else { + String::new() + //~^ ERROR `if` and `else` have incompatible types + }; +} + +fn e(opt_str: Option) { + let s: String = match opt_str { + Some(s) => {} + //~^ ERROR mismatched types + None => String::new(), + }; +} + +fn e2(opt_str: Option) { + let s = match opt_str { + Some(s) => {} + None => String::new(), + //~^ ERROR `match` arms have incompatible types + }; +} + fn main() {} diff --git a/src/test/ui/suggestions/return-bindings.stderr b/src/test/ui/suggestions/return-bindings.stderr index e5d4925500556..c14fb336773d1 100644 --- a/src/test/ui/suggestions/return-bindings.stderr +++ b/src/test/ui/suggestions/return-bindings.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/return-bindings.rs:5:17 + --> $DIR/return-bindings.rs:3:17 | LL | fn a(i: i32) -> i32 {} | - ^^^ expected `i32`, found `()` @@ -12,7 +12,7 @@ LL | fn a(i: i32) -> i32 { i } | + error[E0308]: mismatched types - --> $DIR/return-bindings.rs:9:46 + --> $DIR/return-bindings.rs:7:46 | LL | let s: String = if let Some(s) = opt_str { | ______________________________________________^ @@ -28,7 +28,7 @@ LL ~ | error[E0308]: mismatched types - --> $DIR/return-bindings.rs:16:11 + --> $DIR/return-bindings.rs:14:11 | LL | fn c() -> Option { | - ^^^^^^^^^^^ expected enum `Option`, found `()` @@ -43,6 +43,68 @@ LL ~ let x = Some(1); LL + x | -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/return-bindings.rs:20:46 + | +LL | let s: String = if let Some(s) = opt_str { + | ______________________________________________^ +LL | | +LL | | } else { + | |_____^ expected struct `String`, found `()` + | +help: consider returning the local binding `s` + | +LL ~ let s: String = if let Some(s) = opt_str { +LL + s +LL ~ + | + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/return-bindings.rs:30:9 + | +LL | let s = if let Some(s) = opt_str { + | ______________________________________- +LL | | } else { + | |_____- expected because of this +LL | String::new() + | ^^^^^^^^^^^^^ expected `()`, found struct `String` + | +help: consider returning the local binding `s` + | +LL ~ let s = if let Some(s) = opt_str { +LL + s +LL ~ } else { + | + +error[E0308]: mismatched types + --> $DIR/return-bindings.rs:37:20 + | +LL | Some(s) => {} + | ^^ expected struct `String`, found `()` + | +help: consider returning the local binding `s` + | +LL | Some(s) => { s } + | + + +error[E0308]: `match` arms have incompatible types + --> $DIR/return-bindings.rs:46:17 + | +LL | let s = match opt_str { + | _____________- +LL | | Some(s) => {} + | | -- this is found to be of type `()` +LL | | None => String::new(), + | | ^^^^^^^^^^^^^ expected `()`, found struct `String` +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | +help: consider returning the local binding `s` + | +LL | Some(s) => { s } + | + + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index 6c82d31e18d8b..e7565525ad338 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -25,7 +25,7 @@ error: non-defining opaque type use in defining scope LL | 7u32 | ^^^^ | -note: used non-generic constant `123_usize` for generic parameter +note: used non-generic constant `123` for generic parameter --> $DIR/generic_nondefining_use.rs:11:15 | LL | type OneConst = impl Debug;