diff --git a/.mailmap b/.mailmap index fa30f07ad7310..4a3e39831e8a2 100644 --- a/.mailmap +++ b/.mailmap @@ -259,11 +259,9 @@ Gregor Peach Grzegorz Bartoszek Guanqun Lu Guillaume Gomez -Guillaume Gomez Guillaume Gomez -Guillaume Gomez ggomez -Guillaume Gomez ggomez -Guillaume Gomez Guillaume Gomez -Guillaume Gomez Guillaume Gomez +Guillaume Gomez +Guillaume Gomez +Guillaume Gomez gnzlbg hamidreza kalbasi Hanna Kruppe diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 75dab290d6031..0c0763aeb59fd 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -562,7 +562,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { // Don't hash unless necessary, because it's expensive. let opt_hir_hash = - if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; + if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; let delayed_resolver = Steal::new((resolver, krate)); mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 81160b6c3fed5..dd9ebf298b229 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -3,8 +3,8 @@ use std::ffi::c_uint; use std::{assert_matches, iter, ptr}; use rustc_abi::{ - AddressSpace, Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, - Size, WrappingRange, + AddressSpace, Align, BackendRepr, CVariadicStatus, Float, HasDataLayout, Integer, + NumScalableVectors, Primitive, Size, WrappingRange, }; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; @@ -23,6 +23,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; +use rustc_session::errors::feature_err; use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate}; @@ -288,6 +289,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]), sym::va_arg => { + let target = &self.cx.tcx.sess.target; + let stability = target.supports_c_variadic_definitions(); + if let CVariadicStatus::Unstable { feature } = stability + && !self.tcx.features().enabled(feature) + { + let msg = + format!("C-variadic function definitions on this target are unstable"); + feature_err(&*self.sess(), feature, span, msg).emit(); + } + let BackendRepr::Scalar(scalar) = result.layout.backend_repr else { bug!("the va_arg intrinsic does not support non-scalar types") }; diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 280cbb590781d..cceda09c701cc 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1212,9 +1212,10 @@ pub(crate) struct UnknownCTargetFeature<'a> { #[derive(Diagnostic)] #[diag("unstable feature specified for `-Ctarget-feature`: `{$feature}`")] -#[note("this feature is not stably supported; its behavior can change in the future")] +#[note("{$note}; its behavior can change in the future")] pub(crate) struct UnstableCTargetFeature<'a> { pub feature: &'a str, + pub note: &'a str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index b7d09d69aaecd..2572d21608213 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -62,16 +62,15 @@ pub(crate) fn from_target_feature_attr( feature: feature_str, reason, }); - } else if let Some(nightly_feature) = stability.requires_nightly() + } else if let Some(nightly_feature) = stability.requires_nightly(/* in_cfg */ false) && !rust_features.enabled(nightly_feature) { - feature_err( - &tcx.sess, - nightly_feature, - feature_span, - format!("the target feature `{feature}` is currently unstable"), - ) - .emit(); + let explain = if stability.is_cfg_stable_toggle_unstable() { + format!("the target feature `{feature}` is allowed in cfg but unstable otherwise") + } else { + format!("the target feature `{feature}` is currently unstable") + }; + feature_err(&tcx.sess, nightly_feature, feature_span, explain).emit(); } else { // Add this and the implied features. for &name in tcx.implied_target_features(feature) { @@ -315,12 +314,19 @@ pub fn cfg_target_feature<'a, const N: usize>( enabled: if enable { "enabled" } else { "disabled" }, reason, }); - } else if stability.requires_nightly().is_some() { + } else if stability.requires_nightly(/* in_cfg */ false).is_some() { // An unstable feature. Warn about using it. It makes little sense // to hard-error here since we just warn about fully unknown // features above. - sess.dcx() - .emit_warn(errors::UnstableCTargetFeature { feature: base_feature }); + let note = if stability.is_cfg_stable_toggle_unstable() { + "this feature is allowed in cfg but unstable otherwise" + } else { + "this feature is not stably supported" + }; + sess.dcx().emit_warn(errors::UnstableCTargetFeature { + feature: base_feature, + note, + }); } } } @@ -346,7 +352,8 @@ pub fn cfg_target_feature<'a, const N: usize>( // "forbidden" features. if allow_unstable || (gate.in_cfg() - && (sess.is_nightly_build() || gate.requires_nightly().is_none())) + && (sess.is_nightly_build() + || gate.requires_nightly(/* in_cfg */ true).is_none())) { Some(Symbol::intern(feature)) } else { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 65bb487c7b8eb..5af522486b1f6 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -563,8 +563,9 @@ declare_features! ( /// Allows defining gen blocks and `gen fn`. (unstable, gen_blocks, "1.75.0", Some(117078)), /// Allows using generics in more complex const expressions, based on definitional equality. - (unstable, generic_const_args, "1.95.0", Some(151972)), - /// Allows non-trivial generic constants which have to have wfness manually propagated to callers + (incomplete, generic_const_args, "1.95.0", Some(151972)), + /// Allows non-trivial generic constants which have to be shown to successfully evaluate + /// to a value by being part of an item signature. (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), @@ -626,7 +627,8 @@ declare_features! ( /// Allows additional const parameter types, such as [u8; 10] or user defined types. /// User defined types must not have fields more private than the type itself. (unstable, min_adt_const_params, "1.96.0", Some(154042)), - /// Enables the generic const args MVP (only bare paths, not arbitrary computation). + /// Enables the generic const args MVP (paths to type const items and constructors + /// for ADTs and primitives). (incomplete, min_generic_const_args, "1.84.0", Some(132980)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index fc504116101c9..9730e08c90c37 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -42,7 +42,7 @@ pub(crate) fn check_legal_trait_for_method_call( if tcx.is_lang_item(trait_id, LangItem::Drop) { let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) { errors::ExplicitDestructorCallSugg::Snippet { - lo: expr_span.shrink_to_lo(), + lo: expr_span.shrink_to_lo().to(receiver.shrink_to_lo()), hi: receiver.shrink_to_hi().to(expr_span.shrink_to_hi()), } } else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 50dc150a76668..eae0cb5cb4e2c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1007,10 +1007,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?def_id, ?container, ?container_id); match container { ty::AssocContainer::Trait => { + let arg_span = if let hir::Node::Expr(call_expr) = + self.tcx.parent_hir_node(hir_id) + && let hir::ExprKind::Call(_, args) = call_expr.kind + && let Some(first_arg) = args.first() + { + let mut arg = first_arg; + while let hir::ExprKind::AddrOf(_, _, inner) = arg.kind { + arg = inner; + } + Some(arg.span) + } else { + None + }; + if let Err(e) = callee::check_legal_trait_for_method_call( tcx, path_span, - None, + arg_span, span, container_id, self.body_id.to_def_id(), diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 170393f3b8179..63c7332893b81 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -36,7 +36,7 @@ impl Linker { Linker { dep_graph: tcx.dep_graph.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), - crate_hash: if tcx.needs_crate_hash() { + crate_hash: if tcx.sess.opts.incremental.is_some() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 492d21b3169a8..2d55078bc4d3e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -237,7 +237,7 @@ impl<'tcx> TyCtxt<'tcx> { attrs: &SortedMap, define_opaque: Option<&[(Span, LocalDefId)]>, ) -> Hashes { - if !self.needs_crate_hash() { + if !self.needs_hir_hash() { return Hashes { opt_hash_including_bodies: None, attrs_hash: None }; } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d1048a65a7be0..c25f5b402eb0d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1127,12 +1127,12 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn needs_crate_hash(self) -> bool { - // Why is the crate hash needed for these configurations? + pub fn needs_hir_hash(self) -> bool { + // Why is the hir hash needed for these configurations? // - debug_assertions: for the "fingerprint the result" check in // `rustc_query_impl::execution::execute_job`. // - incremental: for query lookups. - // - needs_metadata: for putting into crate metadata. + // - needs_metadata: it is included in the crate metadata through the crate_hash query // - instrument_coverage: for putting into coverage data (see // `hash_mir_source`). // - metrics_dir: metrics use the strict version hash in the filenames diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 4c307e8a6a3d7..524c9ce8ad5d7 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -9,8 +9,9 @@ use std::sync::Arc; use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind}; use rustc_ast::{ - self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem, - ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, TyAlias, + self as ast, AssocItem, AssocItemKind, Block, ConstItem, DUMMY_NODE_ID, Delegation, Fn, + ForeignItem, ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, + TyAlias, }; use rustc_attr_parsing::AttributeParser; use rustc_expand::base::ResolverExpand; @@ -168,7 +169,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id); let module = self.new_extern_module( parent, - ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))), + ModuleKind::Def( + def_kind, + def_id, + DUMMY_NODE_ID, + Some(self.tcx.item_name(def_id)), + ), expn_id, self.def_span(def_id), // FIXME: Account for `#[no_implicit_prelude]` attributes. @@ -251,7 +257,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Any inherited visibility resolved directly inside an enum or trait // (i.e. variants, fields, and trait items) inherits from the visibility // of the enum or trait. - ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => { + ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _, _) => { self.tcx.visibility(def_id).expect_local() } // Otherwise, the visibility is restricted to the nearest parent `mod` item. @@ -848,7 +854,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { } let module = self.r.new_local_module( Some(parent), - ModuleKind::Def(def_kind, def_id, Some(ident.name)), + ModuleKind::Def(def_kind, def_id, item.id, Some(ident.name)), expansion.to_expn_id(), item.span, parent.no_implicit_prelude @@ -882,7 +888,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { let module = self.r.new_local_module( Some(parent), - ModuleKind::Def(def_kind, def_id, Some(ident.name)), + ModuleKind::Def(def_kind, def_id, item.id, Some(ident.name)), expansion.to_expn_id(), item.span, parent.no_implicit_prelude, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7e1dd19167899..c082455380ce7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -5,7 +5,8 @@ use std::ops::ControlFlow; use itertools::Itertools as _; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ - self as ast, CRATE_NODE_ID, Crate, ItemKind, ModKind, NodeId, Path, join_path_idents, + self as ast, CRATE_NODE_ID, Crate, DUMMY_NODE_ID, ItemKind, ModKind, NodeId, Path, + join_path_idents, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -192,11 +193,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn report_with_use_injections(&mut self, krate: &Crate) { - for UseError { mut err, candidates, def_id, instead, suggestion, path, is_call } in + for UseError { mut err, candidates, node_id, instead, suggestion, path, is_call } in mem::take(&mut self.use_injections) { - let (span, found_use) = if let Some(def_id) = def_id.as_local() { - UsePlacementFinder::check(krate, self.def_id_to_node_id(def_id)) + let (span, found_use) = if node_id != DUMMY_NODE_ID { + UsePlacementFinder::check(krate, node_id) } else { (None, FoundUse::No) }; @@ -242,7 +243,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let container = match old_binding.parent_module.unwrap().kind { // Avoid using TyCtxt::def_kind_descr in the resolver, because it // indirectly *calls* the resolver, and would cause a query cycle. - ModuleKind::Def(kind, def_id, _) => kind.descr(def_id), + ModuleKind::Def(kind, def_id, _, _) => kind.descr(def_id), ModuleKind::Block => "block", }; @@ -1705,9 +1706,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let import_suggestions = self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected); - let (span, found_use) = match parent_scope.module.nearest_parent_mod().as_local() { - Some(def_id) => UsePlacementFinder::check(krate, self.def_id_to_node_id(def_id)), - None => (None, FoundUse::No), + let (span, found_use) = match parent_scope.module.nearest_parent_mod_node_id() { + DUMMY_NODE_ID => (None, FoundUse::No), + node_id => UsePlacementFinder::check(krate, node_id), }; show_candidates( self.tcx, @@ -1764,7 +1765,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } if ident.name == kw::Default - && let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind + && let ModuleKind::Def(DefKind::Enum, def_id, _, _) = parent_scope.module.kind { let span = self.def_span(def_id); let source_map = self.tcx.sess.source_map(); @@ -1892,19 +1893,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { missing a `derive` attribute", ident.name, ); - let sugg_span = if let ModuleKind::Def(DefKind::Enum, id, _) = parent_scope.module.kind - { - let span = self.def_span(id); - if span.from_expansion() { - None + let sugg_span = + if let ModuleKind::Def(DefKind::Enum, id, _, _) = parent_scope.module.kind { + let span = self.def_span(id); + if span.from_expansion() { + None + } else { + // For enum variants sugg_span is empty but we can get the enum's Span. + Some(span.shrink_to_lo()) + } } else { - // For enum variants sugg_span is empty but we can get the enum's Span. - Some(span.shrink_to_lo()) - } - } else { - // For items this `Span` will be populated, everything else it'll be None. - sugg_span - }; + // For items this `Span` will be populated, everything else it'll be None. + sugg_span + }; match sugg_span { Some(span) => { err.span_suggestion_verbose( diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 658e36083b0ad..1c43ca431d8bf 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -644,7 +644,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } Scope::ModuleGlobs(module, _) - if let ModuleKind::Def(_, def_id, _) = module.kind + if let ModuleKind::Def(_, def_id, _, _) = module.kind && !def_id.is_local() => { // Fast path: external module decoding only creates non-glob declarations. diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 014a472c2c1bb..3337a4626b040 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1941,7 +1941,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { && let Some((module, _)) = &self.current_trait_ref && let Some(ty) = &self.diag_metadata.current_self_type && Some(true) == self.diag_metadata.in_non_gat_assoc_type - && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind + && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _, _) = + module.kind { if def_id_matches_path( self.r.tcx, @@ -4514,7 +4515,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { parent_qself, ); - let def_id = this.parent_scope.module.nearest_parent_mod(); + let node_id = this.parent_scope.module.nearest_parent_mod_node_id(); let instead = res.is_some(); let (suggestion, const_err) = if let Some((start, end)) = this.diag_metadata.in_range @@ -4556,7 +4557,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let ue = UseError { err, candidates, - def_id, + node_id, instead, suggestion, path: path.into(), @@ -4645,7 +4646,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { parent_err.cancel(); - let def_id = this.parent_scope.module.nearest_parent_mod(); + let node_id = this.parent_scope.module.nearest_parent_mod_node_id(); if this.should_report_errs() { if candidates.is_empty() { @@ -4670,7 +4671,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.r.use_injections.push(UseError { err, candidates, - def_id, + node_id, instead: false, suggestion: None, path: prefix_path.into(), diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b15e4b1b72774..f5f063ecaf458 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -543,7 +543,7 @@ enum ModuleKind { /// The crate root will have `None` for the symbol. /// * A trait or an enum (it implicitly contains associated types, methods and variant /// constructors). - Def(DefKind, DefId, Option), + Def(DefKind, DefId, NodeId, Option), } impl ModuleKind { @@ -557,7 +557,7 @@ impl ModuleKind { fn opt_def_id(&self) -> Option { match self { - ModuleKind::Def(_, def_id, _) => Some(*def_id), + ModuleKind::Def(_, def_id, _, _) => Some(*def_id), _ => None, } } @@ -726,7 +726,7 @@ impl<'ra> ModuleData<'ra> { self_decl: Option>, ) -> Self { let is_foreign = match kind { - ModuleKind::Def(_, def_id, _) => !def_id.is_local(), + ModuleKind::Def(_, def_id, _, _) => !def_id.is_local(), ModuleKind::Block => false, }; ModuleData { @@ -756,7 +756,7 @@ impl<'ra> ModuleData<'ra> { fn res(&self) -> Option { match self.kind { - ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)), + ModuleKind::Def(kind, def_id, _, _) => Some(Res::Def(kind, def_id)), _ => None, } } @@ -813,11 +813,11 @@ impl<'ra> Module<'ra> { // `self` resolves to the first module ancestor that `is_normal`. fn is_normal(self) -> bool { - matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _)) + matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _, _)) } fn is_trait(self) -> bool { - matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _)) + matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _, _)) } fn nearest_item_scope(self) -> Module<'ra> { @@ -833,11 +833,20 @@ impl<'ra> Module<'ra> { /// This may be the crate root. fn nearest_parent_mod(self) -> DefId { match self.kind { - ModuleKind::Def(DefKind::Mod, def_id, _) => def_id, + ModuleKind::Def(DefKind::Mod, def_id, _, _) => def_id, _ => self.parent.expect("non-root module without parent").nearest_parent_mod(), } } + /// The [`NodeId`] of the nearest `mod` item ancestor (which may be this module). + /// This may be the crate root. + fn nearest_parent_mod_node_id(self) -> NodeId { + match self.kind { + ModuleKind::Def(DefKind::Mod, _, node_id, _) => node_id, + _ => self.parent.expect("non-root module without parent").nearest_parent_mod_node_id(), + } + } + fn is_ancestor_of(self, mut other: Self) -> bool { while self != other { if let Some(parent) = other.parent { @@ -852,7 +861,7 @@ impl<'ra> Module<'ra> { #[track_caller] fn expect_local(self) -> LocalModule<'ra> { match self.kind { - ModuleKind::Def(_, def_id, _) if !def_id.is_local() => { + ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => { panic!("`Module::expect_local` is called on a non-local module: {self:?}") } ModuleKind::Def(..) | ModuleKind::Block => LocalModule(self.0), @@ -862,7 +871,7 @@ impl<'ra> Module<'ra> { #[track_caller] fn expect_extern(self) -> ExternModule<'ra> { match self.kind { - ModuleKind::Def(_, def_id, _) if !def_id.is_local() => ExternModule(self.0), + ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => ExternModule(self.0), ModuleKind::Def(..) | ModuleKind::Block => { panic!("`Module::expect_extern` is called on a local module: {self:?}") } @@ -992,8 +1001,8 @@ struct UseError<'a> { err: Diag<'a>, /// Candidates which user could `use` to access the missing type. candidates: Vec, - /// The `DefId` of the module to place the use-statements in. - def_id: DefId, + /// The `NodeId` of the module to place the use-statements in. + node_id: NodeId, /// Whether the diagnostic should say "instead" (as in `consider importing ... instead`). instead: bool, /// Extra free-form suggestion. @@ -1551,7 +1560,7 @@ impl<'ra> ResolverArenas<'ra> { no_implicit_prelude: bool, ) -> Module<'ra> { let self_decl = match kind { - ModuleKind::Def(def_kind, def_id, _) => Some(self.new_def_decl( + ModuleKind::Def(def_kind, def_id, _, _) => Some(self.new_def_decl( Res::Def(def_kind, def_id), vis, span, @@ -1732,7 +1741,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let root_def_id = CRATE_DEF_ID.to_def_id(); let graph_root = arenas.new_module( None, - ModuleKind::Def(DefKind::Mod, root_def_id, None), + ModuleKind::Def(DefKind::Mod, root_def_id, CRATE_NODE_ID, None), Visibility::Public, ExpnId::root(), crate_span, @@ -1743,7 +1752,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let local_module_map = FxIndexMap::from_iter([(CRATE_DEF_ID, graph_root)]); let empty_module = arenas.new_module( None, - ModuleKind::Def(DefKind::Mod, root_def_id, None), + ModuleKind::Def(DefKind::Mod, root_def_id, CRATE_NODE_ID, None), Visibility::Public, ExpnId::root(), DUMMY_SP, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index dd9f500ff88d0..d4349b9d73a77 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1185,7 +1185,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.get_mut().record_use(ident, fallback_binding, Used::Other); } else { let location = match parent_scope.module.kind { - ModuleKind::Def(kind, def_id, name) => { + ModuleKind::Def(kind, def_id, _, name) => { if let Some(name) = name { format!("{} `{name}`", kind.descr(def_id)) } else { diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index f2ed40e2cd010..e2bf1c48b7b47 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -17,6 +17,13 @@ pub enum Stability { /// This target feature is stable, it can be used in `#[target_feature]` and /// `#[cfg(target_feature)]`. Stable, + /// This target feature is cfg-stable. It can be used for `#[cfg(target_feature)]` on stable, + /// but using it in `#[target_feature]` requires the given nightly feature. + CfgStableToggleUnstable( + /// This must be a *language* feature, or else rustc will ICE when reporting a missing + /// feature gate! + Symbol, + ), /// This target feature is unstable. It is only present in `#[cfg(target_feature)]` on /// nightly and using it in `#[target_feature]` requires enabling the given nightly feature. Unstable( @@ -37,7 +44,12 @@ impl Stability { /// (It might still be nightly-only even if this returns `true`, so make sure to also check /// `requires_nightly`.) pub fn in_cfg(&self) -> bool { - matches!(self, Stability::Stable | Stability::Unstable { .. }) + matches!( + self, + Stability::Stable + | Stability::CfgStableToggleUnstable { .. } + | Stability::Unstable { .. } + ) } /// Returns the nightly feature that is required to toggle this target feature via @@ -48,20 +60,38 @@ impl Stability { /// Before calling this, ensure the feature is even permitted for this use: /// - for `#[target_feature]`/`-Ctarget-feature`, check `toggle_allowed()` /// - for `cfg(target_feature)`, check `in_cfg()` - pub fn requires_nightly(&self) -> Option { + /// + /// The `in_cfg` parameter is used to determine whether it will be used in + /// `cfg(target_feature)` (true) or `#[target_feature]`/`-Ctarget-feature` (false) + pub fn requires_nightly(&self, in_cfg: bool) -> Option { match *self { Stability::Unstable(nightly_feature) => Some(nightly_feature), + Stability::CfgStableToggleUnstable(nightly_feature) => { + if in_cfg { + None + } else { + Some(nightly_feature) + } + } Stability::Stable { .. } => None, Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"), } } + /// Returns whether the feature is cfg-stable but still requires a nightly feature gate to + /// be used in `#[target_feature]`/`-Ctarget-feature`. + pub fn is_cfg_stable_toggle_unstable(&self) -> bool { + matches!(self, Stability::CfgStableToggleUnstable { .. }) + } + /// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`. /// (It might still be nightly-only even if this returns `true`, so make sure to also check /// `requires_nightly`.) pub fn toggle_allowed(&self) -> Result<(), &'static str> { match self { - Stability::Unstable(_) | Stability::Stable { .. } => Ok(()), + Stability::Unstable(_) + | Stability::CfgStableToggleUnstable(_) + | Stability::Stable { .. } => Ok(()), Stability::Forbidden { reason } => Err(reason), } } diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 53c5e28c0be27..7d820403ccb7d 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -1007,18 +1007,23 @@ pub const fn type_name_of_val(_val: &T) -> &'static str { #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] pub const fn try_as_dyn< - T: Any + 'static, + T: Any + ?Sized + 'static, U: ptr::Pointee> + ?Sized + 'static, >( t: &T, ) -> Option<&U> { + // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is + // only supported for sized types). The function therefore unconditionally + // returns `None` in that case. let vtable: Option> = const { TypeId::of::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; match vtable { Some(dyn_metadata) => { - let pointer = ptr::from_raw_parts(t, dyn_metadata); + let pointer = ptr::from_raw_parts(t as *const T as *const (), dyn_metadata); // SAFETY: `t` is a reference to a type, so we know it is valid. // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + // `T` is sized here because `trait_info_of` only returns `Some` for sized types, + // so the thin data pointer fully describes the value. Some(unsafe { &*pointer }) } None => None, @@ -1061,18 +1066,23 @@ pub const fn try_as_dyn< #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] pub const fn try_as_dyn_mut< - T: Any + 'static, + T: Any + ?Sized + 'static, U: ptr::Pointee> + ?Sized + 'static, >( t: &mut T, ) -> Option<&mut U> { + // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is + // only supported for sized types). The function therefore unconditionally + // returns `None` in that case. let vtable: Option> = const { TypeId::of::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; match vtable { Some(dyn_metadata) => { - let pointer = ptr::from_raw_parts_mut(t, dyn_metadata); + let pointer = ptr::from_raw_parts_mut(t as *mut T as *mut (), dyn_metadata); // SAFETY: `t` is a reference to a type, so we know it is valid. // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + // `T` is sized here because `trait_info_of` only returns `Some` for sized types, + // so the thin data pointer fully describes the value. Some(unsafe { &mut *pointer }) } None => None, diff --git a/library/core/src/io/error.rs b/library/core/src/io/error.rs index ff50b2822d05a..67cd1eebf44f2 100644 --- a/library/core/src/io/error.rs +++ b/library/core/src/io/error.rs @@ -21,6 +21,10 @@ pub type RawOsError = cfg_select! { /// This list is intended to grow over time and it is not recommended to /// exhaustively match against it. /// +/// It is used with the [`io::Error`][error] type. +/// +/// [error]: ../../std/io/struct.Error.html +/// /// # Handling errors and matching on `ErrorKind` /// /// In application code, use `match` for the `ErrorKind` values you are @@ -135,12 +139,13 @@ pub enum ErrorKind { #[stable(feature = "rust1", since = "1.0.0")] TimedOut, /// An error returned when an operation could not be completed because a - /// call to an underlying writer returned [`Ok(0)`]. + /// call to [`write`][write] returned [`Ok(0)`]. /// /// This typically means that an operation could only succeed if it wrote a /// particular number of bytes but only a smaller number of bytes could be /// written. /// + /// [write]: ../../std/io/trait.Write.html#tymethod.write /// [`Ok(0)`]: Ok #[stable(feature = "rust1", since = "1.0.0")] WriteZero, @@ -239,7 +244,7 @@ pub enum ErrorKind { // /// A custom error that does not fall under any other I/O error kind. /// - /// This can be used to construct your own errors that do not match any + /// This can be used to construct your own [`Error`][error]s that do not match any /// [`ErrorKind`]. /// /// This [`ErrorKind`] is not used by the standard library. @@ -247,6 +252,8 @@ pub enum ErrorKind { /// Errors from the standard library that do not fall under any of the I/O /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern. /// New [`ErrorKind`]s might be added in the future for some of those. + /// + /// [error]: ../../std/io/struct.Error.html #[stable(feature = "rust1", since = "1.0.0")] Other, @@ -379,7 +386,15 @@ impl ErrorKind { #[stable(feature = "io_errorkind_display", since = "1.60.0")] impl fmt::Display for ErrorKind { - /// Shows a human-readable description of the `ErrorKind`. + /// Shows a human-readable description of the [`ErrorKind`]. + /// + /// This is similar to `impl Display for Error`, but doesn't require first converting to Error. + /// + /// # Examples + /// ``` + /// use core::io::ErrorKind; + /// assert_eq!("entity not found", ErrorKind::NotFound.to_string()); + /// ``` fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.write_str(self.as_str()) } diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index d2dc650910f63..18ad28f8f3b97 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -211,12 +211,7 @@ impl<'a> Iterator for Utf8Chunks<'a> { let mut i = 0; let mut valid_up_to = 0; - while i < self.source.len() { - // SAFETY: `i < self.source.len()` per previous line. - // For some reason the following are both significantly slower: - // while let Some(&byte) = self.source.get(i) { - // while let Some(byte) = self.source.get(i).copied() { - let byte = unsafe { *self.source.get_unchecked(i) }; + while let Some(byte) = self.source.get(i).copied() { i += 1; if byte < 128 { diff --git a/src/doc/reference b/src/doc/reference index 8c88f9d0bdd75..581920f9109f1 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 8c88f9d0bdd75ffdc0691676d83212ae22a18cee +Subproject commit 581920f9109f141b88b860b3e1e8359e3896a150 diff --git a/src/doc/unstable-book/src/language-features/generic-const-args.md b/src/doc/unstable-book/src/language-features/generic-const-args.md new file mode 100644 index 0000000000000..b9870e60d0f91 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-args.md @@ -0,0 +1,37 @@ +# generic_const_args + +Allows using generics in more complex const expressions, based on definitional equality. + +The tracking issue for this feature is: [#151972] + +[#151972]: https://github.com/rust-lang/rust/issues/151972 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +This feature enables many of the same use cases supported by [generic_const_exprs], +but based on the machinery developed for [min_generic_const_args]. In a way, it is +meant to be an interim successor for GCE (though it might not currently support all +the valid cases that supported by GCE). + +See also: [generic_const_items] + +[min_generic_const_args]: min-generic-const-args.md +[generic_const_exprs]: generic-const-exprs.md +[generic_const_items]: generic-const-items.md + +## Examples + +```rust +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![expect(incomplete_features)] + +type const ADD1: usize = const { N + 1 }; + +type const INC: usize = ADD1::; + +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; +``` diff --git a/src/doc/unstable-book/src/language-features/generic-const-exprs.md b/src/doc/unstable-book/src/language-features/generic-const-exprs.md new file mode 100644 index 0000000000000..2085ed8fed0cc --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-exprs.md @@ -0,0 +1,73 @@ +# generic_const_exprs + +Allows non-trivial generic constants which have to be shown to successfully evaluate +to a value by being part of an item signature. + +The tracking issue for this feature is: [#76560] + + +[#76560]: https://github.com/rust-lang/rust/issues/76560 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +See also: [min_generic_const_args], [generic_const_args] + +[min_generic_const_args]: min-generic-const-args.md +[generic_const_args]: generic-const-args.md + +## Examples + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +// Use parameters that depend on a generic argument. +struct Foo +where + [(); N + 1]:, +{ + array: [usize; N + 1], +} + +// Use generic parameters in const operations. +trait Bar { + const X: usize; + const Y: usize; +} + +// Note `B::X * B::Y`. +const fn baz(x: [usize; B::X], y: [usize; B::Y]) -> [usize; B::X * B::Y] { + let mut out = [0; B::X * B::Y]; + let mut i = 0; + while i < B::Y { + let mut j = 0; + while j < B::X { + out[i * B::X + j] = y[i].saturating_mul(x[j]); + j += 1; + } + i += 1; + } + out +} + + +// Create a new type based on a generic argument. +pub struct Grow { + arr: [usize; N], +} + +impl Grow { + pub const fn grow(self, val: usize) -> Grow<{ N + 1 }> { + let mut new_arr = [0; { N + 1 }]; + let mut idx = 0; + while idx < N { + new_arr[idx] = self.arr[idx]; + idx += 1; + } + new_arr[N] = val; + Grow { arr: new_arr } + } +} +``` diff --git a/src/doc/unstable-book/src/language-features/generic-const-items.md b/src/doc/unstable-book/src/language-features/generic-const-items.md new file mode 100644 index 0000000000000..c856c9f135aff --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-items.md @@ -0,0 +1,53 @@ +# generic_const_items + +Allows generic parameters and where-clauses on free & associated const items. + +The tracking issue for this feature is: [#113521] + +[#113521]: https://github.com/rust-lang/rust/issues/113521 + +------------------------ + +Warning: This feature is an [experiment] and lacks an RFC. +There are no guarantees that it will ever be stabilized. + +See also: [generic_const_exprs], [min_generic_const_args]. + +[experiment]: https://lang-team.rust-lang.org/how_to/experiment.html +[generic_const_exprs]: generic-const-exprs.md +[min_generic_const_args]: min-generic-const-args.md + +## Examples + +### Generic constant values + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_items)] + +const GENERIC_VAL: usize = ARG + 1; + +#[test] +fn generic_const_arg() { + assert_eq!(GENERIC_VAL::<1>, 2); + assert_eq!(GENERIC_VAL::<2>, 3); +} +``` + +### Conditional constants + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_items)] + +// `GENERIC_VAL::<0>` will fail to compile +const GENERIC_VAL: usize = if ARG > 0 { ARG + 1 } else { panic!("0 value") }; + +// Will fail to compile if the `Copy` derive is removed. +const COPY_MARKER: () = (); + +#[derive(Clone, Copy)] +struct Foo; + +const FOO_IS_COPY: () = COPY_MARKER::; +``` diff --git a/src/doc/unstable-book/src/language-features/min-generic-const-args.md b/src/doc/unstable-book/src/language-features/min-generic-const-args.md new file mode 100644 index 0000000000000..336b6a420c2d6 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/min-generic-const-args.md @@ -0,0 +1,110 @@ +# min_generic_const_args + +Enables the generic const args MVP (paths to type const items and constructors for ADTs and primitives). + +The tracking issue for this feature is: [#132980] + +[#132980]: https://github.com/rust-lang/rust/issues/132980 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +This feature acts as a minimal alternative to [generic_const_exprs] that allows a smaller subset of functionality, +and uses a different approach for implementation. It is intentionally more restrictive, which helps with avoiding edge +cases that make the `generic_const_exprs` hard to implement properly. See [Feature background][feature_background] +for more details. + +Related features: [generic_const_args], [generic_const_items]. + +[feature_background]: https://github.com/rust-lang/project-const-generics/blob/main/documents/min_const_generics_plan.md +[generic_const_exprs]: generic-const-exprs.md +[generic_const_args]: generic-const-args.md +[generic_const_items]: generic-const-items.md + +## `type const` syntax + +This feature introduces new syntax: `type const`. +Constants marked as `type const` are allowed to be used in type contexts, e.g.: + +```compile_fail +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +type const X: usize = 1; +const Y: usize = 1; + +struct Foo { + good_arr: [(); X], // Allowed + bad_arr: [(); Y], // Will not compile, `Y` must be `type const`. +} +``` + +## Examples + +```rust +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +trait Bar { + type const VAL: usize; + type const VAL2: usize; +} + +struct Baz; + +impl Bar for Baz { + type const VAL: usize = 2; + type const VAL2: usize = const { Self::VAL * 2 }; +} + +struct Foo { + arr1: [usize; B::VAL], + arr2: [usize; B::VAL2], +} +``` + +Note that with [generic_const_exprs] the same example would look as follows: + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +trait Bar { + const VAL: usize; + const VAL2: usize; +} + +struct Baz; + +impl Bar for Baz { + const VAL: usize = 2; + const VAL2: usize = const { Self::VAL * 2 }; +} + +struct Foo +where + [(); B::VAL]:, + [(); B::VAL2]:, +{ + arr1: [usize; B::VAL], + arr2: [usize; B::VAL2], +} +``` + +Use of const functions is allowed: + +```rust +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +const VAL: usize = 1; + +const fn inc(val: usize) -> usize { + val + 1 +} + +type const INC: usize = const { inc(VAL) }; + +const ARR: [usize; INC] = [0; INC]; +``` diff --git a/tests/assembly-llvm/c-variadic/avr.rs b/tests/assembly-llvm/c-variadic/avr.rs new file mode 100644 index 0000000000000..a5f48a2d0533e --- /dev/null +++ b/tests/assembly-llvm/c-variadic/avr.rs @@ -0,0 +1,220 @@ +//@ add-minicore +//@ assembly-output: emit-asm +// +//@ revisions: AVR +//@ [AVR] compile-flags: -Copt-level=3 --target=avr-none -Ctarget-cpu=atmega328p +//@ [AVR] needs-llvm-components: avr +#![feature(c_variadic, c_variadic_experimental_arch, no_core, lang_items, intrinsics, rustc_attrs)] +#![no_core] +#![crate_type = "lib"] + +// Check that rustc and clang output match, see https://godbolt.org/z/1MvxoceeT. + +extern crate minicore; +use minicore::*; + +#[lang = "va_arg_safe"] +pub unsafe trait VaArgSafe {} + +unsafe impl VaArgSafe for i16 {} +unsafe impl VaArgSafe for i32 {} +unsafe impl VaArgSafe for i64 {} +unsafe impl VaArgSafe for f32 {} +unsafe impl VaArgSafe for f64 {} +unsafe impl VaArgSafe for *const T {} + +#[repr(transparent)] +struct VaListInner { + ptr: *const c_void, +} + +#[repr(transparent)] +#[lang = "va_list"] +pub struct VaList<'a> { + inner: VaListInner, + _marker: PhantomData<&'a mut ()>, +} + +#[rustc_intrinsic] +#[rustc_nounwind] +pub const unsafe fn va_arg(ap: &mut VaList<'_>) -> T; + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f32(ap: &mut VaList<'_>) -> f32 { + // CHECK-LABEL: read_f32 + // + // AVR: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r20, r30 + // AVR-NEXT: movw r18, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ld r22, Z + // AVR-NEXT: ldd r23, Z+1 + // AVR-NEXT: adiw r24, 4 + // AVR-NEXT: movw r30, r20 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ldd r24, Z+2 + // AVR-NEXT: ldd r25, Z+3 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { + // CHECK-LABEL: read_f64 + // + // AVR: push r14 + // AVR-NEXT: push r15 + // AVR-NEXT: push r16 + // AVR-NEXT: push r17 + // AVR-NEXT: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r14, r30 + // AVR-NEXT: movw r16, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ld r18, Z + // AVR-NEXT: ldd r19, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 4 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r20, Z+2 + // AVR-NEXT: ldd r21, Z+3 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 6 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r22, Z+4 + // AVR-NEXT: ldd r23, Z+5 + // AVR-NEXT: adiw r24, 8 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r24, Z+6 + // AVR-NEXT: ldd r25, Z+7 + // AVR-NEXT: pop r17 + // AVR-NEXT: pop r16 + // AVR-NEXT: pop r15 + // AVR-NEXT: pop r14 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i16(ap: &mut VaList<'_>) -> i16 { + // CHECK-LABEL: read_i16 + // + // AVR: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { + // CHECK-LABEL: read_i32 + // + // AVR: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r20, r30 + // AVR-NEXT: movw r18, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ld r22, Z + // AVR-NEXT: ldd r23, Z+1 + // AVR-NEXT: adiw r24, 4 + // AVR-NEXT: movw r30, r20 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ldd r24, Z+2 + // AVR-NEXT: ldd r25, Z+3 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { + // CHECK-LABEL: read_i64 + // + // AVR: push r14 + // AVR-NEXT: push r15 + // AVR-NEXT: push r16 + // AVR-NEXT: push r17 + // AVR-NEXT: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r14, r30 + // AVR-NEXT: movw r16, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ld r18, Z + // AVR-NEXT: ldd r19, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 4 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r20, Z+2 + // AVR-NEXT: ldd r21, Z+3 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 6 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r22, Z+4 + // AVR-NEXT: ldd r23, Z+5 + // AVR-NEXT: adiw r24, 8 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r24, Z+6 + // AVR-NEXT: ldd r25, Z+7 + // AVR-NEXT: pop r17 + // AVR-NEXT: pop r16 + // AVR-NEXT: pop r15 + // AVR-NEXT: pop r14 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 { + // AVR: read_ptr = pm(read_i16) + va_arg(ap) +} diff --git a/tests/assembly-llvm/c-variadic/sparc.rs b/tests/assembly-llvm/c-variadic/sparc.rs index 59f039e7df28b..6ce25119a135c 100644 --- a/tests/assembly-llvm/c-variadic/sparc.rs +++ b/tests/assembly-llvm/c-variadic/sparc.rs @@ -7,6 +7,7 @@ //@ [SPARC64] compile-flags: -Copt-level=3 --target sparc64-unknown-linux-gnu //@ [SPARC64] needs-llvm-components: sparc #![feature(c_variadic, no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)] +#![cfg_attr(target_arch = "sparc", feature(c_variadic_experimental_arch))] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/any/try_as_dyn_unsized.rs b/tests/ui/any/try_as_dyn_unsized.rs new file mode 100644 index 0000000000000..83bf1e2863c43 --- /dev/null +++ b/tests/ui/any/try_as_dyn_unsized.rs @@ -0,0 +1,34 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::Debug; + +// Generic over `?Sized` T: relies on the relaxed bound on `try_as_dyn`. +fn try_debug(t: &T) -> Option { + std::any::try_as_dyn::(t).map(|d| format!("{d:?}")) +} + +fn try_debug_mut(t: &mut T) -> Option { + std::any::try_as_dyn_mut::(t).map(|d| format!("{d:?}")) +} + +fn main() { + // Sized case still works through a `?Sized` generic context. + let x: i32 = 7; + assert_eq!(try_debug(&x).as_deref(), Some("7")); + + let mut y: i32 = 8; + assert_eq!(try_debug_mut(&mut y).as_deref(), Some("8")); + + // Unsized `T` always returns `None`, even though `str: Debug` and + // `[T]: Debug` hold — vtable lookup for unsized impl types is not + // currently supported by `TypeId::trait_info_of`. + let s: &str = "hello"; + assert!(try_debug::(s).is_none()); + + let slice: &[i32] = &[1, 2, 3]; + assert!(try_debug::<[i32]>(slice).is_none()); + + let dyn_any: &dyn std::any::Any = &0i32; + assert!(try_debug::(dyn_any).is_none()); +} diff --git a/tests/ui/issues/issue-23073.rs b/tests/ui/associated-types/ambiguous-associated-type-default.rs similarity index 71% rename from tests/ui/issues/issue-23073.rs rename to tests/ui/associated-types/ambiguous-associated-type-default.rs index a0ca91336c365..31d1355d41cee 100644 --- a/tests/ui/issues/issue-23073.rs +++ b/tests/ui/associated-types/ambiguous-associated-type-default.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23073 + #![feature(associated_type_defaults)] trait Foo { type T; } diff --git a/tests/ui/issues/issue-23073.stderr b/tests/ui/associated-types/ambiguous-associated-type-default.stderr similarity index 90% rename from tests/ui/issues/issue-23073.stderr rename to tests/ui/associated-types/ambiguous-associated-type-default.stderr index 87dcf3b328923..38484756fa94a 100644 --- a/tests/ui/issues/issue-23073.stderr +++ b/tests/ui/associated-types/ambiguous-associated-type-default.stderr @@ -1,5 +1,5 @@ error[E0223]: ambiguous associated type - --> $DIR/issue-23073.rs:6:17 + --> $DIR/ambiguous-associated-type-default.rs:8:17 | LL | type FooT = <::Foo>::T; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-20803.rs b/tests/ui/associated-types/assoc-type-add-output-via-operator-syntax.rs similarity index 68% rename from tests/ui/issues/issue-20803.rs rename to tests/ui/associated-types/assoc-type-add-output-via-operator-syntax.rs index 47bf52b31a026..180c3576595de 100644 --- a/tests/ui/issues/issue-20803.rs +++ b/tests/ui/associated-types/assoc-type-add-output-via-operator-syntax.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/20803 + //@ run-pass use std::ops::Add; diff --git a/tests/ui/issues/issue-37051.rs b/tests/ui/associated-types/assoc-type-default-without-override-in-impl.rs similarity index 81% rename from tests/ui/issues/issue-37051.rs rename to tests/ui/associated-types/assoc-type-default-without-override-in-impl.rs index fa9cc5964fe1f..c9f1760787102 100644 --- a/tests/ui/issues/issue-37051.rs +++ b/tests/ui/associated-types/assoc-type-default-without-override-in-impl.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/37051 + //@ check-pass #![feature(associated_type_defaults)] diff --git a/tests/ui/issues/issue-39970.rs b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.rs similarity index 84% rename from tests/ui/issues/issue-39970.rs rename to tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.rs index 40d3ae30a87c6..254fb0051ed30 100644 --- a/tests/ui/issues/issue-39970.rs +++ b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/39970 + trait Array<'a> { type Element: 'a; } diff --git a/tests/ui/issues/issue-39970.stderr b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.stderr similarity index 80% rename from tests/ui/issues/issue-39970.stderr rename to tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.stderr index 0fe73574bad6f..eff0a5b53ae06 100644 --- a/tests/ui/issues/issue-39970.stderr +++ b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.stderr @@ -1,16 +1,16 @@ error[E0271]: type mismatch resolving `<() as Array<'a>>::Element == ()` - --> $DIR/issue-39970.rs:19:6 + --> $DIR/assoc-type-element-mismatch-in-hrtb.rs:21:6 | LL | <() as Visit>::visit(); | ^^ type mismatch resolving `<() as Array<'a>>::Element == ()` | note: expected this to be `()` - --> $DIR/issue-39970.rs:10:20 + --> $DIR/assoc-type-element-mismatch-in-hrtb.rs:12:20 | LL | type Element = &'a (); | ^^^^^^ note: required for `()` to implement `Visit` - --> $DIR/issue-39970.rs:13:6 + --> $DIR/assoc-type-element-mismatch-in-hrtb.rs:15:6 | LL | impl Visit for () where | ^^^^^ ^^ diff --git a/tests/ui/issues/issue-28983.rs b/tests/ui/associated-types/assoc-type-in-extern-fn-signature.rs similarity index 86% rename from tests/ui/issues/issue-28983.rs rename to tests/ui/associated-types/assoc-type-in-extern-fn-signature.rs index 90a4793787d4e..ffd26ad8462f5 100644 --- a/tests/ui/issues/issue-28983.rs +++ b/tests/ui/associated-types/assoc-type-in-extern-fn-signature.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/28983 + //@ run-pass pub trait Test { type T; } diff --git a/tests/ui/issues/issue-19632.rs b/tests/ui/associated-types/assoc-type-in-generic-struct-bound.rs similarity index 69% rename from tests/ui/issues/issue-19632.rs rename to tests/ui/associated-types/assoc-type-in-generic-struct-bound.rs index a99ab5f5ebe1d..4aa4b5f3caa10 100644 --- a/tests/ui/issues/issue-19632.rs +++ b/tests/ui/associated-types/assoc-type-in-generic-struct-bound.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19632 + //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-20797.rs b/tests/ui/associated-types/assoc-type-in-strategy-pattern-iterator.rs similarity index 97% rename from tests/ui/issues/issue-20797.rs rename to tests/ui/associated-types/assoc-type-in-strategy-pattern-iterator.rs index 3d3160c6e85d6..0291b225f6955 100644 --- a/tests/ui/issues/issue-20797.rs +++ b/tests/ui/associated-types/assoc-type-in-strategy-pattern-iterator.rs @@ -1,6 +1,6 @@ //@ build-pass -// Regression test for #20797. +// Regression test for https://github.com/rust-lang/rust/issues/20797 use std::default::Default; use std::io; diff --git a/tests/ui/issues/issue-26127.rs b/tests/ui/associated-types/assoc-type-in-struct-constructor.rs similarity index 71% rename from tests/ui/issues/issue-26127.rs rename to tests/ui/associated-types/assoc-type-in-struct-constructor.rs index 45f50efdccbdb..b041260cfb356 100644 --- a/tests/ui/issues/issue-26127.rs +++ b/tests/ui/associated-types/assoc-type-in-struct-constructor.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/26127 + //@ run-pass trait Tr { type T; } impl Tr for u8 { type T=(); } diff --git a/tests/ui/issues/issue-19631.rs b/tests/ui/associated-types/assoc-type-in-unused-where-clause.rs similarity index 73% rename from tests/ui/issues/issue-19631.rs rename to tests/ui/associated-types/assoc-type-in-unused-where-clause.rs index d13ac216e36ea..7f570015fc752 100644 --- a/tests/ui/issues/issue-19631.rs +++ b/tests/ui/associated-types/assoc-type-in-unused-where-clause.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19631 + //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-36036-associated-type-layout.rs b/tests/ui/associated-types/assoc-type-layout-unsized-allowed-sized-used.rs similarity index 79% rename from tests/ui/issues/issue-36036-associated-type-layout.rs rename to tests/ui/associated-types/assoc-type-layout-unsized-allowed-sized-used.rs index 63f9927c67826..1e6fc4ebbb38f 100644 --- a/tests/ui/issues/issue-36036-associated-type-layout.rs +++ b/tests/ui/associated-types/assoc-type-layout-unsized-allowed-sized-used.rs @@ -1,5 +1,6 @@ //@ run-pass -// Issue 36036: computing the layout of a type composed from another +// Regression test for https://github.com/rust-lang/rust/issues/36036 +// computing the layout of a type composed from another // trait's associated type caused compiler to ICE when the associated // type was allowed to be unsized, even though the known instantiated // type is itself sized. diff --git a/tests/ui/issues/issue-23336.rs b/tests/ui/associated-types/assoc-type-method-call-via-blanket-impl.rs similarity index 77% rename from tests/ui/issues/issue-23336.rs rename to tests/ui/associated-types/assoc-type-method-call-via-blanket-impl.rs index e71c2af0c85d6..d4fa38124a77c 100644 --- a/tests/ui/issues/issue-23336.rs +++ b/tests/ui/associated-types/assoc-type-method-call-via-blanket-impl.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23336 + //@ run-pass pub trait Data { fn doit(&self) {} } impl Data for T {} diff --git a/tests/ui/issues/issue-17732.rs b/tests/ui/associated-types/assoc-type-named-string.rs similarity index 73% rename from tests/ui/issues/issue-17732.rs rename to tests/ui/associated-types/assoc-type-named-string.rs index e093ed7f41fb0..03449e2cdabe5 100644 --- a/tests/ui/issues/issue-17732.rs +++ b/tests/ui/associated-types/assoc-type-named-string.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/17732 + //@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-20009.rs b/tests/ui/associated-types/assoc-type-output-is-sized.rs similarity index 73% rename from tests/ui/issues/issue-20009.rs rename to tests/ui/associated-types/assoc-type-output-is-sized.rs index 4d091f3a962c6..8ef4595843df2 100644 --- a/tests/ui/issues/issue-20009.rs +++ b/tests/ui/associated-types/assoc-type-output-is-sized.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/20009 + //@ check-pass // Check that associated types are `Sized` diff --git a/tests/ui/issues/issue-20971.rs b/tests/ui/associated-types/assoc-type-projection-in-box-return.rs similarity index 83% rename from tests/ui/issues/issue-20971.rs rename to tests/ui/associated-types/assoc-type-projection-in-box-return.rs index 31dd910191935..6c95467d141aa 100644 --- a/tests/ui/issues/issue-20971.rs +++ b/tests/ui/associated-types/assoc-type-projection-in-box-return.rs @@ -1,4 +1,4 @@ -// Regression test for Issue #20971. +// Regression test for Issue https://github.com/rust-lang/rust/issues/20971 //@ run-fail //@ error-pattern:Hello, world! diff --git a/tests/ui/issues/issue-19850.rs b/tests/ui/associated-types/assoc-type-projection-in-let-binding.rs similarity index 84% rename from tests/ui/issues/issue-19850.rs rename to tests/ui/associated-types/assoc-type-projection-in-let-binding.rs index 485b1a763900b..0438bcd96e1f5 100644 --- a/tests/ui/issues/issue-19850.rs +++ b/tests/ui/associated-types/assoc-type-projection-in-let-binding.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19850 + //@ check-pass #![allow(unused_variables)] // Test that `::Output` and `Self::Output` are accepted as type annotations in let diff --git a/tests/ui/issues/issue-23406.rs b/tests/ui/associated-types/assoc-type-projection-on-ref-lifetime.rs similarity index 72% rename from tests/ui/issues/issue-23406.rs rename to tests/ui/associated-types/assoc-type-projection-on-ref-lifetime.rs index 819f0feb6147a..b70d0a7468ff1 100644 --- a/tests/ui/issues/issue-23406.rs +++ b/tests/ui/associated-types/assoc-type-projection-on-ref-lifetime.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23406 + //@ build-pass #![allow(dead_code)] trait Inner { diff --git a/tests/ui/issues/issue-37109.rs b/tests/ui/associated-types/assoc-type-ref-in-tuple-return.rs similarity index 75% rename from tests/ui/issues/issue-37109.rs rename to tests/ui/associated-types/assoc-type-ref-in-tuple-return.rs index 5276266523d8d..a587affb52ef8 100644 --- a/tests/ui/issues/issue-37109.rs +++ b/tests/ui/associated-types/assoc-type-ref-in-tuple-return.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/37109 + //@ run-pass trait ToRef<'a> { type Ref: 'a; diff --git a/tests/ui/issues/issue-23992.rs b/tests/ui/associated-types/assoc-type-returns-outer-wrapping-self.rs similarity index 84% rename from tests/ui/issues/issue-23992.rs rename to tests/ui/associated-types/assoc-type-returns-outer-wrapping-self.rs index 08a99d357bc43..74e941962a16b 100644 --- a/tests/ui/issues/issue-23992.rs +++ b/tests/ui/associated-types/assoc-type-returns-outer-wrapping-self.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23992 + //@ run-pass pub struct Outer(T); pub struct Inner<'a> { value: &'a bool } diff --git a/tests/ui/issues/issue-21909.rs b/tests/ui/associated-types/bound-references-sibling-assoc-type.rs similarity index 67% rename from tests/ui/issues/issue-21909.rs rename to tests/ui/associated-types/bound-references-sibling-assoc-type.rs index ffc75f1f08cdd..18709cec121aa 100644 --- a/tests/ui/issues/issue-21909.rs +++ b/tests/ui/associated-types/bound-references-sibling-assoc-type.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/21909 + //@ check-pass trait A { diff --git a/tests/ui/issues/issue-34839.rs b/tests/ui/associated-types/enum-variant-with-assoc-type-and-lifetimes.rs similarity index 83% rename from tests/ui/issues/issue-34839.rs rename to tests/ui/associated-types/enum-variant-with-assoc-type-and-lifetimes.rs index 73edba5817af3..64de3df1e7c92 100644 --- a/tests/ui/issues/issue-34839.rs +++ b/tests/ui/associated-types/enum-variant-with-assoc-type-and-lifetimes.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/34839 + //@ check-pass trait RegularExpression: Sized { diff --git a/tests/ui/issues/issue-25679.rs b/tests/ui/associated-types/method-on-impl-with-assoc-type-projection.rs similarity index 100% rename from tests/ui/issues/issue-25679.rs rename to tests/ui/associated-types/method-on-impl-with-assoc-type-projection.rs diff --git a/tests/ui/issues/issue-25693.rs b/tests/ui/associated-types/recursive-enum-with-assoc-type-selfref.rs similarity index 100% rename from tests/ui/issues/issue-25693.rs rename to tests/ui/associated-types/recursive-enum-with-assoc-type-selfref.rs diff --git a/tests/ui/issues/issue-35600.rs b/tests/ui/associated-types/same-name-assoc-type-and-method.rs similarity index 76% rename from tests/ui/issues/issue-35600.rs rename to tests/ui/associated-types/same-name-assoc-type-and-method.rs index 40df0b6dfd890..21990ee150ab6 100644 --- a/tests/ui/issues/issue-35600.rs +++ b/tests/ui/associated-types/same-name-assoc-type-and-method.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/35600 + //@ run-pass #![allow(non_camel_case_types)] #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-27281.rs b/tests/ui/associated-types/self-type-alias-for-assoc-type.rs similarity index 78% rename from tests/ui/issues/issue-27281.rs rename to tests/ui/associated-types/self-type-alias-for-assoc-type.rs index e76fd135dcd23..14864ede2a8be 100644 --- a/tests/ui/issues/issue-27281.rs +++ b/tests/ui/associated-types/self-type-alias-for-assoc-type.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/27281 + //@ check-pass pub trait Trait<'a> { type T; diff --git a/tests/ui/issues/issue-18809.rs b/tests/ui/associated-types/simple-associated-type-impl.rs similarity index 64% rename from tests/ui/issues/issue-18809.rs rename to tests/ui/associated-types/simple-associated-type-impl.rs index d3ef6abc8bdc8..1ebaf3b281786 100644 --- a/tests/ui/issues/issue-18809.rs +++ b/tests/ui/associated-types/simple-associated-type-impl.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18809 + //@ check-pass trait Tup { type T0; diff --git a/tests/ui/issues/issue-43357.rs b/tests/ui/associated-types/size-of-assoc-type-output.rs similarity index 66% rename from tests/ui/issues/issue-43357.rs rename to tests/ui/associated-types/size-of-assoc-type-output.rs index fd20bac804074..c8f1865a3a5c1 100644 --- a/tests/ui/issues/issue-43357.rs +++ b/tests/ui/associated-types/size-of-assoc-type-output.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/43357 + //@ check-pass #![allow(dead_code)] trait Trait { diff --git a/tests/ui/issues/issue-19482.rs b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.rs similarity index 78% rename from tests/ui/issues/issue-19482.rs rename to tests/ui/associated-types/unspecified-assoc-type-in-trait-object.rs index 9d0c8d96d29a6..45b0171bccba0 100644 --- a/tests/ui/issues/issue-19482.rs +++ b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.rs @@ -1,3 +1,4 @@ +// Regression test for https://github.com/rust-lang/rust/issues/19842 // Test that a partially specified trait object with unspecified associated // type does not type-check. diff --git a/tests/ui/issues/issue-19482.stderr b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.stderr similarity index 87% rename from tests/ui/issues/issue-19482.stderr rename to tests/ui/associated-types/unspecified-assoc-type-in-trait-object.stderr index 5ac5130b2cd6c..0bcd91e31c2c4 100644 --- a/tests/ui/issues/issue-19482.stderr +++ b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.stderr @@ -1,5 +1,5 @@ error[E0191]: the value of the associated type `A` in `Foo` must be specified - --> $DIR/issue-19482.rs:10:16 + --> $DIR/unspecified-assoc-type-in-trait-object.rs:11:16 | LL | type A; | ------ `A` defined here diff --git a/tests/ui/drop/explicit-drop-call-error.fixed b/tests/ui/drop/explicit-drop-call-error.fixed index f2f0245df96ff..6060d64cebf11 100644 --- a/tests/ui/drop/explicit-drop-call-error.fixed +++ b/tests/ui/drop/explicit-drop-call-error.fixed @@ -11,5 +11,5 @@ impl Drop for Foo { } fn main() { - drop(&mut Foo) //~ ERROR explicit use of destructor method + drop(Foo) //~ ERROR explicit use of destructor method } diff --git a/tests/ui/drop/explicit-drop-call-error.stderr b/tests/ui/drop/explicit-drop-call-error.stderr index 95d5c31ab6d05..159bf8f841aae 100644 --- a/tests/ui/drop/explicit-drop-call-error.stderr +++ b/tests/ui/drop/explicit-drop-call-error.stderr @@ -2,10 +2,13 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-drop-call-error.rs:14:5 | LL | Drop::drop(&mut Foo) - | ^^^^^^^^^^ - | | - | explicit destructor calls not allowed - | help: consider using `drop` function: `drop` + | ^^^^^^^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL - Drop::drop(&mut Foo) +LL + drop(Foo) + | error: aborting due to 1 previous error diff --git a/tests/ui/drop/explicit-drop-call-named-ref.fixed b/tests/ui/drop/explicit-drop-call-named-ref.fixed new file mode 100644 index 0000000000000..68f452d7a0844 --- /dev/null +++ b/tests/ui/drop/explicit-drop-call-named-ref.fixed @@ -0,0 +1,17 @@ +//@ run-rustfix + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn foo(f: Foo) { + drop(f); //~ ERROR explicit use of destructor method + //~| HELP: consider using `drop` function +} + +fn main() { + let f = Foo; + foo(f); +} diff --git a/tests/ui/drop/explicit-drop-call-named-ref.rs b/tests/ui/drop/explicit-drop-call-named-ref.rs new file mode 100644 index 0000000000000..59c05ca01a9e0 --- /dev/null +++ b/tests/ui/drop/explicit-drop-call-named-ref.rs @@ -0,0 +1,17 @@ +//@ run-rustfix + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn foo(f: Foo) { + Drop::drop(&mut f); //~ ERROR explicit use of destructor method + //~| HELP: consider using `drop` function +} + +fn main() { + let f = Foo; + foo(f); +} diff --git a/tests/ui/drop/explicit-drop-call-named-ref.stderr b/tests/ui/drop/explicit-drop-call-named-ref.stderr new file mode 100644 index 0000000000000..f7ad6de895a6f --- /dev/null +++ b/tests/ui/drop/explicit-drop-call-named-ref.stderr @@ -0,0 +1,15 @@ +error[E0040]: explicit use of destructor method + --> $DIR/explicit-drop-call-named-ref.rs:10:5 + | +LL | Drop::drop(&mut f); + | ^^^^^^^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL - Drop::drop(&mut f); +LL + drop(f); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0040`.