Auto merge of #135086 - matthiaskrgr:rollup-3sfnc1w, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #133420 (Switch rtems target to panic unwind)
 - #134965 (Make Boxy UwU)
 - #135007 (Some type-outlives computation tweaks)
 - #135036 (run-make-support: adjust assertion printing, add some basic sanity checks)
 - #135043 (rustdoc: treat `allowed_through_unstable_modules` as deprecation)
 - #135044 (Improve infer (`_`) suggestions in `const`s and `static`s)
 - #135058 (refactor bootstrap path resolution)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-01-03 22:42:57 +00:00
commit 8d2c06d151
52 changed files with 788 additions and 517 deletions

View file

@ -88,7 +88,8 @@ boolean_coercion <booleancoercion@gmail.com>
Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
bors <bors@rust-lang.org> bors[bot] <26634292+bors[bot]@users.noreply.github.com>
bors <bors@rust-lang.org> bors[bot] <bors[bot]@users.noreply.github.com>
Boxy <rust@boxyuwu.dev> <supbscripter@gmail.com>
BoxyUwU <rust@boxyuwu.dev>
BoxyUwU <rust@boxyuwu.dev> <supbscripter@gmail.com>
Braden Nelson <moonheart08@users.noreply.github.com>
Brandon Sanderson <singingboyo@gmail.com> Brandon Sanderson <singingboyo@hotmail.com>
Brett Cannon <brett@python.org> Brett Cannon <brettcannon@users.noreply.github.com>

View file

@ -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),
}

View file

@ -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);

View file

@ -131,19 +131,25 @@ pub struct ItemCtxt<'tcx> {
///////////////////////////////////////////////////////////////////////////
#[derive(Default)]
pub(crate) struct HirPlaceholderCollector(pub(crate) Vec<Span>);
pub(crate) struct HirPlaceholderCollector {
pub spans: Vec<Span>,
// 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!

View file

@ -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);
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);
if !ty.references_error() {
// 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)
}

View file

@ -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(),

View file

@ -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 {

View file

@ -87,21 +87,7 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef
}
fn typeck<'tcx>(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<ObligationInspector<'tcx>>,
) -> &'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 };
}

View file

@ -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., `<T as Foo<'a>>::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> <T as Trait<'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));

View file

@ -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 `<T as Foo<fn(&u32, &u32)>>::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<ty::PolyTypeOutlivesPredicate<'tcx>> {
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 `<T as Foo<'x>>::Bar`, returns any bounds

View file

@ -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<LocalDefId> {
desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) }

View file

@ -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,

View file

@ -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();

View file

@ -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",
))] {

View file

@ -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;

View file

@ -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.

View file

@ -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<'_>) {

View file

@ -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<'_>) {

View file

@ -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<PathBuf>, 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<PathBuf>) {
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<PathBuf> for CLIStepPath {
fn from(path: PathBuf) -> Self {
Self { path, will_be_executed: false }
}
}
impl StepDescription {
fn from<S: Step>(kind: Kind) -> StepDescription {
StepDescription {
@ -478,7 +505,8 @@ impl StepDescription {
return;
}
let mut path_lookup: Vec<(PathBuf, bool)> =
let mut paths: Vec<CLIStepPath> = 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<PathSet>)` 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<PathBuf>,
paths: &mut [CLIStepPath],
kind: Kind,
) -> Vec<PathSet> {
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.
// <https://github.com/rust-lang/rust/pull/134919>
test::CodegenCranelift,
test::CodegenGCC,
test::Crate,
test::CrateLibrustc,
test::CrateRustdoc,
test::CrateRustdocJsonTypes,
test::CrateBootstrap,

View file

@ -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]

View file

@ -400,7 +400,27 @@ impl Item {
}
pub(crate) fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
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 {

View file

@ -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
}

View file

@ -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<str>, E: AsRef<str>>(
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<A: AsRef<str>, E: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<Path>, dir2: impl AsRef<Path>) {
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<u8>`, 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(),
);
}
});
}

View file

