diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d24dc44d2c52f..ebc5c17a4c4f2 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1593,44 +1593,98 @@ fn deny_equality_constraints( } } } - // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo`. - if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind { - if let [potential_param, potential_assoc] = &full_path.segments[..] { - for param in &generics.params { - if param.ident == potential_param.ident { - for bound in ¶m.bounds { - if let ast::GenericBound::Trait(trait_ref, TraitBoundModifiers::NONE) = - bound + + let mut suggest = + |poly: &PolyTraitRef, potential_assoc: &PathSegment, predicate: &WhereEqPredicate| { + if let [trait_segment] = &poly.trait_ref.path.segments[..] { + let assoc = pprust::path_to_string(&ast::Path::from_ident(potential_assoc.ident)); + let ty = pprust::ty_to_string(&predicate.rhs_ty); + let (args, span) = match &trait_segment.args { + Some(args) => match args.deref() { + ast::GenericArgs::AngleBracketed(args) => { + let Some(arg) = args.args.last() else { + return; + }; + (format!(", {assoc} = {ty}"), arg.span().shrink_to_hi()) + } + _ => return, + }, + None => (format!("<{assoc} = {ty}>"), trait_segment.span().shrink_to_hi()), + }; + let removal_span = if generics.where_clause.predicates.len() == 1 { + // We're removing th eonly where bound left, remove the whole thing. + generics.where_clause.span + } else { + let mut span = predicate.span; + let mut prev: Option = None; + let mut preds = generics.where_clause.predicates.iter().peekable(); + // Find the predicate that shouldn't have been in the where bound list. + while let Some(pred) = preds.next() { + if let WherePredicate::EqPredicate(pred) = pred + && pred.span == predicate.span { - if let [trait_segment] = &trait_ref.trait_ref.path.segments[..] { - let assoc = pprust::path_to_string(&ast::Path::from_ident( - potential_assoc.ident, - )); - let ty = pprust::ty_to_string(&predicate.rhs_ty); - let (args, span) = match &trait_segment.args { - Some(args) => match args.deref() { - ast::GenericArgs::AngleBracketed(args) => { - let Some(arg) = args.args.last() else { - continue; - }; - (format!(", {assoc} = {ty}"), arg.span().shrink_to_hi()) - } - _ => continue, - }, - None => ( - format!("<{assoc} = {ty}>"), - trait_segment.span().shrink_to_hi(), - ), - }; - err.assoc2 = Some(errors::AssociatedSuggestion2 { - span, - args, - predicate: predicate.span, - trait_segment: trait_segment.ident, - potential_assoc: potential_assoc.ident, - }); + if let Some(next) = preds.peek() { + // This is the first predicate, remove the trailing comma as well. + span = span.with_hi(next.span().lo()); + } else if let Some(prev) = prev { + // Remove the previous comma as well. + span = span.with_lo(prev.hi()); } } + prev = Some(pred.span()); + } + span + }; + err.assoc2 = Some(errors::AssociatedSuggestion2 { + span, + args, + predicate: removal_span, + trait_segment: trait_segment.ident, + potential_assoc: potential_assoc.ident, + }); + } + }; + + if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind { + // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo`. + for bounds in generics.params.iter().map(|p| &p.bounds).chain( + generics.where_clause.predicates.iter().filter_map(|pred| match pred { + WherePredicate::BoundPredicate(p) => Some(&p.bounds), + _ => None, + }), + ) { + for bound in bounds { + if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if full_path.segments[..full_path.segments.len() - 1] + .iter() + .map(|segment| segment.ident.name) + .zip(poly.trait_ref.path.segments.iter().map(|segment| segment.ident.name)) + .all(|(a, b)| a == b) + && let Some(potential_assoc) = full_path.segments.iter().last() + { + suggest(poly, potential_assoc, predicate); + } + } + } + } + // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo`. + if let [potential_param, potential_assoc] = &full_path.segments[..] { + for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain( + generics.where_clause.predicates.iter().filter_map(|pred| match pred { + WherePredicate::BoundPredicate(p) + if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind + && let [segment] = &path.segments[..] => + { + Some((segment.ident, &p.bounds)) + } + _ => None, + }), + ) { + if ident == potential_param.ident { + for bound in bounds { + if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + suggest(poly, potential_assoc, predicate); + } } } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index e98ace948f921..e6319747e782e 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -98,8 +98,11 @@ struct CollectRetsVisitor<'tcx> { impl<'tcx> Visitor<'tcx> for CollectRetsVisitor<'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Ret(_) = expr.kind { - self.ret_exprs.push(expr); + match expr.kind { + hir::ExprKind::Ret(_) => self.ret_exprs.push(expr), + // `return` in closures does not return from the outer function + hir::ExprKind::Closure(_) => return, + _ => {} } intravisit::walk_expr(self, expr); } @@ -1845,13 +1848,31 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } let parent_id = fcx.tcx.hir().get_parent_item(id); - let parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id); + let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id); + // When suggesting return, we need to account for closures and async blocks, not just items. + for (_, node) in fcx.tcx.hir().parent_iter(id) { + match node { + hir::Node::Expr(&hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { .. }), + .. + }) => { + parent_item = node; + break; + } + hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break, + _ => {} + } + } - if let (Some(expr), Some(_), Some((fn_id, fn_decl, _, _))) = - (expression, blk_id, fcx.get_node_fn_decl(parent_item)) - { + if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) { fcx.suggest_missing_break_or_return_expr( - &mut err, expr, fn_decl, expected, found, id, fn_id, + &mut err, + expr, + fn_decl, + expected, + found, + id, + parent_id.into(), ); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index f7ff9f8224a2c..ec3d4ec66a073 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -963,14 +963,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { owner_id, .. }) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)), - Node::Expr(&hir::Expr { hir_id, kind: hir::ExprKind::Closure(..), .. }) - if let Node::Item(&hir::Item { - ident, - kind: hir::ItemKind::Fn(ref sig, ..), - owner_id, - .. - }) = self.tcx.parent_hir_node(hir_id) => - { + Node::Expr(&hir::Expr { + hir_id, + kind: + hir::ExprKind::Closure(hir::Closure { + kind: hir::ClosureKind::Coroutine(..), .. + }), + .. + }) => { + let (ident, sig, owner_id) = match self.tcx.parent_hir_node(hir_id) { + Node::Item(&hir::Item { + ident, + kind: hir::ItemKind::Fn(ref sig, ..), + owner_id, + .. + }) => (ident, sig, owner_id), + Node::TraitItem(&hir::TraitItem { + ident, + kind: hir::TraitItemKind::Fn(ref sig, ..), + owner_id, + .. + }) => (ident, sig, owner_id), + Node::ImplItem(&hir::ImplItem { + ident, + kind: hir::ImplItemKind::Fn(ref sig, ..), + owner_id, + .. + }) => (ident, sig, owner_id), + _ => return None, + }; Some(( hir::HirId::make_owner(owner_id.def_id), &sig.decl, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 35b3f27d79127..65b8505c09098 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1726,7 +1726,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise. - fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> { + pub(crate) fn get_parent_fn_decl( + &self, + blk_id: hir::HirId, + ) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> { let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id); self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident)) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d68e20541ef0f..8b6f263b1a746 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -827,6 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } hir::FnRetTy::Return(hir_ty) => { if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind + // FIXME: account for RPITIT. && let hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(op_ty), .. }) = self.tcx.hir_node(item_id.hir_id()) @@ -1038,33 +1039,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - if let hir::FnRetTy::Return(ty) = fn_decl.output { - let ty = self.astconv().ast_ty_to_ty(ty); - let bound_vars = self.tcx.late_bound_vars(fn_id); - let ty = self - .tcx - .instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars)); - let ty = match self.tcx.asyncness(fn_id.owner) { - ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| { - span_bug!(fn_decl.output.span(), "failed to get output type of async function") - }), - ty::Asyncness::No => ty, - }; - let ty = self.normalize(expr.span, ty); - if self.can_coerce(found, ty) { - if let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner() - && let Some(span) = expr.span.find_ancestor_inside(*owner_node.span()) - { - err.multipart_suggestion( - "you might have meant to return this value", - vec![ - (span.shrink_to_lo(), "return ".to_string()), - (span.shrink_to_hi(), ";".to_string()), - ], - Applicability::MaybeIncorrect, - ); - } + let scope = self + .tcx + .hir() + .parent_iter(id) + .filter(|(_, node)| { + matches!( + node, + Node::Expr(Expr { kind: ExprKind::Closure(..), .. }) + | Node::Item(_) + | Node::TraitItem(_) + | Node::ImplItem(_) + ) + }) + .next(); + let in_closure = + matches!(scope, Some((_, Node::Expr(Expr { kind: ExprKind::Closure(..), .. })))); + + let can_return = match fn_decl.output { + hir::FnRetTy::Return(ty) => { + let ty = self.astconv().ast_ty_to_ty(ty); + let bound_vars = self.tcx.late_bound_vars(fn_id); + let ty = self + .tcx + .instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars)); + let ty = match self.tcx.asyncness(fn_id.owner) { + ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| { + span_bug!( + fn_decl.output.span(), + "failed to get output type of async function" + ) + }), + ty::Asyncness::No => ty, + }; + let ty = self.normalize(expr.span, ty); + self.can_coerce(found, ty) + } + hir::FnRetTy::DefaultReturn(_) if in_closure => { + self.ret_coercion.as_ref().map_or(false, |ret| { + let ret_ty = ret.borrow().expected_ty(); + self.can_coerce(found, ret_ty) + }) } + _ => false, + }; + if can_return + && let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner() + && let Some(span) = expr.span.find_ancestor_inside(*owner_node.span()) + { + err.multipart_suggestion( + "you might have meant to return this value", + vec![ + (span.shrink_to_lo(), "return ".to_string()), + (span.shrink_to_hi(), ";".to_string()), + ], + Applicability::MaybeIncorrect, + ); } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index ab5c0f327051e..729ce1f00cd8b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1073,12 +1073,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // for instance self.tcx.at(span).type_of(*def_id).instantiate_identity() != rcvr_ty - && self - .tcx - .at(span) - .type_of(*def_id) - .instantiate_identity() - != rcvr_ty } (Mode::Path, false, _) => true, _ => false, @@ -1092,7 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inherent_impls_candidate.sort(); inherent_impls_candidate.dedup(); - // number of type to shows at most. + // number of types to show at most let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 }; let type_candidates = inherent_impls_candidate .iter() diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3b6bf03686b0d..a358a40f92bd0 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -43,6 +43,9 @@ #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Support/TimeProfiler.h" +#if LLVM_VERSION_GE(19, 0) +#include "llvm/Support/PGOOptions.h" +#endif #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" @@ -749,6 +752,9 @@ LLVMRustOptimize( FS, #endif PGOOptions::IRInstr, PGOOptions::NoCSAction, +#if LLVM_VERSION_GE(19, 0) + PGOOptions::ColdFuncOpt::Default, +#endif DebugInfoForProfiling); } else if (PGOUsePath) { assert(!PGOSampleUsePath); @@ -758,6 +764,9 @@ LLVMRustOptimize( FS, #endif PGOOptions::IRUse, PGOOptions::NoCSAction, +#if LLVM_VERSION_GE(19, 0) + PGOOptions::ColdFuncOpt::Default, +#endif DebugInfoForProfiling); } else if (PGOSampleUsePath) { PGOOpt = PGOOptions(PGOSampleUsePath, "", "", @@ -766,6 +775,9 @@ LLVMRustOptimize( FS, #endif PGOOptions::SampleUse, PGOOptions::NoCSAction, +#if LLVM_VERSION_GE(19, 0) + PGOOptions::ColdFuncOpt::Default, +#endif DebugInfoForProfiling); } else if (DebugInfoForProfiling) { PGOOpt = PGOOptions("", "", "", @@ -774,6 +786,9 @@ LLVMRustOptimize( FS, #endif PGOOptions::NoAction, PGOOptions::NoCSAction, +#if LLVM_VERSION_GE(19, 0) + PGOOptions::ColdFuncOpt::Default, +#endif DebugInfoForProfiling); } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index a2dfebec59441..b45706fd1e5b2 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1801,6 +1801,9 @@ extern "C" LLVMRustResult LLVMRustWriteImportLibrary( std::string{}, // ExtName std::string{}, // SymbolName std::string{}, // AliasTarget +#if LLVM_VERSION_GE(19, 0) + std::string{}, // ExportAs +#endif ordinal, // Ordinal ordinal_present, // Noname false, // Data diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 8e1cb6a514f8a..e7d9dc04886b8 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -617,7 +617,7 @@ impl<'hir> Map<'hir> { Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) - | Node::Expr(Expr { kind: ExprKind::Closure { .. }, .. }) + | Node::Expr(Expr { kind: ExprKind::Closure(_), .. }) | Node::ImplItem(_) // The input node `id` must be enclosed in the method's body as opposed // to some other place such as its return type (fixes #114918). diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 80e0d0baf5786..c6ec1b5aee454 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -1,7 +1,7 @@ use rustc_index::IndexVec; use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use smallvec::{smallvec, SmallVec}; use std::mem; @@ -132,6 +132,9 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> { let body = self.builder.body; let tcx = self.builder.tcx; let place_ty = place_ref.ty(body, tcx).ty; + if place_ty.references_error() { + return MovePathResult::Error; + } match elem { ProjectionElem::Deref => match place_ty.kind() { ty::Ref(..) | ty::RawPtr(..) => { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 7a24b819b5f56..445d5b2ce790c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -900,7 +900,7 @@ impl<'a> Parser<'a> { // fn foo() -> Foo { // field: value, // } - info!(?maybe_struct_name, ?self.token); + debug!(?maybe_struct_name, ?self.token); let mut snapshot = self.create_snapshot_for_diagnostic(); let path = Path { segments: ThinVec::new(), diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index fce2585cbf5c4..b9918752540f3 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -278,6 +278,22 @@ //! Hello, ` 123` has 3 right-aligned characters //! ``` //! +//! When truncating these values, Rust uses [round half-to-even](https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even), +//! which is the default rounding mode in IEEE 754. +//! For example, +//! +//! ``` +//! print!("{0:.1$e}", 12345, 3); +//! print!("{0:.1$e}", 12355, 3); +//! ``` +//! +//! Would return: +//! +//! ```text +//! 1.234e4 +//! 1.236e4 +//! ``` +//! //! ## Localization //! //! In some programming languages, the behavior of string formatting functions diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 83f8fd25b50bd..20dd95a3a4623 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -89,8 +89,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// @@ -249,8 +247,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// assert_eq!(a.iter().count(), 3); @@ -280,8 +276,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// assert_eq!(a.iter().last(), Some(&3)); @@ -324,8 +318,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// #![feature(iter_advance_by)] /// @@ -432,8 +424,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [0, 1, 2, 3, 4, 5]; /// let mut iter = a.iter().step_by(2); @@ -1342,8 +1332,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// @@ -1434,8 +1422,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3, 4]; /// @@ -1486,8 +1472,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let words = ["alpha", "beta", "gamma"]; /// @@ -1765,8 +1749,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // an iterator which alternates between Some and None /// struct Alternate { @@ -1911,8 +1893,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let mut words = ["hello", "world", "of", "Rust"].into_iter(); /// @@ -2221,8 +2201,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// @@ -3193,8 +3171,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// let b: Vec = Vec::new(); @@ -3232,8 +3208,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// let b: Vec = Vec::new(); @@ -3420,8 +3394,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [(1, 2), (3, 4), (5, 6)]; /// @@ -3458,8 +3430,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// @@ -3538,8 +3508,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// @@ -3624,8 +3592,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let a = [1, 2, 3]; /// let sum: i32 = a.iter().sum(); @@ -3703,8 +3669,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// #![feature(iter_order_by)] /// @@ -3790,8 +3754,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// #![feature(iter_order_by)] /// @@ -3863,8 +3825,6 @@ pub trait Iterator { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// #![feature(iter_order_by)] /// diff --git a/tests/ui/async-await/missing-return-in-async-block.fixed b/tests/ui/async-await/missing-return-in-async-block.fixed new file mode 100644 index 0000000000000..3dbac7945b6e1 --- /dev/null +++ b/tests/ui/async-await/missing-return-in-async-block.fixed @@ -0,0 +1,22 @@ +// run-rustfix +// edition:2021 +use std::future::Future; +use std::pin::Pin; +pub struct S; +pub fn foo() { + let _ = Box::pin(async move { + if true { + return Ok(S); //~ ERROR mismatched types + } + Err(()) + }); +} +pub fn bar() -> Pin> + 'static>> { + Box::pin(async move { + if true { + return Ok(S); //~ ERROR mismatched types + } + Err(()) + }) +} +fn main() {} diff --git a/tests/ui/async-await/missing-return-in-async-block.rs b/tests/ui/async-await/missing-return-in-async-block.rs new file mode 100644 index 0000000000000..7d04e0e0fad14 --- /dev/null +++ b/tests/ui/async-await/missing-return-in-async-block.rs @@ -0,0 +1,22 @@ +// run-rustfix +// edition:2021 +use std::future::Future; +use std::pin::Pin; +pub struct S; +pub fn foo() { + let _ = Box::pin(async move { + if true { + Ok(S) //~ ERROR mismatched types + } + Err(()) + }); +} +pub fn bar() -> Pin> + 'static>> { + Box::pin(async move { + if true { + Ok(S) //~ ERROR mismatched types + } + Err(()) + }) +} +fn main() {} diff --git a/tests/ui/async-await/missing-return-in-async-block.stderr b/tests/ui/async-await/missing-return-in-async-block.stderr new file mode 100644 index 0000000000000..5ea76e5f7bf93 --- /dev/null +++ b/tests/ui/async-await/missing-return-in-async-block.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/missing-return-in-async-block.rs:9:13 + | +LL | / if true { +LL | | Ok(S) + | | ^^^^^ expected `()`, found `Result` +LL | | } + | |_________- expected this to be `()` + | + = note: expected unit type `()` + found enum `Result` +help: you might have meant to return this value + | +LL | return Ok(S); + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/missing-return-in-async-block.rs:17:13 + | +LL | / if true { +LL | | Ok(S) + | | ^^^^^ expected `()`, found `Result` +LL | | } + | |_________- expected this to be `()` + | + = note: expected unit type `()` + found enum `Result` +help: you might have meant to return this value + | +LL | return Ok(S); + | ++++++ + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index bf52f884209c3..665b876c43e2c 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -1,6 +1,7 @@ // normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" // normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_refs_to_static)] +#![allow(static_mut_ref)] fn invalid() { static S: i8 = 10; @@ -38,7 +39,6 @@ fn mutable() { const C: &i32 = unsafe { &S_MUT }; //~^ERROR: undefined behavior //~| encountered reference to mutable memory - //~| WARN shared reference of mutable static is discouraged // This *must not build*, the constant we are matching against // could change its value! diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index 35051557b614d..082f8532444ad 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -1,20 +1,5 @@ -warning: shared reference of mutable static is discouraged - --> $DIR/const_refs_to_static_fail_invalid.rs:38:30 - | -LL | const C: &i32 = unsafe { &S_MUT }; - | ^^^^^^ shared reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer - | -LL | const C: &i32 = unsafe { addr_of!(S_MUT) }; - | ~~~~~~~~~~~~~~~ - error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:8:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:9:5 | LL | const C: &bool = unsafe { std::mem::transmute(&S) }; | ^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0a, but expected a boolean @@ -25,13 +10,13 @@ LL | const C: &bool = unsafe { std::mem::transmute(&S) }; } error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:14:9 + --> $DIR/const_refs_to_static_fail_invalid.rs:15:9 | LL | C => {} | ^ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:24:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:25:5 | LL | const C: &i8 = unsafe { &S }; | ^^^^^^^^^^^^ constructing invalid value: encountered reference to `extern` static in `const` @@ -42,13 +27,13 @@ LL | const C: &i8 = unsafe { &S }; } error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:30:9 + --> $DIR/const_refs_to_static_fail_invalid.rs:31:9 | LL | C => {} | ^ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:38:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:39:5 | LL | const C: &i32 = unsafe { &S_MUT }; | ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -64,6 +49,6 @@ error: could not evaluate constant pattern LL | C => {}, | ^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index 2b593a192ee9f..0299bfef1b49a 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -1,9 +1,10 @@ +#![allow(static_mut_ref)] + const C1: &'static mut [usize] = &mut []; //~^ ERROR: mutable references are not allowed static mut S: usize = 3; const C2: &'static mut usize = unsafe { &mut S }; //~^ ERROR: referencing statics in constants -//~| WARN mutable reference of mutable static is discouraged [static_mut_ref] fn main() {} diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 92bab1ab53ef4..57fcb1c7e9a52 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -1,26 +1,11 @@ -warning: mutable reference of mutable static is discouraged - --> $DIR/issue-17718-const-bad-values.rs:5:41 - | -LL | const C2: &'static mut usize = unsafe { &mut S }; - | ^^^^^^ mutable reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer - | -LL | const C2: &'static mut usize = unsafe { addr_of_mut!(S) }; - | ~~~~~~~~~~~~~~~ - error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/issue-17718-const-bad-values.rs:1:34 + --> $DIR/issue-17718-const-bad-values.rs:3:34 | LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ error[E0658]: referencing statics in constants is unstable - --> $DIR/issue-17718-const-bad-values.rs:5:46 + --> $DIR/issue-17718-const-bad-values.rs:7:46 | LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ @@ -31,7 +16,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S }; = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0658, E0764. For more information about an error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr index e280fe622ecbe..db7e8b6847a73 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -1,20 +1,5 @@ -warning: shared reference of mutable static is discouraged - --> $DIR/const_refers_to_static_cross_crate.rs:12:14 - | -LL | unsafe { &static_cross_crate::ZERO } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer - | -LL | unsafe { addr_of!(static_cross_crate::ZERO) } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:10:1 + --> $DIR/const_refers_to_static_cross_crate.rs:11:1 | LL | const SLICE_MUT: &[u8; 1] = { | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -79,7 +64,7 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:12:15 + --> $DIR/const_refers_to_static_cross_crate.rs:13:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -99,6 +84,6 @@ help: skipping check for `const_refs_to_static` feature LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors; 2 warnings emitted +error: aborting due to 8 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index 9bca60485c08b..200faf3558762 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -1,20 +1,5 @@ -warning: shared reference of mutable static is discouraged - --> $DIR/const_refers_to_static_cross_crate.rs:12:14 - | -LL | unsafe { &static_cross_crate::ZERO } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer - | -LL | unsafe { addr_of!(static_cross_crate::ZERO) } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:10:1 + --> $DIR/const_refers_to_static_cross_crate.rs:11:1 | LL | const SLICE_MUT: &[u8; 1] = { | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -79,7 +64,7 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:12:15 + --> $DIR/const_refers_to_static_cross_crate.rs:13:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -99,6 +84,6 @@ help: skipping check for `const_refs_to_static` feature LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors; 2 warnings emitted +error: aborting due to 8 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index cdbfb37c7c738..bcd29f8b03441 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -2,6 +2,7 @@ // aux-build:static_cross_crate.rs // stderr-per-bitwidth #![feature(exclusive_range_pattern, half_open_range_patterns_in_slices)] +#![allow(static_mut_ref)] extern crate static_cross_crate; @@ -10,7 +11,6 @@ extern crate static_cross_crate; const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior //~| encountered reference to mutable memory unsafe { &static_cross_crate::ZERO } - //~^ WARN shared reference of mutable static is discouraged [static_mut_ref] }; const U8_MUT: &u8 = { //~ ERROR undefined behavior diff --git a/tests/ui/consts/static_mut_containing_mut_ref.rs b/tests/ui/consts/static_mut_containing_mut_ref.rs index 874aa59df0bb6..495804649b14b 100644 --- a/tests/ui/consts/static_mut_containing_mut_ref.rs +++ b/tests/ui/consts/static_mut_containing_mut_ref.rs @@ -1,8 +1,8 @@ // build-pass (FIXME(62277): could be check-pass?) +#![allow(static_mut_ref)] static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42]; pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE }; -//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref] fn main() {} diff --git a/tests/ui/consts/static_mut_containing_mut_ref.stderr b/tests/ui/consts/static_mut_containing_mut_ref.stderr deleted file mode 100644 index 56ceba41cf88c..0000000000000 --- a/tests/ui/consts/static_mut_containing_mut_ref.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: mutable reference of mutable static is discouraged - --> $DIR/static_mut_containing_mut_ref.rs:5:52 - | -LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer - | -LL | pub static mut STDERR_BUFFER: *mut [u8] = unsafe { addr_of_mut!(STDERR_BUFFER_SPACE) }; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -warning: 1 warning emitted - diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr b/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr index bc32ecc2c35ff..42cb119d2aeeb 100644 --- a/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr +++ b/tests/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr @@ -1,24 +1,9 @@ -warning: mutable reference of mutable static is discouraged - --> $DIR/static_mut_containing_mut_ref2.rs:8:6 - | -LL | *(&mut STDERR_BUFFER_SPACE) = 42; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer - | -LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error[E0080]: could not evaluate static initializer --> $DIR/static_mut_containing_mut_ref2.rs:8:5 | LL | *(&mut STDERR_BUFFER_SPACE) = 42; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.rs b/tests/ui/consts/static_mut_containing_mut_ref2.rs index b71f1122cd00c..e60a17922fd0c 100644 --- a/tests/ui/consts/static_mut_containing_mut_ref2.rs +++ b/tests/ui/consts/static_mut_containing_mut_ref2.rs @@ -1,5 +1,5 @@ // revisions: stock mut_refs - +#![allow(static_mut_ref)] #![cfg_attr(mut_refs, feature(const_mut_refs))] static mut STDERR_BUFFER_SPACE: u8 = 0; @@ -8,8 +8,6 @@ pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; //[mut_refs]~^ ERROR could not evaluate static initializer //[stock]~^^ ERROR mutation through a reference is not allowed in statics - //[mut_refs]~^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref] - //[stock]~^^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref] }; fn main() {} diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr index aea5b8a33b54c..5ff9c0b6e2b90 100644 --- a/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr +++ b/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr @@ -1,18 +1,3 @@ -warning: mutable reference of mutable static is discouraged - --> $DIR/static_mut_containing_mut_ref2.rs:8:6 - | -LL | *(&mut STDERR_BUFFER_SPACE) = 42; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer - | -LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error[E0658]: mutation through a reference is not allowed in statics --> $DIR/static_mut_containing_mut_ref2.rs:8:5 | @@ -23,6 +8,6 @@ LL | *(&mut STDERR_BUFFER_SPACE) = 42; = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/drop/drop_elaboration_with_errors.rs b/tests/ui/drop/drop_elaboration_with_errors.rs new file mode 100644 index 0000000000000..77862762e8724 --- /dev/null +++ b/tests/ui/drop/drop_elaboration_with_errors.rs @@ -0,0 +1,20 @@ +// can't use build-fail, because this also fails check-fail, but +// the ICE from #120787 only reproduces on build-fail. +// compile-flags: --emit=mir + +#![feature(type_alias_impl_trait)] + +struct Foo { + field: String, +} + +type Tait = impl Sized; + +fn ice_cold(beverage: Tait) { + let Foo { field } = beverage; + _ = field; +} + +fn main() { + Ok(()) //~ ERROR mismatched types +} diff --git a/tests/ui/drop/drop_elaboration_with_errors.stderr b/tests/ui/drop/drop_elaboration_with_errors.stderr new file mode 100644 index 0000000000000..bec229631e189 --- /dev/null +++ b/tests/ui/drop/drop_elaboration_with_errors.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/drop_elaboration_with_errors.rs:19:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | Ok(()) + | ^^^^^^ expected `()`, found `Result<(), _>` + | + = note: expected unit type `()` + found enum `Result<(), _>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs index fcc2da8014f87..be05181f5d09e 100644 --- a/tests/ui/generic-associated-types/equality-bound.rs +++ b/tests/ui/generic-associated-types/equality-bound.rs @@ -12,4 +12,71 @@ fn sum3(i: J) -> i32 where I::Item = i32 { panic!() } +use std::iter::FromIterator; + +struct X {} + +impl FromIterator for X { + fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, + //~^ ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR cannot find type `A` in this scope + { + todo!() + } +} + +struct Y {} + +impl FromIterator for Y { + fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, + //~^ ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR cannot find type `A` in this scope + { + todo!() + } +} + +struct Z {} + +impl FromIterator for Z { + fn from_iter(_: T) -> Self where IntoIterator::Item = A, + //~^ ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR cannot find type `A` in this scope + { + todo!() + } +} + +struct K {} + +impl FromIterator for K { + fn from_iter(_: T) -> Self where T::Item = A, + //~^ ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR cannot find type `A` in this scope + { + todo!() + } +} + +struct L {} + +impl FromIterator for L { + fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, + //~^ ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR cannot find type `A` in this scope + { + todo!() + } +} + +struct M {} + +impl FromIterator for M { + fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, + //~^ ERROR equality constraints are not yet supported in `where` clauses + //~| ERROR cannot find type `A` in this scope + { + todo!() + } +} fn main() {} diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index b21ff30a27da9..a054c06caebde 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -8,7 +8,7 @@ LL | fn sum>(i: I) -> i32 where I::Item = i32 { help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax | LL - fn sum>(i: I) -> i32 where I::Item = i32 { -LL + fn sum>(i: I) -> i32 where { +LL + fn sum>(i: I) -> i32 { | error: equality constraints are not yet supported in `where` clauses @@ -21,7 +21,7 @@ LL | fn sum2(i: I) -> i32 where I::Item = i32 { help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax | LL - fn sum2(i: I) -> i32 where I::Item = i32 { -LL + fn sum2>(i: I) -> i32 where { +LL + fn sum2>(i: I) -> i32 { | error: equality constraints are not yet supported in `where` clauses @@ -32,6 +32,138 @@ LL | fn sum3(i: J) -> i32 where I::Item = i32 { | = note: see issue #20041 for more information +error: equality constraints are not yet supported in `where` clauses + --> $DIR/equality-bound.rs:20:58 + | +LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, + | ^^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax + | +LL - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, + | + +error: equality constraints are not yet supported in `where` clauses + --> $DIR/equality-bound.rs:31:58 + | +LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, + | ^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax + | +LL - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, + | + +error: equality constraints are not yet supported in `where` clauses + --> $DIR/equality-bound.rs:42:55 + | +LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, + | ^^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax + | +LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, +LL + fn from_iter>(_: T) -> Self + | + +error: equality constraints are not yet supported in `where` clauses + --> $DIR/equality-bound.rs:53:55 + | +LL | fn from_iter(_: T) -> Self where T::Item = A, + | ^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax + | +LL - fn from_iter(_: T) -> Self where T::Item = A, +LL + fn from_iter>(_: T) -> Self + | + +error: equality constraints are not yet supported in `where` clauses + --> $DIR/equality-bound.rs:64:41 + | +LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, + | ^^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax + | +LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, + | + +error: equality constraints are not yet supported in `where` clauses + --> $DIR/equality-bound.rs:75:41 + | +LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, + | ^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax + | +LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, + | + +error[E0412]: cannot find type `A` in this scope + --> $DIR/equality-bound.rs:20:79 + | +LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, + | ^ help: a struct with a similar name exists: `K` +... +LL | struct K {} + | -------- similarly named struct `K` defined here + +error[E0412]: cannot find type `A` in this scope + --> $DIR/equality-bound.rs:31:68 + | +LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, + | ^ help: a struct with a similar name exists: `K` +... +LL | struct K {} + | -------- similarly named struct `K` defined here + +error[E0412]: cannot find type `A` in this scope + --> $DIR/equality-bound.rs:42:76 + | +LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, + | ^ help: a struct with a similar name exists: `K` +... +LL | struct K {} + | -------- similarly named struct `K` defined here + +error[E0412]: cannot find type `A` in this scope + --> $DIR/equality-bound.rs:53:65 + | +LL | struct K {} + | -------- similarly named struct `K` defined here +... +LL | fn from_iter(_: T) -> Self where T::Item = A, + | ^ help: a struct with a similar name exists: `K` + +error[E0412]: cannot find type `A` in this scope + --> $DIR/equality-bound.rs:64:62 + | +LL | struct K {} + | -------- similarly named struct `K` defined here +... +LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, + | ^ help: a struct with a similar name exists: `K` + +error[E0412]: cannot find type `A` in this scope + --> $DIR/equality-bound.rs:75:51 + | +LL | struct K {} + | -------- similarly named struct `K` defined here +... +LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, + | ^ help: a struct with a similar name exists: `K` + error[E0433]: failed to resolve: use of undeclared type `I` --> $DIR/equality-bound.rs:9:41 | @@ -41,6 +173,7 @@ LL | fn sum3(i: J) -> i32 where I::Item = i32 { | use of undeclared type `I` | help: a type parameter with a similar name exists: `J` -error: aborting due to 4 previous errors +error: aborting due to 16 previous errors -For more information about this error, try `rustc --explain E0433`. +Some errors have detailed explanations: E0412, E0433. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr index 77f6945f064cc..9fa73d817ca91 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/default-body-type-err-2.rs:7:9 | +LL | async fn woopsie_async(&self) -> String { + | ------ expected `String` because of return type LL | 42 | ^^- help: try using a conversion method: `.to_string()` | | diff --git a/tests/ui/loops/dont-suggest-break-thru-item.rs b/tests/ui/loops/dont-suggest-break-thru-item.rs index b46ba89e81d7f..308101115e521 100644 --- a/tests/ui/loops/dont-suggest-break-thru-item.rs +++ b/tests/ui/loops/dont-suggest-break-thru-item.rs @@ -8,6 +8,7 @@ fn closure() { if true { Err(1) //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } Ok(()) @@ -21,6 +22,7 @@ fn async_block() { if true { Err(1) //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } Ok(()) diff --git a/tests/ui/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr index 4fce471511904..c84a98198f55a 100644 --- a/tests/ui/loops/dont-suggest-break-thru-item.stderr +++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr @@ -5,27 +5,37 @@ LL | / if true { LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` LL | | +LL | | LL | | } | |_____________- expected this to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` +help: you might have meant to return this value + | +LL | return Err(1); + | ++++++ + error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:22:17 + --> $DIR/dont-suggest-break-thru-item.rs:23:17 | LL | / if true { LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` LL | | +LL | | LL | | } | |_____________- expected this to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` +help: you might have meant to return this value + | +LL | return Err(1); + | ++++++ + error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:35:17 + --> $DIR/dont-suggest-break-thru-item.rs:37:17 | LL | / if true { LL | | Err(1) @@ -38,7 +48,7 @@ LL | | } found enum `Result<_, {integer}>` error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:47:17 + --> $DIR/dont-suggest-break-thru-item.rs:49:17 | LL | / if true { LL | | Err(1) diff --git a/tests/ui/thread-local/thread-local-static.rs b/tests/ui/thread-local/thread-local-static.rs index dac9259a6a63b..a2c1954881f89 100644 --- a/tests/ui/thread-local/thread-local-static.rs +++ b/tests/ui/thread-local/thread-local-static.rs @@ -2,14 +2,14 @@ #![feature(thread_local)] #![feature(const_swap)] +#![allow(static_mut_ref)] #[thread_local] static mut STATIC_VAR_2: [u32; 8] = [4; 8]; const fn g(x: &mut [u32; 8]) { //~^ ERROR mutable references are not allowed std::mem::swap(x, &mut STATIC_VAR_2) - //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref] - //~^^ ERROR thread-local statics cannot be accessed + //~^ ERROR thread-local statics cannot be accessed //~| ERROR mutable references are not allowed //~| ERROR use of mutable static is unsafe } diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr index 3dd1e2d40001c..a6499fd15ec64 100644 --- a/tests/ui/thread-local/thread-local-static.stderr +++ b/tests/ui/thread-local/thread-local-static.stderr @@ -1,20 +1,5 @@ -warning: mutable reference of mutable static is discouraged - --> $DIR/thread-local-static.rs:10:23 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^^^^^^ mutable reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer - | -LL | std::mem::swap(x, addr_of_mut!(STATIC_VAR_2)) - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/thread-local-static.rs:10:28 + --> $DIR/thread-local-static.rs:11:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ use of mutable static @@ -22,7 +7,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error[E0658]: mutable references are not allowed in constant functions - --> $DIR/thread-local-static.rs:8:12 + --> $DIR/thread-local-static.rs:9:12 | LL | const fn g(x: &mut [u32; 8]) { | ^ @@ -32,13 +17,13 @@ LL | const fn g(x: &mut [u32; 8]) { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0625]: thread-local statics cannot be accessed at compile-time - --> $DIR/thread-local-static.rs:10:28 + --> $DIR/thread-local-static.rs:11:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ error[E0658]: mutable references are not allowed in constant functions - --> $DIR/thread-local-static.rs:10:23 + --> $DIR/thread-local-static.rs:11:23 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^^^^^^ @@ -47,7 +32,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors Some errors have detailed explanations: E0133, E0625, E0658. For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/thread-local/thread-local-static.thir.stderr b/tests/ui/thread-local/thread-local-static.thir.stderr deleted file mode 100644 index 2043b268c090c..0000000000000 --- a/tests/ui/thread-local/thread-local-static.thir.stderr +++ /dev/null @@ -1,59 +0,0 @@ -warning: mutable reference of mutable static is discouraged - --> $DIR/thread-local-static.rs:12:23 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^^^^^^ mutable reference of mutable static - | - = note: for more information, see issue #114447 - = note: reference of mutable static is a hard error from 2024 edition - = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior - = note: `#[warn(static_mut_ref)]` on by default -help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer - | -LL | std::mem::swap(x, addr_of_mut!(STATIC_VAR_2)) - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/thread-local-static.rs:10:12 - | -LL | const fn g(x: &mut [u32; 8]) { - | ^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0625]: thread-local statics cannot be accessed at compile-time - --> $DIR/thread-local-static.rs:12:28 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^ - -error[E0013]: constant functions cannot refer to statics - --> $DIR/thread-local-static.rs:12:28 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error[E0658]: mutable references are not allowed in constant functions - --> $DIR/thread-local-static.rs:12:23 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/thread-local-static.rs:12:23 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^^^^^^ use of mutable static - | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - -error: aborting due to 5 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0013, E0133, E0625, E0658. -For more information about an error, try `rustc --explain E0013`.