diff --git a/.mailmap b/.mailmap index 87f32d28f5895..eb6a9fcabca99 100644 --- a/.mailmap +++ b/.mailmap @@ -88,7 +88,8 @@ boolean_coercion Boris Egorov bors bors[bot] <26634292+bors[bot]@users.noreply.github.com> bors bors[bot] -Boxy +BoxyUwU +BoxyUwU Braden Nelson Brandon Sanderson Brandon Sanderson Brett Cannon Brett Cannon diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 46e91636cfbbb..fe2d5a594f312 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2031,11 +2031,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> { match c.value.kind { ExprKind::Underscore => { - if self.tcx.features().generic_arg_infer() { - let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span)); - self.arena - .alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) - } else { + if !self.tcx.features().generic_arg_infer() { feature_err( &self.tcx.sess, sym::generic_arg_infer, @@ -2043,8 +2039,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fluent_generated::ast_lowering_underscore_array_length_unstable, ) .stash(c.value.span, StashKey::UnderscoreForArrayLengths); - self.lower_anon_const_to_const_arg(c) } + let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span)); + self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) } _ => self.lower_anon_const_to_const_arg(c), } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7a3cde4bc2fb7..44762299ee833 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3387,7 +3387,7 @@ impl<'hir> FnRetTy<'hir> { } } - pub fn get_infer_ret_ty(&self) -> Option<&'hir Ty<'hir>> { + pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> { if let Self::Return(ty) = self { if ty.is_suggestable_infer_ty() { return Some(*ty); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index ada70117b626f..888605b2345df 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -131,19 +131,25 @@ pub struct ItemCtxt<'tcx> { /////////////////////////////////////////////////////////////////////////// #[derive(Default)] -pub(crate) struct HirPlaceholderCollector(pub(crate) Vec); +pub(crate) struct HirPlaceholderCollector { + pub spans: Vec, + // If any of the spans points to a const infer var, then suppress any messages + // that may try to turn that const infer into a type parameter. + pub may_contain_const_infer: bool, +} impl<'v> Visitor<'v> for HirPlaceholderCollector { fn visit_ty(&mut self, t: &'v hir::Ty<'v>) { if let hir::TyKind::Infer = t.kind { - self.0.push(t.span); + self.spans.push(t.span); } intravisit::walk_ty(self, t) } fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) { match generic_arg { hir::GenericArg::Infer(inf) => { - self.0.push(inf.span); + self.spans.push(inf.span); + self.may_contain_const_infer = true; intravisit::walk_inf(self, inf); } hir::GenericArg::Type(t) => self.visit_ty(t), @@ -152,7 +158,8 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector { } fn visit_const_arg(&mut self, const_arg: &'v hir::ConstArg<'v>) { if let hir::ConstArgKind::Infer(span) = const_arg.kind { - self.0.push(span); + self.may_contain_const_infer = true; + self.spans.push(span); } intravisit::walk_const_arg(self, const_arg) } @@ -277,8 +284,8 @@ fn reject_placeholder_type_signatures_in_item<'tcx>( placeholder_type_error( icx.lowerer(), Some(generics), - visitor.0, - suggest, + visitor.spans, + suggest && !visitor.may_contain_const_infer, None, item.kind.descr(), ); @@ -607,16 +614,16 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { hir::FnRetTy::DefaultReturn(..) => tcx.types.unit, }; - if !(visitor.0.is_empty() && infer_replacements.is_empty()) { + if !(visitor.spans.is_empty() && infer_replacements.is_empty()) { // We check for the presence of // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`. let mut diag = crate::collect::placeholder_type_error_diag( self, generics, - visitor.0, + visitor.spans, infer_replacements.iter().map(|(s, _)| *s).collect(), - true, + !visitor.may_contain_const_infer, hir_ty, "function", ); @@ -712,7 +719,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { placeholder_type_error( icx.lowerer(), None, - visitor.0, + visitor.spans, false, None, "static variable", @@ -780,7 +787,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { placeholder_type_error( icx.lowerer(), None, - visitor.0, + visitor.spans, false, None, it.kind.descr(), @@ -822,7 +829,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { placeholder_type_error( icx.lowerer(), None, - visitor.0, + visitor.spans, false, None, "associated constant", @@ -837,7 +844,14 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { // Account for `type T = _;`. let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type"); + placeholder_type_error( + icx.lowerer(), + None, + visitor.spans, + false, + None, + "associated type", + ); } hir::TraitItemKind::Type(_, None) => { @@ -848,7 +862,14 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type"); + placeholder_type_error( + icx.lowerer(), + None, + visitor.spans, + false, + None, + "associated type", + ); } }; @@ -872,7 +893,14 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type"); + placeholder_type_error( + icx.lowerer(), + None, + visitor.spans, + false, + None, + "associated type", + ); } hir::ImplItemKind::Const(ty, _) => { // Account for `const T: _ = ..;` @@ -882,7 +910,7 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { placeholder_type_error( icx.lowerer(), None, - visitor.0, + visitor.spans, false, None, "associated constant", @@ -1371,7 +1399,7 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>( generics: &'tcx hir::Generics<'tcx>, def_id: LocalDefId, ) -> ty::PolyFnSig<'tcx> { - if let Some(infer_ret_ty) = sig.decl.output.get_infer_ret_ty() { + if let Some(infer_ret_ty) = sig.decl.output.is_suggestable_infer_ty() { return recover_infer_ret_ty(icx, infer_ret_ty, generics, def_id); } @@ -1422,7 +1450,7 @@ fn recover_infer_ret_ty<'tcx>( let mut visitor = HirPlaceholderCollector::default(); visitor.visit_ty(infer_ret_ty); - let mut diag = bad_placeholder(icx.lowerer(), visitor.0, "return type"); + let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type"); let ret_ty = fn_sig.output(); // Don't leak types into signatures unless they're nameable! diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c0526903e8881..87a04820f7ec1 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -4,6 +4,7 @@ use rustc_errors::{Applicability, StashKey, Suggestions}; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::Visitor; use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::with_forced_trimmed_paths; @@ -12,7 +13,7 @@ use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableEx use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; -use super::{ItemCtxt, bad_placeholder}; +use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder}; use crate::errors::TypeofReservedKeywordUsed; use crate::hir_ty_lowering::HirTyLowerer; @@ -412,7 +413,7 @@ fn infer_placeholder_type<'tcx>( kind: &'static str, ) -> Ty<'tcx> { let tcx = cx.tcx(); - let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id); + let ty = tcx.typeck(def_id).node_type(body_id.hir_id); // If this came from a free `const` or `static mut?` item, // then the user may have written e.g. `const A = 42;`. @@ -447,13 +448,37 @@ fn infer_placeholder_type<'tcx>( } }) .unwrap_or_else(|| { - let mut diag = bad_placeholder(cx, vec![span], kind); - - if !ty.references_error() { + let mut visitor = HirPlaceholderCollector::default(); + let node = tcx.hir_node_by_def_id(def_id); + if let Some(ty) = node.ty() { + visitor.visit_ty(ty); + } + // If we have just one span, let's try to steal a const `_` feature error. + let try_steal_span = if !tcx.features().generic_arg_infer() && visitor.spans.len() == 1 + { + visitor.spans.first().copied() + } else { + None + }; + // If we didn't find any infer tys, then just fallback to `span`. + if visitor.spans.is_empty() { + visitor.spans.push(span); + } + let mut diag = bad_placeholder(cx, visitor.spans, kind); + + // HACK(#69396): Stashing and stealing diagnostics does not interact + // well with macros which may delay more than one diagnostic on the + // same span. If this happens, we will fall through to this arm, so + // we need to suppress the suggestion since it's invalid. Ideally we + // would suppress the duplicated error too, but that's really hard. + if span.is_empty() && span.from_expansion() { + // An approximately better primary message + no suggestion... + diag.primary_message("missing type for item"); + } else if !ty.references_error() { if let Some(ty) = ty.make_suggestable(tcx, false, None) { - diag.span_suggestion( + diag.span_suggestion_verbose( span, - "replace with the correct type", + "replace this with a fully-specified type", ty, Applicability::MachineApplicable, ); @@ -464,7 +489,16 @@ fn infer_placeholder_type<'tcx>( )); } } - diag.emit() + + if let Some(try_steal_span) = try_steal_span { + cx.dcx().try_steal_replace_and_emit_err( + try_steal_span, + StashKey::UnderscoreForArrayLengths, + diag, + ) + } else { + diag.emit() + } }); Ty::new_error(tcx, guar) } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 66255829dcffe..c933095fd3db5 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -187,7 +187,7 @@ impl TaitConstraintLocator<'_> { "foreign items cannot constrain opaque types", ); if let Some(hir_sig) = hir_node.fn_sig() - && hir_sig.decl.output.get_infer_ret_ty().is_some() + && hir_sig.decl.output.is_suggestable_infer_ty().is_some() { let guar = self.tcx.dcx().span_delayed_bug( hir_sig.decl.output.span(), diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 2f7ed8dd2a877..9edf2485238cb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1771,12 +1771,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let parent_node = self.tcx.hir().parent_iter(expr.hir_id).find(|(_, node)| { !matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::AddrOf(..), .. })) }); - let Some(( - _, - hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) - | hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }), - )) = parent_node - else { + let Some((_, hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }))) = parent_node else { return; }; if let hir::TyKind::Array(_, ct) = ty.peel_refs().kind { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 91ea34eb54d35..5a0a855147deb 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -87,21 +87,7 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - let fallback = move || tcx.type_of(def_id.to_def_id()).instantiate_identity(); - typeck_with_fallback(tcx, def_id, fallback, None) -} - -/// Used only to get `TypeckResults` for type inference during error recovery. -/// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors. -fn diagnostic_only_typeck<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, -) -> &'tcx ty::TypeckResults<'tcx> { - let fallback = move || { - let span = tcx.hir().span(tcx.local_def_id_to_hir_id(def_id)); - Ty::new_error_with_message(tcx, span, "diagnostic only typeck table used") - }; - typeck_with_fallback(tcx, def_id, fallback, None) + typeck_with_fallback(tcx, def_id, None) } /// Same as `typeck` but `inspect` is invoked on evaluation of each root obligation. @@ -113,15 +99,13 @@ pub fn inspect_typeck<'tcx>( def_id: LocalDefId, inspect: ObligationInspector<'tcx>, ) -> &'tcx ty::TypeckResults<'tcx> { - let fallback = move || tcx.type_of(def_id.to_def_id()).instantiate_identity(); - typeck_with_fallback(tcx, def_id, fallback, Some(inspect)) + typeck_with_fallback(tcx, def_id, Some(inspect)) } -#[instrument(level = "debug", skip(tcx, fallback, inspector), ret)] +#[instrument(level = "debug", skip(tcx, inspector), ret)] fn typeck_with_fallback<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, - fallback: impl Fn() -> Ty<'tcx> + 'tcx, inspector: Option>, ) -> &'tcx ty::TypeckResults<'tcx> { // Closures' typeck results come from their outermost function, @@ -150,7 +134,11 @@ fn typeck_with_fallback<'tcx>( let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id); if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() { - let fn_sig = if decl.output.get_infer_ret_ty().is_some() { + let fn_sig = if decl.output.is_suggestable_infer_ty().is_some() { + // In the case that we're recovering `fn() -> W<_>` or some other return + // type that has an infer in it, lower the type directly so that it'll + // be correctly filled with infer. We'll use this inference to provide + // a suggestion later on. fcx.lowerer().lower_fn_ty(id, header.safety, header.abi, decl, None, None) } else { tcx.fn_sig(def_id).instantiate_identity() @@ -164,8 +152,19 @@ fn typeck_with_fallback<'tcx>( check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params()); } else { - let expected_type = infer_type_if_missing(&fcx, node); - let expected_type = expected_type.unwrap_or_else(fallback); + let expected_type = if let Some(infer_ty) = infer_type_if_missing(&fcx, node) { + infer_ty + } else if let Some(ty) = node.ty() + && ty.is_suggestable_infer_ty() + { + // In the case that we're recovering `const X: [T; _]` or some other + // type that has an infer in it, lower the type directly so that it'll + // be correctly filled with infer. We'll use this inference to provide + // a suggestion later on. + fcx.lowerer().lower_ty(ty) + } else { + tcx.type_of(def_id).instantiate_identity() + }; let expected_type = fcx.normalize(body.value.span, expected_type); @@ -506,5 +505,5 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! { pub fn provide(providers: &mut Providers) { method::provide(providers); - *providers = Providers { typeck, diagnostic_only_typeck, used_trait_imports, ..*providers }; + *providers = Providers { typeck, used_trait_imports, ..*providers }; } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index b1d5d688295d9..0383c81f2af0d 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -363,6 +363,13 @@ where return; } + if alias_ty.has_non_region_infer() { + self.tcx + .dcx() + .span_delayed_bug(origin.span(), "an alias has infers during region solving"); + return; + } + // This case is thorny for inference. The fundamental problem is // that there are many cases where we have choice, and inference // doesn't like choice (the current region inference in @@ -388,26 +395,9 @@ where // Compute the bounds we can derive from the environment. This // is an "approximate" match -- in some cases, these bounds // may not apply. - let mut approx_env_bounds = self.verify_bound.approx_declared_bounds_from_env(alias_ty); + let approx_env_bounds = self.verify_bound.approx_declared_bounds_from_env(alias_ty); debug!(?approx_env_bounds); - // Remove outlives bounds that we get from the environment but - // which are also deducible from the trait. This arises (cc - // #55756) in cases where you have e.g., `>::Item: - // 'a` in the environment but `trait Foo<'b> { type Item: 'b - // }` in the trait definition. - approx_env_bounds.retain(|bound_outlives| { - // OK to skip binder because we only manipulate and compare against other values from - // the same binder. e.g. if we have (e.g.) `for<'a> >::Item: 'a` in - // `bound`, the `'a` will be a `^1` (bound, debruijn index == innermost) region. If the - // declaration is `trait Trait<'b> { type Item: 'b; }`, then - // `projection_declared_bounds_from_trait` will be invoked with `['b => ^1]` and so we - // will get `^1` returned. - let bound = bound_outlives.skip_binder(); - let ty::Alias(_, alias_ty) = bound.0.kind() else { bug!("expected AliasTy") }; - self.verify_bound.declared_bounds_from_definition(*alias_ty).all(|r| r != bound.1) - }); - // If declared bounds list is empty, the only applicable rule is // OutlivesProjectionComponent. If there are inference variables, // then, we can break down the outlives into more primitive @@ -425,7 +415,7 @@ where let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque; if approx_env_bounds.is_empty() && trait_bounds.is_empty() - && (alias_ty.has_infer() || is_opaque) + && (alias_ty.has_infer_regions() || is_opaque) { debug!("no declared bounds"); let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id)); diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 247fbc259652e..7a21c2883d1ac 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -192,7 +192,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { /// Obviously these must be approximate -- they are in fact both *over* and /// and *under* approximated: /// - /// * Over-approximated because we erase regions, so + /// * Over-approximated because we don't consider equality of regions. /// * Under-approximated because we look for syntactic equality and so for complex types /// like `>::Item` or whatever we may fail to figure out /// all the subtleties. @@ -205,13 +205,14 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { erased_ty: Ty<'tcx>, ) -> Vec> { let tcx = self.tcx; + let mut bounds = vec![]; // To start, collect bounds from user environment. Note that // parameter environments are already elaborated, so we don't // have to worry about that. - let param_bounds = self.caller_bounds.iter().copied().filter(move |outlives_predicate| { + bounds.extend(self.caller_bounds.iter().copied().filter(move |outlives_predicate| { super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty) - }); + })); // Next, collect regions we scraped from the well-formedness // constraints in the fn signature. To do that, we walk the list @@ -224,37 +225,27 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // The problem is that the type of `x` is `&'a A`. To be // well-formed, then, A must outlive `'a`, but we don't know that // this holds from first principles. - let from_region_bound_pairs = - self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| { - debug!( - "declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}", - (r, p) - ); - // Fast path for the common case. - match (&p, erased_ty.kind()) { - // In outlive routines, all types are expected to be fully normalized. - // And therefore we can safely use structural equality for alias types. - (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {} - (GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {} - (GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {} - _ => return None, - } + bounds.extend(self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| { + debug!( + "declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}", + (r, p) + ); + // Fast path for the common case. + match (&p, erased_ty.kind()) { + // In outlive routines, all types are expected to be fully normalized. + // And therefore we can safely use structural equality for alias types. + (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {} + (GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {} + (GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {} + _ => return None, + } - let p_ty = p.to_ty(tcx); - let erased_p_ty = self.tcx.erase_regions(p_ty); - (erased_p_ty == erased_ty) - .then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r))) - }); + let p_ty = p.to_ty(tcx); + let erased_p_ty = self.tcx.erase_regions(p_ty); + (erased_p_ty == erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r))) + })); - param_bounds - .chain(from_region_bound_pairs) - .inspect(|bound| { - debug!( - "declared_generic_bounds_from_env_for_erased_ty: result predicate = {:?}", - bound - ) - }) - .collect() + bounds } /// Given a projection like `>::Bar`, returns any bounds diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7e7b602c560ba..b6934495e4419 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1100,9 +1100,6 @@ rustc_queries! { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } } - query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } - } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet { desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } diff --git a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs index 8c3bff2a90638..4e8a9d55f9a97 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), linker: None, relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, + panic_strategy: PanicStrategy::Unwind, features: "+thumb2,+neon,+vfp3".into(), max_atomic_width: Some(64), emit_debug_gdb_scripts: false, diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 6f1cbb0fee700..64e5a609b2f6d 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -31,7 +31,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( // If the type of the item uses `_`, we're gonna error out anyway, but // typeck (which type_of invokes below), will call back into opaque_types_defined_by // causing a cycle. So we just bail out in this case. - if hir_sig.output.get_infer_ret_ty().is_some() { + if hir_sig.output.is_suggestable_infer_ty().is_some() { return V::Result::output(); } let ty_sig = tcx.fn_sig(item).instantiate_identity(); diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 1981675f40922..8c28bb5c5b033 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -46,7 +46,7 @@ cfg_if::cfg_if! { target_os = "psp", target_os = "xous", target_os = "solid_asp3", - all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems", target_os = "nuttx"))), + all(target_family = "unix", not(any(target_os = "espidf", target_os = "nuttx"))), all(target_vendor = "fortanix", target_env = "sgx"), target_family = "wasm", ))] { diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs index 9754e840d151a..2e1d2e53a2979 100644 --- a/library/std/src/sys/personality/mod.rs +++ b/library/std/src/sys/personality/mod.rs @@ -31,7 +31,7 @@ cfg_if::cfg_if! { target_os = "psp", target_os = "xous", target_os = "solid_asp3", - all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems"), not(target_os = "nuttx")), + all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "nuttx")), all(target_vendor = "fortanix", target_env = "sgx"), ))] { mod gcc; diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 40d409310ffab..7af1882ab73a9 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -20,7 +20,6 @@ cfg_if::cfg_if! { target_os = "l4re", target_os = "none", target_os = "espidf", - target_os = "rtems", target_os = "nuttx", ))] { // These "unix" family members do not have unwinder. diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index ca337aa9f4c32..148b96181d1d2 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -93,7 +93,7 @@ impl Step for Std { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.crate_or_deps("sysroot").path("library") + run.crate_or_deps("sysroot").path("library").alias("core") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 1e9f7cbd9b4ca..75edc8ff78128 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -574,7 +574,10 @@ impl Step for Std { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.crate_or_deps("sysroot").path("library").default_condition(builder.config.docs) + run.crate_or_deps("sysroot") + .path("library") + .alias("core") + .default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 30e42a5bfb78d..04d51fab5d521 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -3,7 +3,7 @@ mod cargo; use std::any::{Any, type_name}; use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; -use std::fmt::{Debug, Write}; +use std::fmt::{self, Debug, Write}; use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; @@ -271,16 +271,17 @@ impl PathSet { /// This is used for `StepDescription::krate`, which passes all matching crates at once to /// `Step::make_run`, rather than calling it many times with a single crate. /// See `tests.rs` for examples. - fn intersection_removing_matches(&self, needles: &mut Vec, module: Kind) -> PathSet { + fn intersection_removing_matches(&self, needles: &mut [CLIStepPath], module: Kind) -> PathSet { let mut check = |p| { - for (i, n) in needles.iter().enumerate() { - let matched = Self::check(p, n, module); + let mut result = false; + for n in needles.iter_mut() { + let matched = Self::check(p, &n.path, module); if matched { - needles.remove(i); - return true; + n.will_be_executed = true; + result = true; } } - false + result }; match self { PathSet::Set(set) => PathSet::Set(set.iter().filter(|&p| check(p)).cloned().collect()), @@ -361,6 +362,32 @@ fn remap_paths(paths: &mut Vec) { paths.append(&mut add); } +#[derive(Clone, PartialEq)] +struct CLIStepPath { + path: PathBuf, + will_be_executed: bool, +} + +#[cfg(test)] +impl CLIStepPath { + fn will_be_executed(mut self, will_be_executed: bool) -> Self { + self.will_be_executed = will_be_executed; + self + } +} + +impl Debug for CLIStepPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.path.display()) + } +} + +impl From for CLIStepPath { + fn from(path: PathBuf) -> Self { + Self { path, will_be_executed: false } + } +} + impl StepDescription { fn from(kind: Kind) -> StepDescription { StepDescription { @@ -478,7 +505,8 @@ impl StepDescription { return; } - let mut path_lookup: Vec<(PathBuf, bool)> = + let mut paths: Vec = paths.into_iter().map(|p| p.into()).collect(); + let mut path_lookup: Vec<(CLIStepPath, bool)> = paths.clone().into_iter().map(|p| (p, false)).collect(); // List of `(usize, &StepDescription, Vec)` where `usize` is the closest index of a path @@ -518,8 +546,10 @@ impl StepDescription { } } + paths.retain(|p| !p.will_be_executed); + if !paths.is_empty() { - eprintln!("ERROR: no `{}` rules matched {:?}", builder.kind.as_str(), paths,); + eprintln!("ERROR: no `{}` rules matched {:?}", builder.kind.as_str(), paths); eprintln!( "HELP: run `x.py {} --help --verbose` to show a list of available paths", builder.kind.as_str() @@ -682,7 +712,7 @@ impl<'a> ShouldRun<'a> { /// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?) fn pathset_for_paths_removing_matches( &self, - paths: &mut Vec, + paths: &mut [CLIStepPath], kind: Kind, ) -> Vec { let mut sets = vec![]; @@ -825,12 +855,8 @@ impl<'a> Builder<'a> { match kind { Kind::Build => describe!( compile::Std, - // FIXME(#135022): `compile::Assemble` **must** come before `compile::Rustc` after - // `PathSet` also permits prefix-matching, because `compile::Rustc` can consume the - // `"compiler"` path filter first, causing `compile::Assemble` to no longer run when - // the user writes `./x build compiler --stage 0`. - compile::Assemble, compile::Rustc, + compile::Assemble, compile::CodegenBackend, compile::StartupObjects, tool::BuildManifest, @@ -929,14 +955,10 @@ impl<'a> Builder<'a> { test::Rustdoc, test::CoverageRunRustdoc, test::Pretty, - test::Crate, - test::CrateLibrustc, - // The cranelift and gcc tests need to be listed after the - // compiler unit tests (CrateLibrustc) so that they don't - // hijack the whole `compiler` directory during path matching. - // test::CodegenCranelift, test::CodegenGCC, + test::Crate, + test::CrateLibrustc, test::CrateRustdoc, test::CrateRustdocJsonTypes, test::CrateBootstrap, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 21694cf46fe21..5769198afac64 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -108,13 +108,37 @@ fn test_intersection() { }; let library_set = set(&["library/core", "library/alloc", "library/std"]); let mut command_paths = vec![ - PathBuf::from("library/core"), - PathBuf::from("library/alloc"), - PathBuf::from("library/stdarch"), + CLIStepPath::from(PathBuf::from("library/core")), + CLIStepPath::from(PathBuf::from("library/alloc")), + CLIStepPath::from(PathBuf::from("library/stdarch")), ]; let subset = library_set.intersection_removing_matches(&mut command_paths, Kind::Build); assert_eq!(subset, set(&["library/core", "library/alloc"]),); - assert_eq!(command_paths, vec![PathBuf::from("library/stdarch")]); + assert_eq!(command_paths, vec![ + CLIStepPath::from(PathBuf::from("library/core")).will_be_executed(true), + CLIStepPath::from(PathBuf::from("library/alloc")).will_be_executed(true), + CLIStepPath::from(PathBuf::from("library/stdarch")).will_be_executed(false), + ]); +} + +#[test] +fn test_resolve_parent_and_subpaths() { + let set = |paths: &[&str]| { + PathSet::Set(paths.into_iter().map(|p| TaskPath { path: p.into(), kind: None }).collect()) + }; + + let mut command_paths = vec![ + CLIStepPath::from(PathBuf::from("src/tools/miri")), + CLIStepPath::from(PathBuf::from("src/tools/miri/cargo-miri")), + ]; + + let library_set = set(&["src/tools/miri", "src/tools/miri/cargo-miri"]); + library_set.intersection_removing_matches(&mut command_paths, Kind::Build); + + assert_eq!(command_paths, vec![ + CLIStepPath::from(PathBuf::from("src/tools/miri")).will_be_executed(true), + CLIStepPath::from(PathBuf::from("src/tools/miri/cargo-miri")).will_be_executed(true), + ]); } #[test] diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 3c4fad4bca97e..dcee96978d2b5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -400,7 +400,27 @@ impl Item { } pub(crate) fn deprecation(&self, tcx: TyCtxt<'_>) -> Option { - self.def_id().and_then(|did| tcx.lookup_deprecation(did)) + self.def_id().and_then(|did| tcx.lookup_deprecation(did)).or_else(|| { + // `allowed_through_unstable_modules` is a bug-compatibility hack for old rustc + // versions; the paths that are exposed through it are "deprecated" because they + // were never supposed to work at all. + let stab = self.stability(tcx)?; + if let rustc_attr_parsing::StabilityLevel::Stable { + allowed_through_unstable_modules: true, + .. + } = stab.level + { + Some(Deprecation { + // FIXME(#131676, #135003): when a note is added to this stability tag, + // translate it here + since: rustc_attr_parsing::DeprecatedSince::Unspecified, + note: None, + suggestion: None, + }) + } else { + None + } + }) } pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index 4c682c3d4ca05..d892c58583778 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -107,6 +107,14 @@ fn merge_stability( || parent_stab.stable_since().is_some_and(|parent_since| parent_since > own_since)) { parent_stability + } else if let Some(mut own_stab) = own_stability + && let StabilityLevel::Stable { since, allowed_through_unstable_modules: true } = + own_stab.level + && parent_stability.is_some_and(|stab| stab.is_stable()) + { + // this property does not apply transitively through re-exports + own_stab.level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; + Some(own_stab) } else { own_stability } diff --git a/src/tools/run-make-support/src/assertion_helpers.rs b/src/tools/run-make-support/src/assertion_helpers.rs deleted file mode 100644 index e84a3cf633f97..0000000000000 --- a/src/tools/run-make-support/src/assertion_helpers.rs +++ /dev/null @@ -1,107 +0,0 @@ -//! Collection of assertions and assertion-related helpers. - -use std::panic; -use std::path::Path; - -use crate::{fs, regex}; - -fn print<'a, 'e, A: AsRef, E: AsRef>( - assertion_kind: &str, - haystack: &'a A, - needle: &'e E, -) -> (&'a str, &'e str) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); - eprintln!("{assertion_kind}:"); - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); - (haystack, needle) -} - -/// Assert that `actual` is equal to `expected`. -#[track_caller] -pub fn assert_equals, E: AsRef>(actual: A, expected: E) { - let actual = actual.as_ref(); - let expected = expected.as_ref(); - eprintln!("=== ACTUAL TEXT ==="); - eprintln!("{}", actual); - eprintln!("=== EXPECTED ==="); - eprintln!("{}", expected); - if actual != expected { - panic!("expected text was not found in actual text"); - } -} - -/// Assert that `haystack` contains `needle`. -#[track_caller] -pub fn assert_contains, N: AsRef>(haystack: H, needle: N) { - let (haystack, needle) = print("assert_contains", &haystack, &needle); - if !haystack.contains(needle) { - panic!("needle was not found in haystack"); - } -} - -/// Assert that `haystack` does not contain `needle`. -#[track_caller] -pub fn assert_not_contains, N: AsRef>(haystack: H, needle: N) { - let (haystack, needle) = print("assert_not_contains", &haystack, &needle); - if haystack.contains(needle) { - panic!("needle was unexpectedly found in haystack"); - } -} - -/// Assert that `haystack` contains the regex pattern `needle`. -#[track_caller] -pub fn assert_contains_regex, N: AsRef>(haystack: H, needle: N) { - let (haystack, needle) = print("assert_contains_regex", &haystack, &needle); - let re = regex::Regex::new(needle).unwrap(); - if !re.is_match(haystack) { - panic!("needle was not found in haystack"); - } -} - -/// Assert that `haystack` does not contain the regex pattern `needle`. -#[track_caller] -pub fn assert_not_contains_regex, N: AsRef>(haystack: H, needle: N) { - let (haystack, needle) = print("assert_not_contains_regex", &haystack, &needle); - let re = regex::Regex::new(needle).unwrap(); - if re.is_match(haystack) { - panic!("needle was unexpectedly found in haystack"); - } -} - -/// Assert that `haystack` contains `needle` a `count` number of times. -#[track_caller] -pub fn assert_count_is, N: AsRef>(count: usize, haystack: H, needle: N) { - let (haystack, needle) = print("assert_count_is", &haystack, &needle); - if count != haystack.matches(needle).count() { - panic!("needle did not appear {count} times in haystack"); - } -} - -/// Assert that all files in `dir1` exist and have the same content in `dir2` -pub fn assert_dirs_are_equal(dir1: impl AsRef, dir2: impl AsRef) { - let dir2 = dir2.as_ref(); - fs::read_dir_entries(dir1, |entry_path| { - let entry_name = entry_path.file_name().unwrap(); - if entry_path.is_dir() { - assert_dirs_are_equal(&entry_path, &dir2.join(entry_name)); - } else { - let path2 = dir2.join(entry_name); - let file1 = fs::read(&entry_path); - let file2 = fs::read(&path2); - - // We don't use `assert_eq!` because they are `Vec`, so not great for display. - // Why not using String? Because there might be minified files or even potentially - // binary ones, so that would display useless output. - assert!( - file1 == file2, - "`{}` and `{}` have different content", - entry_path.display(), - path2.display(), - ); - } - }); -} diff --git a/src/tools/run-make-support/src/assertion_helpers/mod.rs b/src/tools/run-make-support/src/assertion_helpers/mod.rs new file mode 100644 index 0000000000000..9b666473b5b37 --- /dev/null +++ b/src/tools/run-make-support/src/assertion_helpers/mod.rs @@ -0,0 +1,135 @@ +//! Collection of assertions and assertion-related helpers. + +#[cfg(test)] +mod tests; + +use std::panic; +use std::path::Path; + +use crate::{fs, regex}; + +/// Assert that `actual` is equal to `expected`. +#[track_caller] +pub fn assert_equals, E: AsRef>(actual: A, expected: E) { + let actual = actual.as_ref(); + let expected = expected.as_ref(); + + if actual != expected { + eprintln!("=== ACTUAL TEXT ==="); + eprintln!("{}", actual); + eprintln!("=== EXPECTED ==="); + eprintln!("{}", expected); + panic!("expected text does not match actual text"); + } +} + +struct SearchDetails<'assertion_name, 'haystack, 'needle> { + assertion_name: &'assertion_name str, + haystack: &'haystack str, + needle: &'needle str, +} + +impl<'assertion_name, 'haystack, 'needle> SearchDetails<'assertion_name, 'haystack, 'needle> { + fn dump(&self) { + eprintln!("{}:", self.assertion_name); + eprintln!("=== HAYSTACK ==="); + eprintln!("{}", self.haystack); + eprintln!("=== NEEDLE ==="); + eprintln!("{}", self.needle); + } +} + +/// Assert that `haystack` contains `needle`. +#[track_caller] +pub fn assert_contains, N: AsRef>(haystack: H, needle: N) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + if !haystack.contains(needle) { + SearchDetails { assertion_name: "assert_contains", haystack, needle }.dump(); + panic!("needle was not found in haystack"); + } +} + +/// Assert that `haystack` does not contain `needle`. +#[track_caller] +pub fn assert_not_contains, N: AsRef>(haystack: H, needle: N) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + if haystack.contains(needle) { + SearchDetails { assertion_name: "assert_not_contains", haystack, needle }.dump(); + panic!("needle was unexpectedly found in haystack"); + } +} + +/// Assert that `haystack` contains the regex `needle`. +#[track_caller] +pub fn assert_contains_regex, N: AsRef>(haystack: H, needle: N) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + let re = regex::Regex::new(needle).unwrap(); + if !re.is_match(haystack) { + SearchDetails { assertion_name: "assert_contains_regex", haystack, needle }.dump(); + panic!("regex was not found in haystack"); + } +} + +/// Assert that `haystack` does not contain the regex `needle`. +#[track_caller] +pub fn assert_not_contains_regex, N: AsRef>(haystack: H, needle: N) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + let re = regex::Regex::new(needle).unwrap(); + if re.is_match(haystack) { + SearchDetails { assertion_name: "assert_not_contains_regex", haystack, needle }.dump(); + panic!("regex was unexpectedly found in haystack"); + } +} + +/// Assert that `haystack` contains regex `needle` an `expected_count` number of times. +#[track_caller] +pub fn assert_count_is, N: AsRef>( + expected_count: usize, + haystack: H, + needle: N, +) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + + let actual_count = haystack.matches(needle).count(); + if expected_count != actual_count { + let count_fmt = format!( + "assert_count_is (expected_count = {expected_count}, actual_count = {actual_count})" + ); + SearchDetails { assertion_name: &count_fmt, haystack, needle }.dump(); + panic!( + "regex did not appear {expected_count} times in haystack (expected_count = \ + {expected_count}, actual_count = {actual_count})" + ); + } +} + +/// Assert that all files in `dir1` exist and have the same content in `dir2` +// FIXME(#135037): not robust against symlinks, lacks sanity test coverage. +pub fn assert_dirs_are_equal(dir1: impl AsRef, dir2: impl AsRef) { + let dir2 = dir2.as_ref(); + fs::read_dir_entries(dir1, |entry_path| { + let entry_name = entry_path.file_name().unwrap(); + if entry_path.is_dir() { + assert_dirs_are_equal(&entry_path, &dir2.join(entry_name)); + } else { + let path2 = dir2.join(entry_name); + let file1 = fs::read(&entry_path); + let file2 = fs::read(&path2); + + // We don't use `assert_eq!` because they are `Vec`, so not great for display. + // Why not using String? Because there might be minified files or even potentially + // binary ones, so that would display useless output. + assert!( + file1 == file2, + "`{}` and `{}` have different content", + entry_path.display(), + path2.display(), + ); + } + }); +} diff --git a/src/tools/run-make-support/src/assertion_helpers/tests.rs b/src/tools/run-make-support/src/assertion_helpers/tests.rs new file mode 100644 index 0000000000000..8bf7740d2e69e --- /dev/null +++ b/src/tools/run-make-support/src/assertion_helpers/tests.rs @@ -0,0 +1,100 @@ +//! Basic sanity checks for assertion helpers. +use super::*; + +mod test_assert_equals { + use super::*; + + #[test] + fn assert_equals_same() { + assert_equals("foo", "foo"); + assert_equals("", ""); + } + + #[test] + #[should_panic] + fn assert_equals_different() { + assert_equals("foo", "bar"); + } +} + +mod test_assert_contains { + use super::*; + + #[test] + fn assert_contains_yes() { + assert_contains("", ""); + assert_contains(" ", ""); + assert_contains("a", "a"); + assert_contains("ab", "a"); + } + + #[test] + #[should_panic] + fn assert_contains_no() { + assert_contains("a", "b"); + } +} + +mod test_assert_not_contains { + use super::*; + + #[test] + fn assert_not_contains_yes() { + assert_not_contains("a", "b"); + } + + #[test] + #[should_panic] + fn assert_not_contains_no() { + assert_not_contains(" ", ""); + } +} + +mod assert_contains_regex { + use super::*; + + #[test] + fn assert_contains_regex_yes() { + assert_contains_regex("", ""); + assert_contains_regex("", ".*"); + assert_contains_regex("abcde", ".*"); + assert_contains_regex("abcde", ".+"); + } + + #[test] + #[should_panic] + fn assert_contains_regex_no() { + assert_contains_regex("", ".+"); + } +} + +mod assert_not_contains_regex_regex { + use super::*; + + #[test] + fn assert_not_contains_regex_yes() { + assert_not_contains_regex("abc", "d"); + } + + #[test] + #[should_panic] + fn assert_not_contains_regex_no() { + assert_not_contains_regex("abc", ".*"); + } +} + +mod test_assert_count_is { + use super::*; + + #[test] + fn assert_count_is_yes() { + assert_count_is(0, "", "b"); + assert_count_is(3, "abcbdb", "b"); + } + + #[test] + #[should_panic] + fn assert_count_is_no() { + assert_count_is(2, "abcbdb", "b"); + } +} diff --git a/tests/rustdoc-js-std/core-transmute.js b/tests/rustdoc-js-std/core-transmute.js new file mode 100644 index 0000000000000..8c9910a32d7f1 --- /dev/null +++ b/tests/rustdoc-js-std/core-transmute.js @@ -0,0 +1,11 @@ +const FILTER_CRATE = "core"; +const EXPECTED = [ + { + 'query': 'generic:T -> generic:U', + 'others': [ + { 'path': 'core::intrinsics::simd', 'name': 'simd_as' }, + { 'path': 'core::intrinsics::simd', 'name': 'simd_cast' }, + { 'path': 'core::mem', 'name': 'transmute' }, + ], + }, +]; diff --git a/tests/rustdoc-js-std/transmute-fail.js b/tests/rustdoc-js-std/transmute-fail.js index c4dddf3cf3cee..ddfb276194818 100644 --- a/tests/rustdoc-js-std/transmute-fail.js +++ b/tests/rustdoc-js-std/transmute-fail.js @@ -1,4 +1,5 @@ // should-fail +const FILTER_CRATE = "std"; const EXPECTED = [ { // Keep this test case identical to `transmute`, except the @@ -7,7 +8,7 @@ const EXPECTED = [ 'others': [ { 'path': 'std::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'std::intrinsics', 'name': 'transmute' }, + { 'path': 'std::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js-std/transmute.js b/tests/rustdoc-js-std/transmute.js index 0e52e21e0dead..f52e0ab14362d 100644 --- a/tests/rustdoc-js-std/transmute.js +++ b/tests/rustdoc-js-std/transmute.js @@ -1,3 +1,4 @@ +const FILTER_CRATE = "std"; const EXPECTED = [ { // Keep this test case identical to `transmute-fail`, except the @@ -6,7 +7,7 @@ const EXPECTED = [ 'others': [ { 'path': 'std::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'std::intrinsics', 'name': 'transmute' }, + { 'path': 'std::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/ui/array-slice-vec/suggest-array-length.fixed b/tests/ui/array-slice-vec/suggest-array-length.fixed index 29f85da56e578..2eacc2517d310 100644 --- a/tests/ui/array-slice-vec/suggest-array-length.fixed +++ b/tests/ui/array-slice-vec/suggest-array-length.fixed @@ -3,24 +3,21 @@ fn main() { const Foo: [i32; 3] = [1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants const REF_FOO: &[u8; 1] = &[1]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + static Statik: [i32; 3] = [1, 2, 3]; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + static REF_STATIK: &[u8; 1] = &[1]; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables let foo: [i32; 3] = [1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let bar: [i32; 3] = [0; 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let ref_foo: &[i32; 3] = &[1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let ref_bar: &[i32; 3] = &[0; 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let multiple_ref_foo: &&[i32; 3] = &&[1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable } diff --git a/tests/ui/array-slice-vec/suggest-array-length.rs b/tests/ui/array-slice-vec/suggest-array-length.rs index 82d871cf8754a..fb4424cfed99d 100644 --- a/tests/ui/array-slice-vec/suggest-array-length.rs +++ b/tests/ui/array-slice-vec/suggest-array-length.rs @@ -3,24 +3,21 @@ fn main() { const Foo: [i32; _] = [1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants const REF_FOO: &[u8; _] = &[1]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + static Statik: [i32; _] = [1, 2, 3]; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + static REF_STATIK: &[u8; _] = &[1]; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables let foo: [i32; _] = [1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let bar: [i32; _] = [0; 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let ref_foo: &[i32; _] = &[1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let ref_bar: &[i32; _] = &[0; 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3]; - //~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment - //~| ERROR using `_` for array lengths is unstable + //~^ ERROR using `_` for array lengths is unstable } diff --git a/tests/ui/array-slice-vec/suggest-array-length.stderr b/tests/ui/array-slice-vec/suggest-array-length.stderr index fdab7ba7064e4..b71be306780fc 100644 --- a/tests/ui/array-slice-vec/suggest-array-length.stderr +++ b/tests/ui/array-slice-vec/suggest-array-length.stderr @@ -1,67 +1,49 @@ -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:11:20 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/suggest-array-length.rs:5:22 | -LL | let foo: [i32; _] = [1, 2, 3]; - | ^ `_` not allowed here - -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:14:20 +LL | const Foo: [i32; _] = [1, 2, 3]; + | ^ not allowed in type signatures | -LL | let bar: [i32; _] = [0; 3]; - | ^ `_` not allowed here - -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:17:25 +help: replace this with a fully-specified type | -LL | let ref_foo: &[i32; _] = &[1, 2, 3]; - | ^ `_` not allowed here +LL | const Foo: [i32; 3] = [1, 2, 3]; + | ~~~~~~~~ -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:20:25 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/suggest-array-length.rs:7:26 | -LL | let ref_bar: &[i32; _] = &[0; 3]; - | ^ `_` not allowed here - -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:23:35 +LL | const REF_FOO: &[u8; _] = &[1]; + | ^ not allowed in type signatures | -LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3]; - | ^ `_` not allowed here - -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:5:22 +help: replace this with a fully-specified type | -LL | const Foo: [i32; _] = [1, 2, 3]; - | ^ `_` not allowed here +LL | const REF_FOO: &[u8; 1] = &[1]; + | ~~~~~~~~ -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/suggest-array-length.rs:8:26 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/suggest-array-length.rs:9:26 | -LL | const REF_FOO: &[u8; _] = &[1]; - | ^ `_` not allowed here - -error[E0658]: using `_` for array lengths is unstable - --> $DIR/suggest-array-length.rs:5:22 +LL | static Statik: [i32; _] = [1, 2, 3]; + | ^ not allowed in type signatures | -LL | const Foo: [i32; _] = [1, 2, 3]; - | ^ help: consider specifying the array length: `3` +help: replace this with a fully-specified type | - = note: see issue #85077 for more information - = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +LL | static Statik: [i32; 3] = [1, 2, 3]; + | ~~~~~~~~ -error[E0658]: using `_` for array lengths is unstable - --> $DIR/suggest-array-length.rs:8:26 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/suggest-array-length.rs:11:30 | -LL | const REF_FOO: &[u8; _] = &[1]; - | ^ help: consider specifying the array length: `1` +LL | static REF_STATIK: &[u8; _] = &[1]; + | ^ not allowed in type signatures | - = note: see issue #85077 for more information - = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +help: replace this with a fully-specified type + | +LL | static REF_STATIK: &[u8; 1] = &[1]; + | ~~~~~~~~ error[E0658]: using `_` for array lengths is unstable - --> $DIR/suggest-array-length.rs:11:20 + --> $DIR/suggest-array-length.rs:13:20 | LL | let foo: [i32; _] = [1, 2, 3]; | ^ help: consider specifying the array length: `3` @@ -71,7 +53,7 @@ LL | let foo: [i32; _] = [1, 2, 3]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: using `_` for array lengths is unstable - --> $DIR/suggest-array-length.rs:14:20 + --> $DIR/suggest-array-length.rs:15:20 | LL | let bar: [i32; _] = [0; 3]; | ^ help: consider specifying the array length: `3` @@ -91,7 +73,7 @@ LL | let ref_foo: &[i32; _] = &[1, 2, 3]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: using `_` for array lengths is unstable - --> $DIR/suggest-array-length.rs:20:25 + --> $DIR/suggest-array-length.rs:19:25 | LL | let ref_bar: &[i32; _] = &[0; 3]; | ^ help: consider specifying the array length: `3` @@ -101,7 +83,7 @@ LL | let ref_bar: &[i32; _] = &[0; 3]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: using `_` for array lengths is unstable - --> $DIR/suggest-array-length.rs:23:35 + --> $DIR/suggest-array-length.rs:21:35 | LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3]; | ^ help: consider specifying the array length: `3` @@ -110,6 +92,7 @@ LL | let multiple_ref_foo: &&[i32; _] = &&[1, 2, 3]; = help: add `#![feature(generic_arg_infer)]` 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 14 previous errors +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0121, E0658. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/async-await/issues/issue-95307.rs b/tests/ui/async-await/issues/issue-95307.rs index 40700c610f33b..27903a667fb5c 100644 --- a/tests/ui/async-await/issues/issue-95307.rs +++ b/tests/ui/async-await/issues/issue-95307.rs @@ -5,8 +5,8 @@ pub trait C { async fn new() -> [u8; _]; - //~^ ERROR: using `_` for array lengths is unstable - //~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions + //~| ERROR using `_` for array lengths is unstable } fn main() {} diff --git a/tests/ui/async-await/issues/issue-95307.stderr b/tests/ui/async-await/issues/issue-95307.stderr index dd8fcd3690a71..90100f391637a 100644 --- a/tests/ui/async-await/issues/issue-95307.stderr +++ b/tests/ui/async-await/issues/issue-95307.stderr @@ -1,8 +1,8 @@ -error: in expressions, `_` can only be used on the left-hand side of an assignment +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/issue-95307.rs:7:28 | LL | async fn new() -> [u8; _]; - | ^ `_` not allowed here + | ^ not allowed in type signatures error[E0658]: using `_` for array lengths is unstable --> $DIR/issue-95307.rs:7:28 @@ -16,4 +16,5 @@ LL | async fn new() -> [u8; _]; error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0121, E0658. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr index fcac95732d12e..5999bc1820405 100644 --- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr +++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr @@ -27,52 +27,74 @@ LL | fn ty_fn_mixed() -> 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 + --> $DIR/in-signature.rs:22:20 | LL | const ARR_CT: [u8; _] = [0; 3]; - | ^^^^^^^ not allowed in type signatures + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const ARR_CT: [u8; 3] = [0; 3]; + | ~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/in-signature.rs:24:20 + --> $DIR/in-signature.rs:24:25 | LL | static ARR_STATIC: [u8; _] = [0; 3]; - | ^^^^^^^ not allowed in type signatures + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static ARR_STATIC: [u8; 3] = [0; 3]; + | ~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/in-signature.rs:26:14 + --> $DIR/in-signature.rs:26:23 | LL | const TY_CT: Bar = Bar::(0); - | ^^^^^^^^^^^ - | | - | not allowed in type signatures - | help: replace with the correct type: `Bar` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const TY_CT: Bar = Bar::(0); + | ~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/in-signature.rs:28:19 + --> $DIR/in-signature.rs:28:28 | LL | static TY_STATIC: Bar = Bar::(0); - | ^^^^^^^^^^^ - | | - | not allowed in type signatures - | help: replace with the correct type: `Bar` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static TY_STATIC: Bar = Bar::(0); + | ~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/in-signature.rs:30:20 + --> $DIR/in-signature.rs:30:24 | LL | const TY_CT_MIXED: Bar<_, _> = Bar::(0); - | ^^^^^^^^^ - | | - | not allowed in type signatures - | help: replace with the correct type: `Bar` + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const TY_CT_MIXED: Bar = Bar::(0); + | ~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/in-signature.rs:32:25 + --> $DIR/in-signature.rs:32:29 | LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::(0); - | ^^^^^^^^^ - | | - | not allowed in type signatures - | help: replace with the correct type: `Bar` + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static TY_STATIC_MIXED: Bar = Bar::(0); + | ~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types --> $DIR/in-signature.rs:51:23 diff --git a/tests/ui/consts/issue-104768.rs b/tests/ui/consts/issue-104768.rs index 3192daafa0b92..52a8070be4e41 100644 --- a/tests/ui/consts/issue-104768.rs +++ b/tests/ui/consts/issue-104768.rs @@ -1,4 +1,5 @@ const A: &_ = 0_u32; //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for constants +//~| ERROR: mismatched types fn main() {} diff --git a/tests/ui/consts/issue-104768.stderr b/tests/ui/consts/issue-104768.stderr index 8a4a41e4d68a8..41a9bab0961ab 100644 --- a/tests/ui/consts/issue-104768.stderr +++ b/tests/ui/consts/issue-104768.stderr @@ -1,12 +1,28 @@ +error[E0308]: mismatched types + --> $DIR/issue-104768.rs:1:15 + | +LL | const A: &_ = 0_u32; + | ^^^^^ expected `&_`, found `u32` + | + = note: expected reference `&'static _` + found type `u32` +help: consider borrowing here + | +LL | const A: &_ = &0_u32; + | + + error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/issue-104768.rs:1:10 + --> $DIR/issue-104768.rs:1:11 | LL | const A: &_ = 0_u32; - | ^^ - | | - | not allowed in type signatures - | help: replace with the correct type: `u32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const A: u32 = 0_u32; + | ~~~ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0121`. +Some errors have detailed explanations: E0121, E0308. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/error-codes/E0121.stderr b/tests/ui/error-codes/E0121.stderr index 023d7e011bf3a..5f5df0fd0ae0e 100644 --- a/tests/ui/error-codes/E0121.stderr +++ b/tests/ui/error-codes/E0121.stderr @@ -11,10 +11,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/E0121.rs:3:13 | LL | static BAR: _ = "test"; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `&str` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static BAR: &str = "test"; + | ~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr index 97370f0489b56..96fb4a53609eb 100644 --- a/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr +++ b/tests/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr @@ -1,17 +1,5 @@ -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/feature-gate-generic_arg_infer.rs:11:27 - | -LL | let _x: [u8; 3] = [0; _]; - | ^ `_` not allowed here - -error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/feature-gate-generic_arg_infer.rs:14:18 - | -LL | let _y: [u8; _] = [0; 3]; - | ^ `_` not allowed here - error[E0658]: using `_` for array lengths is unstable - --> $DIR/feature-gate-generic_arg_infer.rs:14:18 + --> $DIR/feature-gate-generic_arg_infer.rs:13:18 | LL | let _y: [u8; _] = [0; 3]; | ^ help: consider specifying the array length: `3` @@ -21,7 +9,7 @@ LL | let _y: [u8; _] = [0; 3]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0747]: type provided when a constant was expected - --> $DIR/feature-gate-generic_arg_infer.rs:20:20 + --> $DIR/feature-gate-generic_arg_infer.rs:18:20 | LL | let _x = foo::<_>([1,2]); | ^ @@ -42,7 +30,7 @@ LL | let _x: [u8; 3] = [0; _]; = help: add `#![feature(generic_arg_infer)]` 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 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0658, E0747. For more information about an error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs b/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs index 0473253004a45..de4b7078ea683 100644 --- a/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs +++ b/tests/ui/feature-gates/feature-gate-generic_arg_infer.rs @@ -10,10 +10,8 @@ fn foo(_: [u8; N]) -> [u8; N] { fn bar() { let _x: [u8; 3] = [0; _]; //[normal]~^ ERROR: using `_` for array lengths is unstable - //[normal]~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment let _y: [u8; _] = [0; 3]; //[normal]~^ ERROR: using `_` for array lengths is unstable - //[normal]~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment } fn main() { diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs index 93160f0b5758d..0c94a4262ef47 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.rs +++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs @@ -12,7 +12,6 @@ impl Trait for () { const K = (); //~^ ERROR missing type for `const` item //~| ERROR mismatched types - //~| ERROR mismatched types const Q = ""; //~^ ERROR missing type for `const` item //~| ERROR lifetime parameters or bounds on const `Q` do not match the trait declaration diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr index 6f35c0958d45c..5af119dffa7c8 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.stderr +++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr @@ -16,7 +16,7 @@ LL | const K = (); | ^ help: provide a type for the associated constant: `()` error[E0195]: lifetime parameters or bounds on const `Q` do not match the trait declaration - --> $DIR/assoc-const-missing-type.rs:16:12 + --> $DIR/assoc-const-missing-type.rs:15:12 | LL | const Q<'a>: &'a str; | ---- lifetimes in impl do not match this const in trait @@ -25,24 +25,12 @@ LL | const Q = ""; | ^ lifetimes do not match const in trait error: missing type for `const` item - --> $DIR/assoc-const-missing-type.rs:16:12 + --> $DIR/assoc-const-missing-type.rs:15:12 | LL | const Q = ""; | ^ help: provide a type for the associated constant: `: &str` -error[E0308]: mismatched types - --> $DIR/assoc-const-missing-type.rs:12:18 - | -LL | const K = (); - | - ^^ expected type parameter `T`, found `()` - | | - | expected this type parameter - | - = note: expected type parameter `T` - found unit type `()` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0195, E0308. For more information about an error, try `rustc --explain E0195`. diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs index 45a30857413b9..c200a1fd0b41e 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs @@ -4,7 +4,7 @@ macro_rules! suite { const A = "A".$fn(); //~^ ERROR the name `A` is defined multiple times //~| ERROR missing type for `const` item - //~| ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~| ERROR missing type for item )* } } diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr index 89aeafebac497..4342d7d88f54b 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr @@ -27,14 +27,11 @@ LL | | } | = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants +error[E0121]: missing type for item --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 | LL | const A = "A".$fn(); - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `bool` + | ^ not allowed in type signatures ... LL | / suite! { LL | | len; diff --git a/tests/ui/parser/issues/issue-89574.rs b/tests/ui/parser/issues/issue-89574.rs index bafb0ce5e6680..276abfe71102b 100644 --- a/tests/ui/parser/issues/issue-89574.rs +++ b/tests/ui/parser/issues/issue-89574.rs @@ -2,5 +2,4 @@ fn main() { const EMPTY_ARRAY = []; //~^ missing type for `const` item //~| ERROR type annotations needed - //~| ERROR type annotations needed } diff --git a/tests/ui/parser/issues/issue-89574.stderr b/tests/ui/parser/issues/issue-89574.stderr index aa5e66b18a927..f40f5aded8ef1 100644 --- a/tests/ui/parser/issues/issue-89574.stderr +++ b/tests/ui/parser/issues/issue-89574.stderr @@ -15,14 +15,6 @@ help: provide a type for the item LL | const EMPTY_ARRAY: = []; | ++++++++ -error[E0282]: type annotations needed - --> $DIR/issue-89574.rs:2:25 - | -LL | const EMPTY_ARRAY = []; - | ^^ cannot infer type - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/suggestions/unnamable-types.rs b/tests/ui/suggestions/unnamable-types.rs index dd2c3536eb92e..094584ff850b3 100644 --- a/tests/ui/suggestions/unnamable-types.rs +++ b/tests/ui/suggestions/unnamable-types.rs @@ -10,7 +10,7 @@ const A = 5; static B: _ = "abc"; //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static variables //~| NOTE: not allowed in type signatures -//~| HELP: replace with the correct type +//~| HELP: replace this with a fully-specified type // FIXME: this should also suggest a function pointer, as the closure is non-capturing diff --git a/tests/ui/suggestions/unnamable-types.stderr b/tests/ui/suggestions/unnamable-types.stderr index 6623678fd0c2d..dc236af91f823 100644 --- a/tests/ui/suggestions/unnamable-types.stderr +++ b/tests/ui/suggestions/unnamable-types.stderr @@ -8,10 +8,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/unnamable-types.rs:10:11 | LL | static B: _ = "abc"; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `&str` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static B: &str = "abc"; + | ~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/unnamable-types.rs:17:10 diff --git a/tests/ui/typeck/issue-79040.rs b/tests/ui/typeck/issue-79040.rs index 03e008207566e..f8e38e7867d52 100644 --- a/tests/ui/typeck/issue-79040.rs +++ b/tests/ui/typeck/issue-79040.rs @@ -1,6 +1,6 @@ fn main() { - const FOO = "hello" + 1; //~ ERROR cannot add `{integer}` to `&str` - //~^ missing type for `const` item - //~| ERROR cannot add `{integer}` to `&str` + const FOO = "hello" + 1; + //~^ ERROR cannot add `{integer}` to `&str` + //~| missing type for `const` item println!("{}", FOO); } diff --git a/tests/ui/typeck/issue-79040.stderr b/tests/ui/typeck/issue-79040.stderr index 39636db85a784..4ab8df8f6c936 100644 --- a/tests/ui/typeck/issue-79040.stderr +++ b/tests/ui/typeck/issue-79040.stderr @@ -17,16 +17,6 @@ help: provide a type for the item LL | const FOO: = "hello" + 1; | ++++++++ -error[E0369]: cannot add `{integer}` to `&str` - --> $DIR/issue-79040.rs:2:25 - | -LL | const FOO = "hello" + 1; - | ------- ^ - {integer} - | | - | &str - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index 437a1aed40307..9f1bfd7909e38 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -221,6 +221,7 @@ fn value() -> Option<&'static _> { const _: Option<_> = map(value); //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants +//~| ERROR cannot call non-const function `map::` in constants fn evens_squared(n: usize) -> _ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index e62ebae5fd24b..c97b9312076d3 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -67,25 +67,36 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:13:15 | LL | static TEST3: _ = "test"; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `&str` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static TEST3: &str = "test"; + | ~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:16:15 | LL | static TEST4: _ = 145; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static TEST4: i32 = 145; + | ~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:19:15 + --> $DIR/typeck_type_placeholder_item.rs:19:16 | LL | static TEST5: (_, _) = (1, 2); - | ^^^^^^ not allowed in type signatures + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static TEST5: (i32, i32) = (1, 2); + | ~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:22:13 @@ -220,16 +231,23 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:75:15 | LL | static B: _ = 42; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static B: i32 = 42; + | ~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:77:15 + --> $DIR/typeck_type_placeholder_item.rs:77:22 | LL | static C: Option<_> = Some(42); - | ^^^^^^^^^ not allowed in type signatures + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static C: Option = Some(42); + | ~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:79:21 @@ -254,25 +272,36 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:85:22 | LL | static FN_TEST3: _ = "test"; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `&str` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static FN_TEST3: &str = "test"; + | ~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:88:22 | LL | static FN_TEST4: _ = 145; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static FN_TEST4: i32 = 145; + | ~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables - --> $DIR/typeck_type_placeholder_item.rs:91:22 + --> $DIR/typeck_type_placeholder_item.rs:91:23 | LL | static FN_TEST5: (_, _) = (1, 2); - | ^^^^^^ not allowed in type signatures + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | static FN_TEST5: (i32, i32) = (1, 2); + | ~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:94:20 @@ -539,10 +568,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:194:14 | LL | const D: _ = 42; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const D: i32 = 42; + | ~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item.rs:209:14 @@ -569,16 +600,18 @@ LL | fn value() -> Option<&'static _> { | help: replace with the correct return type: `Option<&'static u8>` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:222:10 + --> $DIR/typeck_type_placeholder_item.rs:222:17 | LL | const _: Option<_> = map(value); - | ^^^^^^^^^ - | | - | not allowed in type signatures - | help: replace with the correct type: `Option` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const _: Option = map(value); + | ~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:225:31 + --> $DIR/typeck_type_placeholder_item.rs:226:31 | LL | fn evens_squared(n: usize) -> _ { | ^ @@ -587,13 +620,13 @@ LL | fn evens_squared(n: usize) -> _ { | help: replace with an appropriate return type: `impl Iterator` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:230:10 + --> $DIR/typeck_type_placeholder_item.rs:231:10 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^ not allowed in type signatures | -note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:230:29}>, {closure@typeck_type_placeholder_item.rs:230:49}>` cannot be named - --> $DIR/typeck_type_placeholder_item.rs:230:14 +note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:231:29}>, {closure@typeck_type_placeholder_item.rs:231:49}>` cannot be named + --> $DIR/typeck_type_placeholder_item.rs:231:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -668,23 +701,31 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | type F: std::ops::Fn(_); | ^ not allowed in type signatures -error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}>` in constants - --> $DIR/typeck_type_placeholder_item.rs:230:22 +error[E0015]: cannot call non-const function `map::` in constants + --> $DIR/typeck_type_placeholder_item.rs:222:22 + | +LL | const _: Option<_> = map(value); + | ^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}>` in constants + --> $DIR/typeck_type_placeholder_item.rs:231:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}> as Iterator>::map::` in constants - --> $DIR/typeck_type_placeholder_item.rs:230:45 +error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}> as Iterator>::map::` in constants + --> $DIR/typeck_type_placeholder_item.rs:231:45 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error: aborting due to 74 previous errors +error: aborting due to 75 previous errors Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr index 32585e2937b77..a05e27cebfcd1 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -11,19 +11,23 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item_help.rs:7:14 | LL | const TEST2: _ = 42u32; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `u32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const TEST2: u32 = 42u32; + | ~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item_help.rs:10:14 | LL | const TEST3: _ = Some(42); - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `Option` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const TEST3: Option = Some(42); + | ~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item_help.rs:13:22 @@ -41,19 +45,23 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item_help.rs:25:18 | LL | const TEST6: _ = 13; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const TEST6: i32 = 13; + | ~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants --> $DIR/typeck_type_placeholder_item_help.rs:18:18 | LL | const TEST5: _ = 42; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures + | +help: replace this with a fully-specified type + | +LL | const TEST5: i32 = 42; + | ~~~ error[E0308]: mismatched types --> $DIR/typeck_type_placeholder_item_help.rs:30:28