@ -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<A: AsRef<str>, E: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(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<H: AsRef<str>, N: AsRef<str>>(
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<Path>, dir2: impl AsRef<Path>) {
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<u8>`, 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(),
);
}
});
}

View file

@ -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");
}
}

View file

@ -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' },
],
},
];

View file

@ -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' },
],
},
];

View file

@ -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' },
],
},
];

View file

@ -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
}

View file

@ -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
}

View file

@ -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
|
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 | 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
|
LL | let 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:20:25
|
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 | 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
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/suggest-array-length.rs:5:22
|
LL | const Foo: [i32; _] = [1, 2, 3];
| ^ `_` not allowed here
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
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:8:26
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/suggest-array-length.rs:7:26
|
LL | const REF_FOO: &[u8; _] = &[1];
| ^ `_` not allowed here
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | const REF_FOO: &[u8; 1] = &[1];
| ~~~~~~~~
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/suggest-array-length.rs:9:26
|
LL | static Statik: [i32; _] = [1, 2, 3];
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | static Statik: [i32; 3] = [1, 2, 3];
| ~~~~~~~~
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/suggest-array-length.rs:11:30
|
LL | static REF_STATIK: &[u8; _] = &[1];
| ^ not allowed in type signatures
|
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:5:22
|
LL | const Foo: [i32; _] = [1, 2, 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/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
error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:8:26
|
LL | const REF_FOO: &[u8; _] = &[1];
| ^ help: consider specifying the array length: `1`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/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
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`.

View file

@ -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() {}

View file

@ -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`.

View file

@ -27,52 +27,74 @@ LL | fn ty_fn_mixed() -> Bar<_, _> {
| help: replace with the correct return type: `Bar<i32, 3>`
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<i32, _> = Bar::<i32, 3>(0);
| ^^^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3>`
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | const TY_CT: Bar<i32, 3> = Bar::<i32, 3>(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<i32, _> = Bar::<i32, 3>(0);
| ^^^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3>`
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | static TY_STATIC: Bar<i32, 3> = Bar::<i32, 3>(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::<i32, 3>(0);
| ^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3>`
| ^ ^ not allowed in type signatures
| |
| not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | const TY_CT_MIXED: Bar<i32, 3> = Bar::<i32, 3>(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::<i32, 3>(0);
| ^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3>`
| ^ ^ not allowed in type signatures
| |
| not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | static TY_STATIC_MIXED: Bar<i32, 3> = Bar::<i32, 3>(0);
| ~~~~~~~~~~~
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
--> $DIR/in-signature.rs:51:23

View file

@ -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() {}

View file

@ -1,12 +1,28 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/issue-104768.rs:1:10
error[E0308]: mismatched types
--> $DIR/issue-104768.rs:1:15
|
LL | const A: &_ = 0_u32;
| ^^
| |
| not allowed in type signatures
| help: replace with the correct type: `u32`
| ^^^^^ expected `&_`, found `u32`
|
= note: expected reference `&'static _`
found type `u32`
help: consider borrowing here
|
LL | const A: &_ = &0_u32;
| +
error: aborting due to 1 previous error
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/issue-104768.rs:1:11
|
LL | const A: &_ = 0_u32;
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | const A: u32 = 0_u32;
| ~~~
For more information about this error, try `rustc --explain E0121`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0121, E0308.
For more information about an error, try `rustc --explain E0121`.

View file

@ -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

View file

@ -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`.

View file

@ -10,10 +10,8 @@ fn foo<const N: usize>(_: [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() {

View file

@ -12,7 +12,6 @@ impl Trait for () {
const K<T> = ();
//~^ 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

View file

@ -16,7 +16,7 @@ LL | const K<T> = ();
| ^ 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<T> = ();
| - ^^ 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`.

View file

@ -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
)*
}
}

View file

@ -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;

View file

@ -2,5 +2,4 @@ fn main() {
const EMPTY_ARRAY = [];
//~^ missing type for `const` item
//~| ERROR type annotations needed
//~| ERROR type annotations needed
}

View file

@ -15,14 +15,6 @@ help: provide a type for the item
LL | const EMPTY_ARRAY: <type> = [];
| ++++++++
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`.

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -17,16 +17,6 @@ help: provide a type for the item
LL | const FOO: <type> = "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`.

View file

@ -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::<u8>` in constants
fn evens_squared(n: usize) -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types

View file

@ -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<i32> = 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<u8>`
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | const _: Option<u8> = 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<Item = usize>`
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<Filter<Range<i32>, {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<Filter<Range<i32>, {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 `<std::ops::Range<i32> 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::<u8>` 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 `<std::ops::Range<i32> 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 `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:230:49: 230:52}>` in constants
--> $DIR/typeck_type_placeholder_item.rs:230:45
error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:231:49: 231:52}>` 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`.

View file

@ -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<i32>`
| ^ not allowed in type signatures
|
help: replace this with a fully-specified type
|
LL | const TEST3: Option<i32> = 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