diff options
132 files changed, 1214 insertions, 639 deletions
diff --git a/.gitmodules b/.gitmodules index 439fde6d766..8617643a120 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,7 +25,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/20.1-2025-07-13 + branch = rustc/21.1-2025-08-01 shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1245d489754..fb42cfea30b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -98,7 +98,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } let expr_hir_id = self.lower_node_id(e.id); - self.lower_attrs(expr_hir_id, &e.attrs, e.span); + let attrs = self.lower_attrs(expr_hir_id, &e.attrs, e.span); let kind = match &e.kind { ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), @@ -232,10 +232,10 @@ impl<'hir> LoweringContext<'_, 'hir> { *fn_arg_span, ), None => self.lower_expr_closure( + attrs, binder, *capture_clause, e.id, - expr_hir_id, *constness, *movability, fn_decl, @@ -1052,10 +1052,10 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_closure( &mut self, + attrs: &[rustc_hir::Attribute], binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, - closure_hir_id: hir::HirId, constness: Const, movability: Movability, decl: &FnDecl, @@ -1067,15 +1067,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let (binder_clause, generic_params) = self.lower_closure_binder(binder); let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| { - let mut coroutine_kind = if this - .attrs - .get(&closure_hir_id.local_id) - .is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine))) - { - Some(hir::CoroutineKind::Coroutine(Movability::Movable)) - } else { - None - }; + + let mut coroutine_kind = find_attr!(attrs, AttributeKind::Coroutine(_) => hir::CoroutineKind::Coroutine(Movability::Movable)); + // FIXME(contracts): Support contracts on closures? let body_id = this.lower_fn_body(decl, None, |this| { this.coroutine_kind = coroutine_kind; diff --git a/compiler/rustc_attr_parsing/src/attributes/body.rs b/compiler/rustc_attr_parsing/src/attributes/body.rs new file mode 100644 index 00000000000..ab9330216f6 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/body.rs @@ -0,0 +1,15 @@ +//! Attributes that can be found in function body. + +use rustc_hir::attrs::AttributeKind; +use rustc_span::{Symbol, sym}; + +use super::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; + +pub(crate) struct CoroutineParser; + +impl<S: Stage> NoArgsAttributeParser<S> for CoroutineParser { + const PATH: &[Symbol] = &[sym::coroutine]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(rustc_span::Span) -> AttributeKind = |span| AttributeKind::Coroutine(span); +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index c574ef78bdf..f7946ade6d2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -26,6 +26,7 @@ use crate::parser::ArgParser; use crate::session_diagnostics::UnusedMultiple; pub(crate) mod allow_unstable; +pub(crate) mod body; pub(crate) mod cfg; pub(crate) mod cfg_old; pub(crate) mod codegen_attrs; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c6599f20c2d..911d2e13310 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -16,6 +16,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{ AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser, }; +use crate::attributes::body::CoroutineParser; use crate::attributes::codegen_attrs::{ ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser, TrackCallerParser, UsedParser, @@ -184,6 +185,7 @@ attribute_parsers!( Single<WithoutArgs<ConstContinueParser>>, Single<WithoutArgs<ConstStabilityIndirectParser>>, Single<WithoutArgs<ConstTraitParser>>, + Single<WithoutArgs<CoroutineParser>>, Single<WithoutArgs<DenyExplicitImplParser>>, Single<WithoutArgs<DoNotImplementViaObjectParser>>, Single<WithoutArgs<ExportStableParser>>, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index f5fedbf95c1..148d0de3bab 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -769,9 +769,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } TerminatorKind::Call { func, args, .. } | TerminatorKind::TailCall { func, args, .. } => { - let call_source = match term.kind { - TerminatorKind::Call { call_source, .. } => call_source, - TerminatorKind::TailCall { .. } => CallSource::Normal, + let (call_source, destination, is_diverging) = match term.kind { + TerminatorKind::Call { call_source, destination, target, .. } => { + (call_source, destination, target.is_none()) + } + TerminatorKind::TailCall { .. } => { + (CallSource::Normal, RETURN_PLACE.into(), false) + } _ => unreachable!(), }; @@ -845,9 +849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } - if let TerminatorKind::Call { destination, target, .. } = term.kind { - self.check_call_dest(term, &sig, destination, target, term_location); - } + self.check_call_dest(term, &sig, destination, is_diverging, term_location); // The ordinary liveness rules will ensure that all // regions in the type of the callee are live here. We @@ -1874,65 +1876,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { term: &Terminator<'tcx>, sig: &ty::FnSig<'tcx>, destination: Place<'tcx>, - target: Option<BasicBlock>, + is_diverging: bool, term_location: Location, ) { let tcx = self.tcx(); - match target { - Some(_) => { - let dest_ty = destination.ty(self.body, tcx).ty; - let dest_ty = self.normalize(dest_ty, term_location); - let category = match destination.as_local() { - Some(RETURN_PLACE) => { - if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = - self.universal_regions.defining_ty - { - if tcx.is_static(def_id) { - ConstraintCategory::UseAsStatic - } else { - ConstraintCategory::UseAsConst - } + if is_diverging { + // The signature in this call can reference region variables, + // so erase them before calling a query. + let output_ty = self.tcx().erase_regions(sig.output()); + if !output_ty + .is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env)) + { + span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); + } + } else { + let dest_ty = destination.ty(self.body, tcx).ty; + let dest_ty = self.normalize(dest_ty, term_location); + let category = match destination.as_local() { + Some(RETURN_PLACE) => { + if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = + self.universal_regions.defining_ty + { + if tcx.is_static(def_id) { + ConstraintCategory::UseAsStatic } else { - ConstraintCategory::Return(ReturnConstraint::Normal) + ConstraintCategory::UseAsConst } + } else { + ConstraintCategory::Return(ReturnConstraint::Normal) } - Some(l) if !self.body.local_decls[l].is_user_variable() => { - ConstraintCategory::Boring - } - // The return type of a call is interesting for diagnostics. - _ => ConstraintCategory::Assignment, - }; - - let locations = term_location.to_locations(); - - if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { - span_mirbug!( - self, - term, - "call dest mismatch ({:?} <- {:?}): {:?}", - dest_ty, - sig.output(), - terr - ); } - - // When `unsized_fn_params` is not enabled, - // this check is done at `check_local`. - if self.unsized_feature_enabled() { - let span = term.source_info.span; - self.ensure_place_sized(dest_ty, span); + Some(l) if !self.body.local_decls[l].is_user_variable() => { + ConstraintCategory::Boring } + // The return type of a call is interesting for diagnostics. + _ => ConstraintCategory::Assignment, + }; + + let locations = term_location.to_locations(); + + if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { + span_mirbug!( + self, + term, + "call dest mismatch ({:?} <- {:?}): {:?}", + dest_ty, + sig.output(), + terr + ); } - None => { - // The signature in this call can reference region variables, - // so erase them before calling a query. - let output_ty = self.tcx().erase_regions(sig.output()); - if !output_ty.is_privately_uninhabited( - self.tcx(), - self.infcx.typing_env(self.infcx.param_env), - ) { - span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); - } + + // When `unsized_fn_params` is not enabled, + // this check is done at `check_local`. + if self.unsized_feature_enabled() { + let span = term.source_info.span; + self.ensure_place_sized(dest_ty, span); } } } diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 4c8585192a1..4c0b6439523 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -254,7 +254,8 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // TODO(antoyo): implement. } - fn debuginfo_finalize(&self) { + fn debuginfo_finalize(&mut self) { + // TODO: emit section `.debug_gdb_scripts`. self.context.set_debug_info(true) } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 5dda836988c..d7da03bf490 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -109,11 +109,16 @@ pub(crate) fn compile_codegen_unit( } // Finalize code coverage by injecting the coverage map. Note, the coverage map will - // also be added to the `llvm.compiler.used` variable, created next. + // also be added to the `llvm.compiler.used` variable, created below. if cx.sess().instrument_coverage() { cx.coverageinfo_finalize(); } + // Finalize debuginfo. This adds to `llvm.used`, created below. + if cx.sess().opts.debuginfo != DebugInfo::None { + cx.debuginfo_finalize(); + } + // Create the llvm.used and llvm.compiler.used variables. if !cx.used_statics.is_empty() { cx.create_used_variable_impl(c"llvm.used", &cx.used_statics); @@ -130,11 +135,6 @@ pub(crate) fn compile_codegen_unit( llvm::LLVMDeleteGlobal(old_g); } } - - // Finalize debuginfo - if cx.sess().opts.debuginfo != DebugInfo::None { - cx.debuginfo_finalize(); - } } ModuleCodegen::new_regular(cgu_name.to_string(), llvm_module) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 6eb7042da61..fccd32dec95 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -1,11 +1,13 @@ // .debug_gdb_scripts binary section. -use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive; +use std::collections::BTreeSet; +use std::ffi::CString; + use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType; -use rustc_session::config::{CrateType, DebugInfo}; +use rustc_session::config::DebugInfo; use crate::builder::Builder; use crate::common::CodegenCx; @@ -31,7 +33,12 @@ pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Buil pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( cx: &CodegenCx<'ll, '_>, ) -> &'ll Value { - let c_section_var_name = c"__rustc_debug_gdb_scripts_section__"; + let c_section_var_name = CString::new(format!( + "__rustc_debug_gdb_scripts_section_{}_{:08x}", + cx.tcx.crate_name(LOCAL_CRATE), + cx.tcx.stable_crate_id(LOCAL_CRATE), + )) + .unwrap(); let section_var_name = c_section_var_name.to_str().unwrap(); let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr()) }; @@ -44,10 +51,14 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( // Next, add the pretty printers that were specified via the `#[debugger_visualizer]` // attribute. - let visualizers = collect_debugger_visualizers_transitive( - cx.tcx, - DebuggerVisualizerType::GdbPrettyPrinter, - ); + let visualizers = cx + .tcx + .debugger_visualizers(LOCAL_CRATE) + .iter() + .filter(|visualizer| { + visualizer.visualizer_type == DebuggerVisualizerType::GdbPrettyPrinter + }) + .collect::<BTreeSet<_>>(); let crate_name = cx.tcx.crate_name(LOCAL_CRATE); for (index, visualizer) in visualizers.iter().enumerate() { // The initial byte `4` instructs GDB that the following pretty printer @@ -84,35 +95,5 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( } pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { - // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create - // ODR violations at link time, this section will not be emitted for rlibs since - // each rlib could produce a different set of visualizers that would be embedded - // in the `.debug_gdb_scripts` section. For that reason, we make sure that the - // section is only emitted for leaf crates. - let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type { - CrateType::Executable - | CrateType::Dylib - | CrateType::Cdylib - | CrateType::Staticlib - | CrateType::Sdylib => { - // These are crate types for which we will embed pretty printers since they - // are treated as leaf crates. - true - } - CrateType::ProcMacro => { - // We could embed pretty printers for proc macro crates too but it does not - // seem like a good default, since this is a rare use case and we don't - // want to slow down the common case. - false - } - CrateType::Rlib => { - // As per the above description, embedding pretty printers for rlibs could - // lead to ODR violations so we skip this crate type as well. - false - } - }); - - cx.sess().opts.debuginfo != DebugInfo::None - && cx.sess().target.emit_debug_gdb_scripts - && embed_visualizers + cx.sess().opts.debuginfo != DebugInfo::None && cx.sess().target.emit_debug_gdb_scripts } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 6cbf2dbf7d3..c911435967c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -30,7 +30,7 @@ use tracing::debug; use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node}; use self::namespace::mangled_name_of_instance; -use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; +use self::utils::{DIB, create_DIArray, debug_context, is_node_local_to_unit}; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; use crate::llvm; @@ -131,20 +131,28 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { } /// Creates any deferred debug metadata nodes -pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { - if let Some(dbg_cx) = &cx.dbg_cx { - debug!("finalize"); - - if gdb::needs_gdb_debug_scripts_section(cx) { - // Add a .debug_gdb_scripts section to this compile-unit. This will - // cause GDB to try and load the gdb_load_rust_pretty_printers.py file, - // which activates the Rust pretty printers for binary this section is - // contained in. - gdb::get_or_insert_gdb_debug_scripts_section_global(cx); - } +pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) { + if cx.dbg_cx.is_none() { + return; + } + + debug!("finalize"); - dbg_cx.finalize(cx.sess()); + if gdb::needs_gdb_debug_scripts_section(cx) { + // Add a .debug_gdb_scripts section to this compile-unit. This will + // cause GDB to try and load the gdb_load_rust_pretty_printers.py file, + // which activates the Rust pretty printers for binary this section is + // contained in. + let section_var = gdb::get_or_insert_gdb_debug_scripts_section_global(cx); + + // Make sure that the linker doesn't optimize the global away. Adding + // it to `llvm.used` has the advantage that it works even in no_std + // binaries, where we don't have a main shim and thus don't emit a + // volatile load to preserve the global. + cx.add_used_global(section_var); } + + debug_context(cx).finalize(cx.sess()); } impl<'ll> Builder<'_, 'll, '_> { @@ -614,7 +622,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { metadata::extend_scope_to_file(self, scope_metadata, file) } - fn debuginfo_finalize(&self) { + fn debuginfo_finalize(&mut self) { finalize(self) } diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index b9d4950e0ad..30a3bd5abe4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -50,7 +50,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes { scope_metadata: Self::DIScope, file: &SourceFile, ) -> Self::DIScope; - fn debuginfo_finalize(&self); + fn debuginfo_finalize(&mut self); // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 80618422b56..d9d2ec48948 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -297,6 +297,9 @@ pub enum AttributeKind { /// Represents `#[const_trait]`. ConstTrait(Span), + /// Represents `#[coroutine]`. + Coroutine(Span), + /// Represents `#[coverage(..)]`. Coverage(Span, CoverageAttrKind), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 9644a597a31..b66e5bbeabe 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -28,6 +28,7 @@ impl AttributeKind { ConstStability { .. } => Yes, ConstStabilityIndirect => No, ConstTrait(..) => No, + Coroutine(..) => No, Coverage(..) => No, DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2941808e806..a4589576594 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1178,11 +1178,10 @@ rustc_queries! { /// Return the live symbols in the crate for dead code check. /// - /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone) and - /// their respective impl (i.e., part of the derive macro) + /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone). query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx ( LocalDefIdSet, - LocalDefIdMap<FxIndexSet<(DefId, DefId)>> + LocalDefIdMap<FxIndexSet<DefId>>, ) { arena_cache desc { "finding live symbols in crate" } diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b4c8b20e50f..3ecccb422c4 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -60,9 +60,13 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { let BodyTy::Fn(caller_sig) = self.thir.body_type else { span_bug!( call.span, - "`become` outside of functions should have been disallowed by hit_typeck" + "`become` outside of functions should have been disallowed by hir_typeck" ) }; + // While the `caller_sig` does have its regions erased, it does not have its + // binders anonymized. We call `erase_regions` once again to anonymize any binders + // within the signature, such as in function pointer or `dyn Trait` args. + let caller_sig = self.tcx.erase_regions(caller_sig); let ExprKind::Scope { value, .. } = call.kind else { span_bug!(call.span, "expected scope, found: {call:?}") diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 231fb3e2964..5e08c3a03d8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -959,36 +959,23 @@ where // Even when a trait bound has been proven using a where-bound, we // still need to consider alias-bounds for normalization, see // `tests/ui/next-solver/alias-bound-shadowed-by-env.rs`. - let candidates_from_env_and_bounds: Vec<_> = self + let mut candidates: Vec<_> = self .assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::EnvAndBounds); // We still need to prefer where-bounds over alias-bounds however. // See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`. - let mut considered_candidates: Vec<_> = if candidates_from_env_and_bounds - .iter() - .any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - { - candidates_from_env_and_bounds - .into_iter() - .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - .map(|c| c.result) - .collect() - } else { - candidates_from_env_and_bounds.into_iter().map(|c| c.result).collect() - }; - - // If the trait goal has been proven by using the environment, we want to treat - // aliases as rigid if there are no applicable projection bounds in the environment. - if considered_candidates.is_empty() { - if let Ok(response) = inject_normalize_to_rigid_candidate(self) { - considered_candidates.push(response); - } + if candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) { + candidates.retain(|c| matches!(c.source, CandidateSource::ParamEnv(_))); + } else if candidates.is_empty() { + // If the trait goal has been proven by using the environment, we want to treat + // aliases as rigid if there are no applicable projection bounds in the environment. + return inject_normalize_to_rigid_candidate(self); } - if let Some(response) = self.try_merge_responses(&considered_candidates) { + if let Some(response) = self.try_merge_candidates(&candidates) { Ok(response) } else { - self.flounder(&considered_candidates) + self.flounder(&candidates) } } TraitGoalProvenVia::Misc => { @@ -998,11 +985,9 @@ where // Prefer "orphaned" param-env normalization predicates, which are used // (for example, and ideally only) when proving item bounds for an impl. let candidates_from_env: Vec<_> = candidates - .iter() - .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - .map(|c| c.result) + .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_))) .collect(); - if let Some(response) = self.try_merge_responses(&candidates_from_env) { + if let Some(response) = self.try_merge_candidates(&candidates_from_env) { return Ok(response); } @@ -1012,12 +997,10 @@ where // means we can just ignore inference constraints and don't have to special-case // constraining the normalized-to `term`. self.filter_specialized_impls(AllowInferenceConstraints::Yes, &mut candidates); - - let responses: Vec<_> = candidates.iter().map(|c| c.result).collect(); - if let Some(response) = self.try_merge_responses(&responses) { + if let Some(response) = self.try_merge_candidates(&candidates) { Ok(response) } else { - self.flounder(&responses) + self.flounder(&candidates) } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index aec9594b834..2feebe270a6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -29,6 +29,7 @@ use tracing::instrument; pub use self::eval_ctxt::{EvalCtxt, GenerateProofTree, SolverDelegateEvalExt}; use crate::delegate::SolverDelegate; +use crate::solve::assembly::Candidate; /// How many fixpoint iterations we should attempt inside of the solver before bailing /// with overflow. @@ -244,50 +245,51 @@ where /// /// In this case we tend to flounder and return ambiguity by calling `[EvalCtxt::flounder]`. #[instrument(level = "trace", skip(self), ret)] - fn try_merge_responses( + fn try_merge_candidates( &mut self, - responses: &[CanonicalResponse<I>], + candidates: &[Candidate<I>], ) -> Option<CanonicalResponse<I>> { - if responses.is_empty() { + if candidates.is_empty() { return None; } - let one = responses[0]; - if responses[1..].iter().all(|&resp| resp == one) { + let one: CanonicalResponse<I> = candidates[0].result; + if candidates[1..].iter().all(|candidate| candidate.result == one) { return Some(one); } - responses + candidates .iter() - .find(|response| { - response.value.certainty == Certainty::Yes - && has_no_inference_or_external_constraints(**response) + .find(|candidate| { + candidate.result.value.certainty == Certainty::Yes + && has_no_inference_or_external_constraints(candidate.result) }) - .copied() + .map(|candidate| candidate.result) } - fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse<I>]) -> CanonicalResponse<I> { - debug_assert!(responses.len() > 1); - let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| { - // Pull down the certainty of `Certainty::Yes` to ambiguity when combining - // these responses, b/c we're combining more than one response and this we - // don't know which one applies. - let candidate = match response.value.certainty { - Certainty::Yes => MaybeCause::Ambiguity, - Certainty::Maybe(candidate) => candidate, - }; - maybe_cause.or(candidate) - }); + fn bail_with_ambiguity(&mut self, candidates: &[Candidate<I>]) -> CanonicalResponse<I> { + debug_assert!(candidates.len() > 1); + let maybe_cause = + candidates.iter().fold(MaybeCause::Ambiguity, |maybe_cause, candidates| { + // Pull down the certainty of `Certainty::Yes` to ambiguity when combining + // these responses, b/c we're combining more than one response and this we + // don't know which one applies. + let candidate = match candidates.result.value.certainty { + Certainty::Yes => MaybeCause::Ambiguity, + Certainty::Maybe(candidate) => candidate, + }; + maybe_cause.or(candidate) + }); self.make_ambiguous_response_no_constraints(maybe_cause) } /// If we fail to merge responses we flounder and return overflow or ambiguity. #[instrument(level = "trace", skip(self), ret)] - fn flounder(&mut self, responses: &[CanonicalResponse<I>]) -> QueryResult<I> { - if responses.is_empty() { + fn flounder(&mut self, candidates: &[Candidate<I>]) -> QueryResult<I> { + if candidates.is_empty() { return Err(NoSolution); } else { - Ok(self.bail_with_ambiguity(responses)) + Ok(self.bail_with_ambiguity(candidates)) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f760c2c07ff..60bae738e61 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1346,11 +1346,10 @@ where mut candidates: Vec<Candidate<I>>, ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> { if let TypingMode::Coherence = self.typing_mode() { - let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); - return if let Some(response) = self.try_merge_responses(&all_candidates) { + return if let Some(response) = self.try_merge_candidates(&candidates) { Ok((response, Some(TraitGoalProvenVia::Misc))) } else { - self.flounder(&all_candidates).map(|r| (r, None)) + self.flounder(&candidates).map(|r| (r, None)) }; } @@ -1375,11 +1374,9 @@ where .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal))); if has_non_global_where_bounds { let where_bounds: Vec<_> = candidates - .iter() - .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - .map(|c| c.result) + .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_))) .collect(); - return if let Some(response) = self.try_merge_responses(&where_bounds) { + return if let Some(response) = self.try_merge_candidates(&where_bounds) { Ok((response, Some(TraitGoalProvenVia::ParamEnv))) } else { Ok((self.bail_with_ambiguity(&where_bounds), None)) @@ -1388,11 +1385,9 @@ where if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)) { let alias_bounds: Vec<_> = candidates - .iter() - .filter(|c| matches!(c.source, CandidateSource::AliasBound)) - .map(|c| c.result) + .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound)) .collect(); - return if let Some(response) = self.try_merge_responses(&alias_bounds) { + return if let Some(response) = self.try_merge_candidates(&alias_bounds) { Ok((response, Some(TraitGoalProvenVia::AliasBound))) } else { Ok((self.bail_with_ambiguity(&alias_bounds), None)) @@ -1417,11 +1412,10 @@ where TraitGoalProvenVia::Misc }; - let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); - if let Some(response) = self.try_merge_responses(&all_candidates) { + if let Some(response) = self.try_merge_candidates(&candidates) { Ok((response, Some(proven_via))) } else { - self.flounder(&all_candidates).map(|r| (r, None)) + self.flounder(&candidates).map(|r| (r, None)) } } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 859118a4ade..7059ffbf375 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -71,6 +71,17 @@ parse_attr_without_generics = attribute without generic parameters parse_attribute_on_param_type = attributes cannot be applied to a function parameter's type .label = attributes are not allowed here +parse_attribute_on_type = attributes cannot be applied to types + .label = attributes are not allowed here + .suggestion = remove attribute from here + +parse_attribute_on_generic_arg = attributes cannot be applied to generic arguments + .label = attributes are not allowed here + .suggestion = remove attribute from here + +parse_attribute_on_empty_type = attributes cannot be applied here + .label = attributes are not allowed here + parse_bad_assoc_type_bounds = bounds on associated types do not belong here .label = belongs in `where` clause diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 4aaaba01fae..48ff0394d46 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1490,6 +1490,34 @@ pub(crate) struct AttributeOnParamType { } #[derive(Diagnostic)] +#[diag(parse_attribute_on_type)] +pub(crate) struct AttributeOnType { + #[primary_span] + #[label] + pub span: Span, + #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + pub fix_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_attribute_on_generic_arg)] +pub(crate) struct AttributeOnGenericArg { + #[primary_span] + #[label] + pub span: Span, + #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + pub fix_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_attribute_on_empty_type)] +pub(crate) struct AttributeOnEmptyType { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] #[diag(parse_pattern_method_param_without_body, code = E0642)] pub(crate) struct PatternMethodParamWithoutBody { #[primary_span] diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 65d84b3e3d9..cb7c5649433 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -885,6 +885,9 @@ impl<'a> Parser<'a> { /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> { let constness = self.parse_constness(Case::Sensitive); + if let Const::Yes(span) = constness { + self.psess.gated_spans.gate(sym::const_trait_impl, span); + } let safety = self.parse_safety(Case::Sensitive); // Parse optional `auto` prefix. let is_auto = if self.eat_keyword(exp!(Auto)) { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 1f4049f197f..8e65ab99c5e 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -17,11 +17,11 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::ast::{PatKind, TyKind}; use crate::errors::{ - self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams, - PathSingleColon, PathTripleColon, + self, AttributeOnEmptyType, AttributeOnGenericArg, FnPathFoundNamedParams, + PathFoundAttributeInParams, PathFoundCVariadicParams, PathSingleColon, PathTripleColon, }; use crate::exp; -use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; +use crate::parser::{CommaRecoveryMode, ExprKind, RecoverColon, RecoverComma}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -880,6 +880,12 @@ impl<'a> Parser<'a> { &mut self, ty_generics: Option<&Generics>, ) -> PResult<'a, Option<GenericArg>> { + let mut attr_span: Option<Span> = None; + if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { + let attrs_wrapper = self.parse_outer_attributes()?; + let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); + attr_span = Some(raw_attrs[0].span.to(raw_attrs.last().unwrap().span)); + } let start = self.token.span; let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. @@ -934,6 +940,9 @@ impl<'a> Parser<'a> { } } else if self.token.is_keyword(kw::Const) { return self.recover_const_param_declaration(ty_generics); + } else if let Some(attr_span) = attr_span { + let diag = self.dcx().create_err(AttributeOnEmptyType { span: attr_span }); + return Err(diag); } else { // Fall back by trying to parse a const-expr expression. If we successfully do so, // then we should report an error that it needs to be wrapped in braces. @@ -953,6 +962,22 @@ impl<'a> Parser<'a> { } } }; + + if let Some(attr_span) = attr_span { + let guar = self.dcx().emit_err(AttributeOnGenericArg { + span: attr_span, + fix_span: attr_span.until(arg.span()), + }); + return Ok(Some(match arg { + GenericArg::Type(_) => GenericArg::Type(self.mk_ty(attr_span, TyKind::Err(guar))), + GenericArg::Const(_) => { + let error_expr = self.mk_expr(attr_span, ExprKind::Err(guar)); + GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value: error_expr }) + } + GenericArg::Lifetime(lt) => GenericArg::Lifetime(lt), + })); + } + Ok(Some(arg)) } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 740dd10ea8b..59048e42e6f 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -14,10 +14,10 @@ use thin_vec::{ThinVec, thin_vec}; use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; use crate::errors::{ - self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, - FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidDynKeyword, - LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, - ReturnTypesUseThinArrow, + self, AttributeOnEmptyType, AttributeOnType, DynAfterMut, ExpectedFnPathFoundFnKeyword, + ExpectedMutOrConstInRawPointerType, FnPtrWithGenerics, FnPtrWithGenericsSugg, + HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, + NestedCVariadicType, ReturnTypesUseThinArrow, }; use crate::parser::item::FrontMatterParsingMode; use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; @@ -253,7 +253,27 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P<Ty>> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); + if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { + let attrs_wrapper = self.parse_outer_attributes()?; + let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); + let attr_span = raw_attrs[0].span.to(raw_attrs.last().unwrap().span); + let (full_span, guar) = match self.parse_ty() { + Ok(ty) => { + let full_span = attr_span.until(ty.span); + let guar = self + .dcx() + .emit_err(AttributeOnType { span: attr_span, fix_span: full_span }); + (attr_span, guar) + } + Err(err) => { + err.cancel(); + let guar = self.dcx().emit_err(AttributeOnEmptyType { span: attr_span }); + (attr_span, guar) + } + }; + return Ok(self.mk_ty(full_span, TyKind::Err(guar))); + } if let Some(ty) = self.eat_metavar_seq_with_matcher( |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }), |this| this.parse_ty_no_question_mark_recover(), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2663d5fe99c..890028d977d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -324,6 +324,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::Coverage(attr_span, _)) => { self.check_coverage(attr_span, span, target) } + &Attribute::Parsed(AttributeKind::Coroutine(attr_span)) => { + self.check_coroutine(attr_span, target) + } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { @@ -390,9 +393,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) } - [sym::coroutine, ..] => { - self.check_coroutine(attr, target); - } [sym::linkage, ..] => self.check_linkage(attr, span, target), [ // ok @@ -2651,11 +2651,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_coroutine(&self, attr: &Attribute, target: Target) { + fn check_coroutine(&self, attr_span: Span, target: Target) { match target { Target::Closure => return, _ => { - self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr.span() }); + self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr_span }); } } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index a90d1af87ca..fa9d0c7b1b7 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -5,7 +5,6 @@ use std::mem; -use hir::ItemKind; use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use rustc_abi::FieldIdx; use rustc_data_structures::fx::FxIndexSet; @@ -14,7 +13,7 @@ use rustc_errors::MultiSpan; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, ImplItem, ImplItemKind, Node, PatKind, QPath, TyKind}; +use rustc_hir::{self as hir, Node, PatKind, QPath}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy::Level; use rustc_middle::query::Providers; @@ -28,37 +27,43 @@ use crate::errors::{ ChangeFields, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, UselessAssignment, }; -// Any local node that may call something in its body block should be -// explored. For example, if it's a live Node::Item that is a -// function, then we should explore its block to check for codes that -// may need to be marked as live. +/// Any local definition that may call something in its body block should be explored. For example, +/// if it's a live function, then we should explore its block to check for codes that may need to +/// be marked as live. fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - matches!( - tcx.hir_node_by_def_id(def_id), - Node::Item(..) - | Node::ImplItem(..) - | Node::ForeignItem(..) - | Node::TraitItem(..) - | Node::Variant(..) - | Node::AnonConst(..) - | Node::OpaqueTy(..) - ) -} - -/// Returns the local def id of the ADT if the given ty refers to a local one. -fn local_adt_def_of_ty<'tcx>(ty: &hir::Ty<'tcx>) -> Option<LocalDefId> { - match ty.kind { - TyKind::Path(QPath::Resolved(_, path)) => { - if let Res::Def(def_kind, def_id) = path.res - && let Some(local_def_id) = def_id.as_local() - && matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union) - { - Some(local_def_id) - } else { - None - } - } - _ => None, + match tcx.def_kind(def_id) { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::Fn + | DefKind::Const + | DefKind::Static { .. } + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::GlobalAsm + | DefKind::Impl { .. } + | DefKind::OpaqueTy + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::ExternCrate + | DefKind::Use + | DefKind::Ctor(..) + | DefKind::ForeignMod => true, + + DefKind::TyParam + | DefKind::ConstParam + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => false, } } @@ -74,17 +79,16 @@ struct MarkSymbolVisitor<'tcx> { worklist: Vec<(LocalDefId, ComesFromAllowExpect)>, tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, + scanned: UnordSet<(LocalDefId, ComesFromAllowExpect)>, live_symbols: LocalDefIdSet, repr_unconditionally_treats_fields_as_live: bool, repr_has_repr_simd: bool, in_pat: bool, ignore_variant_stack: Vec<DefId>, - // maps from tuple struct constructors to tuple struct items - struct_constructors: LocalDefIdMap<LocalDefId>, // maps from ADTs to ignored derived traits (e.g. Debug and Clone) // and the span of their respective impl (i.e., part of the derive // macro) - ignored_derived_traits: LocalDefIdMap<FxIndexSet<(DefId, DefId)>>, + ignored_derived_traits: LocalDefIdMap<FxIndexSet<DefId>>, } impl<'tcx> MarkSymbolVisitor<'tcx> { @@ -99,7 +103,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn check_def_id(&mut self, def_id: DefId) { if let Some(def_id) = def_id.as_local() { - if should_explore(self.tcx, def_id) || self.struct_constructors.contains_key(&def_id) { + if should_explore(self.tcx, def_id) { self.worklist.push((def_id, ComesFromAllowExpect::No)); } self.live_symbols.insert(def_id); @@ -318,13 +322,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } fn mark_live_symbols(&mut self) { - let mut scanned = UnordSet::default(); while let Some(work) = self.worklist.pop() { - if !scanned.insert(work) { + if !self.scanned.insert(work) { continue; } - let (id, comes_from_allow_expect) = work; + let (mut id, comes_from_allow_expect) = work; // Avoid accessing the HIR for the synthesized associated type generated for RPITITs. if self.tcx.is_impl_trait_in_trait(id.to_def_id()) { @@ -332,9 +335,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { continue; } - // in the case of tuple struct constructors we want to check the item, not the generated - // tuple struct constructor function - let id = self.struct_constructors.get(&id).copied().unwrap_or(id); + // in the case of tuple struct constructors we want to check the item, + // not the generated tuple struct constructor function + if let DefKind::Ctor(..) = self.tcx.def_kind(id) { + id = self.tcx.local_parent(id); + } // When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement // by declaring fn calls, statics, ... within said items as live, as well as @@ -380,10 +385,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() && let Some(adt_def_id) = adt_def.did().as_local() { - self.ignored_derived_traits - .entry(adt_def_id) - .or_default() - .insert((trait_of, impl_of)); + self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_of); } return true; } @@ -478,24 +480,24 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { /// `local_def_id` points to an impl or an impl item, /// both impl and impl item that may be passed to this function are of a trait, /// and added into the unsolved_items during `create_and_seed_worklist` - fn check_impl_or_impl_item_live( - &mut self, - impl_id: hir::ItemId, - local_def_id: LocalDefId, - ) -> bool { - let trait_def_id = match self.tcx.def_kind(local_def_id) { + fn check_impl_or_impl_item_live(&mut self, local_def_id: LocalDefId) -> bool { + let (impl_block_id, trait_def_id) = match self.tcx.def_kind(local_def_id) { // assoc impl items of traits are live if the corresponding trait items are live - DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => self - .tcx - .associated_item(local_def_id) - .trait_item_def_id - .and_then(|def_id| def_id.as_local()), + DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => ( + self.tcx.local_parent(local_def_id), + self.tcx + .associated_item(local_def_id) + .trait_item_def_id + .and_then(|def_id| def_id.as_local()), + ), // impl items are live if the corresponding traits are live - DefKind::Impl { of_trait: true } => self - .tcx - .impl_trait_ref(impl_id.owner_id.def_id) - .and_then(|trait_ref| trait_ref.skip_binder().def_id.as_local()), - _ => None, + DefKind::Impl { of_trait: true } => ( + local_def_id, + self.tcx + .impl_trait_ref(local_def_id) + .and_then(|trait_ref| trait_ref.skip_binder().def_id.as_local()), + ), + _ => bug!(), }; if let Some(trait_def_id) = trait_def_id @@ -505,9 +507,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } // The impl or impl item is used if the corresponding trait or trait item is used and the ty is used. - if let Some(local_def_id) = - local_adt_def_of_ty(self.tcx.hir_item(impl_id).expect_impl().self_ty) - && !self.live_symbols.contains(&local_def_id) + if let ty::Adt(adt, _) = self.tcx.type_of(impl_block_id).instantiate_identity().kind() + && let Some(adt_def_id) = adt.did().as_local() + && !self.live_symbols.contains(&adt_def_id) { return false; } @@ -714,139 +716,86 @@ fn has_allow_dead_code_or_lang_attr( } } -// These check_* functions seeds items that -// 1) We want to explicitly consider as live: -// * Item annotated with #[allow(dead_code)] -// - This is done so that if we want to suppress warnings for a -// group of dead functions, we only have to annotate the "root". -// For example, if both `f` and `g` are dead and `f` calls `g`, -// then annotating `f` with `#[allow(dead_code)]` will suppress -// warning for both `f` and `g`. -// * Item annotated with #[lang=".."] -// - This is because lang items are always callable from elsewhere. -// or -// 2) We are not sure to be live or not -// * Implementations of traits and trait methods -fn check_item<'tcx>( +/// Examine the given definition and record it in the worklist if it should be considered live. +/// +/// We want to explicitly consider as live: +/// * Item annotated with #[allow(dead_code)] +/// This is done so that if we want to suppress warnings for a +/// group of dead functions, we only have to annotate the "root". +/// For example, if both `f` and `g` are dead and `f` calls `g`, +/// then annotating `f` with `#[allow(dead_code)]` will suppress +/// warning for both `f` and `g`. +/// +/// * Item annotated with #[lang=".."] +/// Lang items are always callable from elsewhere. +/// +/// For trait methods and implementations of traits, we are not certain that the definitions are +/// live at this stage. We record them in `unsolved_items` for later examination. +fn maybe_record_as_seed<'tcx>( tcx: TyCtxt<'tcx>, + owner_id: hir::OwnerId, worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, - struct_constructors: &mut LocalDefIdMap<LocalDefId>, - unsolved_items: &mut Vec<(hir::ItemId, LocalDefId)>, - id: hir::ItemId, + unsolved_items: &mut Vec<LocalDefId>, ) { - let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id); + let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, owner_id.def_id); if let Some(comes_from_allow) = allow_dead_code { - worklist.push((id.owner_id.def_id, comes_from_allow)); + worklist.push((owner_id.def_id, comes_from_allow)); } - match tcx.def_kind(id.owner_id) { + match tcx.def_kind(owner_id) { DefKind::Enum => { - let item = tcx.hir_item(id); - if let hir::ItemKind::Enum(_, _, ref enum_def) = item.kind { - if let Some(comes_from_allow) = allow_dead_code { - worklist.extend( - enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)), - ); - } - - for variant in enum_def.variants { - if let Some(ctor_def_id) = variant.data.ctor_def_id() { - struct_constructors.insert(ctor_def_id, variant.def_id); - } - } + if let Some(comes_from_allow) = allow_dead_code { + let adt = tcx.adt_def(owner_id); + worklist.extend( + adt.variants() + .iter() + .map(|variant| (variant.def_id.expect_local(), comes_from_allow)), + ); } } - DefKind::Impl { of_trait } => { - if let Some(comes_from_allow) = - has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id) - { - worklist.push((id.owner_id.def_id, comes_from_allow)); - } else if of_trait { - unsolved_items.push((id, id.owner_id.def_id)); - } - - for def_id in tcx.associated_item_def_ids(id.owner_id) { - let local_def_id = def_id.expect_local(); - - if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, local_def_id) - { - worklist.push((local_def_id, comes_from_allow)); - } else if of_trait { - // We only care about associated items of traits, - // because they cannot be visited directly, - // so we later mark them as live if their corresponding traits - // or trait items and self types are both live, - // but inherent associated items can be visited and marked directly. - unsolved_items.push((id, local_def_id)); + DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy => { + if allow_dead_code.is_none() { + let parent = tcx.local_parent(owner_id.def_id); + match tcx.def_kind(parent) { + DefKind::Impl { of_trait: false } | DefKind::Trait => {} + DefKind::Impl { of_trait: true } => { + // We only care about associated items of traits, + // because they cannot be visited directly, + // so we later mark them as live if their corresponding traits + // or trait items and self types are both live, + // but inherent associated items can be visited and marked directly. + unsolved_items.push(owner_id.def_id); + } + _ => bug!(), } } } - DefKind::Struct => { - let item = tcx.hir_item(id); - if let hir::ItemKind::Struct(_, _, ref variant_data) = item.kind - && let Some(ctor_def_id) = variant_data.ctor_def_id() - { - struct_constructors.insert(ctor_def_id, item.owner_id.def_id); + DefKind::Impl { of_trait: true } => { + if allow_dead_code.is_none() { + unsolved_items.push(owner_id.def_id); } } DefKind::GlobalAsm => { // global_asm! is always live. - worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); + worklist.push((owner_id.def_id, ComesFromAllowExpect::No)); } DefKind::Const => { - let item = tcx.hir_item(id); - if let hir::ItemKind::Const(ident, ..) = item.kind - && ident.name == kw::Underscore - { + if tcx.item_name(owner_id.def_id) == kw::Underscore { // `const _` is always live, as that syntax only exists for the side effects // of type checking and evaluating the constant expression, and marking them // as dead code would defeat that purpose. - worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); + worklist.push((owner_id.def_id, ComesFromAllowExpect::No)); } } _ => {} } } -fn check_trait_item( - tcx: TyCtxt<'_>, - worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, - id: hir::TraitItemId, -) { - use hir::TraitItemKind::{Const, Fn, Type}; - - let trait_item = tcx.hir_trait_item(id); - if matches!(trait_item.kind, Const(_, Some(_)) | Type(_, Some(_)) | Fn(..)) - && let Some(comes_from_allow) = - has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) - { - worklist.push((trait_item.owner_id.def_id, comes_from_allow)); - } -} - -fn check_foreign_item( - tcx: TyCtxt<'_>, - worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, - id: hir::ForeignItemId, -) { - if matches!(tcx.def_kind(id.owner_id), DefKind::Static { .. } | DefKind::Fn) - && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id) - { - worklist.push((id.owner_id.def_id, comes_from_allow)); - } -} - fn create_and_seed_worklist( tcx: TyCtxt<'_>, -) -> ( - Vec<(LocalDefId, ComesFromAllowExpect)>, - LocalDefIdMap<LocalDefId>, - Vec<(hir::ItemId, LocalDefId)>, -) { +) -> (Vec<(LocalDefId, ComesFromAllowExpect)>, Vec<LocalDefId>) { let effective_visibilities = &tcx.effective_visibilities(()); - // see `MarkSymbolVisitor::struct_constructors` let mut unsolved_impl_item = Vec::new(); - let mut struct_constructors = Default::default(); let mut worklist = effective_visibilities .iter() .filter_map(|(&id, effective_vis)| { @@ -863,54 +812,49 @@ fn create_and_seed_worklist( .collect::<Vec<_>>(); let crate_items = tcx.hir_crate_items(()); - for id in crate_items.free_items() { - check_item(tcx, &mut worklist, &mut struct_constructors, &mut unsolved_impl_item, id); - } - - for id in crate_items.trait_items() { - check_trait_item(tcx, &mut worklist, id); - } - - for id in crate_items.foreign_items() { - check_foreign_item(tcx, &mut worklist, id); + for id in crate_items.owners() { + maybe_record_as_seed(tcx, id, &mut worklist, &mut unsolved_impl_item); } - (worklist, struct_constructors, unsolved_impl_item) + (worklist, unsolved_impl_item) } fn live_symbols_and_ignored_derived_traits( tcx: TyCtxt<'_>, (): (), -) -> (LocalDefIdSet, LocalDefIdMap<FxIndexSet<(DefId, DefId)>>) { - let (worklist, struct_constructors, mut unsolved_items) = create_and_seed_worklist(tcx); +) -> (LocalDefIdSet, LocalDefIdMap<FxIndexSet<DefId>>) { + let (worklist, mut unsolved_items) = create_and_seed_worklist(tcx); let mut symbol_visitor = MarkSymbolVisitor { worklist, tcx, maybe_typeck_results: None, + scanned: Default::default(), live_symbols: Default::default(), repr_unconditionally_treats_fields_as_live: false, repr_has_repr_simd: false, in_pat: false, ignore_variant_stack: vec![], - struct_constructors, ignored_derived_traits: Default::default(), }; symbol_visitor.mark_live_symbols(); - let mut items_to_check; - (items_to_check, unsolved_items) = - unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| { - symbol_visitor.check_impl_or_impl_item_live(impl_id, local_def_id) - }); + + // We have marked the primary seeds as live. We now need to process unsolved items from traits + // and trait impls: add them to the work list if the trait or the implemented type is live. + let mut items_to_check: Vec<_> = unsolved_items + .extract_if(.., |&mut local_def_id| { + symbol_visitor.check_impl_or_impl_item_live(local_def_id) + }) + .collect(); while !items_to_check.is_empty() { - symbol_visitor.worklist = - items_to_check.into_iter().map(|(_, id)| (id, ComesFromAllowExpect::No)).collect(); + symbol_visitor + .worklist + .extend(items_to_check.drain(..).map(|id| (id, ComesFromAllowExpect::No))); symbol_visitor.mark_live_symbols(); - (items_to_check, unsolved_items) = - unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| { - symbol_visitor.check_impl_or_impl_item_live(impl_id, local_def_id) - }); + items_to_check.extend(unsolved_items.extract_if(.., |&mut local_def_id| { + symbol_visitor.check_impl_or_impl_item_live(local_def_id) + })); } (symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits) @@ -925,7 +869,7 @@ struct DeadItem { struct DeadVisitor<'tcx> { tcx: TyCtxt<'tcx>, live_symbols: &'tcx LocalDefIdSet, - ignored_derived_traits: &'tcx LocalDefIdMap<FxIndexSet<(DefId, DefId)>>, + ignored_derived_traits: &'tcx LocalDefIdMap<FxIndexSet<DefId>>, } enum ShouldWarnAboutField { @@ -984,25 +928,7 @@ impl<'tcx> DeadVisitor<'tcx> { parent_item: Option<LocalDefId>, report_on: ReportOn, ) { - fn get_parent_if_enum_variant<'tcx>( - tcx: TyCtxt<'tcx>, - may_variant: LocalDefId, - ) -> LocalDefId { - if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant) - && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id()) - && let Some(enum_local_id) = enum_did.as_local() - && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id) - && let ItemKind::Enum(..) = item.kind - { - enum_local_id - } else { - may_variant - } - } - - let Some(&first_item) = dead_codes.first() else { - return; - }; + let Some(&first_item) = dead_codes.first() else { return }; let tcx = self.tcx; let first_lint_level = first_item.level; @@ -1011,81 +937,54 @@ impl<'tcx> DeadVisitor<'tcx> { let names: Vec<_> = dead_codes.iter().map(|item| item.name).collect(); let spans: Vec<_> = dead_codes .iter() - .map(|item| match tcx.def_ident_span(item.def_id) { - Some(s) => s.with_ctxt(tcx.def_span(item.def_id).ctxt()), - None => tcx.def_span(item.def_id), + .map(|item| { + let span = tcx.def_span(item.def_id); + let ident_span = tcx.def_ident_span(item.def_id); + // FIXME(cjgillot) this SyntaxContext manipulation does not make any sense. + ident_span.map(|s| s.with_ctxt(span.ctxt())).unwrap_or(span) }) .collect(); - let descr = tcx.def_descr(first_item.def_id.to_def_id()); + let mut descr = tcx.def_descr(first_item.def_id.to_def_id()); // `impl` blocks are "batched" and (unlike other batching) might // contain different kinds of associated items. - let descr = if dead_codes.iter().any(|item| tcx.def_descr(item.def_id.to_def_id()) != descr) - { - "associated item" - } else { - descr - }; + if dead_codes.iter().any(|item| tcx.def_descr(item.def_id.to_def_id()) != descr) { + descr = "associated item" + } + let num = dead_codes.len(); let multiple = num > 6; let name_list = names.into(); - let parent_info = if let Some(parent_item) = parent_item { + let parent_info = parent_item.map(|parent_item| { let parent_descr = tcx.def_descr(parent_item.to_def_id()); let span = if let DefKind::Impl { .. } = tcx.def_kind(parent_item) { tcx.def_span(parent_item) } else { tcx.def_ident_span(parent_item).unwrap() }; - Some(ParentInfo { num, descr, parent_descr, span }) - } else { - None - }; + ParentInfo { num, descr, parent_descr, span } + }); - let encl_def_id = parent_item.unwrap_or(first_item.def_id); - // If parent of encl_def_id is an enum, use the parent ID instead. - let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id); + let mut encl_def_id = parent_item.unwrap_or(first_item.def_id); + // `ignored_derived_traits` is computed for the enum, not for the variants. + if let DefKind::Variant = tcx.def_kind(encl_def_id) { + encl_def_id = tcx.local_parent(encl_def_id); + } let ignored_derived_impls = - if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { + self.ignored_derived_traits.get(&encl_def_id).map(|ign_traits| { let trait_list = ign_traits .iter() - .map(|(trait_id, _)| self.tcx.item_name(*trait_id)) + .map(|trait_id| self.tcx.item_name(*trait_id)) .collect::<Vec<_>>(); let trait_list_len = trait_list.len(); - Some(IgnoredDerivedImpls { + IgnoredDerivedImpls { name: self.tcx.item_name(encl_def_id.to_def_id()), trait_list: trait_list.into(), trait_list_len, - }) - } else { - None - }; - - let enum_variants_with_same_name = dead_codes - .iter() - .filter_map(|dead_item| { - if let Node::ImplItem(ImplItem { - kind: ImplItemKind::Fn(..) | ImplItemKind::Const(..), - .. - }) = tcx.hir_node_by_def_id(dead_item.def_id) - && let Some(impl_did) = tcx.opt_parent(dead_item.def_id.to_def_id()) - && let DefKind::Impl { of_trait: false } = tcx.def_kind(impl_did) - && let ty::Adt(maybe_enum, _) = tcx.type_of(impl_did).skip_binder().kind() - && maybe_enum.is_enum() - && let Some(variant) = - maybe_enum.variants().iter().find(|i| i.name == dead_item.name) - { - Some(crate::errors::EnumVariantSameName { - dead_descr: tcx.def_descr(dead_item.def_id.to_def_id()), - dead_name: dead_item.name, - variant_span: tcx.def_span(variant.def_id), - }) - } else { - None } - }) - .collect(); + }); let diag = match report_on { ReportOn::TupleField => { @@ -1132,16 +1031,42 @@ impl<'tcx> DeadVisitor<'tcx> { ignored_derived_impls, } } - ReportOn::NamedField => MultipleDeadCodes::DeadCodes { - multiple, - num, - descr, - participle, - name_list, - parent_info, - ignored_derived_impls, - enum_variants_with_same_name, - }, + ReportOn::NamedField => { + let enum_variants_with_same_name = dead_codes + .iter() + .filter_map(|dead_item| { + if let DefKind::AssocFn | DefKind::AssocConst = + tcx.def_kind(dead_item.def_id) + && let impl_did = tcx.local_parent(dead_item.def_id) + && let DefKind::Impl { of_trait: false } = tcx.def_kind(impl_did) + && let ty::Adt(maybe_enum, _) = + tcx.type_of(impl_did).instantiate_identity().kind() + && maybe_enum.is_enum() + && let Some(variant) = + maybe_enum.variants().iter().find(|i| i.name == dead_item.name) + { + Some(crate::errors::EnumVariantSameName { + dead_descr: tcx.def_descr(dead_item.def_id.to_def_id()), + dead_name: dead_item.name, + variant_span: tcx.def_span(variant.def_id), + }) + } else { + None + } + }) + .collect(); + + MultipleDeadCodes::DeadCodes { + multiple, + num, + descr, + participle, + name_list, + parent_info, + ignored_derived_impls, + enum_variants_with_same_name, + } + } }; let hir_id = tcx.local_def_id_to_hir_id(first_item.def_id); diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index af7ecf0830c..2ad0b5ff60e 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -8,6 +8,7 @@ #![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] +#![feature(if_let_guard)] #![feature(map_try_insert)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/compiler/rustc_thread_pool/Cargo.toml b/compiler/rustc_thread_pool/Cargo.toml index b0194834264..c92984470b7 100644 --- a/compiler/rustc_thread_pool/Cargo.toml +++ b/compiler/rustc_thread_pool/Cargo.toml @@ -7,7 +7,6 @@ authors = [ ] description = "Core APIs for Rayon - fork for rustc" license = "MIT OR Apache-2.0" -rust-version = "1.63" edition = "2021" readme = "README.md" keywords = ["parallel", "thread", "concurrency", "join", "performance"] diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 17c16e4aaff..acbbb6df9a5 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -382,6 +382,7 @@ impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> { /// documentation for more. /// /// [`iter_mut`]: BTreeMap::iter_mut +#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, K: 'a, V: 'a> { range: LazyLeafRange<marker::ValMut<'a>, K, V>, @@ -391,7 +392,6 @@ pub struct IterMut<'a, K: 'a, V: 'a> { _marker: PhantomData<&'a mut (K, V)>, } -#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "collection_debug", since = "1.17.0")] impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 106cc725fee..c6b92df5fe1 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2667,7 +2667,7 @@ pub unsafe fn vtable_align(ptr: *const ()) -> usize; /// More specifically, this is the offset in bytes between successive /// items of the same type, including alignment padding. /// -/// The stabilized version of this intrinsic is [`size_of`]. +/// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] @@ -2681,7 +2681,7 @@ pub const fn size_of<T>() -> usize; /// Therefore, implementations must not require the user to uphold /// any safety invariants. /// -/// The stabilized version of this intrinsic is [`align_of`]. +/// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] @@ -2704,7 +2704,7 @@ pub const fn variant_count<T>() -> usize; /// The size of the referenced value in bytes. /// -/// The stabilized version of this intrinsic is [`size_of_val`]. +/// The stabilized version of this intrinsic is [`core::mem::size_of_val`]. /// /// # Safety /// @@ -2717,7 +2717,7 @@ pub const unsafe fn size_of_val<T: ?Sized>(ptr: *const T) -> usize; /// The required alignment of the referenced value. /// -/// The stabilized version of this intrinsic is [`align_of_val`]. +/// The stabilized version of this intrinsic is [`core::mem::align_of_val`]. /// /// # Safety /// diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 5683d5ec92d..10efb8aff4a 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -177,14 +177,14 @@ macro_rules! int_impl { /// #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] /// - /// assert_eq!(n.isolate_most_significant_one(), 0b_01000000); - #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_most_significant_one(), 0);")] + /// assert_eq!(n.isolate_highest_one(), 0b_01000000); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_highest_one(), 0);")] /// ``` #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - pub const fn isolate_most_significant_one(self) -> Self { + pub const fn isolate_highest_one(self) -> Self { self & (((1 as $SelfT) << (<$SelfT>::BITS - 1)).wrapping_shr(self.leading_zeros())) } @@ -198,14 +198,14 @@ macro_rules! int_impl { /// #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] /// - /// assert_eq!(n.isolate_least_significant_one(), 0b_00000100); - #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_least_significant_one(), 0);")] + /// assert_eq!(n.isolate_lowest_one(), 0b_00000100); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_lowest_one(), 0);")] /// ``` #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - pub const fn isolate_least_significant_one(self) -> Self { + pub const fn isolate_lowest_one(self) -> Self { self & self.wrapping_neg() } diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index f793602de50..2d3a680b348 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -629,7 +629,7 @@ macro_rules! nonzero_integer { #[doc = concat!("let a = NonZero::<", stringify!($Int), ">::new(0b_01100100)?;")] #[doc = concat!("let b = NonZero::<", stringify!($Int), ">::new(0b_01000000)?;")] /// - /// assert_eq!(a.isolate_most_significant_one(), b); + /// assert_eq!(a.isolate_highest_one(), b); /// # Some(()) /// # } /// ``` @@ -637,7 +637,7 @@ macro_rules! nonzero_integer { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - pub const fn isolate_most_significant_one(self) -> Self { + pub const fn isolate_highest_one(self) -> Self { let n = self.get() & (((1 as $Int) << (<$Int>::BITS - 1)).wrapping_shr(self.leading_zeros())); // SAFETY: @@ -659,7 +659,7 @@ macro_rules! nonzero_integer { #[doc = concat!("let a = NonZero::<", stringify!($Int), ">::new(0b_01100100)?;")] #[doc = concat!("let b = NonZero::<", stringify!($Int), ">::new(0b_00000100)?;")] /// - /// assert_eq!(a.isolate_least_significant_one(), b); + /// assert_eq!(a.isolate_lowest_one(), b); /// # Some(()) /// # } /// ``` @@ -667,7 +667,7 @@ macro_rules! nonzero_integer { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - pub const fn isolate_least_significant_one(self) -> Self { + pub const fn isolate_lowest_one(self) -> Self { let n = self.get(); let n = n & n.wrapping_neg(); diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 584cd60fbe5..5a41a302916 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -229,14 +229,14 @@ macro_rules! uint_impl { /// #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] /// - /// assert_eq!(n.isolate_most_significant_one(), 0b_01000000); - #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_most_significant_one(), 0);")] + /// assert_eq!(n.isolate_highest_one(), 0b_01000000); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_highest_one(), 0);")] /// ``` #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - pub const fn isolate_most_significant_one(self) -> Self { + pub const fn isolate_highest_one(self) -> Self { self & (((1 as $SelfT) << (<$SelfT>::BITS - 1)).wrapping_shr(self.leading_zeros())) } @@ -250,14 +250,14 @@ macro_rules! uint_impl { /// #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] /// - /// assert_eq!(n.isolate_least_significant_one(), 0b_00000100); - #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_least_significant_one(), 0);")] + /// assert_eq!(n.isolate_lowest_one(), 0b_00000100); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_lowest_one(), 0);")] /// ``` #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - pub const fn isolate_least_significant_one(self) -> Self { + pub const fn isolate_lowest_one(self) -> Self { self & self.wrapping_neg() } diff --git a/library/coretests/tests/nonzero.rs b/library/coretests/tests/nonzero.rs index 00232c9b706..60e1149f6e6 100644 --- a/library/coretests/tests/nonzero.rs +++ b/library/coretests/tests/nonzero.rs @@ -321,7 +321,7 @@ fn nonzero_trailing_zeros() { } #[test] -fn test_nonzero_isolate_most_significant_one() { +fn test_nonzero_isolate_highest_one() { // Signed most significant one macro_rules! nonzero_int_impl { ($($T:ty),+) => { @@ -335,8 +335,8 @@ fn test_nonzero_isolate_most_significant_one() { let mut i = 0; while i < <$T>::BITS { assert_eq!( - NonZero::<$T>::new(BITS >> i).unwrap().isolate_most_significant_one(), - NonZero::<$T>::new(MOST_SIG_ONE >> i).unwrap().isolate_most_significant_one() + NonZero::<$T>::new(BITS >> i).unwrap().isolate_highest_one(), + NonZero::<$T>::new(MOST_SIG_ONE >> i).unwrap().isolate_highest_one() ); i += 1; } @@ -356,8 +356,8 @@ fn test_nonzero_isolate_most_significant_one() { let mut i = 0; while i < <$T>::BITS { assert_eq!( - NonZero::<$T>::new(BITS >> i).unwrap().isolate_most_significant_one(), - NonZero::<$T>::new(MOST_SIG_ONE >> i).unwrap().isolate_most_significant_one(), + NonZero::<$T>::new(BITS >> i).unwrap().isolate_highest_one(), + NonZero::<$T>::new(MOST_SIG_ONE >> i).unwrap().isolate_highest_one(), ); i += 1; } @@ -371,7 +371,7 @@ fn test_nonzero_isolate_most_significant_one() { } #[test] -fn test_nonzero_isolate_least_significant_one() { +fn test_nonzero_isolate_lowest_one() { // Signed least significant one macro_rules! nonzero_int_impl { ($($T:ty),+) => { @@ -385,8 +385,8 @@ fn test_nonzero_isolate_least_significant_one() { let mut i = 0; while i < <$T>::BITS { assert_eq!( - NonZero::<$T>::new(BITS << i).unwrap().isolate_least_significant_one(), - NonZero::<$T>::new(LEAST_SIG_ONE << i).unwrap().isolate_least_significant_one() + NonZero::<$T>::new(BITS << i).unwrap().isolate_lowest_one(), + NonZero::<$T>::new(LEAST_SIG_ONE << i).unwrap().isolate_lowest_one() ); i += 1; } @@ -406,8 +406,8 @@ fn test_nonzero_isolate_least_significant_one() { let mut i = 0; while i < <$T>::BITS { assert_eq!( - NonZero::<$T>::new(BITS << i).unwrap().isolate_least_significant_one(), - NonZero::<$T>::new(LEAST_SIG_ONE << i).unwrap().isolate_least_significant_one(), + NonZero::<$T>::new(BITS << i).unwrap().isolate_lowest_one(), + NonZero::<$T>::new(LEAST_SIG_ONE << i).unwrap().isolate_lowest_one(), ); i += 1; } diff --git a/library/coretests/tests/num/int_macros.rs b/library/coretests/tests/num/int_macros.rs index 41d399c1ad9..ca32fce861f 100644 --- a/library/coretests/tests/num/int_macros.rs +++ b/library/coretests/tests/num/int_macros.rs @@ -194,7 +194,7 @@ macro_rules! int_module { } #[test] - fn test_isolate_most_significant_one() { + fn test_isolate_highest_one() { const BITS: $T = -1; const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1); @@ -203,15 +203,15 @@ macro_rules! int_module { let mut i = 0; while i < <$T>::BITS { assert_eq!( - (BITS >> i).isolate_most_significant_one(), - (MOST_SIG_ONE >> i).isolate_most_significant_one() + (BITS >> i).isolate_highest_one(), + (MOST_SIG_ONE >> i).isolate_highest_one() ); i += 1; } } #[test] - fn test_isolate_least_significant_one() { + fn test_isolate_lowest_one() { const BITS: $T = -1; const LEAST_SIG_ONE: $T = 1; @@ -220,8 +220,8 @@ macro_rules! int_module { let mut i = 0; while i < <$T>::BITS { assert_eq!( - (BITS << i).isolate_least_significant_one(), - (LEAST_SIG_ONE << i).isolate_least_significant_one() + (BITS << i).isolate_lowest_one(), + (LEAST_SIG_ONE << i).isolate_lowest_one() ); i += 1; } diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs index 7e02027bdd6..8f389de70aa 100644 --- a/library/coretests/tests/num/uint_macros.rs +++ b/library/coretests/tests/num/uint_macros.rs @@ -151,7 +151,7 @@ macro_rules! uint_module { } #[test] - fn test_isolate_most_significant_one() { + fn test_isolate_highest_one() { const BITS: $T = <$T>::MAX; const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1); @@ -160,15 +160,15 @@ macro_rules! uint_module { let mut i = 0; while i < <$T>::BITS { assert_eq!( - (BITS >> i).isolate_most_significant_one(), - (MOST_SIG_ONE >> i).isolate_most_significant_one(), + (BITS >> i).isolate_highest_one(), + (MOST_SIG_ONE >> i).isolate_highest_one(), ); i += 1; } } #[test] - fn test_isolate_least_significant_one() { + fn test_isolate_lowest_one() { const BITS: $T = <$T>::MAX; const LEAST_SIG_ONE: $T = 1; @@ -177,8 +177,8 @@ macro_rules! uint_module { let mut i = 0; while i < <$T>::BITS { assert_eq!( - (BITS << i).isolate_least_significant_one(), - (LEAST_SIG_ONE << i).isolate_least_significant_one(), + (BITS << i).isolate_lowest_one(), + (LEAST_SIG_ONE << i).isolate_lowest_one(), ); i += 1; } diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 913ef72f674..cff4f20b5a8 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -108,8 +108,6 @@ impl<'a> PanicHookInfo<'a> { /// # Example /// /// ```should_panic - /// #![feature(panic_payload_as_str)] - /// /// std::panic::set_hook(Box::new(|panic_info| { /// if let Some(s) = panic_info.payload_as_str() { /// println!("panic occurred: {s:?}"); @@ -122,7 +120,7 @@ impl<'a> PanicHookInfo<'a> { /// ``` #[must_use] #[inline] - #[unstable(feature = "panic_payload_as_str", issue = "125175")] + #[stable(feature = "panic_payload_as_str", since = "CURRENT_RUSTC_VERSION")] pub fn payload_as_str(&self) -> Option<&str> { if let Some(s) = self.payload.downcast_ref::<&str>() { Some(s) diff --git a/library/std/src/sys/args/common.rs b/library/std/src/sys/args/common.rs index e787105a05a..33f3794ee63 100644 --- a/library/std/src/sys/args/common.rs +++ b/library/std/src/sys/args/common.rs @@ -12,7 +12,7 @@ impl !Sync for Args {} impl Args { #[inline] - pub(super) fn new(args: Vec<OsString>) -> Self { + pub fn new(args: Vec<OsString>) -> Self { Args { iter: args.into_iter() } } } diff --git a/src/ci/docker/scripts/build-clang.sh b/src/ci/docker/scripts/build-clang.sh index 536991cc06b..905c4077304 100755 --- a/src/ci/docker/scripts/build-clang.sh +++ b/src/ci/docker/scripts/build-clang.sh @@ -5,7 +5,7 @@ set -ex source shared.sh # Try to keep the LLVM version here in sync with src/ci/scripts/install-clang.sh -LLVM=llvmorg-20.1.0-rc2 +LLVM=llvmorg-21.1.0-rc2 mkdir llvm-project cd llvm-project @@ -44,8 +44,10 @@ hide_output \ -DLLVM_INCLUDE_BENCHMARKS=OFF \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ - -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \ + -DLLVM_ENABLE_PROJECTS="clang;lld;bolt" \ + -DLLVM_ENABLE_RUNTIMES="compiler-rt" \ -DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/$GCC_PLUGIN_TARGET/$GCC_VERSION/plugin/include/" \ + -DRUNTIMES_CMAKE_ARGS="-DCMAKE_CXX_FLAGS=\"--gcc-toolchain=/rustroot\"" \ -DC_INCLUDE_DIRS="$INC" hide_output make -j$(nproc) diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index d0cee54adb6..c26d34273d7 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -181,4 +181,7 @@ the `deprecated_in_future` lint is triggered which is default `allow`, but most of the standard library raises it to a warning with `#![warn(deprecated_in_future)]`. +## unstable_feature_bound +The `#[unstable_feature_bound(foo)]` attribute can be used together with `#[unstable]` attribute to mark an `impl` of stable type and stable trait as unstable. In std/core, an item annotated with `#[unstable_feature_bound(foo)]` can only be used by another item that is also annotated with `#[unstable_feature_bound(foo)]`. Outside of std/core, using an item with `#[unstable_feature_bound(foo)]` requires the feature to be enabled with `#![feature(foo)]` attribute on the crate. Currently, only `impl`s and free functions can be annotated with `#[unstable_feature_bound]`. + [blog]: https://www.ralfj.de/blog/2018/07/19/const.html diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 782311e593b..26b087feb16 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -480,10 +480,28 @@ impl Item { } } + /// If the item has doc comments from a reexport, returns the item id of that reexport, + /// otherwise returns returns the item id. + /// + /// This is used as a key for caching intra-doc link resolution, + /// to prevent two reexports of the same item from using the same cache. + pub(crate) fn item_or_reexport_id(&self) -> ItemId { + // added documentation on a reexport is always prepended. + self.attrs + .doc_strings + .first() + .map(|x| x.item_id) + .flatten() + .map(ItemId::from) + .unwrap_or(self.item_id) + } + pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> { use crate::html::format::{href, link_tooltip}; - let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] }; + let Some(links) = cx.cache().intra_doc_links.get(&self.item_or_reexport_id()) else { + return vec![]; + }; links .iter() .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 99b3da8b2cd..c48863b4681 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1838,6 +1838,10 @@ instead, we check that it's not a "finger" cursor. border-right: 3px solid var(--target-border-color); } +a.tooltip { + font-family: var(--font-family); +} + .code-header a.tooltip { color: inherit; margin-right: 15px; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c9fa3a4837f..bcb676cd1f1 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1082,7 +1082,12 @@ impl LinkCollector<'_, '_> { for md_link in preprocessed_markdown_links(&doc) { let link = self.resolve_link(&doc, item, item_id, module_id, &md_link); if let Some(link) = link { - self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link); + self.cx + .cache + .intra_doc_links + .entry(item.item_or_reexport_id()) + .or_default() + .insert(link); } } } diff --git a/src/llvm-project b/src/llvm-project -Subproject e8a2ffcf322f45b8dce82c65ab27a3e2430a6b5 +Subproject d35840afa50d2615835d6a836f1967c57008188 diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index f7955429d83..099058bf051 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -68,6 +68,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-gnu", "ignore-haiku", "ignore-horizon", + "ignore-i586-unknown-linux-gnu", "ignore-i686-pc-windows-gnu", "ignore-i686-pc-windows-msvc", "ignore-illumos", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 35670ba89e9..84c6df5c744 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -356,7 +356,7 @@ impl<'test> TestCx<'test> { if proc_res.status.success() { let err = &format!("{} test did not emit an error", self.config.mode); let extra_note = (self.config.mode == crate::common::TestMode::Ui) - .then_some("note: by default, ui tests are expected not to compile"); + .then_some("note: by default, ui tests are expected not to compile.\nhint: use check-pass, build-pass, or run-pass directive to change this behavior."); self.fatal_proc_rec_general(err, extra_note, proc_res, || ()); } diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index ee48e373366..739eff72f05 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -23,6 +23,7 @@ pub struct Diff { actual: Option<String>, actual_name: Option<String>, normalizers: Vec<(String, String)>, + bless_dir: Option<String>, drop_bomb: DropBomb, } @@ -37,6 +38,7 @@ impl Diff { actual: None, actual_name: None, normalizers: Vec::new(), + bless_dir: std::env::var("RUSTC_BLESS_TEST").ok(), drop_bomb: DropBomb::arm("diff"), } } @@ -44,6 +46,13 @@ impl Diff { /// Specify the expected output for the diff from a file. pub fn expected_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self { let path = path.as_ref(); + // In `--bless` mode, create the snapshot file if it doesn't already exist. + // The empty file will be overwritten with the actual text. + if self.bless_dir.is_some() + && let Ok(false) = std::fs::exists(path) + { + fs::write(path, ""); + } let content = fs::read_to_string(path); let name = path.to_string_lossy().to_string(); @@ -148,7 +157,7 @@ impl Diff { let Some(ref expected_file) = self.expected_file else { return false; }; - let Ok(bless_dir) = std::env::var("RUSTC_BLESS_TEST") else { + let Some(ref bless_dir) = self.bless_dir else { return false; }; diff --git a/tests/codegen-llvm/gdb_debug_script_load.rs b/tests/codegen-llvm/gdb_debug_script_load.rs index 3e92eba10b1..90f2be41cf2 100644 --- a/tests/codegen-llvm/gdb_debug_script_load.rs +++ b/tests/codegen-llvm/gdb_debug_script_load.rs @@ -9,6 +9,8 @@ #![feature(lang_items)] #![no_std] +// CHECK: @llvm.used = {{.+}} @__rustc_debug_gdb_scripts_section + #[panic_handler] fn panic_handler(_: &core::panic::PanicInfo) -> ! { loop {} @@ -22,7 +24,7 @@ extern "C" fn rust_eh_personality() { // Needs rustc to generate `main` as that's where the magic load is inserted. // IOW, we cannot write this test with `#![no_main]`. // CHECK-LABEL: @main -// CHECK: load volatile i8, {{.+}} @__rustc_debug_gdb_scripts_section__ +// CHECK: load volatile i8, {{.+}} @__rustc_debug_gdb_scripts_section #[lang = "start"] fn lang_start<T: 'static>( diff --git a/tests/debuginfo/embedded-visualizer.rs b/tests/debuginfo/embedded-visualizer.rs index cbd8691394d..12d87be7c66 100644 --- a/tests/debuginfo/embedded-visualizer.rs +++ b/tests/debuginfo/embedded-visualizer.rs @@ -1,6 +1,8 @@ //@ compile-flags:-g //@ ignore-lldb //@ ignore-windows-gnu: #128981 +//@ ignore-musl: linker too old in CI +//@ ignore-i586-unknown-linux-gnu: linker too old in CI // === CDB TESTS ================================================================================== diff --git a/tests/run-make/symbols-all-mangled/rmake.rs b/tests/run-make/symbols-all-mangled/rmake.rs index 2cf57975800..e30bef98580 100644 --- a/tests/run-make/symbols-all-mangled/rmake.rs +++ b/tests/run-make/symbols-all-mangled/rmake.rs @@ -35,13 +35,7 @@ fn symbols_check_archive(path: &str) { continue; // All compiler-builtins symbols must remain unmangled } - if name.contains("rust_eh_personality") { - continue; // Unfortunately LLVM doesn't allow us to mangle this symbol - } - - if name.contains(".llvm.") { - // Starting in LLVM 21 we get various implementation-detail functions which - // contain .llvm. that are not a problem. + if symbol_ok_everywhere(name) { continue; } @@ -71,13 +65,7 @@ fn symbols_check(path: &str) { continue; } - if name.contains("rust_eh_personality") { - continue; // Unfortunately LLVM doesn't allow us to mangle this symbol - } - - if name.contains(".llvm.") { - // Starting in LLVM 21 we get various implementation-detail functions which - // contain .llvm. that are not a problem. + if symbol_ok_everywhere(name) { continue; } @@ -88,3 +76,22 @@ fn symbols_check(path: &str) { fn strip_underscore_if_apple(symbol: &str) -> &str { if cfg!(target_vendor = "apple") { symbol.strip_prefix("_").unwrap() } else { symbol } } + +fn symbol_ok_everywhere(name: &str) -> bool { + if name.contains("rust_eh_personality") { + return true; // Unfortunately LLVM doesn't allow us to mangle this symbol + } + + if name.contains(".llvm.") { + // Starting in LLVM 21 we get various implementation-detail functions which + // contain .llvm. that are not a problem. + return true; + } + + if name.starts_with("__rustc_debug_gdb_scripts_section") { + // These symbols are fine; they're made unique by the crate ID. + return true; + } + + return false; +} diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index 7fc70e0675d..423a273fde7 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -8,10 +8,10 @@ define-function: ( [x, i_x], block { // Checking they have the same y position. - compare-elements-position: ( + compare-elements-position-near: ( "//*[@id='method.create_an_iterator_from_read']//a[normalize-space()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ["y"], + {"y": 1}, ) // Checking they don't have the same x position. compare-elements-position-false: ( diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index e8afe8b5687..623f5b33e9b 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -767,3 +767,17 @@ pub mod impls_indent { pub fn bar() {} } } + +pub mod tooltips { + pub struct X; + + impl X { + pub fn bar() -> Vec<u8> { + Vec::new() + } + } + + pub fn bar() -> Vec<u8> { + Vec::new() + } +} diff --git a/tests/rustdoc-gui/tooltips.goml b/tests/rustdoc-gui/tooltips.goml new file mode 100644 index 00000000000..6e79196be27 --- /dev/null +++ b/tests/rustdoc-gui/tooltips.goml @@ -0,0 +1,15 @@ +// This test checks that the right font is applied to the `i` tooltip element. + +define-function: ( + "check-font", + [path], + block { + go-to: "file://" + |DOC_PATH| + "/test_docs/" + |path| + assert-css: ( + "a.tooltip", {"font-family": '"Source Serif 4", NanumBarunGothic, serif'}, ALL, + ) + } +) + +call-function: ("check-font", {"path": "tooltips/fn.bar.html"}) +call-function: ("check-font", {"path": "tooltips/struct.X.html"}) diff --git a/tests/rustdoc/intra-doc/macro-caching-144965.rs b/tests/rustdoc/intra-doc/macro-caching-144965.rs new file mode 100644 index 00000000000..e14b465aeea --- /dev/null +++ b/tests/rustdoc/intra-doc/macro-caching-144965.rs @@ -0,0 +1,35 @@ +// regression test for https://github.com/rust-lang/rust/issues/144965 + +#![crate_name = "foo"] +#![no_std] + +#[doc(hidden)] +pub struct MyStruct; + +macro_rules! my_macro { + () => { + pub fn my_function() {} + + /// Incorrect: [`my_function()`]. + #[doc(inline)] + pub use $crate::MyStruct; + + /// Correct: [`my_function`]. + pub struct AnotherStruct; + }; +} + + +pub mod one { + //@ has 'foo/one/index.html' + //@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function' + //@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()' + my_macro!(); +} + +pub mod two { + //@ has 'foo/two/index.html' + //@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function' + //@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()' + my_macro!(); +} diff --git a/tests/ui/issues/issue-5754.rs b/tests/ui/abi/extern-c-two-doubles-x86_64-5754.rs index 0aa09882959..7f44ef9c685 100644 --- a/tests/ui/issues/issue-5754.rs +++ b/tests/ui/abi/extern-c-two-doubles-x86_64-5754.rs @@ -1,8 +1,8 @@ +// https://github.com/rust-lang/rust/issues/5754 //@ build-pass #![allow(dead_code)] #![allow(improper_ctypes)] - struct TwoDoubles { r: f64, i: f64 diff --git a/tests/ui/issues/issue-8898.rs b/tests/ui/array-slice-vec/fixed-size-arrays-zero-size-types-8898.rs index 4447704f059..fe627b00f53 100644 --- a/tests/ui/issues/issue-8898.rs +++ b/tests/ui/array-slice-vec/fixed-size-arrays-zero-size-types-8898.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/8898 //@ run-pass fn assert_repr_eq<T: std::fmt::Debug>(obj : T, expected : String) { diff --git a/tests/ui/issues/issue-43483.rs b/tests/ui/associated-consts/trait-associated-const-usage-43483.rs index 2c62671d0c7..c24157d45e7 100644 --- a/tests/ui/issues/issue-43483.rs +++ b/tests/ui/associated-consts/trait-associated-const-usage-43483.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/43483 //@ check-pass #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-21946.rs b/tests/ui/associated-types/recursive-associated-type-overflow-21946.rs index d0c052cb2fd..ba84ea11300 100644 --- a/tests/ui/issues/issue-21946.rs +++ b/tests/ui/associated-types/recursive-associated-type-overflow-21946.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/21946 trait Foo { type A; } diff --git a/tests/ui/issues/issue-21946.stderr b/tests/ui/associated-types/recursive-associated-type-overflow-21946.stderr index d1b4a808d2e..37fb0ed7eb8 100644 --- a/tests/ui/issues/issue-21946.stderr +++ b/tests/ui/associated-types/recursive-associated-type-overflow-21946.stderr @@ -1,5 +1,5 @@ error[E0275]: overflow evaluating the requirement `<FooStruct as Foo>::A == _` - --> $DIR/issue-21946.rs:8:14 + --> $DIR/recursive-associated-type-overflow-21946.rs:9:14 | LL | type A = <FooStruct as Foo>::A; | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 1b51075b4e8..e8ae4715398 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -55,12 +55,6 @@ error: malformed `patchable_function_entry` attribute input LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` -error: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:108:5 - | -LL | #[coroutine = 63] || {} - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` - error: malformed `must_not_suspend` attribute input --> $DIR/malformed-attrs.rs:129:1 | @@ -436,6 +430,15 @@ LL | #[proc_macro = 18] | | didn't expect any arguments here | help: must be of the form: `#[proc_macro]` +error[E0565]: malformed `coroutine` attribute input + --> $DIR/malformed-attrs.rs:108:5 + | +LL | #[coroutine = 63] || {} + | ^^^^^^^^^^^^----^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[coroutine]` + error[E0565]: malformed `proc_macro_attribute` attribute input --> $DIR/malformed-attrs.rs:113:1 | diff --git a/tests/ui/issues/issue-7061.rs b/tests/ui/borrowck/mismatched-pointer-type-in-self-7061.rs index c5d5a9d9498..521a5ee9c37 100644 --- a/tests/ui/issues/issue-7061.rs +++ b/tests/ui/borrowck/mismatched-pointer-type-in-self-7061.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/7061 //@ dont-require-annotations: NOTE struct BarStruct; diff --git a/tests/ui/issues/issue-7061.stderr b/tests/ui/borrowck/mismatched-pointer-type-in-self-7061.stderr index b4c0ebfbdd5..39b9072dc30 100644 --- a/tests/ui/issues/issue-7061.stderr +++ b/tests/ui/borrowck/mismatched-pointer-type-in-self-7061.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-7061.rs:6:46 + --> $DIR/mismatched-pointer-type-in-self-7061.rs:7:46 | LL | fn foo(&'a mut self) -> Box<BarStruct> { self } | -------------- ^^^^ expected `Box<BarStruct>`, found `&mut BarStruct` diff --git a/tests/ui/issues/issue-13665.rs b/tests/ui/borrowck/region-checker-map-closure-13665.rs index e1d8be16f45..72efa42fe38 100644 --- a/tests/ui/issues/issue-13665.rs +++ b/tests/ui/borrowck/region-checker-map-closure-13665.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/13665 //@ run-pass fn foo<'r>() { diff --git a/tests/ui/issues/issue-21600.rs b/tests/ui/closures/aliasability-violation-with-closure-21600.rs index 2e22e5e6fa2..d4c658319ab 100644 --- a/tests/ui/issues/issue-21600.rs +++ b/tests/ui/closures/aliasability-violation-with-closure-21600.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/21600 fn call_it<F>(f: F) where F: Fn() { f(); } struct A; diff --git a/tests/ui/issues/issue-21600.stderr b/tests/ui/closures/aliasability-violation-with-closure-21600.stderr index f7905934424..2d2397a2141 100644 --- a/tests/ui/issues/issue-21600.stderr +++ b/tests/ui/closures/aliasability-violation-with-closure-21600.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/issue-21600.rs:14:20 + --> $DIR/aliasability-violation-with-closure-21600.rs:15:20 | LL | fn call_it<F>(f: F) where F: Fn() { f(); } | - change this to accept `FnMut` instead of `Fn` @@ -11,7 +11,7 @@ LL | call_it(|| x.gen_mut()); | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/issue-21600.rs:14:17 + --> $DIR/aliasability-violation-with-closure-21600.rs:15:17 | LL | fn call_it<F>(f: F) where F: Fn() { f(); } | - change this to accept `FnMut` instead of `Fn` diff --git a/tests/ui/issues/issue-32086.rs b/tests/ui/consts/const-pattern-rewrite-error-32086.rs index d595d1dd7e6..d35dfe57687 100644 --- a/tests/ui/issues/issue-32086.rs +++ b/tests/ui/consts/const-pattern-rewrite-error-32086.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/32086 struct S(u8); const C: S = S(10); diff --git a/tests/ui/issues/issue-32086.stderr b/tests/ui/consts/const-pattern-rewrite-error-32086.stderr index e566dea8908..47616b06632 100644 --- a/tests/ui/issues/issue-32086.stderr +++ b/tests/ui/consts/const-pattern-rewrite-error-32086.stderr @@ -1,5 +1,5 @@ error[E0532]: expected tuple struct or tuple variant, found constant `C` - --> $DIR/issue-32086.rs:5:9 + --> $DIR/const-pattern-rewrite-error-32086.rs:6:9 | LL | struct S(u8); | ------------- similarly named tuple struct `S` defined here @@ -8,7 +8,7 @@ LL | let C(a) = S(11); | ^ help: a tuple struct with a similar name exists: `S` error[E0532]: expected tuple struct or tuple variant, found constant `C` - --> $DIR/issue-32086.rs:6:9 + --> $DIR/const-pattern-rewrite-error-32086.rs:7:9 | LL | struct S(u8); | ------------- similarly named tuple struct `S` defined here diff --git a/tests/ui/issues/auxiliary/issue-5521.rs b/tests/ui/cross-crate/auxiliary/aux-5521.rs index c2f81779b35..c2f81779b35 100644 --- a/tests/ui/issues/auxiliary/issue-5521.rs +++ b/tests/ui/cross-crate/auxiliary/aux-5521.rs diff --git a/tests/ui/issues/issue-5521.rs b/tests/ui/cross-crate/cross-crate-map-usage-5521.rs index 45896ae8128..ffce846be2c 100644 --- a/tests/ui/issues/issue-5521.rs +++ b/tests/ui/cross-crate/cross-crate-map-usage-5521.rs @@ -1,10 +1,9 @@ +// https://github.com/rust-lang/rust/issues/5521 //@ run-pass #![allow(dead_code)] -//@ aux-build:issue-5521.rs +//@ aux-build:aux-5521.rs - - -extern crate issue_5521 as foo; +extern crate aux_5521 as foo; fn bar(a: foo::map) { if false { diff --git a/tests/ui/issues/issue-46332.rs b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.rs index bed74e3138a..3dd686a66b0 100644 --- a/tests/ui/issues/issue-46332.rs +++ b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/46332 // Original Levenshtein distance for both of this is 1. We improved accuracy with // additional case insensitive comparison. diff --git a/tests/ui/issues/issue-46332.stderr b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr index 8c0c1dfa6ee..502f8151878 100644 --- a/tests/ui/issues/issue-46332.stderr +++ b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr @@ -1,5 +1,5 @@ error[E0422]: cannot find struct, variant or union type `TyUInt` in this scope - --> $DIR/issue-46332.rs:9:5 + --> $DIR/typo-suggestion-improvement-46332.rs:10:5 | LL | struct TyUint {} | ------------- similarly named struct `TyUint` defined here diff --git a/tests/ui/issues/issue-6892.rs b/tests/ui/drop/destructor-run-for-let-ignore-6892.rs index 7d99aef4ac5..0fcf133c2b1 100644 --- a/tests/ui/issues/issue-6892.rs +++ b/tests/ui/drop/destructor-run-for-let-ignore-6892.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/6892 //@ run-pass #![allow(dead_code)] // Ensures that destructors are run for expressions of the form "let _ = e;" diff --git a/tests/ui/issues/issue-16151.rs b/tests/ui/drop/drop-count-assertion-16151.rs index b18108e0a8a..ede6bc23e73 100644 --- a/tests/ui/issues/issue-16151.rs +++ b/tests/ui/drop/drop-count-assertion-16151.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/16151 //@ run-pass // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint diff --git a/tests/ui/issues/issue-20939.rs b/tests/ui/dyn-compatibility/dyn-compatible-trait-implementation-20939.rs index c0c22297897..c7938b275e9 100644 --- a/tests/ui/issues/issue-20939.rs +++ b/tests/ui/dyn-compatibility/dyn-compatible-trait-implementation-20939.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/20939 trait Foo {} impl<'a> Foo for dyn Foo + 'a {} diff --git a/tests/ui/issues/issue-20939.stderr b/tests/ui/dyn-compatibility/dyn-compatible-trait-implementation-20939.stderr index 00357155c8a..196d8b6a880 100644 --- a/tests/ui/issues/issue-20939.stderr +++ b/tests/ui/dyn-compatibility/dyn-compatible-trait-implementation-20939.stderr @@ -1,5 +1,5 @@ error[E0371]: the object type `(dyn Foo + 'a)` automatically implements the trait `Foo` - --> $DIR/issue-20939.rs:3:1 + --> $DIR/dyn-compatible-trait-implementation-20939.rs:4:1 | LL | impl<'a> Foo for dyn Foo + 'a {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Foo + 'a)` automatically implements trait `Foo` diff --git a/tests/ui/explicit-tail-calls/higher-ranked-arg.rs b/tests/ui/explicit-tail-calls/higher-ranked-arg.rs new file mode 100644 index 00000000000..e60686ab511 --- /dev/null +++ b/tests/ui/explicit-tail-calls/higher-ranked-arg.rs @@ -0,0 +1,13 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/144826>. +//@ check-pass + +#![feature(explicit_tail_calls)] +#![expect(incomplete_features)] + +fn foo(x: fn(&i32)) { + become bar(x); +} + +fn bar(_: fn(&i32)) {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs new file mode 100644 index 00000000000..111ae849c0f --- /dev/null +++ b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs @@ -0,0 +1,16 @@ +#![feature(explicit_tail_calls)] +#![expect(incomplete_features)] + +fn link(x: &str) -> &'static str { + become passthrough(x); + //~^ ERROR lifetime may not live long enough +} + +fn passthrough<T>(t: T) -> T { t } + +fn main() { + let x = String::from("hello, world"); + let s = link(&x); + drop(x); + println!("{s}"); +} diff --git a/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.stderr b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.stderr new file mode 100644 index 00000000000..26a8e1f0122 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/ret-ty-borrowck-constraints.rs:5:5 + | +LL | fn link(x: &str) -> &'static str { + | - let's call the lifetime of this reference `'1` +LL | become passthrough(x); + | ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/issues/issue-36075.rs b/tests/ui/generics/unused-type-parameter-regression-36075.rs index a563332ad78..4d6eb617b59 100644 --- a/tests/ui/issues/issue-36075.rs +++ b/tests/ui/generics/unused-type-parameter-regression-36075.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/36075 //@ check-pass #![allow(dead_code)] trait DeclarationParser { diff --git a/tests/ui/issues/issue-9188.rs b/tests/ui/issues/issue-9188.rs deleted file mode 100644 index df2f90a0f16..00000000000 --- a/tests/ui/issues/issue-9188.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -//@ aux-build:issue-9188.rs - - -extern crate issue_9188; - -pub fn main() { - let a = issue_9188::bar(); - let b = issue_9188::foo::<isize>(); - assert_eq!(*a, *b); -} diff --git a/tests/ui/issues/issue-23966.rs b/tests/ui/iterators/fold-iterator-error-23966.rs index 5fdec28ac2c..970c943da0b 100644 --- a/tests/ui/issues/issue-23966.rs +++ b/tests/ui/iterators/fold-iterator-error-23966.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/23966 fn main() { "".chars().fold(|_, _| (), ()); //~^ ERROR E0277 diff --git a/tests/ui/issues/issue-23966.stderr b/tests/ui/iterators/fold-iterator-error-23966.stderr index 3f7a4fa312f..15249a93597 100644 --- a/tests/ui/issues/issue-23966.stderr +++ b/tests/ui/iterators/fold-iterator-error-23966.stderr @@ -1,5 +1,5 @@ error[E0277]: expected a `FnMut(_, char)` closure, found `()` - --> $DIR/issue-23966.rs:2:32 + --> $DIR/fold-iterator-error-23966.rs:3:32 | LL | "".chars().fold(|_, _| (), ()); | ---- ^^ expected an `FnMut(_, char)` closure, found `()` diff --git a/tests/ui/issues/issue-15735.rs b/tests/ui/lifetimes/lifetime-inference-miss-15735.rs index f5b3803f155..c75d59a2f4b 100644 --- a/tests/ui/issues/issue-15735.rs +++ b/tests/ui/lifetimes/lifetime-inference-miss-15735.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/15735 //@ check-pass #![allow(dead_code)] struct A<'a> { diff --git a/tests/ui/issues/issue-75704.rs b/tests/ui/loops/infinite-loop-simplify-cfg-75704.rs index 1672bf0b4c3..8bc5fba7a68 100644 --- a/tests/ui/issues/issue-75704.rs +++ b/tests/ui/loops/infinite-loop-simplify-cfg-75704.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/75704 // Caused an infinite loop during SimlifyCfg MIR transform previously. // //@ build-pass diff --git a/tests/ui/issues/issue-19100.fixed b/tests/ui/match/unreachable-pattern-if-variant-not-imported-19100.fixed index 1162490048c..40c92322519 100644 --- a/tests/ui/issues/issue-19100.fixed +++ b/tests/ui/match/unreachable-pattern-if-variant-not-imported-19100.fixed @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/19100 //@ run-rustfix #![allow(non_snake_case)] diff --git a/tests/ui/issues/issue-19100.rs b/tests/ui/match/unreachable-pattern-if-variant-not-imported-19100.rs index fefed0daa72..9ef6fd77b50 100644 --- a/tests/ui/issues/issue-19100.rs +++ b/tests/ui/match/unreachable-pattern-if-variant-not-imported-19100.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/19100 //@ run-rustfix #![allow(non_snake_case)] diff --git a/tests/ui/issues/issue-19100.stderr b/tests/ui/match/unreachable-pattern-if-variant-not-imported-19100.stderr index ebbf083b7de..7356a4a003b 100644 --- a/tests/ui/issues/issue-19100.stderr +++ b/tests/ui/match/unreachable-pattern-if-variant-not-imported-19100.stderr @@ -1,5 +1,5 @@ error[E0170]: pattern binding `Bar` is named the same as one of the variants of the type `Foo` - --> $DIR/issue-19100.rs:17:1 + --> $DIR/unreachable-pattern-if-variant-not-imported-19100.rs:18:1 | LL | Bar if true | ^^^ help: to match on the variant, qualify the path: `Foo::Bar` @@ -7,7 +7,7 @@ LL | Bar if true = note: `#[deny(bindings_with_variant_name)]` on by default error[E0170]: pattern binding `Baz` is named the same as one of the variants of the type `Foo` - --> $DIR/issue-19100.rs:21:1 + --> $DIR/unreachable-pattern-if-variant-not-imported-19100.rs:22:1 | LL | Baz if false | ^^^ help: to match on the variant, qualify the path: `Foo::Baz` diff --git a/tests/ui/issues/issue-22684.rs b/tests/ui/methods/trait-method-resolution-over-inherent-22684.rs index a5b042706ed..9f317b576e6 100644 --- a/tests/ui/issues/issue-22684.rs +++ b/tests/ui/methods/trait-method-resolution-over-inherent-22684.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/22684 mod foo { pub struct Foo; impl Foo { diff --git a/tests/ui/issues/issue-22684.stderr b/tests/ui/methods/trait-method-resolution-over-inherent-22684.stderr index e2ca54caeac..0ab7701fa9e 100644 --- a/tests/ui/issues/issue-22684.stderr +++ b/tests/ui/methods/trait-method-resolution-over-inherent-22684.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-22684.rs:17:17 + --> $DIR/trait-method-resolution-over-inherent-22684.rs:18:17 | LL | let _: () = foo::Foo.bar(); | -- ^^^^^^^^^^^^^^ expected `()`, found `bool` diff --git a/tests/ui/issues/issue-24352.rs b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.rs index 5c8246d179f..eb632398c62 100644 --- a/tests/ui/issues/issue-24352.rs +++ b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/24352 fn main() { 1.0f64 - 1.0; 1.0f64 - 1 //~ ERROR E0277 diff --git a/tests/ui/issues/issue-24352.stderr b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr index 3e0f812b5c7..7dc1fa777fc 100644 --- a/tests/ui/issues/issue-24352.stderr +++ b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr @@ -1,5 +1,5 @@ error[E0277]: cannot subtract `{integer}` from `f64` - --> $DIR/issue-24352.rs:3:12 + --> $DIR/float-integer-subtraction-error-24352.rs:4:12 | LL | 1.0f64 - 1 | ^ no implementation for `f64 - {integer}` diff --git a/tests/ui/issues/issue-50585.rs b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.rs index ca2ece8d53b..4abef0bee81 100644 --- a/tests/ui/issues/issue-50585.rs +++ b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/50585 fn main() { |y: Vec<[(); for x in 0..2 {}]>| {}; //~^ ERROR mismatched types diff --git a/tests/ui/issues/issue-50585.stderr b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.stderr index 7e83ea35fbb..d60d97a02ab 100644 --- a/tests/ui/issues/issue-50585.stderr +++ b/tests/ui/mismatched_types/for-loop-in-vec-type-mismatchrs-50585.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-50585.rs:2:18 + --> $DIR/for-loop-in-vec-type-mismatchrs-50585.rs:3:18 | LL | |y: Vec<[(); for x in 0..2 {}]>| {}; | ^^^^^^^^^^^^^^^^ expected `usize`, found `()` diff --git a/tests/ui/issues/issue-48364.rs b/tests/ui/mismatched_types/starts-with-stringify-type-mismatch-48364.rs index 14ee75e7c9c..13ba8b1e59c 100644 --- a/tests/ui/issues/issue-48364.rs +++ b/tests/ui/mismatched_types/starts-with-stringify-type-mismatch-48364.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/48364 fn foo() -> bool { b"".starts_with(stringify!(foo)) //~^ ERROR mismatched types diff --git a/tests/ui/issues/issue-48364.stderr b/tests/ui/mismatched_types/starts-with-stringify-type-mismatch-48364.stderr index 74bfa1e0693..bb767d50bb0 100644 --- a/tests/ui/issues/issue-48364.stderr +++ b/tests/ui/mismatched_types/starts-with-stringify-type-mismatch-48364.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-48364.rs:2:21 + --> $DIR/starts-with-stringify-type-mismatch-48364.rs:3:21 | LL | b"".starts_with(stringify!(foo)) | ----------- ^^^^^^^^^^^^^^^ expected `&[u8]`, found `&str` diff --git a/tests/ui/issues/issue-32797.rs b/tests/ui/modules/circular-module-imports-32797.rs index 470d661cb28..5a2f2990795 100644 --- a/tests/ui/issues/issue-32797.rs +++ b/tests/ui/modules/circular-module-imports-32797.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/32797 //@ check-pass pub use bar::*; diff --git a/tests/ui/issues/issue-17385.rs b/tests/ui/moves/matching-partially-moved-value-17385.rs index 7400aadb059..c50fe048bfb 100644 --- a/tests/ui/issues/issue-17385.rs +++ b/tests/ui/moves/matching-partially-moved-value-17385.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/17385 struct X(isize); enum Enum { diff --git a/tests/ui/issues/issue-17385.stderr b/tests/ui/moves/matching-partially-moved-value-17385.stderr index 3c451a859e9..906f7868bcc 100644 --- a/tests/ui/issues/issue-17385.stderr +++ b/tests/ui/moves/matching-partially-moved-value-17385.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `foo` - --> $DIR/issue-17385.rs:18:5 + --> $DIR/matching-partially-moved-value-17385.rs:19:5 | LL | let foo = X(1); | --- move occurs because `foo` has type `X`, which does not implement the `Copy` trait @@ -9,7 +9,7 @@ LL | match foo { | ^^^^^^^^^ value used here after move | note: if `X` implemented `Clone`, you could clone the value - --> $DIR/issue-17385.rs:1:1 + --> $DIR/matching-partially-moved-value-17385.rs:2:1 | LL | struct X(isize); | ^^^^^^^^ consider implementing `Clone` for this type @@ -18,7 +18,7 @@ LL | drop(foo); | --- you could clone this value error[E0382]: use of moved value: `e` - --> $DIR/issue-17385.rs:25:11 + --> $DIR/matching-partially-moved-value-17385.rs:26:11 | LL | let e = Enum::Variant2; | - move occurs because `e` has type `Enum`, which does not implement the `Copy` trait @@ -28,7 +28,7 @@ LL | match e { | ^ value used here after move | note: if `Enum` implemented `Clone`, you could clone the value - --> $DIR/issue-17385.rs:3:1 + --> $DIR/matching-partially-moved-value-17385.rs:4:1 | LL | enum Enum { | ^^^^^^^^^ consider implementing `Clone` for this type diff --git a/tests/ui/issues/issue-32805.rs b/tests/ui/numbers-arithmetic/f32-literal-rounding-32805.rs index 717c00a248a..59efdb9a1aa 100644 --- a/tests/ui/issues/issue-32805.rs +++ b/tests/ui/numbers-arithmetic/f32-literal-rounding-32805.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/32805 //@ run-pass fn const_mir() -> f32 { 9007199791611905.0 } diff --git a/tests/ui/parser/attribute-on-empty.rs b/tests/ui/parser/attribute-on-empty.rs new file mode 100644 index 00000000000..5932377f73e --- /dev/null +++ b/tests/ui/parser/attribute-on-empty.rs @@ -0,0 +1,29 @@ +//! Regression test for: <https://github.com/rust-lang/rust/issues/144132> +//! <https://github.com/rust-lang/rust/issues/135017> + +struct Baz<const N: usize>(i32); + +fn main() { + let _: Baz<#[cfg(any())]> = todo!(); + //~^ ERROR attributes cannot be applied here +} + +fn f(_param: #[attr]) {} +//~^ ERROR attributes cannot be applied to a function parameter's type +//~| ERROR expected type, found `)` + +fn g() -> #[attr] { 0 } +//~^ ERROR attributes cannot be applied here + +struct S { + field: #[attr], + //~^ ERROR attributes cannot be applied here + field1: (#[attr], i32), + //~^ ERROR attributes cannot be applied here +} + +type Tuple = (#[attr], String); +//~^ ERROR attributes cannot be applied here + +impl #[attr] {} +//~^ ERROR attributes cannot be applied here diff --git a/tests/ui/parser/attribute-on-empty.stderr b/tests/ui/parser/attribute-on-empty.stderr new file mode 100644 index 00000000000..7c4806c8704 --- /dev/null +++ b/tests/ui/parser/attribute-on-empty.stderr @@ -0,0 +1,52 @@ +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:7:16 + | +LL | let _: Baz<#[cfg(any())]> = todo!(); + | - ^^^^^^^^^^^^^ attributes are not allowed here + | | + | while parsing the type for `_` + +error: attributes cannot be applied to a function parameter's type + --> $DIR/attribute-on-empty.rs:11:14 + | +LL | fn f(_param: #[attr]) {} + | ^^^^^^^ attributes are not allowed here + +error: expected type, found `)` + --> $DIR/attribute-on-empty.rs:11:21 + | +LL | fn f(_param: #[attr]) {} + | ^ expected type + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:15:11 + | +LL | fn g() -> #[attr] { 0 } + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:19:12 + | +LL | field: #[attr], + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:21:14 + | +LL | field1: (#[attr], i32), + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:25:15 + | +LL | type Tuple = (#[attr], String); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:28:6 + | +LL | impl #[attr] {} + | ^^^^^^^ attributes are not allowed here + +error: aborting due to 8 previous errors + diff --git a/tests/ui/parser/attribute-on-type.fixed b/tests/ui/parser/attribute-on-type.fixed new file mode 100644 index 00000000000..5024bfdc2bc --- /dev/null +++ b/tests/ui/parser/attribute-on-type.fixed @@ -0,0 +1,58 @@ +//! Regression test for: <https://github.com/rust-lang/rust/issues/144132> +//! <https://github.com/rust-lang/rust/issues/135017> + +//@ run-rustfix + +#![allow(dead_code, unused_variables)] + +struct Foo<T>(T); +struct Bar<'a>(&'a i32); +struct Baz<const N: usize>(i32); + +fn main() { + let foo: Foo<i32> = Foo(2i32); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: &'static str = "123"; + //~^ ERROR attributes cannot be applied to types + + let _: Bar<'static> = Bar(&123); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Baz<42> = Baz(42); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Foo<String> = Foo(String::new()); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Bar<'static> = Bar(&456); + //~^ ERROR attributes cannot be applied to generic arguments + + let _generic: Box<i32> = Box::new(1); + //~^ ERROR attributes cannot be applied to generic arguments + + let _assignment: i32 = *Box::new(1); + //~^ ERROR attributes cannot be applied to types + + let _complex: Vec<String> = vec![]; + //~^ ERROR attributes cannot be applied to generic arguments + + let _nested: Box<Vec<u64>> = Box::new(vec![]); + //~^ ERROR attributes cannot be applied to generic arguments +} + +fn g() -> i32 { 0 } +//~^ ERROR attributes cannot be applied to types + +struct S { + field: i32, + //~^ ERROR attributes cannot be applied to types + field1: (i32, i32), + //~^ ERROR attributes cannot be applied to types +} + +type Tuple = (i32, String); +//~^ ERROR attributes cannot be applied to types + +impl S {} +//~^ ERROR attributes cannot be applied to types diff --git a/tests/ui/parser/attribute-on-type.rs b/tests/ui/parser/attribute-on-type.rs new file mode 100644 index 00000000000..196d322bdf8 --- /dev/null +++ b/tests/ui/parser/attribute-on-type.rs @@ -0,0 +1,58 @@ +//! Regression test for: <https://github.com/rust-lang/rust/issues/144132> +//! <https://github.com/rust-lang/rust/issues/135017> + +//@ run-rustfix + +#![allow(dead_code, unused_variables)] + +struct Foo<T>(T); +struct Bar<'a>(&'a i32); +struct Baz<const N: usize>(i32); + +fn main() { + let foo: Foo<#[cfg(not(wrong))] i32> = Foo(2i32); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: #[attr] &'static str = "123"; + //~^ ERROR attributes cannot be applied to types + + let _: Bar<#[cfg(any())] 'static> = Bar(&123); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Baz<#[cfg(any())] 42> = Baz(42); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Bar<#[cfg(any())] 'static> = Bar(&456); + //~^ ERROR attributes cannot be applied to generic arguments + + let _generic: Box<#[attr] i32> = Box::new(1); + //~^ ERROR attributes cannot be applied to generic arguments + + let _assignment: #[attr] i32 = *Box::new(1); + //~^ ERROR attributes cannot be applied to types + + let _complex: Vec<#[derive(Debug)] String> = vec![]; + //~^ ERROR attributes cannot be applied to generic arguments + + let _nested: Box<Vec<#[cfg(feature = "test")] u64>> = Box::new(vec![]); + //~^ ERROR attributes cannot be applied to generic arguments +} + +fn g() -> #[attr] i32 { 0 } +//~^ ERROR attributes cannot be applied to types + +struct S { + field: #[attr] i32, + //~^ ERROR attributes cannot be applied to types + field1: (#[attr] i32, i32), + //~^ ERROR attributes cannot be applied to types +} + +type Tuple = (#[attr] i32, String); +//~^ ERROR attributes cannot be applied to types + +impl #[attr] S {} +//~^ ERROR attributes cannot be applied to types diff --git a/tests/ui/parser/attribute-on-type.stderr b/tests/ui/parser/attribute-on-type.stderr new file mode 100644 index 00000000000..603c7e2be51 --- /dev/null +++ b/tests/ui/parser/attribute-on-type.stderr @@ -0,0 +1,92 @@ +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:13:18 + | +LL | let foo: Foo<#[cfg(not(wrong))] i32> = Foo(2i32); + | ^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:16:12 + | +LL | let _: #[attr] &'static str = "123"; + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:19:16 + | +LL | let _: Bar<#[cfg(any())] 'static> = Bar(&123); + | ^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:22:16 + | +LL | let _: Baz<#[cfg(any())] 42> = Baz(42); + | ^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:25:16 + | +LL | let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); + | ^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:28:16 + | +LL | let _: Bar<#[cfg(any())] 'static> = Bar(&456); + | ^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:31:23 + | +LL | let _generic: Box<#[attr] i32> = Box::new(1); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:34:22 + | +LL | let _assignment: #[attr] i32 = *Box::new(1); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:37:23 + | +LL | let _complex: Vec<#[derive(Debug)] String> = vec![]; + | ^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:40:26 + | +LL | let _nested: Box<Vec<#[cfg(feature = "test")] u64>> = Box::new(vec![]); + | ^^^^^^^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:44:11 + | +LL | fn g() -> #[attr] i32 { 0 } + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:48:12 + | +LL | field: #[attr] i32, + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:50:14 + | +LL | field1: (#[attr] i32, i32), + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:54:15 + | +LL | type Tuple = (#[attr] i32, String); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:57:6 + | +LL | impl #[attr] S {} + | ^^^^^^^ attributes are not allowed here + +error: aborting due to 15 previous errors + diff --git a/tests/ui/parser/issues/issue-103143.rs b/tests/ui/parser/issues/issue-103143.rs index a584274c405..90f10fc1a08 100644 --- a/tests/ui/parser/issues/issue-103143.rs +++ b/tests/ui/parser/issues/issue-103143.rs @@ -1,5 +1,5 @@ fn main() { x::<#[a]y::<z>> - //~^ ERROR invalid const generic expression + //~^ ERROR attributes cannot be applied to generic arguments //~| ERROR cannot find value `x` in this scope } diff --git a/tests/ui/parser/issues/issue-103143.stderr b/tests/ui/parser/issues/issue-103143.stderr index 4035c69afa7..168a2077396 100644 --- a/tests/ui/parser/issues/issue-103143.stderr +++ b/tests/ui/parser/issues/issue-103143.stderr @@ -1,13 +1,8 @@ -error: invalid const generic expression - --> $DIR/issue-103143.rs:2:13 +error: attributes cannot be applied to generic arguments + --> $DIR/issue-103143.rs:2:9 | LL | x::<#[a]y::<z>> - | ^^^^^^ - | -help: expressions must be enclosed in braces to be used as const generic arguments - | -LL | x::<#[a]{ y::<z> }> - | + + + | ^^^^ attributes are not allowed here error[E0425]: cannot find value `x` in this scope --> $DIR/issue-103143.rs:2:5 diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed index a851300a982..40028307a8c 100644 --- a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed @@ -1,7 +1,9 @@ // Regression test for issues #100790 and #106439. //@ run-rustfix -pub struct Example(#[allow(dead_code)] usize) +#![allow(dead_code)] + +pub struct Example(usize) where (): Sized; //~^^^ ERROR where clauses are not allowed before tuple struct bodies diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs index 10f435859f1..d8dbb4238d2 100644 --- a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs @@ -1,10 +1,12 @@ // Regression test for issues #100790 and #106439. //@ run-rustfix +#![allow(dead_code)] + pub struct Example where (): Sized, -(#[allow(dead_code)] usize); +(usize); //~^^^ ERROR where clauses are not allowed before tuple struct bodies struct _Demo diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr index ddbf237e866..66dadd9fd4c 100644 --- a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr @@ -1,23 +1,23 @@ error: where clauses are not allowed before tuple struct bodies - --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:5:1 + --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:7:1 | LL | pub struct Example | ------- while parsing this tuple struct LL | / where LL | | (): Sized, | |______________^ unexpected where clause -LL | (#[allow(dead_code)] usize); - | --------------------------- the struct body +LL | (usize); + | ------- the struct body | help: move the body before the where clause | -LL ~ pub struct Example(#[allow(dead_code)] usize) +LL ~ pub struct Example(usize) LL | where LL ~ (): Sized; | error: where clauses are not allowed before tuple struct bodies - --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:11:1 + --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:13:1 | LL | struct _Demo | ----- while parsing this tuple struct diff --git a/tests/ui/issues/issue-3763.rs b/tests/ui/privacy/private-field-access-violation-3763.rs index 893009a2cd9..3fc2337086d 100644 --- a/tests/ui/issues/issue-3763.rs +++ b/tests/ui/privacy/private-field-access-violation-3763.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/3763 // Regression test for #3763 mod my_mod { diff --git a/tests/ui/issues/issue-3763.stderr b/tests/ui/privacy/private-field-access-violation-3763.stderr index d101e4c33ad..6ba83dc4d78 100644 --- a/tests/ui/issues/issue-3763.stderr +++ b/tests/ui/privacy/private-field-access-violation-3763.stderr @@ -1,17 +1,17 @@ error[E0616]: field `priv_field` of struct `MyStruct` is private - --> $DIR/issue-3763.rs:17:32 + --> $DIR/private-field-access-violation-3763.rs:18:32 | LL | let _woohoo = (&my_struct).priv_field; | ^^^^^^^^^^ private field error[E0616]: field `priv_field` of struct `MyStruct` is private - --> $DIR/issue-3763.rs:20:41 + --> $DIR/private-field-access-violation-3763.rs:21:41 | LL | let _woohoo = (Box::new(my_struct)).priv_field; | ^^^^^^^^^^ private field error[E0624]: method `happyfun` is private - --> $DIR/issue-3763.rs:23:18 + --> $DIR/private-field-access-violation-3763.rs:24:18 | LL | fn happyfun(&self) {} | ------------------ private method defined here @@ -20,7 +20,7 @@ LL | (&my_struct).happyfun(); | ^^^^^^^^ private method error[E0624]: method `happyfun` is private - --> $DIR/issue-3763.rs:25:27 + --> $DIR/private-field-access-violation-3763.rs:26:27 | LL | fn happyfun(&self) {} | ------------------ private method defined here @@ -29,7 +29,7 @@ LL | (Box::new(my_struct)).happyfun(); | ^^^^^^^^ private method error[E0616]: field `priv_field` of struct `MyStruct` is private - --> $DIR/issue-3763.rs:26:26 + --> $DIR/private-field-access-violation-3763.rs:27:26 | LL | let nope = my_struct.priv_field; | ^^^^^^^^^^ private field diff --git a/tests/ui/issues/issue-2281-part1.rs b/tests/ui/resolve/cannot-find-value-in-scope-22811.rs index 8340ade2239..fc07ae5e60e 100644 --- a/tests/ui/issues/issue-2281-part1.rs +++ b/tests/ui/resolve/cannot-find-value-in-scope-22811.rs @@ -1 +1,2 @@ +// https://github.com/rust-lang/rust/issues/22811 fn main() { println!("{}", foobar); } //~ ERROR cannot find value `foobar` in this scope diff --git a/tests/ui/issues/issue-2281-part1.stderr b/tests/ui/resolve/cannot-find-value-in-scope-22811.stderr index 47a1ef8cc02..529fd7e8f49 100644 --- a/tests/ui/issues/issue-2281-part1.stderr +++ b/tests/ui/resolve/cannot-find-value-in-scope-22811.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `foobar` in this scope - --> $DIR/issue-2281-part1.rs:1:28 + --> $DIR/cannot-find-value-in-scope-22811.rs:2:28 | LL | fn main() { println!("{}", foobar); } | ^^^^^^ not found in this scope diff --git a/tests/ui/issues/issue-33293.rs b/tests/ui/resolve/unresolved-module-error-33293.rs index 115ae3aad20..354f9914d44 100644 --- a/tests/ui/issues/issue-33293.rs +++ b/tests/ui/resolve/unresolved-module-error-33293.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/33293 fn main() { match 0 { aaa::bbb(_) => () diff --git a/tests/ui/issues/issue-33293.stderr b/tests/ui/resolve/unresolved-module-error-33293.stderr index a82813194d7..28528148387 100644 --- a/tests/ui/issues/issue-33293.stderr +++ b/tests/ui/resolve/unresolved-module-error-33293.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve: use of unresolved module or unlinked crate `aaa` - --> $DIR/issue-33293.rs:3:9 + --> $DIR/unresolved-module-error-33293.rs:4:9 | LL | aaa::bbb(_) => () | ^^^ use of unresolved module or unlinked crate `aaa` diff --git a/tests/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs b/tests/ui/structs/tuple-struct-field-naming-47073.rs index 6cd1f144359..6cf27e55c4b 100644 --- a/tests/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs +++ b/tests/ui/structs/tuple-struct-field-naming-47073.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/47073 type Guilty = bool; type FineDollars = u32; diff --git a/tests/ui/issues/issue-47073-zero-padded-tuple-struct-indices.stderr b/tests/ui/structs/tuple-struct-field-naming-47073.stderr index 0a6fe24d5e3..efbdaeca4ea 100644 --- a/tests/ui/issues/issue-47073-zero-padded-tuple-struct-indices.stderr +++ b/tests/ui/structs/tuple-struct-field-naming-47073.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `00` on type `Verdict` - --> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:8:30 + --> $DIR/tuple-struct-field-naming-47073.rs:9:30 | LL | let _condemned = justice.00; | ^^ unknown field @@ -11,7 +11,7 @@ LL + let _condemned = justice.0; | error[E0609]: no field `001` on type `Verdict` - --> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:10:31 + --> $DIR/tuple-struct-field-naming-47073.rs:11:31 | LL | let _punishment = justice.001; | ^^^ unknown field diff --git a/tests/ui/issues/auxiliary/issue-9188.rs b/tests/ui/symbol-names/auxiliary/aux-9188.rs index 3bc5697a1a6..3bc5697a1a6 100644 --- a/tests/ui/issues/auxiliary/issue-9188.rs +++ b/tests/ui/symbol-names/auxiliary/aux-9188.rs diff --git a/tests/ui/symbol-names/same-symbol-name-for-inner-statics-9188.rs b/tests/ui/symbol-names/same-symbol-name-for-inner-statics-9188.rs new file mode 100644 index 00000000000..a1014bb813f --- /dev/null +++ b/tests/ui/symbol-names/same-symbol-name-for-inner-statics-9188.rs @@ -0,0 +1,11 @@ +// https://github.com/rust-lang/rust/issues/9188 +//@ run-pass +//@ aux-build:aux-9188.rs + +extern crate aux_9188 as lib; + +pub fn main() { + let a = lib::bar(); + let b = lib::foo::<isize>(); + assert_eq!(*a, *b); +} diff --git a/tests/ui/issues/issue-72839-error-overflow.rs b/tests/ui/trait-bounds/trait-selection-overflow-prevention-72839.rs index 6562d228409..436657e3de5 100644 --- a/tests/ui/issues/issue-72839-error-overflow.rs +++ b/tests/ui/trait-bounds/trait-selection-overflow-prevention-72839.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/72839 // Regression test for issue #72839 // Tests that we do not overflow during trait selection after // a type error occurs diff --git a/tests/ui/issues/issue-72839-error-overflow.stderr b/tests/ui/trait-bounds/trait-selection-overflow-prevention-72839.stderr index 35be632f579..da7500f77e1 100644 --- a/tests/ui/issues/issue-72839-error-overflow.stderr +++ b/tests/ui/trait-bounds/trait-selection-overflow-prevention-72839.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `missing_var` in this scope - --> $DIR/issue-72839-error-overflow.rs:18:8 + --> $DIR/trait-selection-overflow-prevention-72839.rs:19:8 | LL | if missing_var % 8 == 0 {} | ^^^^^^^^^^^ not found in this scope diff --git a/tests/ui/issues/issue-47638.rs b/tests/ui/trait-objects/trait-object-lifetime-conversion-47638.rs index e5a51ce0c06..c70dc74f3e5 100644 --- a/tests/ui/issues/issue-47638.rs +++ b/tests/ui/trait-objects/trait-object-lifetime-conversion-47638.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/47638 //@ run-pass #![allow(unused_variables)] fn id<'c, 'b>(f: &'c &'b dyn Fn(&i32)) -> &'c &'b dyn Fn(&'static i32) { diff --git a/tests/ui/traits/const-traits/const-closure-issue-125866-error.rs b/tests/ui/traits/const-traits/const-closure-issue-125866-error.rs new file mode 100644 index 00000000000..7a44920bb72 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-issue-125866-error.rs @@ -0,0 +1,24 @@ +#![allow(incomplete_features)] +#![feature(const_closures, const_trait_impl)] + +const fn create_array<const N: usize>(mut f: impl FnMut(usize) -> u32 + Copy) -> [u32; N] { + let mut array = [0; N]; + let mut i = 0; + loop { + array[i] = f(i); + //~^ ERROR the trait bound `impl FnMut(usize) -> u32 + Copy: [const] FnMut(usize)` is not satisfied [E0277] + i += 1; + if i == N { + break; + } + } + array +} + +fn main() { + let x = create_array(const |i| 2 * i as u32); + assert_eq!(x, [0, 2, 4, 6, 8]); + + let y = create_array(const |i| 2 * i as u32 + 1); + assert_eq!(y, [1, 3, 5, 7, 9]); +} diff --git a/tests/ui/traits/const-traits/const-closure-issue-125866-error.stderr b/tests/ui/traits/const-traits/const-closure-issue-125866-error.stderr new file mode 100644 index 00000000000..1eadd1d8426 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-issue-125866-error.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `impl FnMut(usize) -> u32 + Copy: [const] FnMut(usize)` is not satisfied + --> $DIR/const-closure-issue-125866-error.rs:8:22 + | +LL | array[i] = f(i); + | - ^ + | | + | required by a bound introduced by this call + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-closure-issue-125866-pass.rs b/tests/ui/traits/const-traits/const-closure-issue-125866-pass.rs new file mode 100644 index 00000000000..af7375172e6 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-issue-125866-pass.rs @@ -0,0 +1,25 @@ +//@ check-pass + +#![allow(incomplete_features)] +#![feature(const_closures, const_trait_impl)] + +const fn create_array<const N: usize>(mut f: impl [const] FnMut(usize) -> u32 + Copy) -> [u32; N] { + let mut array = [0; N]; + let mut i = 0; + loop { + array[i] = f(i); + i += 1; + if i == N { + break; + } + } + array +} + +fn main() { + let x = create_array(const |i| 2 * i as u32); + assert_eq!(x, [0, 2, 4, 6, 8]); + + let y = create_array(const |i| 2 * i as u32 + 1); + assert_eq!(y, [1, 3, 5, 7, 9]); +} diff --git a/tests/ui/traits/const-traits/const-fn-trait-bound-issue-104314.rs b/tests/ui/traits/const-traits/const-fn-trait-bound-issue-104314.rs new file mode 100644 index 00000000000..09c89c9cecd --- /dev/null +++ b/tests/ui/traits/const-traits/const-fn-trait-bound-issue-104314.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(const_trait_impl, const_destruct, const_clone)] + +use std::marker::Destruct; + +const fn f<T, F: [const] Fn(&T) -> T + [const] Destruct>(_: F) {} + +const fn g<T: [const] Clone>() { + f(<T as Clone>::clone); +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/feature-gate.rs b/tests/ui/traits/const-traits/feature-gate.rs index 5ad56ddcd33..c2918f0249b 100644 --- a/tests/ui/traits/const-traits/feature-gate.rs +++ b/tests/ui/traits/const-traits/feature-gate.rs @@ -13,6 +13,9 @@ impl const T for S {} const fn f<A: [const] T>() {} //[stock]~ ERROR const trait impls are experimental fn g<A: const T>() {} //[stock]~ ERROR const trait impls are experimental +const trait Trait {} //[stock]~ ERROR const trait impls are experimental +#[cfg(false)] const trait Trait {} //[stock]~ ERROR const trait impls are experimental + macro_rules! discard { ($ty:ty) => {} } discard! { impl [const] T } //[stock]~ ERROR const trait impls are experimental diff --git a/tests/ui/traits/const-traits/feature-gate.stock.stderr b/tests/ui/traits/const-traits/feature-gate.stock.stderr index f3ba3039a23..551c7ced7c1 100644 --- a/tests/ui/traits/const-traits/feature-gate.stock.stderr +++ b/tests/ui/traits/const-traits/feature-gate.stock.stderr @@ -29,7 +29,27 @@ LL | fn g<A: const T>() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:18:17 + --> $DIR/feature-gate.rs:16:1 + | +LL | const trait Trait {} + | ^^^^^ + | + = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information + = help: add `#![feature(const_trait_impl)]` 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]: const trait impls are experimental + --> $DIR/feature-gate.rs:17:15 + | +LL | #[cfg(false)] const trait Trait {} + | ^^^^^ + | + = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information + = help: add `#![feature(const_trait_impl)]` 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]: const trait impls are experimental + --> $DIR/feature-gate.rs:21:17 | LL | discard! { impl [const] T } | ^^^^^^^ @@ -39,7 +59,7 @@ LL | discard! { impl [const] T } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:19:17 + --> $DIR/feature-gate.rs:22:17 | LL | discard! { impl const T } | ^^^^^ @@ -58,6 +78,6 @@ LL | #[const_trait] = help: add `#![feature(const_trait_impl)]` 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 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/issue-20413.rs b/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.rs index 138a235e675..e8c27ff5cc8 100644 --- a/tests/ui/issues/issue-20413.rs +++ b/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/20413 trait Foo { fn answer(self); } diff --git a/tests/ui/issues/issue-20413.stderr b/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.stderr index 42f3cd2d062..72aff1b9ee8 100644 --- a/tests/ui/issues/issue-20413.stderr +++ b/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.stderr @@ -1,5 +1,5 @@ error[E0392]: type parameter `T` is never used - --> $DIR/issue-20413.rs:5:15 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:6:15 | LL | struct NoData<T>; | ^ unused type parameter @@ -8,14 +8,14 @@ LL | struct NoData<T>; = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo` - --> $DIR/issue-20413.rs:8:36 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:9:36 | LL | impl<T> Foo for T where NoData<T>: Foo { | ^^^ | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_impl_overflow_with_where_clause_20413`) note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` - --> $DIR/issue-20413.rs:8:9 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:9:9 | LL | impl<T> Foo for T where NoData<T>: Foo { | ^^^ ^ --- unsatisfied trait bound introduced here @@ -23,19 +23,19 @@ LL | impl<T> Foo for T where NoData<T>: Foo { = note: required for `NoData<T>` to implement `Foo` error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>: Bar` - --> $DIR/issue-20413.rs:27:42 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:28:42 | LL | impl<T> Bar for T where EvenLessData<T>: Baz { | ^^^ | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_impl_overflow_with_where_clause_20413`) note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz` - --> $DIR/issue-20413.rs:34:9 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:35:9 | LL | impl<T> Baz for T where AlmostNoData<T>: Bar { | ^^^ ^ --- unsatisfied trait bound introduced here note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar` - --> $DIR/issue-20413.rs:27:9 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:28:9 | LL | impl<T> Bar for T where EvenLessData<T>: Baz { | ^^^ ^ --- unsatisfied trait bound introduced here @@ -43,19 +43,19 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz { = note: required for `EvenLessData<T>` to implement `Baz` error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>: Baz` - --> $DIR/issue-20413.rs:34:42 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:35:42 | LL | impl<T> Baz for T where AlmostNoData<T>: Bar { | ^^^ | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_impl_overflow_with_where_clause_20413`) note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar` - --> $DIR/issue-20413.rs:27:9 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:28:9 | LL | impl<T> Bar for T where EvenLessData<T>: Baz { | ^^^ ^ --- unsatisfied trait bound introduced here note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz` - --> $DIR/issue-20413.rs:34:9 + --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:35:9 | LL | impl<T> Baz for T where AlmostNoData<T>: Bar { | ^^^ ^ --- unsatisfied trait bound introduced here diff --git a/tests/ui/issues/issue-51632-try-desugar-incompatible-types.rs b/tests/ui/try-trait/incompatible-types-with-question-mark-51632.rs index 35402dff675..4b2081d14d0 100644 --- a/tests/ui/issues/issue-51632-try-desugar-incompatible-types.rs +++ b/tests/ui/try-trait/incompatible-types-with-question-mark-51632.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/51632 #![allow(dead_code)] fn missing_discourses() -> Result<isize, ()> { diff --git a/tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr b/tests/ui/try-trait/incompatible-types-with-question-mark-51632.stderr index 99fce1eeea6..c624605d76a 100644 --- a/tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr +++ b/tests/ui/try-trait/incompatible-types-with-question-mark-51632.stderr @@ -1,5 +1,5 @@ error[E0308]: `?` operator has incompatible types - --> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5 + --> $DIR/incompatible-types-with-question-mark-51632.rs:9:5 | LL | fn forbidden_narratives() -> Result<isize, ()> { | ----------------- expected `Result<isize, ()>` because of return type diff --git a/triagebot.toml b/triagebot.toml index fefff78d64e..e8c15bb9bfd 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -287,6 +287,11 @@ trigger_files = [ "compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs", ] +[autolabel."F-explicit_tail_calls"] +trigger_files = [ + "tests/ui/explicit-tail-calls", +] + [autolabel."T-rustdoc-frontend"] trigger_labels = [ "A-rustdoc-search", |
