diff --git a/Cargo.lock b/Cargo.lock index 91daa229a95e3..e7f713936f16e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6088,6 +6088,8 @@ name = "unstable-book-gen" version = "0.1.0" dependencies = [ "num-traits", + "proc-macro2", + "syn 2.0.110", "tidy", ] diff --git a/bootstrap.example.toml b/bootstrap.example.toml index f3b2a64df853b..25e2ca5948bfb 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -826,7 +826,8 @@ # in the sysroot. It is required for running nvptx tests. #rust.llvm-bitcode-linker = false -# Whether to deny warnings in crates +# Whether to deny warnings in crates. Set to `false` to avoid +# error: warnings are denied by `build.warnings` configuration #rust.deny-warnings = true # Print backtrace on internal compiler errors during bootstrap diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7bbce730c1658..a63c54a2618b7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1569,10 +1569,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id()); - let Some(hir_generics) = tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| tcx.hir_get_generics(def_id)) + let Some(hir_generics) = + tcx.hir_get_generics(tcx.typeck_root_def_id_local(self.mir_def_id())) else { return; }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 8b4bda8f7fefc..86d7119639a3f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1274,12 +1274,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let ty::Param(param_ty) = *self_ty.kind() && let generics = self.infcx.tcx.generics_of(self.mir_def_id()) && let param = generics.type_param(param_ty, self.infcx.tcx) - && let Some(hir_generics) = self - .infcx - .tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| self.infcx.tcx.hir_get_generics(def_id)) + && let Some(hir_generics) = self.infcx.tcx.hir_get_generics( + self.infcx.tcx.typeck_root_def_id_local(self.mir_def_id()), + ) && let spans = hir_generics .predicates .iter() diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index aeba5ee70cf17..e96c6c7c56f9b 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -476,12 +476,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let mut indices = self.compute_indices(fr_static, defining_ty); debug!("build: indices={:?}", indices); - let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id()); - // If this is a 'root' body (not a closure/coroutine/inline const), then // there are no extern regions, so the local regions start at the same // position as the (empty) sub-list of extern regions - let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id { + let first_local_index = if !self.infcx.tcx.is_typeck_child(self.mir_def.to_def_id()) { first_extern_index } else { // If this is a closure, coroutine, or inline-const, then the late-bound regions from the enclosing @@ -583,7 +581,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { /// see `DefiningTy` for details. fn defining_ty(&self) -> DefiningTy<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id_local(self.mir_def); match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { @@ -614,7 +612,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id { + if self.mir_def == typeck_root_def_id { let args = self.infcx.replace_free_regions_with_nll_infer_vars( NllRegionVariableOrigin::FreeRegion, identity_args, @@ -660,7 +658,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id_local(self.mir_def); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); let renumbered_args = defining_ty.args(); @@ -948,16 +946,14 @@ fn for_each_late_bound_region_in_recursive_scope<'tcx>( mut mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id()); - // Walk up the tree, collecting late-bound regions until we hit the typeck root loop { for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f); - if mir_def_id.to_def_id() == typeck_root_def_id { - break; - } else { + if tcx.is_typeck_child(mir_def_id.to_def_id()) { mir_def_id = tcx.local_parent(mir_def_id); + } else { + break; } } } diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 8865638e3af2f..e31beca390837 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -11,7 +11,7 @@ use std::mem; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt}; use rustc_index::Idx; @@ -849,13 +849,13 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { /// re-use in incremental scenarios. We may sometimes need to rerun the /// type checker even when the HIR hasn't changed, and in those cases /// we can avoid reconstructing the region scope tree. -pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { - let typeck_root_def_id = tcx.typeck_root_def_id(def_id); +pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &ScopeTree { + let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id); if typeck_root_def_id != def_id { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(), diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 866787a457180..ea98beb955805 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -76,12 +76,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { | Node::Ctor(..) | Node::Field(_) => { let parent_id = tcx.hir_get_parent_item(hir_id); - Some(parent_id.to_def_id()) + Some(parent_id.def_id) } // FIXME(#43408) always enable this once `lazy_normalization` is // stable enough and does not need a feature gate anymore. Node::AnonConst(_) => { - let parent_did = tcx.parent(def_id.to_def_id()); + let parent_did = tcx.local_parent(def_id); debug!(?parent_did); let mut in_param_ty = false; @@ -175,7 +175,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } Node::ConstBlock(_) | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { - Some(tcx.typeck_root_def_id(def_id.to_def_id())) + Some(tcx.typeck_root_def_id_local(def_id)) } Node::OpaqueTy(&hir::OpaqueTy { origin: @@ -188,7 +188,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } else { assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn); } - Some(fn_def_id.to_def_id()) + Some(fn_def_id) } Node::OpaqueTy(&hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty }, @@ -202,7 +202,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent); // Opaque types are always nested within another item, and // inherit the generics of the item. - Some(parent.to_def_id()) + Some(parent) } // All of these nodes have no parent from which to inherit generics. @@ -380,7 +380,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { own_params.iter().map(|param| (param.def_id, param.index)).collect(); ty::Generics { - parent: parent_def_id, + parent: parent_def_id.map(LocalDefId::to_def_id), parent_count, own_params, param_def_id_to_index, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 98999232a7435..8fd3d631962c8 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -107,7 +107,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ); return ty::GenericPredicates { - parent: Some(tcx.parent(def_id.to_def_id())), + parent: Some(tcx.local_parent(def_id).to_def_id()), predicates: tcx.arena.alloc_from_iter(predicates), }; } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 82b7c578a1f25..1a9c2a21c7ef3 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?bound_sig, ?liberated_sig); let parent_args = - GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id(expr_def_id.to_def_id())); + GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id_local(expr_def_id)); let tupled_upvars_ty = self.next_ty_var(expr_span); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 734e5136f8806..6cfcdfe87480e 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -106,7 +106,7 @@ fn typeck_with_inspect<'tcx>( ) -> &'tcx ty::TypeckResults<'tcx> { // Closures' typeck results come from their outermost function, // as they are part of the same "inference environment". - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(); + let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id); if typeck_root_def_id != def_id { return tcx.typeck(typeck_root_def_id); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e554da362f83e..8bf919dab8e79 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -727,7 +727,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { is_stub: false, }, extra_filename: tcx.sess.opts.cg.extra_filename.clone(), - stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), + stable_crate_id: tcx.stable_crate_id(LOCAL_CRATE), required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE), panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, edition: tcx.sess.edition(), diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index ff96f5044dc14..3572e3ff35cbe 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1413,7 +1413,7 @@ rustc_queries! { /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; /// in the case of closures, this will be redirected to the enclosing function. - query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { + query region_scope_tree(def_id: LocalDefId) -> &'tcx crate::middle::region::ScopeTree { desc { "computing drop scopes for `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 58a2edca8ecef..28688bcbfafc4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -899,12 +899,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn has_typeck_results(self, def_id: LocalDefId) -> bool { // Closures' typeck results come from their outermost function, // as they are part of the same "inference environment". - let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id()); - if typeck_root_def_id != def_id.to_def_id() { - return self.has_typeck_results(typeck_root_def_id.expect_local()); - } - - self.hir_node_by_def_id(def_id).body_id().is_some() + let root = self.typeck_root_def_id_local(def_id); + self.hir_node_by_def_id(root).body_id().is_some() } /// Expects a body and returns its codegen attributes. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e7c7d59248700..d0cbdff366dfa 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -650,6 +650,20 @@ impl<'tcx> TyCtxt<'tcx> { def_id } + /// Given the `LocalDefId`, returns the `LocalDefId` of the innermost item that + /// has its own type-checking context or "inference environment". + /// + /// For example, a closure has its own `LocalDefId`, but it is type-checked + /// with the containing item. Therefore, when we fetch the `typeck` of the closure, + /// for example, we really wind up fetching the `typeck` of the enclosing fn item. + pub fn typeck_root_def_id_local(self, def_id: LocalDefId) -> LocalDefId { + let mut def_id = def_id; + while self.is_typeck_child(def_id.to_def_id()) { + def_id = self.local_parent(def_id); + } + def_id + } + /// Given the `DefId` and args a closure, creates the type of /// `self` argument that the closure expects. For example, for a /// `Fn` closure, this would return a reference type `&T` where diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 4256ee45f8501..7e6f30378a490 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -816,8 +816,8 @@ impl<'tcx> ThirBuildCx<'tcx> { } hir::InlineAsmOperand::Const { ref anon_const } => { let ty = self.typeck_results.node_type(anon_const.hir_id); - let did = anon_const.def_id.to_def_id(); - let typeck_root_def_id = tcx.typeck_root_def_id(did); + let did = anon_const.def_id; + let typeck_root_def_id = tcx.typeck_root_def_id_local(did); let parent_args = tcx.erase_and_anonymize_regions( GenericArgs::identity_for_item(tcx, typeck_root_def_id), ); @@ -825,7 +825,7 @@ impl<'tcx> ThirBuildCx<'tcx> { InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }) .args; - let uneval = mir::UnevaluatedConst::new(did, args); + let uneval = mir::UnevaluatedConst::new(did.to_def_id(), args); let value = mir::Const::Unevaluated(uneval, ty); InlineAsmOperand::Const { value, span: tcx.def_span(did) } } @@ -895,15 +895,15 @@ impl<'tcx> ThirBuildCx<'tcx> { hir::ExprKind::ConstBlock(ref anon_const) => { let ty = self.typeck_results.node_type(anon_const.hir_id); - let did = anon_const.def_id.to_def_id(); - let typeck_root_def_id = tcx.typeck_root_def_id(did); + let did = anon_const.def_id; + let typeck_root_def_id = tcx.typeck_root_def_id_local(did); let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item( tcx, typeck_root_def_id, )); let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args; - ExprKind::ConstBlock { did, args } + ExprKind::ConstBlock { did: did.to_def_id(), args } } // Now comes the rote stuff: hir::ExprKind::Repeat(v, _) => { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 094aae499c4b4..9273c2103d442 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -526,7 +526,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // We only need to borrowck non-synthetic MIR. let tainted_by_errors = if !tcx.is_synthetic_mir(def) { - tcx.mir_borrowck(tcx.typeck_root_def_id(def.to_def_id()).expect_local()).err() + tcx.mir_borrowck(tcx.typeck_root_def_id_local(def)).err() } else { None }; @@ -554,14 +554,14 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // // We do this check here and not during `mir_promoted` because that may result // in borrowck cycles if WF requires looking into an opaque hidden type. - let root = tcx.typeck_root_def_id(def.to_def_id()); + let root = tcx.typeck_root_def_id_local(def); match tcx.def_kind(root) { DefKind::Fn | DefKind::AssocFn | DefKind::Static { .. } | DefKind::Const { .. } | DefKind::AssocConst { .. } => { - if let Err(guar) = tcx.ensure_result().check_well_formed(root.expect_local()) { + if let Err(guar) = tcx.ensure_result().check_well_formed(root) { body.tainted_by_errors = Some(guar); } } @@ -840,7 +840,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den } // Don't run unused pass for #[derive] - let parent = tcx.parent(tcx.typeck_root_def_id(def_id.to_def_id())); + let parent = tcx.local_parent(tcx.typeck_root_def_id_local(def_id)); if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent) && find_attr!(tcx, parent, AutomaticallyDerived(..)) { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8bd6730ab0eba..4698e054daf6e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1615,7 +1615,7 @@ impl<'v> RootCollector<'_, 'v> { if (self.strategy == MonoItemCollectionStrategy::Eager || is_pub_fn_coroutine) && !self .tcx - .generics_of(self.tcx.typeck_root_def_id(def_id.to_def_id())) + .generics_of(self.tcx.typeck_root_def_id_local(def_id)) .requires_monomorphization(self.tcx) { let instance = match *self.tcx.type_of(def_id).instantiate_identity().kind() { diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 0e852d2abda04..6faaafcc01005 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -4344,7 +4344,7 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels { pub(crate) enum HiddenUnicodeCodepointsDiagSub { Escape { spans: Vec<(char, Span)> }, - NoEscape { spans: Vec<(char, Span)> }, + NoEscape { spans: Vec<(char, Span)>, is_doc_comment: bool }, } // Used because of multiple multipart_suggestion and note @@ -4370,7 +4370,7 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { Applicability::MachineApplicable, ); } - HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => { + HiddenUnicodeCodepointsDiagSub::NoEscape { spans, is_doc_comment } => { // FIXME: in other suggestions we've reversed the inner spans of doc comments. We // should do the same here to provide the same good suggestions as we do for // literals above. @@ -4383,7 +4383,11 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { .join(", "), ); diag.note(msg!("if their presence wasn't intentional, you can remove them")); - diag.note(msg!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}")); + if is_doc_comment { + diag.note(msg!(r#"if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as {$escaped}"#)); + } else { + diag.note(msg!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}")); + } } } } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 2223e6a265759..5766d25bc86ce 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -546,6 +546,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { self.mk_sp(start, self.pos), 0, false, + true, "doc comment", ); } @@ -580,6 +581,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { span, padding, point_at_inner_spans, + false, label, ); } @@ -590,6 +592,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { span: Span, padding: u32, point_at_inner_spans: bool, + is_doc_comment: bool, label: &str, ) { // Obtain the `Span`s for each of the forbidden chars. @@ -610,7 +613,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let sub = if point_at_inner_spans && !spans.is_empty() { errors::HiddenUnicodeCodepointsDiagSub::Escape { spans } } else { - errors::HiddenUnicodeCodepointsDiagSub::NoEscape { spans } + errors::HiddenUnicodeCodepointsDiagSub::NoEscape { spans, is_doc_comment } }; self.psess.buffer_lint( diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 30634c800e819..d5ef9ee9335c5 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -380,8 +380,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { /// for discussion). fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool { if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind - && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id()) - && self.tcx.is_automatically_derived(impl_of) + && let impl_of = self.tcx.local_parent(impl_item.owner_id.def_id) + && self.tcx.is_automatically_derived(impl_of.to_def_id()) && let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity() && find_attr!(self.tcx, trait_ref.def_id, RustcTrivialFieldReads) { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7abaae1c17606..a9db6979cc797 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -605,6 +605,10 @@ macro_rules! tmod_enum { /// necessary code. The main gotcha of this macro is the `cgsetters` module which is a bunch of /// generated code to parse an option into its respective field in the struct. There are a few /// hand-written parsers for parsing specific types of values in this module. +/// +/// Note: this macro's invocation is also parsed by a `syn`-based parser in +/// `src/tools/unstable-book-gen/src/main.rs` to extract unstable option names and descriptions. +/// If the format of this macro changes, that parser may need to be updated as well. macro_rules! options { ($struct_name:ident, $tmod_enum_name:ident, $stat:ident, $optmod:ident, $prefix:expr, $outputname:expr, $($( #[$attr:meta] )* $opt:ident : $t:ty = ( @@ -2215,588 +2219,4 @@ options! { // - src/doc/rustc/src/codegen-options/index.md } -options! { - UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable", - - // If you add a new option, please update: - // - compiler/rustc_interface/src/tests.rs - // - src/doc/unstable-book/src/compiler-flags - - // tidy-alphabetical-start - allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], - "only allow the listed language features to be enabled in code (comma separated)"), - always_encode_mir: bool = (false, parse_bool, [TRACKED], - "encode MIR of all functions into the crate metadata (default: no)"), - annotate_moves: AnnotateMoves = (AnnotateMoves::Disabled, parse_annotate_moves, [TRACKED], - "emit debug info for compiler-generated move and copy operations \ - to make them visible in profilers. Can be a boolean or a size limit in bytes (default: disabled)"), - assert_incr_state: Option = (None, parse_opt_string, [UNTRACKED], - "assert that the incremental cache is in given state: \ - either `loaded` or `not-loaded`."), - assume_incomplete_release: bool = (false, parse_bool, [TRACKED], - "make cfg(version) treat the current version as incomplete (default: no)"), - autodiff: Vec = (Vec::new(), parse_autodiff, [TRACKED], - "a list of autodiff flags to enable - Mandatory setting: - `=Enable` - Optional extra settings: - `=PrintTA` - `=PrintAA` - `=PrintPerf` - `=PrintSteps` - `=PrintModBefore` - `=PrintModAfter` - `=PrintModFinal` - `=PrintPasses`, - `=NoPostopt` - `=LooseTypes` - `=Inline` - Multiple options can be combined with commas."), - #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")] - binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], - "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ - (default: no)"), - box_noalias: bool = (true, parse_bool, [TRACKED], - "emit noalias metadata for box (default: yes)"), - branch_protection: Option = (None, parse_branch_protection, [TRACKED TARGET_MODIFIER], - "set options for branch target identification and pointer authentication on AArch64"), - build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED], - "whether the stable interface is being built"), - cache_proc_macros: bool = (false, parse_bool, [TRACKED], - "cache the results of derive proc macro invocations (potentially unsound!) (default: no"), - cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED], - "instrument control-flow architecture protection"), - check_cfg_all_expected: bool = (false, parse_bool, [UNTRACKED], - "show all expected values in check-cfg diagnostics (default: no)"), - checksum_hash_algorithm: Option = (None, parse_cargo_src_file_hash, [TRACKED], - "hash algorithm of source files used to check freshness in cargo (`blake3` or `sha256`)"), - codegen_backend: Option = (None, parse_opt_string, [TRACKED], - "the backend to use"), - codegen_source_order: bool = (false, parse_bool, [UNTRACKED], - "emit mono items in the order of spans in source files (default: no)"), - contract_checks: Option = (None, parse_opt_bool, [TRACKED], - "emit runtime checks for contract pre- and post-conditions (default: no)"), - coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED], - "control details of coverage instrumentation"), - crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], - "inject the given attribute in the crate"), - cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED], - "threshold to allow cross crate inlining of functions"), - debug_info_for_profiling: bool = (false, parse_bool, [TRACKED], - "emit discriminators and other data necessary for AutoFDO"), - debug_info_type_line_numbers: bool = (false, parse_bool, [TRACKED], - "emit type and line information for additional data types (default: no)"), - debuginfo_compression: DebugInfoCompression = (DebugInfoCompression::None, parse_debuginfo_compression, [TRACKED], - "compress debug info sections (none, zlib, zstd, default: none)"), - deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], - "deduplicate identical diagnostics (default: yes)"), - default_visibility: Option = (None, parse_opt_symbol_visibility, [TRACKED], - "overrides the `default_visibility` setting of the target"), - dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], - "in dep-info output, omit targets for tracking dependencies of the dep-info files \ - themselves (default: no)"), - direct_access_external_data: Option = (None, parse_opt_bool, [TRACKED], - "Direct or use GOT indirect to reference external data symbols"), - dual_proc_macros: bool = (false, parse_bool, [TRACKED], - "load proc macros for both target and host, but only link to the target (default: no)"), - dump_dep_graph: bool = (false, parse_bool, [UNTRACKED], - "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \ - (default: no)"), - dump_mir: Option = (None, parse_opt_string, [UNTRACKED], - "dump MIR state to file. - `val` is used to select which passes and functions to dump. For example: - `all` matches all passes and functions, - `foo` matches all passes for functions whose name contains 'foo', - `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo', - `foo | bar` all passes for function names containing 'foo' or 'bar'."), - dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED], - "in addition to `.mir` files, create graphviz `.dot` files with dataflow results \ - (default: no)"), - dump_mir_dir: String = ("mir_dump".to_string(), parse_string, [UNTRACKED], - "the directory the MIR is dumped into (default: `mir_dump`)"), - dump_mir_exclude_alloc_bytes: bool = (false, parse_bool, [UNTRACKED], - "exclude the raw bytes of allocations when dumping MIR (used in tests) (default: no)"), - dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], - "exclude the pass number when dumping MIR (used in tests) (default: no)"), - dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], - "in addition to `.mir` files, create graphviz `.dot` files (default: no)"), - dump_mono_stats: SwitchWithOptPath = (SwitchWithOptPath::Disabled, - parse_switch_with_opt_path, [UNTRACKED], - "output statistics about monomorphization collection"), - dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED], - "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"), - #[rustc_lint_opt_deny_field_access("use `Session::dwarf_version` instead of this field")] - dwarf_version: Option = (None, parse_opt_number, [TRACKED], - "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), - dylib_lto: bool = (false, parse_bool, [UNTRACKED], - "enables LTO for dylib crate type"), - eagerly_emit_delayed_bugs: bool = (false, parse_bool, [UNTRACKED], - "emit delayed bugs eagerly as errors instead of stashing them and emitting \ - them only if an error has not been emitted"), - ehcont_guard: bool = (false, parse_bool, [TRACKED], - "generate Windows EHCont Guard tables"), - embed_metadata: bool = (true, parse_bool, [TRACKED], - "embed metadata in rlibs and dylibs (default: yes)"), - embed_source: bool = (false, parse_bool, [TRACKED], - "embed source text in DWARF debug sections (default: no)"), - emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], - "emit a section containing stack size metadata (default: no)"), - emscripten_wasm_eh: bool = (true, parse_bool, [TRACKED], - "Use WebAssembly error handling for wasm32-unknown-emscripten"), - enforce_type_length_limit: bool = (false, parse_bool, [TRACKED], - "enforce the type length limit when monomorphizing instances in codegen"), - experimental_default_bounds: bool = (false, parse_bool, [TRACKED], - "enable default bounds for experimental group of auto traits"), - export_executable_symbols: bool = (false, parse_bool, [TRACKED], - "export symbols from executables, as if they were dynamic libraries"), - external_clangrt: bool = (false, parse_bool, [UNTRACKED], - "rely on user specified linker commands to find clangrt"), - extra_const_ub_checks: bool = (false, parse_bool, [TRACKED], - "turns on more checks to detect const UB, which can be slow (default: no)"), - #[rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field")] - fewer_names: Option = (None, parse_opt_bool, [TRACKED], - "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ - (default: no)"), - fixed_x18: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], - "make the x18 register reserved on AArch64 (default: no)"), - flatten_format_args: bool = (true, parse_bool, [TRACKED], - "flatten nested format_args!() and literals into a simplified format_args!() call \ - (default: yes)"), - fmt_debug: FmtDebug = (FmtDebug::Full, parse_fmt_debug, [TRACKED], - "how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \ - `shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"), - force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], - "force all crates to be `rustc_private` unstable (default: no)"), - function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED], - "replace returns with jumps to `__x86_return_thunk` (default: `keep`)"), - function_sections: Option = (None, parse_opt_bool, [TRACKED], - "whether each function should go in its own section"), - future_incompat_test: bool = (false, parse_bool, [UNTRACKED], - "forces all lints to be future incompatible, used for internal testing (default: no)"), - graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED], - "use dark-themed colors in graphviz output (default: no)"), - graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED], - "use the given `fontname` in graphviz output; can be overridden by setting \ - environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"), - has_thread_local: Option = (None, parse_opt_bool, [TRACKED], - "explicitly enable the `cfg(target_thread_local)` directive"), - help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"), - higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED], - "allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"), - hint_mostly_unused: bool = (false, parse_bool, [TRACKED], - "hint that most of this crate will go unused, to minimize work for uncalled functions"), - human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], - "generate human-readable, predictable names for codegen units (default: no)"), - identify_regions: bool = (false, parse_bool, [UNTRACKED], - "display unnamed regions as `'`, using a non-ident unique id (default: no)"), - ignore_directory_in_diagnostics_source_blocks: Vec = (Vec::new(), parse_string_push, [UNTRACKED], - "do not display the source code block in diagnostics for files in the directory"), - incremental_ignore_spans: bool = (false, parse_bool, [TRACKED], - "ignore spans during ICH computation -- used for testing (default: no)"), - incremental_info: bool = (false, parse_bool, [UNTRACKED], - "print high-level information about incremental reuse (or the lack thereof) \ - (default: no)"), - incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], - "verify extended properties for incr. comp. (default: no): - - hashes of green query instances - - hash collisions of query keys - - hash collisions when creating dep-nodes"), - indirect_branch_cs_prefix: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], - "add `cs` prefix to `call` and `jmp` to indirect thunks (default: no)"), - inline_llvm: bool = (true, parse_bool, [TRACKED], - "enable LLVM inlining (default: yes)"), - inline_mir: Option = (None, parse_opt_bool, [TRACKED], - "enable MIR inlining (default: no)"), - inline_mir_forwarder_threshold: Option = (None, parse_opt_number, [TRACKED], - "inlining threshold when the caller is a simple forwarding function (default: 30)"), - inline_mir_hint_threshold: Option = (None, parse_opt_number, [TRACKED], - "inlining threshold for functions with inline hint (default: 100)"), - inline_mir_preserve_debug: Option = (None, parse_opt_bool, [TRACKED], - "when MIR inlining, whether to preserve debug info for callee variables \ - (default: preserve for debuginfo != None, otherwise remove)"), - inline_mir_threshold: Option = (None, parse_opt_number, [TRACKED], - "a default MIR inlining threshold (default: 50)"), - input_stats: bool = (false, parse_bool, [UNTRACKED], - "print some statistics about AST and HIR (default: no)"), - instrument_mcount: bool = (false, parse_bool, [TRACKED], - "insert function instrument code for mcount-based tracing (default: no)"), - instrument_xray: Option = (None, parse_instrument_xray, [TRACKED], - "insert function instrument code for XRay-based tracing (default: no) - Optional extra settings: - `=always` - `=never` - `=ignore-loops` - `=instruction-threshold=N` - `=skip-entry` - `=skip-exit` - Multiple options can be combined with commas."), - large_data_threshold: Option = (None, parse_opt_number, [TRACKED], - "set the threshold for objects to be stored in a \"large data\" section \ - (only effective with -Ccode-model=medium, default: 65536)"), - layout_seed: Option = (None, parse_opt_number, [TRACKED], - "seed layout randomization"), - link_directives: bool = (true, parse_bool, [TRACKED], - "honor #[link] directives in the compiled crate (default: yes)"), - link_native_libraries: bool = (true, parse_bool, [UNTRACKED], - "link native libraries in the linker invocation (default: yes)"), - link_only: bool = (false, parse_bool, [TRACKED], - "link the `.rlink` file generated by `-Z no-link` (default: no)"), - lint_llvm_ir: bool = (false, parse_bool, [TRACKED], - "lint LLVM IR (default: no)"), - lint_mir: bool = (false, parse_bool, [UNTRACKED], - "lint MIR before and after each transformation"), - llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED], - "a list of module flags to pass to LLVM (space separated)"), - llvm_plugins: Vec = (Vec::new(), parse_list, [TRACKED], - "a list LLVM plugins to enable (space separated)"), - llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], - "generate JSON tracing data file from LLVM data (default: no)"), - location_detail: LocationDetail = (LocationDetail::all(), parse_location_detail, [TRACKED], - "what location details should be tracked when using caller_location, either \ - `none`, or a comma separated list of location details, for which \ - valid options are `file`, `line`, and `column` (default: `file,line,column`)"), - ls: Vec = (Vec::new(), parse_list, [UNTRACKED], - "decode and print various parts of the crate metadata for a library crate \ - (space separated)"), - macro_backtrace: bool = (false, parse_bool, [UNTRACKED], - "show macro backtraces (default: no)"), - macro_stats: bool = (false, parse_bool, [UNTRACKED], - "print some statistics about macro expansions (default: no)"), - maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED], - "save as much information as possible about the correspondence between MIR and HIR \ - as source scopes (default: no)"), - merge_functions: Option = (None, parse_merge_functions, [TRACKED], - "control the operation of the MergeFunctions LLVM pass, taking \ - the same values as the target option of the same name"), - meta_stats: bool = (false, parse_bool, [UNTRACKED], - "gather metadata statistics (default: no)"), - metrics_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], - "the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"), - min_function_alignment: Option = (None, parse_align, [TRACKED], - "align all functions to at least this many bytes. Must be a power of 2"), - min_recursion_limit: Option = (None, parse_opt_number, [TRACKED], - "set a minimum recursion limit (final limit = max(this, recursion_limit_from_crate))"), - mir_emit_retag: bool = (false, parse_bool, [TRACKED], - "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ - (default: no)"), - mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED], - "use like `-Zmir-enable-passes=+DestinationPropagation,-InstSimplify`. Forces the \ - specified passes to be enabled, overriding all other checks. In particular, this will \ - enable unsound (known-buggy and hence usually disabled) passes without further warning! \ - Passes that are not specified are enabled or disabled by other flags as usual."), - mir_include_spans: MirIncludeSpans = (MirIncludeSpans::default(), parse_mir_include_spans, [UNTRACKED], - "include extra comments in mir pretty printing, like line numbers and statement indices, \ - details about types, etc. (boolean for all passes, 'nll' to enable in NLL MIR only, default: 'nll')"), - mir_opt_bisect_limit: Option = (None, parse_opt_number, [TRACKED], - "limit the number of MIR optimization pass executions (global across all bodies). \ - Pass executions after this limit are skipped and reported. (default: no limit)"), - #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] - mir_opt_level: Option = (None, parse_opt_number, [TRACKED], - "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), - mir_preserve_ub: bool = (false, parse_bool, [TRACKED], - "keep place mention statements and reads in trivial SwitchInt terminators, which are interpreted \ - e.g., by miri; implies -Zmir-opt-level=0 (default: no)"), - mir_strip_debuginfo: MirStripDebugInfo = (MirStripDebugInfo::None, parse_mir_strip_debuginfo, [TRACKED], - "Whether to remove some of the MIR debug info from methods. Default: None"), - move_size_limit: Option = (None, parse_opt_number, [TRACKED], - "the size at which the `large_assignments` lint starts to be emitted"), - mutable_noalias: bool = (true, parse_bool, [TRACKED], - "emit noalias metadata for mutable references (default: yes)"), - namespaced_crates: bool = (false, parse_bool, [TRACKED], - "allow crates to be namespaced by other crates (default: no)"), - next_solver: NextSolverConfig = (NextSolverConfig::default(), parse_next_solver_config, [TRACKED], - "enable and configure the next generation trait solver used by rustc"), - nll_facts: bool = (false, parse_bool, [UNTRACKED], - "dump facts from NLL analysis into side files (default: no)"), - nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED], - "the directory the NLL facts are dumped into (default: `nll-facts`)"), - no_analysis: bool = (false, parse_no_value, [UNTRACKED], - "parse and expand the source, but run no analysis"), - no_codegen: bool = (false, parse_no_value, [TRACKED_NO_CRATE_HASH], - "run all passes except codegen; no output"), - no_generate_arange_section: bool = (false, parse_no_value, [TRACKED], - "omit DWARF address ranges that give faster lookups"), - no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED], - "disable the compatibility version of the `implied_bounds_ty` query"), - no_leak_check: bool = (false, parse_no_value, [UNTRACKED], - "disable the 'leak check' for subtyping; unsound, but useful for tests"), - no_link: bool = (false, parse_no_value, [TRACKED], - "compile without linking"), - no_parallel_backend: bool = (false, parse_no_value, [UNTRACKED], - "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), - no_profiler_runtime: bool = (false, parse_no_value, [TRACKED], - "prevent automatic injection of the profiler_builtins crate"), - no_steal_thir: bool = (false, parse_bool, [UNTRACKED], - "don't steal the THIR when we're done with it; useful for rustc drivers (default: no)"), - no_trait_vptr: bool = (false, parse_no_value, [TRACKED], - "disable generation of trait vptr in vtable for upcasting"), - no_unique_section_names: bool = (false, parse_bool, [TRACKED], - "do not use unique names for text and data sections when -Z function-sections is used"), - normalize_docs: bool = (false, parse_bool, [TRACKED], - "normalize associated items in rustdoc when generating documentation"), - offload: Vec = (Vec::new(), parse_offload, [TRACKED], - "a list of offload flags to enable - Mandatory setting: - `=Enable` - Currently the only option available"), - on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED], - "behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"), - osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], - "pass `-install_name @rpath/...` to the macOS linker (default: no)"), - packed_bundled_libs: bool = (false, parse_bool, [TRACKED], - "change rlib format to store native libraries as archives"), - panic_abort_tests: bool = (false, parse_bool, [TRACKED], - "support compiling tests with panic=abort (default: no)"), - panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED], - "panic strategy for panics in drops"), - parse_crate_root_only: bool = (false, parse_bool, [UNTRACKED], - "parse the crate root file only; do not parse other files, compile, assemble, or link \ - (default: no)"), - patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED], - "nop padding at function entry"), - plt: Option = (None, parse_opt_bool, [TRACKED], - "whether to use the PLT when calling into shared libraries; - only has effect for PIC code on systems with ELF binaries - (default: PLT is disabled if full relro is enabled on x86_64)"), - polonius: Polonius = (Polonius::default(), parse_polonius, [TRACKED], - "enable polonius-based borrow-checker (default: no)"), - pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED], - "a single extra argument to prepend the linker invocation (can be used several times)"), - pre_link_args: Vec = (Vec::new(), parse_list, [UNTRACKED], - "extra arguments to prepend to the linker invocation (space separated)"), - precise_enum_drop_elaboration: bool = (true, parse_bool, [TRACKED], - "use a more precise version of drop elaboration for matches on enums (default: yes). \ - This results in better codegen, but has caused miscompilations on some tier 2 platforms. \ - See #77382 and #74551."), - #[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")] - print_codegen_stats: bool = (false, parse_bool, [UNTRACKED], - "print codegen statistics (default: no)"), - print_llvm_passes: bool = (false, parse_bool, [UNTRACKED], - "print the LLVM optimization passes being run (default: no)"), - print_mono_items: bool = (false, parse_bool, [UNTRACKED], - "print the result of the monomorphization collection pass (default: no)"), - print_type_sizes: bool = (false, parse_bool, [UNTRACKED], - "print layout information for each type encountered (default: no)"), - proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], - "show backtraces for panics during proc-macro execution (default: no)"), - proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, - parse_proc_macro_execution_strategy, [UNTRACKED], - "how to run proc-macro code (default: same-thread)"), - profile_closures: bool = (false, parse_no_value, [UNTRACKED], - "profile size of closures"), - profile_sample_use: Option = (None, parse_opt_pathbuf, [TRACKED], - "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), - profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED], - "name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)"), - query_dep_graph: bool = (false, parse_bool, [UNTRACKED], - "enable queries of the dependency graph for regression testing (default: no)"), - randomize_layout: bool = (false, parse_bool, [TRACKED], - "randomize the layout of types (default: no)"), - reg_struct_return: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], - "On x86-32 targets, it overrides the default ABI to return small structs in registers. - It is UNSOUND to link together crates that use different values for this flag!"), - regparm: Option = (None, parse_opt_number, [TRACKED TARGET_MODIFIER], - "On x86-32 targets, setting this to N causes the compiler to pass N arguments \ - in registers EAX, EDX, and ECX instead of on the stack for\ - \"C\", \"cdecl\", and \"stdcall\" fn.\ - It is UNSOUND to link together crates that use different values for this flag!"), - relax_elf_relocations: Option = (None, parse_opt_bool, [TRACKED], - "whether ELF relocations can be relaxed"), - remap_cwd_prefix: Option = (None, parse_opt_pathbuf, [TRACKED], - "remap paths under the current working directory to this path prefix"), - remark_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], - "directory into which to write optimization remarks (if not specified, they will be \ -written to standard error output)"), - retpoline: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], - "enables retpoline-indirect-branches and retpoline-indirect-calls target features (default: no)"), - retpoline_external_thunk: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], - "enables retpoline-external-thunk, retpoline-indirect-branches and retpoline-indirect-calls \ - target features (default: no)"), - #[rustc_lint_opt_deny_field_access("use `Session::sanitizers()` instead of this field")] - sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER], - "use a sanitizer"), - sanitizer_cfi_canonical_jump_tables: Option = (Some(true), parse_opt_bool, [TRACKED], - "enable canonical jump tables (default: yes)"), - sanitizer_cfi_generalize_pointers: Option = (None, parse_opt_bool, [TRACKED], - "enable generalizing pointer types (default: no)"), - sanitizer_cfi_normalize_integers: Option = (None, parse_opt_bool, [TRACKED TARGET_MODIFIER], - "enable normalizing integer types (default: no)"), - sanitizer_dataflow_abilist: Vec = (Vec::new(), parse_comma_list, [TRACKED], - "additional ABI list files that control how shadow parameters are passed (comma separated)"), - sanitizer_kcfi_arity: Option = (None, parse_opt_bool, [TRACKED], - "enable KCFI arity indicator (default: no)"), - sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED], - "enable origins tracking in MemorySanitizer"), - sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], - "enable recovery for selected sanitizers"), - saturating_float_casts: Option = (None, parse_opt_bool, [TRACKED], - "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ - the max/min integer respectively, and NaN is mapped to 0 (default: yes)"), - self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled, - parse_switch_with_opt_path, [UNTRACKED], - "run the self profiler and output the raw event data"), - self_profile_counter: String = ("wall-time".to_string(), parse_string, [UNTRACKED], - "counter used by the self profiler (default: `wall-time`), one of: - `wall-time` (monotonic clock, i.e. `std::time::Instant`) - `instructions:u` (retired instructions, userspace-only) - `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)" - ), - /// keep this in sync with the event filter names in librustc_data_structures/profiling.rs - self_profile_events: Option> = (None, parse_opt_comma_list, [UNTRACKED], - "specify the events recorded by the self profiler; - for example: `-Z self-profile-events=default,query-keys` - all options: none, all, default, generic-activity, query-provider, query-cache-hit - query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"), - share_generics: Option = (None, parse_opt_bool, [TRACKED], - "make the current crate share its generic instantiations"), - shell_argfiles: bool = (false, parse_bool, [UNTRACKED], - "allow argument files to be specified with POSIX \"shell-style\" argument quoting"), - simulate_remapped_rust_src_base: Option = (None, parse_opt_pathbuf, [TRACKED], - "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \ - to rust's source base directory. only meant for testing purposes"), - small_data_threshold: Option = (None, parse_opt_number, [TRACKED], - "Set the threshold for objects to be stored in a \"small data\" section"), - span_debug: bool = (false, parse_bool, [UNTRACKED], - "forward proc_macro::Span's `Debug` impl to `Span`"), - /// o/w tests have closure@path - span_free_formats: bool = (false, parse_bool, [UNTRACKED], - "exclude spans when debug-printing compiler state (default: no)"), - split_dwarf_inlining: bool = (false, parse_bool, [TRACKED], - "provide minimal debug info in the object/executable to facilitate online \ - symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"), - split_dwarf_kind: SplitDwarfKind = (SplitDwarfKind::Split, parse_split_dwarf_kind, [TRACKED], - "split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform) - (default: `split`) - - `split`: sections which do not require relocation are written into a DWARF object (`.dwo`) - file which is ignored by the linker - `single`: sections which do not require relocation are written into object file but ignored - by the linker"), - split_dwarf_out_dir : Option = (None, parse_opt_pathbuf, [TRACKED], - "location for writing split DWARF objects (`.dwo`) if enabled"), - split_lto_unit: Option = (None, parse_opt_bool, [TRACKED], - "enable LTO unit splitting (default: no)"), - src_hash_algorithm: Option = (None, parse_src_file_hash, [TRACKED], - "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), - #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] - stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED], - "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), - staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED], - "allow staticlibs to have rust dylib dependencies"), - staticlib_prefer_dynamic: bool = (false, parse_bool, [TRACKED], - "prefer dynamic linking to static linking for staticlibs (default: no)"), - strict_init_checks: bool = (false, parse_bool, [TRACKED], - "control if mem::uninitialized and mem::zeroed panic on more UB"), - #[rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field")] - teach: bool = (false, parse_bool, [TRACKED], - "show extended diagnostic help (default: no)"), - temps_dir: Option = (None, parse_opt_string, [UNTRACKED], - "the directory the intermediate files are written to"), - terminal_urls: TerminalUrl = (TerminalUrl::No, parse_terminal_url, [UNTRACKED], - "use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output"), - #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")] - thinlto: Option = (None, parse_opt_bool, [TRACKED], - "enable ThinLTO when possible"), - /// We default to 1 here since we want to behave like - /// a sequential compiler for now. This'll likely be adjusted - /// in the future. Note that -Zthreads=0 is the way to get - /// the num_cpus behavior. - #[rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field")] - threads: usize = (1, parse_threads, [UNTRACKED], - "use a thread pool with N threads"), - time_llvm_passes: bool = (false, parse_bool, [UNTRACKED], - "measure time of each LLVM pass (default: no)"), - time_passes: bool = (false, parse_bool, [UNTRACKED], - "measure time of each rustc pass (default: no)"), - time_passes_format: TimePassesFormat = (TimePassesFormat::Text, parse_time_passes_format, [UNTRACKED], - "the format to use for -Z time-passes (`text` (default) or `json`)"), - tiny_const_eval_limit: bool = (false, parse_bool, [TRACKED], - "sets a tiny, non-configurable limit for const eval; useful for compiler tests"), - #[rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field")] - tls_model: Option = (None, parse_tls_model, [TRACKED], - "choose the TLS model to use (`rustc --print tls-models` for details)"), - trace_macros: bool = (false, parse_bool, [UNTRACKED], - "for every macro invocation, print its name and arguments (default: no)"), - track_diagnostics: bool = (false, parse_bool, [UNTRACKED], - "tracks where in rustc a diagnostic was emitted"), - translate_remapped_path_to_local_path: bool = (true, parse_bool, [TRACKED], - "translate remapped paths into local paths when possible (default: yes)"), - trap_unreachable: Option = (None, parse_opt_bool, [TRACKED], - "generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)"), - treat_err_as_bug: Option> = (None, parse_treat_err_as_bug, [TRACKED], - "treat the `val`th error that occurs as bug (default if not specified: 0 - don't treat errors as bugs. \ - default if specified without a value: 1 - treat the first error as bug)"), - trim_diagnostic_paths: bool = (true, parse_bool, [UNTRACKED], - "in diagnostics, use heuristics to shorten paths referring to items"), - tune_cpu: Option = (None, parse_opt_string, [TRACKED], - "select processor to schedule for (`rustc --print target-cpus` for details)"), - #[rustc_lint_opt_deny_field_access("use `TyCtxt::use_typing_mode_borrowck` instead of this field")] - typing_mode_borrowck: bool = (false, parse_bool, [TRACKED], - "enable `TypingMode::Borrowck`, changing the way opaque types are handled during MIR borrowck"), - #[rustc_lint_opt_deny_field_access("use `Session::ub_checks` instead of this field")] - ub_checks: Option = (None, parse_opt_bool, [TRACKED], - "emit runtime checks for Undefined Behavior (default: -Cdebug-assertions)"), - ui_testing: bool = (false, parse_bool, [UNTRACKED], - "emit compiler diagnostics in a form suitable for UI testing (default: no)"), - uninit_const_chunk_threshold: usize = (16, parse_number, [TRACKED], - "allow generating const initializers with mixed init/uninit chunks, \ - and set the maximum number of chunks for which this is allowed (default: 16)"), - unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED], - "take the brakes off const evaluation. NOTE: this is unsound (default: no)"), - unpretty: Option = (None, parse_unpretty, [UNTRACKED], - "present the input source, unstable (and less-pretty) variants; - `normal`, `identified`, - `expanded`, `expanded,identified`, - `expanded,hygiene` (with internal representations), - `ast-tree` (raw AST before expansion), - `ast-tree,expanded` (raw AST after expansion), - `hir` (the HIR), `hir,identified`, - `hir,typed` (HIR with types for each node), - `hir-tree` (dump the raw HIR), - `thir-tree`, `thir-flat`, - `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"), - unsound_mir_opts: bool = (false, parse_bool, [TRACKED], - "enable unsound and buggy MIR optimizations (default: no)"), - /// This name is kind of confusing: Most unstable options enable something themselves, while - /// this just allows "normal" options to be feature-gated. - /// - /// The main check for `-Zunstable-options` takes place separately from the - /// usual parsing of `-Z` options (see [`crate::config::nightly_options`]), - /// so this boolean value is mostly used for enabling unstable _values_ of - /// stable options. That separate check doesn't handle boolean values, so - /// to avoid an inconsistent state we also forbid them here. - #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")] - unstable_options: bool = (false, parse_no_value, [UNTRACKED], - "adds unstable command line options to rustc interface (default: no)"), - use_ctors_section: Option = (None, parse_opt_bool, [TRACKED], - "use legacy .ctors section for initializers rather than .init_array"), - use_sync_unwind: Option = (None, parse_opt_bool, [TRACKED], - "Generate sync unwind tables instead of async unwind tables (default: no)"), - validate_mir: bool = (false, parse_bool, [UNTRACKED], - "validate MIR after each transformation"), - verbose_asm: bool = (false, parse_bool, [TRACKED], - "add descriptive comments from LLVM to the assembly (may change behavior) (default: no)"), - #[rustc_lint_opt_deny_field_access("use `Session::verbose_internals` instead of this field")] - verbose_internals: bool = (false, parse_bool, [TRACKED_NO_CRATE_HASH], - "in general, enable more debug printouts (default: no)"), - #[rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field")] - verify_llvm_ir: bool = (false, parse_bool, [TRACKED], - "verify LLVM IR (default: no)"), - virtual_function_elimination: bool = (false, parse_bool, [TRACKED], - "enables dead virtual function elimination optimization. \ - Requires `-Clto[=[fat,yes]]`"), - wasi_exec_model: Option = (None, parse_wasi_exec_model, [TRACKED], - "whether to build a wasi command or reactor"), - // This option only still exists to provide a more gradual transition path for people who need - // the spec-complaint C ABI to be used. - // FIXME remove this after a couple releases - wasm_c_abi: () = ((), parse_wasm_c_abi, [TRACKED], - "use spec-compliant C ABI for `wasm32-unknown-unknown` (deprecated, always enabled)"), - write_long_types_to_disk: bool = (true, parse_bool, [UNTRACKED], - "whether long type names should be written to files instead of being printed in errors"), - // tidy-alphabetical-end - - // If you add a new option, please update: - // - compiler/rustc_interface/src/tests.rs - // - src/doc/unstable-book/src/compiler-flags -} +include!("options/unstable.rs"); diff --git a/compiler/rustc_session/src/options/unstable.rs b/compiler/rustc_session/src/options/unstable.rs new file mode 100644 index 0000000000000..dc00bd8a223af --- /dev/null +++ b/compiler/rustc_session/src/options/unstable.rs @@ -0,0 +1,585 @@ +options! { + UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable", + + // If you add a new option, please update: + // - compiler/rustc_interface/src/tests.rs + // - src/doc/unstable-book/src/compiler-flags + + // tidy-alphabetical-start + allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], + "only allow the listed language features to be enabled in code (comma separated)"), + always_encode_mir: bool = (false, parse_bool, [TRACKED], + "encode MIR of all functions into the crate metadata (default: no)"), + annotate_moves: AnnotateMoves = (AnnotateMoves::Disabled, parse_annotate_moves, [TRACKED], + "emit debug info for compiler-generated move and copy operations \ + to make them visible in profilers. Can be a boolean or a size limit in bytes (default: disabled)"), + assert_incr_state: Option = (None, parse_opt_string, [UNTRACKED], + "assert that the incremental cache is in given state: \ + either `loaded` or `not-loaded`."), + assume_incomplete_release: bool = (false, parse_bool, [TRACKED], + "make cfg(version) treat the current version as incomplete (default: no)"), + autodiff: Vec = (Vec::new(), parse_autodiff, [TRACKED], + "a list of autodiff flags to enable + Mandatory setting: + `=Enable` + Optional extra settings: + `=PrintTA` + `=PrintAA` + `=PrintPerf` + `=PrintSteps` + `=PrintModBefore` + `=PrintModAfter` + `=PrintModFinal` + `=PrintPasses`, + `=NoPostopt` + `=LooseTypes` + `=Inline` + Multiple options can be combined with commas."), + #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")] + binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], + "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ + (default: no)"), + box_noalias: bool = (true, parse_bool, [TRACKED], + "emit noalias metadata for box (default: yes)"), + branch_protection: Option = (None, parse_branch_protection, [TRACKED TARGET_MODIFIER], + "set options for branch target identification and pointer authentication on AArch64"), + build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED], + "whether the stable interface is being built"), + cache_proc_macros: bool = (false, parse_bool, [TRACKED], + "cache the results of derive proc macro invocations (potentially unsound!) (default: no"), + cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED], + "instrument control-flow architecture protection"), + check_cfg_all_expected: bool = (false, parse_bool, [UNTRACKED], + "show all expected values in check-cfg diagnostics (default: no)"), + checksum_hash_algorithm: Option = (None, parse_cargo_src_file_hash, [TRACKED], + "hash algorithm of source files used to check freshness in cargo (`blake3` or `sha256`)"), + codegen_backend: Option = (None, parse_opt_string, [TRACKED], + "the backend to use"), + codegen_source_order: bool = (false, parse_bool, [UNTRACKED], + "emit mono items in the order of spans in source files (default: no)"), + contract_checks: Option = (None, parse_opt_bool, [TRACKED], + "emit runtime checks for contract pre- and post-conditions (default: no)"), + coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED], + "control details of coverage instrumentation"), + crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], + "inject the given attribute in the crate"), + cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED], + "threshold to allow cross crate inlining of functions"), + debug_info_for_profiling: bool = (false, parse_bool, [TRACKED], + "emit discriminators and other data necessary for AutoFDO"), + debug_info_type_line_numbers: bool = (false, parse_bool, [TRACKED], + "emit type and line information for additional data types (default: no)"), + debuginfo_compression: DebugInfoCompression = (DebugInfoCompression::None, parse_debuginfo_compression, [TRACKED], + "compress debug info sections (none, zlib, zstd, default: none)"), + deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], + "deduplicate identical diagnostics (default: yes)"), + default_visibility: Option = (None, parse_opt_symbol_visibility, [TRACKED], + "overrides the `default_visibility` setting of the target"), + dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], + "in dep-info output, omit targets for tracking dependencies of the dep-info files \ + themselves (default: no)"), + direct_access_external_data: Option = (None, parse_opt_bool, [TRACKED], + "Direct or use GOT indirect to reference external data symbols"), + dual_proc_macros: bool = (false, parse_bool, [TRACKED], + "load proc macros for both target and host, but only link to the target (default: no)"), + dump_dep_graph: bool = (false, parse_bool, [UNTRACKED], + "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \ + (default: no)"), + dump_mir: Option = (None, parse_opt_string, [UNTRACKED], + "dump MIR state to file. + `val` is used to select which passes and functions to dump. For example: + `all` matches all passes and functions, + `foo` matches all passes for functions whose name contains 'foo', + `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo', + `foo | bar` all passes for function names containing 'foo' or 'bar'."), + dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED], + "in addition to `.mir` files, create graphviz `.dot` files with dataflow results \ + (default: no)"), + dump_mir_dir: String = ("mir_dump".to_string(), parse_string, [UNTRACKED], + "the directory the MIR is dumped into (default: `mir_dump`)"), + dump_mir_exclude_alloc_bytes: bool = (false, parse_bool, [UNTRACKED], + "exclude the raw bytes of allocations when dumping MIR (used in tests) (default: no)"), + dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], + "exclude the pass number when dumping MIR (used in tests) (default: no)"), + dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], + "in addition to `.mir` files, create graphviz `.dot` files (default: no)"), + dump_mono_stats: SwitchWithOptPath = (SwitchWithOptPath::Disabled, + parse_switch_with_opt_path, [UNTRACKED], + "output statistics about monomorphization collection"), + dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED], + "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"), + #[rustc_lint_opt_deny_field_access("use `Session::dwarf_version` instead of this field")] + dwarf_version: Option = (None, parse_opt_number, [TRACKED], + "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), + dylib_lto: bool = (false, parse_bool, [UNTRACKED], + "enables LTO for dylib crate type"), + eagerly_emit_delayed_bugs: bool = (false, parse_bool, [UNTRACKED], + "emit delayed bugs eagerly as errors instead of stashing them and emitting \ + them only if an error has not been emitted"), + ehcont_guard: bool = (false, parse_bool, [TRACKED], + "generate Windows EHCont Guard tables"), + embed_metadata: bool = (true, parse_bool, [TRACKED], + "embed metadata in rlibs and dylibs (default: yes)"), + embed_source: bool = (false, parse_bool, [TRACKED], + "embed source text in DWARF debug sections (default: no)"), + emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], + "emit a section containing stack size metadata (default: no)"), + emscripten_wasm_eh: bool = (true, parse_bool, [TRACKED], + "Use WebAssembly error handling for wasm32-unknown-emscripten"), + enforce_type_length_limit: bool = (false, parse_bool, [TRACKED], + "enforce the type length limit when monomorphizing instances in codegen"), + experimental_default_bounds: bool = (false, parse_bool, [TRACKED], + "enable default bounds for experimental group of auto traits"), + export_executable_symbols: bool = (false, parse_bool, [TRACKED], + "export symbols from executables, as if they were dynamic libraries"), + external_clangrt: bool = (false, parse_bool, [UNTRACKED], + "rely on user specified linker commands to find clangrt"), + extra_const_ub_checks: bool = (false, parse_bool, [TRACKED], + "turns on more checks to detect const UB, which can be slow (default: no)"), + #[rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field")] + fewer_names: Option = (None, parse_opt_bool, [TRACKED], + "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ + (default: no)"), + fixed_x18: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], + "make the x18 register reserved on AArch64 (default: no)"), + flatten_format_args: bool = (true, parse_bool, [TRACKED], + "flatten nested format_args!() and literals into a simplified format_args!() call \ + (default: yes)"), + fmt_debug: FmtDebug = (FmtDebug::Full, parse_fmt_debug, [TRACKED], + "how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \ + `shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"), + force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], + "force all crates to be `rustc_private` unstable (default: no)"), + function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED], + "replace returns with jumps to `__x86_return_thunk` (default: `keep`)"), + function_sections: Option = (None, parse_opt_bool, [TRACKED], + "whether each function should go in its own section"), + future_incompat_test: bool = (false, parse_bool, [UNTRACKED], + "forces all lints to be future incompatible, used for internal testing (default: no)"), + graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED], + "use dark-themed colors in graphviz output (default: no)"), + graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED], + "use the given `fontname` in graphviz output; can be overridden by setting \ + environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"), + has_thread_local: Option = (None, parse_opt_bool, [TRACKED], + "explicitly enable the `cfg(target_thread_local)` directive"), + help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"), + higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED], + "allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"), + hint_mostly_unused: bool = (false, parse_bool, [TRACKED], + "hint that most of this crate will go unused, to minimize work for uncalled functions"), + human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], + "generate human-readable, predictable names for codegen units (default: no)"), + identify_regions: bool = (false, parse_bool, [UNTRACKED], + "display unnamed regions as `'`, using a non-ident unique id (default: no)"), + ignore_directory_in_diagnostics_source_blocks: Vec = (Vec::new(), parse_string_push, [UNTRACKED], + "do not display the source code block in diagnostics for files in the directory"), + incremental_ignore_spans: bool = (false, parse_bool, [TRACKED], + "ignore spans during ICH computation -- used for testing (default: no)"), + incremental_info: bool = (false, parse_bool, [UNTRACKED], + "print high-level information about incremental reuse (or the lack thereof) \ + (default: no)"), + incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], + "verify extended properties for incr. comp. (default: no): + - hashes of green query instances + - hash collisions of query keys + - hash collisions when creating dep-nodes"), + indirect_branch_cs_prefix: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], + "add `cs` prefix to `call` and `jmp` to indirect thunks (default: no)"), + inline_llvm: bool = (true, parse_bool, [TRACKED], + "enable LLVM inlining (default: yes)"), + inline_mir: Option = (None, parse_opt_bool, [TRACKED], + "enable MIR inlining (default: no)"), + inline_mir_forwarder_threshold: Option = (None, parse_opt_number, [TRACKED], + "inlining threshold when the caller is a simple forwarding function (default: 30)"), + inline_mir_hint_threshold: Option = (None, parse_opt_number, [TRACKED], + "inlining threshold for functions with inline hint (default: 100)"), + inline_mir_preserve_debug: Option = (None, parse_opt_bool, [TRACKED], + "when MIR inlining, whether to preserve debug info for callee variables \ + (default: preserve for debuginfo != None, otherwise remove)"), + inline_mir_threshold: Option = (None, parse_opt_number, [TRACKED], + "a default MIR inlining threshold (default: 50)"), + input_stats: bool = (false, parse_bool, [UNTRACKED], + "print some statistics about AST and HIR (default: no)"), + instrument_mcount: bool = (false, parse_bool, [TRACKED], + "insert function instrument code for mcount-based tracing (default: no)"), + instrument_xray: Option = (None, parse_instrument_xray, [TRACKED], + "insert function instrument code for XRay-based tracing (default: no) + Optional extra settings: + `=always` + `=never` + `=ignore-loops` + `=instruction-threshold=N` + `=skip-entry` + `=skip-exit` + Multiple options can be combined with commas."), + large_data_threshold: Option = (None, parse_opt_number, [TRACKED], + "set the threshold for objects to be stored in a \"large data\" section \ + (only effective with -Ccode-model=medium, default: 65536)"), + layout_seed: Option = (None, parse_opt_number, [TRACKED], + "seed layout randomization"), + link_directives: bool = (true, parse_bool, [TRACKED], + "honor #[link] directives in the compiled crate (default: yes)"), + link_native_libraries: bool = (true, parse_bool, [UNTRACKED], + "link native libraries in the linker invocation (default: yes)"), + link_only: bool = (false, parse_bool, [TRACKED], + "link the `.rlink` file generated by `-Z no-link` (default: no)"), + lint_llvm_ir: bool = (false, parse_bool, [TRACKED], + "lint LLVM IR (default: no)"), + lint_mir: bool = (false, parse_bool, [UNTRACKED], + "lint MIR before and after each transformation"), + llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED], + "a list of module flags to pass to LLVM (space separated)"), + llvm_plugins: Vec = (Vec::new(), parse_list, [TRACKED], + "a list LLVM plugins to enable (space separated)"), + llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], + "generate JSON tracing data file from LLVM data (default: no)"), + location_detail: LocationDetail = (LocationDetail::all(), parse_location_detail, [TRACKED], + "what location details should be tracked when using caller_location, either \ + `none`, or a comma separated list of location details, for which \ + valid options are `file`, `line`, and `column` (default: `file,line,column`)"), + ls: Vec = (Vec::new(), parse_list, [UNTRACKED], + "decode and print various parts of the crate metadata for a library crate \ + (space separated)"), + macro_backtrace: bool = (false, parse_bool, [UNTRACKED], + "show macro backtraces (default: no)"), + macro_stats: bool = (false, parse_bool, [UNTRACKED], + "print some statistics about macro expansions (default: no)"), + maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED], + "save as much information as possible about the correspondence between MIR and HIR \ + as source scopes (default: no)"), + merge_functions: Option = (None, parse_merge_functions, [TRACKED], + "control the operation of the MergeFunctions LLVM pass, taking \ + the same values as the target option of the same name"), + meta_stats: bool = (false, parse_bool, [UNTRACKED], + "gather metadata statistics (default: no)"), + metrics_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], + "the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"), + min_function_alignment: Option = (None, parse_align, [TRACKED], + "align all functions to at least this many bytes. Must be a power of 2"), + min_recursion_limit: Option = (None, parse_opt_number, [TRACKED], + "set a minimum recursion limit (final limit = max(this, recursion_limit_from_crate))"), + mir_emit_retag: bool = (false, parse_bool, [TRACKED], + "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ + (default: no)"), + mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED], + "use like `-Zmir-enable-passes=+DestinationPropagation,-InstSimplify`. Forces the \ + specified passes to be enabled, overriding all other checks. In particular, this will \ + enable unsound (known-buggy and hence usually disabled) passes without further warning! \ + Passes that are not specified are enabled or disabled by other flags as usual."), + mir_include_spans: MirIncludeSpans = (MirIncludeSpans::default(), parse_mir_include_spans, [UNTRACKED], + "include extra comments in mir pretty printing, like line numbers and statement indices, \ + details about types, etc. (boolean for all passes, 'nll' to enable in NLL MIR only, default: 'nll')"), + mir_opt_bisect_limit: Option = (None, parse_opt_number, [TRACKED], + "limit the number of MIR optimization pass executions (global across all bodies). \ + Pass executions after this limit are skipped and reported. (default: no limit)"), + #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] + mir_opt_level: Option = (None, parse_opt_number, [TRACKED], + "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), + mir_preserve_ub: bool = (false, parse_bool, [TRACKED], + "keep place mention statements and reads in trivial SwitchInt terminators, which are interpreted \ + e.g., by miri; implies -Zmir-opt-level=0 (default: no)"), + mir_strip_debuginfo: MirStripDebugInfo = (MirStripDebugInfo::None, parse_mir_strip_debuginfo, [TRACKED], + "Whether to remove some of the MIR debug info from methods. Default: None"), + move_size_limit: Option = (None, parse_opt_number, [TRACKED], + "the size at which the `large_assignments` lint starts to be emitted"), + mutable_noalias: bool = (true, parse_bool, [TRACKED], + "emit noalias metadata for mutable references (default: yes)"), + namespaced_crates: bool = (false, parse_bool, [TRACKED], + "allow crates to be namespaced by other crates (default: no)"), + next_solver: NextSolverConfig = (NextSolverConfig::default(), parse_next_solver_config, [TRACKED], + "enable and configure the next generation trait solver used by rustc"), + nll_facts: bool = (false, parse_bool, [UNTRACKED], + "dump facts from NLL analysis into side files (default: no)"), + nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED], + "the directory the NLL facts are dumped into (default: `nll-facts`)"), + no_analysis: bool = (false, parse_no_value, [UNTRACKED], + "parse and expand the source, but run no analysis"), + no_codegen: bool = (false, parse_no_value, [TRACKED_NO_CRATE_HASH], + "run all passes except codegen; no output"), + no_generate_arange_section: bool = (false, parse_no_value, [TRACKED], + "omit DWARF address ranges that give faster lookups"), + no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED], + "disable the compatibility version of the `implied_bounds_ty` query"), + no_leak_check: bool = (false, parse_no_value, [UNTRACKED], + "disable the 'leak check' for subtyping; unsound, but useful for tests"), + no_link: bool = (false, parse_no_value, [TRACKED], + "compile without linking"), + no_parallel_backend: bool = (false, parse_no_value, [UNTRACKED], + "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), + no_profiler_runtime: bool = (false, parse_no_value, [TRACKED], + "prevent automatic injection of the profiler_builtins crate"), + no_steal_thir: bool = (false, parse_bool, [UNTRACKED], + "don't steal the THIR when we're done with it; useful for rustc drivers (default: no)"), + no_trait_vptr: bool = (false, parse_no_value, [TRACKED], + "disable generation of trait vptr in vtable for upcasting"), + no_unique_section_names: bool = (false, parse_bool, [TRACKED], + "do not use unique names for text and data sections when -Z function-sections is used"), + normalize_docs: bool = (false, parse_bool, [TRACKED], + "normalize associated items in rustdoc when generating documentation"), + offload: Vec = (Vec::new(), parse_offload, [TRACKED], + "a list of offload flags to enable + Mandatory setting: + `=Enable` + Currently the only option available"), + on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED], + "behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"), + osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], + "pass `-install_name @rpath/...` to the macOS linker (default: no)"), + packed_bundled_libs: bool = (false, parse_bool, [TRACKED], + "change rlib format to store native libraries as archives"), + panic_abort_tests: bool = (false, parse_bool, [TRACKED], + "support compiling tests with panic=abort (default: no)"), + panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED], + "panic strategy for panics in drops"), + parse_crate_root_only: bool = (false, parse_bool, [UNTRACKED], + "parse the crate root file only; do not parse other files, compile, assemble, or link \ + (default: no)"), + patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED], + "nop padding at function entry"), + plt: Option = (None, parse_opt_bool, [TRACKED], + "whether to use the PLT when calling into shared libraries; + only has effect for PIC code on systems with ELF binaries + (default: PLT is disabled if full relro is enabled on x86_64)"), + polonius: Polonius = (Polonius::default(), parse_polonius, [TRACKED], + "enable polonius-based borrow-checker (default: no)"), + pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED], + "a single extra argument to prepend the linker invocation (can be used several times)"), + pre_link_args: Vec = (Vec::new(), parse_list, [UNTRACKED], + "extra arguments to prepend to the linker invocation (space separated)"), + precise_enum_drop_elaboration: bool = (true, parse_bool, [TRACKED], + "use a more precise version of drop elaboration for matches on enums (default: yes). \ + This results in better codegen, but has caused miscompilations on some tier 2 platforms. \ + See #77382 and #74551."), + #[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")] + print_codegen_stats: bool = (false, parse_bool, [UNTRACKED], + "print codegen statistics (default: no)"), + print_llvm_passes: bool = (false, parse_bool, [UNTRACKED], + "print the LLVM optimization passes being run (default: no)"), + print_mono_items: bool = (false, parse_bool, [UNTRACKED], + "print the result of the monomorphization collection pass (default: no)"), + print_type_sizes: bool = (false, parse_bool, [UNTRACKED], + "print layout information for each type encountered (default: no)"), + proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], + "show backtraces for panics during proc-macro execution (default: no)"), + proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, + parse_proc_macro_execution_strategy, [UNTRACKED], + "how to run proc-macro code (default: same-thread)"), + profile_closures: bool = (false, parse_no_value, [UNTRACKED], + "profile size of closures"), + profile_sample_use: Option = (None, parse_opt_pathbuf, [TRACKED], + "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), + profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED], + "name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)"), + query_dep_graph: bool = (false, parse_bool, [UNTRACKED], + "enable queries of the dependency graph for regression testing (default: no)"), + randomize_layout: bool = (false, parse_bool, [TRACKED], + "randomize the layout of types (default: no)"), + reg_struct_return: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], + "On x86-32 targets, it overrides the default ABI to return small structs in registers. + It is UNSOUND to link together crates that use different values for this flag!"), + regparm: Option = (None, parse_opt_number, [TRACKED TARGET_MODIFIER], + "On x86-32 targets, setting this to N causes the compiler to pass N arguments \ + in registers EAX, EDX, and ECX instead of on the stack for\ + \"C\", \"cdecl\", and \"stdcall\" fn.\ + It is UNSOUND to link together crates that use different values for this flag!"), + relax_elf_relocations: Option = (None, parse_opt_bool, [TRACKED], + "whether ELF relocations can be relaxed"), + remap_cwd_prefix: Option = (None, parse_opt_pathbuf, [TRACKED], + "remap paths under the current working directory to this path prefix"), + remark_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], + "directory into which to write optimization remarks (if not specified, they will be \ +written to standard error output)"), + retpoline: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], + "enables retpoline-indirect-branches and retpoline-indirect-calls target features (default: no)"), + retpoline_external_thunk: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER], + "enables retpoline-external-thunk, retpoline-indirect-branches and retpoline-indirect-calls \ + target features (default: no)"), + #[rustc_lint_opt_deny_field_access("use `Session::sanitizers()` instead of this field")] + sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER], + "use a sanitizer"), + sanitizer_cfi_canonical_jump_tables: Option = (Some(true), parse_opt_bool, [TRACKED], + "enable canonical jump tables (default: yes)"), + sanitizer_cfi_generalize_pointers: Option = (None, parse_opt_bool, [TRACKED], + "enable generalizing pointer types (default: no)"), + sanitizer_cfi_normalize_integers: Option = (None, parse_opt_bool, [TRACKED TARGET_MODIFIER], + "enable normalizing integer types (default: no)"), + sanitizer_dataflow_abilist: Vec = (Vec::new(), parse_comma_list, [TRACKED], + "additional ABI list files that control how shadow parameters are passed (comma separated)"), + sanitizer_kcfi_arity: Option = (None, parse_opt_bool, [TRACKED], + "enable KCFI arity indicator (default: no)"), + sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED], + "enable origins tracking in MemorySanitizer"), + sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], + "enable recovery for selected sanitizers"), + saturating_float_casts: Option = (None, parse_opt_bool, [TRACKED], + "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ + the max/min integer respectively, and NaN is mapped to 0 (default: yes)"), + self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled, + parse_switch_with_opt_path, [UNTRACKED], + "run the self profiler and output the raw event data"), + self_profile_counter: String = ("wall-time".to_string(), parse_string, [UNTRACKED], + "counter used by the self profiler (default: `wall-time`), one of: + `wall-time` (monotonic clock, i.e. `std::time::Instant`) + `instructions:u` (retired instructions, userspace-only) + `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)" + ), + /// keep this in sync with the event filter names in librustc_data_structures/profiling.rs + self_profile_events: Option> = (None, parse_opt_comma_list, [UNTRACKED], + "specify the events recorded by the self profiler; + for example: `-Z self-profile-events=default,query-keys` + all options: none, all, default, generic-activity, query-provider, query-cache-hit + query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"), + share_generics: Option = (None, parse_opt_bool, [TRACKED], + "make the current crate share its generic instantiations"), + shell_argfiles: bool = (false, parse_bool, [UNTRACKED], + "allow argument files to be specified with POSIX \"shell-style\" argument quoting"), + simulate_remapped_rust_src_base: Option = (None, parse_opt_pathbuf, [TRACKED], + "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \ + to rust's source base directory. only meant for testing purposes"), + small_data_threshold: Option = (None, parse_opt_number, [TRACKED], + "Set the threshold for objects to be stored in a \"small data\" section"), + span_debug: bool = (false, parse_bool, [UNTRACKED], + "forward proc_macro::Span's `Debug` impl to `Span`"), + /// o/w tests have closure@path + span_free_formats: bool = (false, parse_bool, [UNTRACKED], + "exclude spans when debug-printing compiler state (default: no)"), + split_dwarf_inlining: bool = (false, parse_bool, [TRACKED], + "provide minimal debug info in the object/executable to facilitate online \ + symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"), + split_dwarf_kind: SplitDwarfKind = (SplitDwarfKind::Split, parse_split_dwarf_kind, [TRACKED], + "split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform) + (default: `split`) + + `split`: sections which do not require relocation are written into a DWARF object (`.dwo`) + file which is ignored by the linker + `single`: sections which do not require relocation are written into object file but ignored + by the linker"), + split_dwarf_out_dir : Option = (None, parse_opt_pathbuf, [TRACKED], + "location for writing split DWARF objects (`.dwo`) if enabled"), + split_lto_unit: Option = (None, parse_opt_bool, [TRACKED], + "enable LTO unit splitting (default: no)"), + src_hash_algorithm: Option = (None, parse_src_file_hash, [TRACKED], + "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), + #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] + stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED], + "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), + staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED], + "allow staticlibs to have rust dylib dependencies"), + staticlib_prefer_dynamic: bool = (false, parse_bool, [TRACKED], + "prefer dynamic linking to static linking for staticlibs (default: no)"), + strict_init_checks: bool = (false, parse_bool, [TRACKED], + "control if mem::uninitialized and mem::zeroed panic on more UB"), + #[rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field")] + teach: bool = (false, parse_bool, [TRACKED], + "show extended diagnostic help (default: no)"), + temps_dir: Option = (None, parse_opt_string, [UNTRACKED], + "the directory the intermediate files are written to"), + terminal_urls: TerminalUrl = (TerminalUrl::No, parse_terminal_url, [UNTRACKED], + "use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output"), + #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")] + thinlto: Option = (None, parse_opt_bool, [TRACKED], + "enable ThinLTO when possible"), + /// We default to 1 here since we want to behave like + /// a sequential compiler for now. This'll likely be adjusted + /// in the future. Note that -Zthreads=0 is the way to get + /// the num_cpus behavior. + #[rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field")] + threads: usize = (1, parse_threads, [UNTRACKED], + "use a thread pool with N threads"), + time_llvm_passes: bool = (false, parse_bool, [UNTRACKED], + "measure time of each LLVM pass (default: no)"), + time_passes: bool = (false, parse_bool, [UNTRACKED], + "measure time of each rustc pass (default: no)"), + time_passes_format: TimePassesFormat = (TimePassesFormat::Text, parse_time_passes_format, [UNTRACKED], + "the format to use for -Z time-passes (`text` (default) or `json`)"), + tiny_const_eval_limit: bool = (false, parse_bool, [TRACKED], + "sets a tiny, non-configurable limit for const eval; useful for compiler tests"), + #[rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field")] + tls_model: Option = (None, parse_tls_model, [TRACKED], + "choose the TLS model to use (`rustc --print tls-models` for details)"), + trace_macros: bool = (false, parse_bool, [UNTRACKED], + "for every macro invocation, print its name and arguments (default: no)"), + track_diagnostics: bool = (false, parse_bool, [UNTRACKED], + "tracks where in rustc a diagnostic was emitted"), + translate_remapped_path_to_local_path: bool = (true, parse_bool, [TRACKED], + "translate remapped paths into local paths when possible (default: yes)"), + trap_unreachable: Option = (None, parse_opt_bool, [TRACKED], + "generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)"), + treat_err_as_bug: Option> = (None, parse_treat_err_as_bug, [TRACKED], + "treat the `val`th error that occurs as bug (default if not specified: 0 - don't treat errors as bugs. \ + default if specified without a value: 1 - treat the first error as bug)"), + trim_diagnostic_paths: bool = (true, parse_bool, [UNTRACKED], + "in diagnostics, use heuristics to shorten paths referring to items"), + tune_cpu: Option = (None, parse_opt_string, [TRACKED], + "select processor to schedule for (`rustc --print target-cpus` for details)"), + #[rustc_lint_opt_deny_field_access("use `TyCtxt::use_typing_mode_borrowck` instead of this field")] + typing_mode_borrowck: bool = (false, parse_bool, [TRACKED], + "enable `TypingMode::Borrowck`, changing the way opaque types are handled during MIR borrowck"), + #[rustc_lint_opt_deny_field_access("use `Session::ub_checks` instead of this field")] + ub_checks: Option = (None, parse_opt_bool, [TRACKED], + "emit runtime checks for Undefined Behavior (default: -Cdebug-assertions)"), + ui_testing: bool = (false, parse_bool, [UNTRACKED], + "emit compiler diagnostics in a form suitable for UI testing (default: no)"), + uninit_const_chunk_threshold: usize = (16, parse_number, [TRACKED], + "allow generating const initializers with mixed init/uninit chunks, \ + and set the maximum number of chunks for which this is allowed (default: 16)"), + unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED], + "take the brakes off const evaluation. NOTE: this is unsound (default: no)"), + unpretty: Option = (None, parse_unpretty, [UNTRACKED], + "present the input source, unstable (and less-pretty) variants; + `normal`, `identified`, + `expanded`, `expanded,identified`, + `expanded,hygiene` (with internal representations), + `ast-tree` (raw AST before expansion), + `ast-tree,expanded` (raw AST after expansion), + `hir` (the HIR), `hir,identified`, + `hir,typed` (HIR with types for each node), + `hir-tree` (dump the raw HIR), + `thir-tree`, `thir-flat`, + `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"), + unsound_mir_opts: bool = (false, parse_bool, [TRACKED], + "enable unsound and buggy MIR optimizations (default: no)"), + /// This name is kind of confusing: Most unstable options enable something themselves, while + /// this just allows "normal" options to be feature-gated. + /// + /// The main check for `-Zunstable-options` takes place separately from the + /// usual parsing of `-Z` options (see [`crate::config::nightly_options`]), + /// so this boolean value is mostly used for enabling unstable _values_ of + /// stable options. That separate check doesn't handle boolean values, so + /// to avoid an inconsistent state we also forbid them here. + #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")] + unstable_options: bool = (false, parse_no_value, [UNTRACKED], + "adds unstable command line options to rustc interface (default: no)"), + use_ctors_section: Option = (None, parse_opt_bool, [TRACKED], + "use legacy .ctors section for initializers rather than .init_array"), + use_sync_unwind: Option = (None, parse_opt_bool, [TRACKED], + "Generate sync unwind tables instead of async unwind tables (default: no)"), + validate_mir: bool = (false, parse_bool, [UNTRACKED], + "validate MIR after each transformation"), + verbose_asm: bool = (false, parse_bool, [TRACKED], + "add descriptive comments from LLVM to the assembly (may change behavior) (default: no)"), + #[rustc_lint_opt_deny_field_access("use `Session::verbose_internals` instead of this field")] + verbose_internals: bool = (false, parse_bool, [TRACKED_NO_CRATE_HASH], + "in general, enable more debug printouts (default: no)"), + #[rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field")] + verify_llvm_ir: bool = (false, parse_bool, [TRACKED], + "verify LLVM IR (default: no)"), + virtual_function_elimination: bool = (false, parse_bool, [TRACKED], + "enables dead virtual function elimination optimization. \ + Requires `-Clto[=[fat,yes]]`"), + wasi_exec_model: Option = (None, parse_wasi_exec_model, [TRACKED], + "whether to build a wasi command or reactor"), + // This option only still exists to provide a more gradual transition path for people who need + // the spec-complaint C ABI to be used. + // FIXME remove this after a couple releases + wasm_c_abi: () = ((), parse_wasm_c_abi, [TRACKED], + "use spec-compliant C ABI for `wasm32-unknown-unknown` (deprecated, always enabled)"), + write_long_types_to_disk: bool = (true, parse_bool, [UNTRACKED], + "whether long type names should be written to files instead of being printed in errors"), + // tidy-alphabetical-end + + // If you add a new option, please update: + // - compiler/rustc_interface/src/tests.rs + // - src/doc/unstable-book/src/compiler-flags +} diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index ea16231880e2c..54ecf277cd3df 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -155,9 +155,7 @@ fn get_symbol_hash<'tcx>( args.hash_stable(hcx, &mut hasher); if let Some(instantiating_crate) = instantiating_crate { - tcx.def_path_hash(instantiating_crate.as_def_id()) - .stable_crate_id() - .hash_stable(hcx, &mut hasher); + tcx.stable_crate_id(instantiating_crate).hash_stable(hcx, &mut hasher); } // We want to avoid accidental collision between different types of instances. diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 95cbb9e07ebb7..eff8cbef99541 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -841,7 +841,7 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { fn print_crate_name(&mut self, cnum: CrateNum) -> Result<(), PrintError> { self.push("C"); if !self.is_exportable { - let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); + let stable_crate_id = self.tcx.stable_crate_id(cnum); self.push_disambiguator(stable_crate_id.as_u64()); } let name = self.tcx.crate_name(cnum); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 7fcaea3a629f1..46bc9bdee04b8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -507,18 +507,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term, ty); - if let Some(body) = self.tcx.hir_maybe_body_owned_by( - self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), - ) { + if let Some(body) = + self.tcx.hir_maybe_body_owned_by(self.tcx.typeck_root_def_id_local(body_def_id)) + { let expr = body.value; local_visitor.visit_expr(expr); } let Some(InferSource { span, kind }) = local_visitor.infer_source else { let silence = if let DefKind::AssocFn = self.tcx.def_kind(body_def_id) - && let parent = self.tcx.parent(body_def_id.into()) - && self.tcx.is_automatically_derived(parent) - && let Some(parent) = parent.as_local() + && let parent = self.tcx.local_parent(body_def_id) + && self.tcx.is_automatically_derived(parent.to_def_id()) && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(parent) && let hir::ItemKind::Impl(imp) = item.kind && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = imp.self_ty.kind diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index eeccf1eb0ecfa..d6cfc993c8b83 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -285,14 +285,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); let trait_def_id = main_trait_predicate.def_id(); - if self.tcx.is_diagnostic_item(sym::From, trait_def_id) - || self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) + let leaf_trait_def_id = leaf_trait_predicate.def_id(); + if (self.tcx.is_diagnostic_item(sym::From, trait_def_id) + || self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id)) + && (self.tcx.is_diagnostic_item(sym::From, leaf_trait_def_id) + || self.tcx.is_diagnostic_item(sym::TryFrom, leaf_trait_def_id)) { let trait_ref = leaf_trait_predicate.skip_binder().trait_ref; - // Defensive: next-solver may produce fewer args than expected. - if trait_ref.args.len() > 1 { - let found_ty = trait_ref.args.type_at(1); + if let Some(found_ty) = trait_ref.args.get(1).and_then(|arg| arg.as_type()) + { let ty = main_trait_predicate.skip_binder().self_ty(); if let Some(cast_ty) = self.find_explicit_cast_type( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 4a6d5eb48f8f1..a16bbf20238c0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1966,10 +1966,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut span = obligation.cause.span; if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) - && let parent = self.tcx.parent(obligation.cause.body_id.into()) + && let parent = self.tcx.local_parent(obligation.cause.body_id) && let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent) && self.tcx.asyncness(parent).is_async() - && let Some(parent) = parent.as_local() && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) | Node::TraitItem(hir::TraitItem { diff --git a/compiler/rustc_ty_utils/src/nested_bodies.rs b/compiler/rustc_ty_utils/src/nested_bodies.rs index 11dfbad7dbb7a..874c8161453b3 100644 --- a/compiler/rustc_ty_utils/src/nested_bodies.rs +++ b/compiler/rustc_ty_utils/src/nested_bodies.rs @@ -1,27 +1,26 @@ use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::Visitor; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List { let body = tcx.hir_body_owned_by(item); - let mut collector = - NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] }; + let mut collector = NestedBodiesVisitor { tcx, root_def_id: item, nested_bodies: vec![] }; collector.visit_body(body); tcx.mk_local_def_ids(&collector.nested_bodies) } struct NestedBodiesVisitor<'tcx> { tcx: TyCtxt<'tcx>, - root_def_id: DefId, + root_def_id: LocalDefId, nested_bodies: Vec, } impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> { fn visit_nested_body(&mut self, id: hir::BodyId) { let body_def_id = self.tcx.hir_body_owner_def_id(id); - if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id { + if self.tcx.typeck_root_def_id_local(body_def_id) == self.root_def_id { // We visit nested bodies before adding the current body. This // means that nested bodies are always stored before their parent. let body = self.tcx.hir_body(id); diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 16065cbdae1fa..b4ef00bd4ea0d 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -122,6 +122,9 @@ impl Cargo { cmd_kind: Kind, ) -> Cargo { let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind); + if target.synthetic { + cargo.arg("-Zjson-target-spec"); + } match cmd_kind { // No need to configure the target linker for these command types. @@ -165,7 +168,11 @@ impl Cargo { target: TargetSelection, cmd_kind: Kind, ) -> Cargo { - builder.cargo(compiler, mode, source_type, target, cmd_kind) + let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind); + if target.synthetic { + cargo.arg("-Zjson-target-spec"); + } + cargo } pub fn rustdocflag(&mut self, arg: &str) -> &mut Cargo { diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile index 4a090dcdd5085..3d7f5f81fbec6 100644 --- a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile @@ -26,5 +26,5 @@ ENV \ ENV HOSTS=mips-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile index 18b0375f40080..3c798d737a48d 100644 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile @@ -26,5 +26,5 @@ ENV \ ENV HOSTS=mips64-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile index 87407203880b4..32fd634555c2b 100644 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile @@ -26,5 +26,5 @@ ENV \ ENV HOSTS=mips64el-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile index 553f6ea86b72d..73ab0cf5bab65 100644 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile @@ -26,5 +26,5 @@ ENV \ ENV HOSTS=mipsel-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index d721034c2d71d..3caff6edd504a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -522,6 +522,18 @@ impl Options { } } + if output_format == OutputFormat::Json { + if let Some(emit_flag) = emit.iter().find_map(|emit| match emit { + EmitType::HtmlStaticFiles => Some("html-static-files"), + EmitType::HtmlNonStaticFiles => Some("html-non-static-files"), + EmitType::DepInfo(_) => None, + }) { + dcx.fatal(format!( + "the `--emit={emit_flag}` flag is not supported with `--output-format=json`", + )); + } + } + let to_check = matches.opt_strs("check-theme"); if !to_check.is_empty() { let mut content = diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 8b0743c8d9d59..6c45964da0dab 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -332,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { if let ImplItemImplKind::Trait { trait_item_def_id, .. } = impl_kind && let Ok(trait_item_id) = trait_item_def_id { - let impl_id = cx.tcx.parent(owner_id.into()); + let impl_id = cx.tcx.local_parent(owner_id.def_id); let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity(); ( trait_item_id, diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 4fa22ff0cdb5a..4ddf82773d872 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -179,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { } fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool { - let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id()); + let scope_tree = cx.tcx.region_scope_tree(owner); if let Some(first_scope) = scope_tree.var_scope(first) && let Some(second_scope) = scope_tree.var_scope(second) { diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 6048084c8da68..560d62e9d57d7 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -665,11 +665,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } // TODO(calebcartwright): consider enabling box_patterns feature gate - match (&ai.kind, visitor_kind) { - (ast::AssocItemKind::Const(c), AssocTraitItem) => { + match (&ai.kind, assoc_ctxt) { + (ast::AssocItemKind::Const(c), visit::AssocCtxt::Trait) => { self.visit_static(&StaticParts::from_trait_item(ai, c.ident)) } - (ast::AssocItemKind::Const(c), AssocImplItem) => { + (ast::AssocItemKind::Const(c), visit::AssocCtxt::Impl { .. }) => { self.visit_static(&StaticParts::from_impl_item(ai, c.ident)) } (ast::AssocItemKind::Fn(ref fn_kind), _) => { @@ -714,7 +714,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { (ast::AssocItemKind::MacCall(ref mac), _) => { self.visit_mac(mac, MacroPosition::Item); } - _ => unreachable!(), + (ast::AssocItemKind::Delegation(_) | ast::AssocItemKind::DelegationMac(_), _) => { + // TODO(ytmimi) #![feature(fn_delegation)] + // add formatting for `AssocItemKind::Delegation` and `AssocItemKind::DelegationMac` + self.push_rewrite(ai.span, None); + } } } diff --git a/src/tools/rustfmt/tests/target/issue_6513.rs b/src/tools/rustfmt/tests/target/issue_6513.rs new file mode 100644 index 0000000000000..827d4ccdf27fd --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_6513.rs @@ -0,0 +1,10 @@ +#![feature(fn_delegation)] + +struct Ty; +impl Ty { + reuse std::convert::identity; +} + +trait Trait { + reuse std::convert::identity; +} diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml index 73e5a91bec70a..12dd2eda3d9e2 100644 --- a/src/tools/unstable-book-gen/Cargo.toml +++ b/src/tools/unstable-book-gen/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [dependencies] tidy = { path = "../tidy" } +proc-macro2 = { version = "1.0", features = ["span-locations"] } +syn = { version = "2.0", features = ["full", "parsing"] } # not actually needed but required for now to unify the feature selection of # `num-traits` between this and `rustbook` diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 16550f83003dc..21d4da46bef54 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -5,11 +5,16 @@ use std::env; use std::fs::{self, write}; use std::path::Path; +use proc_macro2::{Span, TokenStream, TokenTree}; +use syn::parse::{Parse, ParseStream}; +use syn::{Attribute, Ident, Item, LitStr, Token, parenthesized}; use tidy::diagnostics::RunningCheck; -use tidy::features::{Features, collect_env_vars, collect_lang_features, collect_lib_features}; +use tidy::features::{ + Feature, Features, Status, collect_env_vars, collect_lang_features, collect_lib_features, +}; use tidy::t; use tidy::unstable_book::{ - ENV_VARS_DIR, LANG_FEATURES_DIR, LIB_FEATURES_DIR, PATH_STR, + COMPILER_FLAGS_DIR, ENV_VARS_DIR, LANG_FEATURES_DIR, LIB_FEATURES_DIR, PATH_STR, collect_unstable_book_section_file_names, collect_unstable_feature_names, }; @@ -113,6 +118,188 @@ fn copy_recursive(from: &Path, to: &Path) { } } +fn collect_compiler_flags(compiler_path: &Path) -> Features { + let options_path = compiler_path.join("rustc_session/src/options/unstable.rs"); + let options_rs = t!(fs::read_to_string(&options_path), options_path); + parse_compiler_flags(&options_rs, &options_path) +} + +const DESCRIPTION_FIELD: usize = 3; +const REQUIRED_FIELDS: usize = 4; +const OPTIONAL_FIELDS: usize = 5; + +struct ParsedOptionEntry { + name: String, + line: usize, + description: String, +} + +struct UnstableOptionsInput { + struct_name: Ident, + entries: Vec, +} + +impl Parse for ParsedOptionEntry { + fn parse(input: ParseStream<'_>) -> syn::Result { + let _attrs = input.call(Attribute::parse_outer)?; + + let name: Ident = input.parse()?; + let line = name.span().start().line; + input.parse::()?; + let _ty: syn::Type = input.parse()?; + input.parse::()?; + + let tuple_content; + parenthesized!(tuple_content in input); + let tuple_tokens: TokenStream = tuple_content.parse()?; + let tuple_fields = split_tuple_fields(tuple_tokens); + + if !matches!(tuple_fields.len(), REQUIRED_FIELDS | OPTIONAL_FIELDS) { + return Err(syn::Error::new( + name.span(), + format!( + "unexpected field count for option `{name}`: expected {REQUIRED_FIELDS} or {OPTIONAL_FIELDS}, found {}", + tuple_fields.len() + ), + )); + } + + if tuple_fields.len() == OPTIONAL_FIELDS + && !is_deprecated_marker_field(&tuple_fields[REQUIRED_FIELDS]) + { + return Err(syn::Error::new( + name.span(), + format!( + "unexpected trailing field in option `{name}`: expected `is_deprecated_and_do_nothing: ...`" + ), + )); + } + + let description = parse_description_field(&tuple_fields[DESCRIPTION_FIELD], &name)?; + Ok(Self { name: name.to_string(), line, description }) + } +} + +impl Parse for UnstableOptionsInput { + fn parse(input: ParseStream<'_>) -> syn::Result { + let struct_name: Ident = input.parse()?; + input.parse::()?; + let _tmod_enum_name: Ident = input.parse()?; + input.parse::()?; + let _stat_name: Ident = input.parse()?; + input.parse::()?; + let _opt_module_name: Ident = input.parse()?; + input.parse::()?; + let _prefix: LitStr = input.parse()?; + input.parse::()?; + let _output_name: LitStr = input.parse()?; + input.parse::()?; + + let entries = + syn::punctuated::Punctuated::::parse_terminated(input)? + .into_iter() + .collect(); + + Ok(Self { struct_name, entries }) + } +} + +fn parse_compiler_flags(options_rs: &str, options_path: &Path) -> Features { + let options_input = parse_unstable_options_macro(options_rs).unwrap_or_else(|error| { + panic!("failed to parse unstable options from `{}`: {error}", options_path.display()) + }); + + let mut features = Features::new(); + for entry in options_input.entries { + if entry.name == "help" { + continue; + } + + features.insert( + entry.name, + Feature { + level: Status::Unstable, + since: None, + has_gate_test: false, + tracking_issue: None, + file: options_path.to_path_buf(), + line: entry.line, + description: Some(entry.description), + }, + ); + } + + features +} + +fn parse_unstable_options_macro(source: &str) -> syn::Result { + let ast = syn::parse_file(source)?; + + for item in ast.items { + let Item::Macro(item_macro) = item else { + continue; + }; + + if !item_macro.mac.path.is_ident("options") { + continue; + } + + let parsed = syn::parse2::(item_macro.mac.tokens)?; + if parsed.struct_name == "UnstableOptions" { + return Ok(parsed); + } + } + + Err(syn::Error::new( + Span::call_site(), + "could not find `options!` invocation for `UnstableOptions`", + )) +} + +fn parse_description_field(field: &TokenStream, option_name: &Ident) -> syn::Result { + let lit = syn::parse2::(field.clone()).map_err(|_| { + syn::Error::new_spanned( + field.clone(), + format!("expected description string literal in option `{option_name}`"), + ) + })?; + Ok(lit.value()) +} + +fn split_tuple_fields(tuple_tokens: TokenStream) -> Vec { + let mut fields = Vec::new(); + let mut current = TokenStream::new(); + + for token in tuple_tokens { + if let TokenTree::Punct(punct) = &token { + if punct.as_char() == ',' { + fields.push(current); + current = TokenStream::new(); + continue; + } + } + current.extend([token]); + } + fields.push(current); + + while matches!(fields.last(), Some(field) if field.is_empty()) { + fields.pop(); + } + + fields +} + +fn is_deprecated_marker_field(field: &TokenStream) -> bool { + let mut tokens = field.clone().into_iter(); + let Some(TokenTree::Ident(name)) = tokens.next() else { + return false; + }; + let Some(TokenTree::Punct(colon)) = tokens.next() else { + return false; + }; + name == "is_deprecated_and_do_nothing" && colon.as_char() == ':' +} + fn main() { let library_path_str = env::args_os().nth(1).expect("library/ path required"); let compiler_path_str = env::args_os().nth(2).expect("compiler/ path required"); @@ -129,6 +316,7 @@ fn main() { .filter(|&(ref name, _)| !lang_features.contains_key(name)) .collect(); let env_vars = collect_env_vars(compiler_path); + let compiler_flags = collect_compiler_flags(compiler_path); let doc_src_path = src_path.join(PATH_STR); @@ -144,9 +332,17 @@ fn main() { &dest_path.join(LIB_FEATURES_DIR), &lib_features, ); + generate_feature_files( + &doc_src_path.join(COMPILER_FLAGS_DIR), + &dest_path.join(COMPILER_FLAGS_DIR), + &compiler_flags, + ); generate_env_files(&doc_src_path.join(ENV_VARS_DIR), &dest_path.join(ENV_VARS_DIR), &env_vars); copy_recursive(&doc_src_path, &dest_path); generate_summary(&dest_path, &lang_features, &lib_features); } + +#[cfg(test)] +mod tests; diff --git a/src/tools/unstable-book-gen/src/tests.rs b/src/tools/unstable-book-gen/src/tests.rs new file mode 100644 index 0000000000000..000cfaebdac30 --- /dev/null +++ b/src/tools/unstable-book-gen/src/tests.rs @@ -0,0 +1,73 @@ +use std::path::{Path, PathBuf}; + +use super::parse_compiler_flags; + +#[test] +fn parses_unstable_options_entries() { + let options_rs = r#"options! { + UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable", + + #[rustc_lint_opt_deny_field_access("test attr")] + allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], + "only allow the listed language features to be enabled in code (comma separated)"), + dump_mir: Option = (None, parse_opt_string, [UNTRACKED], + "dump MIR state to file.\n\ + `val` is used to select which passes and functions to dump."), + join_lines: bool = (false, parse_bool, [TRACKED], + "join \ + continued lines"), + help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"), +}"#; + + let features = parse_compiler_flags(options_rs, Path::new("options/unstable.rs")); + + assert!(features.contains_key("allow_features")); + assert!(features.contains_key("dump_mir")); + assert!(features.contains_key("join_lines")); + assert!(!features.contains_key("help")); + + assert!( + features["dump_mir"] + .description + .as_deref() + .expect("dump_mir description should exist") + .starts_with("dump MIR state to file.\n"), + ); + assert_eq!(features["join_lines"].description.as_deref(), Some("join continued lines")); + assert_eq!( + features["allow_features"].description.as_deref(), + Some("only allow the listed language features to be enabled in code (comma separated)"), + ); + assert_eq!(features["allow_features"].file, PathBuf::from("options/unstable.rs")); + assert_eq!(features["allow_features"].line, 5); +} + +#[test] +fn parser_accepts_optional_trailing_metadata() { + let options_rs = r##"options! { + UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable", + + deprecated_flag: bool = (false, parse_no_value, [UNTRACKED], "deprecated flag", + is_deprecated_and_do_nothing: true), + raw_description: bool = (false, parse_no_value, [UNTRACKED], r#"raw "quoted" text"#), +}"##; + + let features = parse_compiler_flags(options_rs, Path::new("options/unstable.rs")); + assert_eq!(features["deprecated_flag"].description.as_deref(), Some("deprecated flag")); + assert_eq!(features["raw_description"].description.as_deref(), Some("raw \"quoted\" text"),); +} + +#[test] +fn parses_real_unstable_options_file() { + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let options_path = manifest_dir.join("../../../compiler/rustc_session/src/options/unstable.rs"); + let options_rs = std::fs::read_to_string(&options_path).unwrap(); + let features = parse_compiler_flags(&options_rs, &options_path); + + assert!(features.contains_key("allow_features")); + assert!(features.contains_key("dump_mir")); + assert!(features.contains_key("unstable_options")); + assert!(!features.contains_key("help")); + assert!(features["dump_mir"].line > 0); + assert!(features["dump_mir"].description.as_deref().unwrap().starts_with("dump MIR state")); +} diff --git a/tests/rustdoc-ui/output-format-json-emit-html.html_non_static.stderr b/tests/rustdoc-ui/output-format-json-emit-html.html_non_static.stderr new file mode 100644 index 0000000000000..8d8e8c6d12281 --- /dev/null +++ b/tests/rustdoc-ui/output-format-json-emit-html.html_non_static.stderr @@ -0,0 +1,2 @@ +error: the `--emit=html-non-static-files` flag is not supported with `--output-format=json` + diff --git a/tests/rustdoc-ui/output-format-json-emit-html.html_static.stderr b/tests/rustdoc-ui/output-format-json-emit-html.html_static.stderr new file mode 100644 index 0000000000000..bc1ddc1b155d1 --- /dev/null +++ b/tests/rustdoc-ui/output-format-json-emit-html.html_static.stderr @@ -0,0 +1,2 @@ +error: the `--emit=html-static-files` flag is not supported with `--output-format=json` + diff --git a/tests/rustdoc-ui/output-format-json-emit-html.rs b/tests/rustdoc-ui/output-format-json-emit-html.rs new file mode 100644 index 0000000000000..7a99cbd91ba6e --- /dev/null +++ b/tests/rustdoc-ui/output-format-json-emit-html.rs @@ -0,0 +1,8 @@ +//@ revisions: html_static html_non_static +//@ check-fail +//@[html_static] compile-flags: -Z unstable-options --output-format=json --emit=html-static-files +//@[html_non_static] compile-flags: -Z unstable-options --output-format=json --emit=html-non-static-files +//[html_static]~? ERROR the `--emit=html-static-files` flag is not supported with `--output-format=json` +//[html_non_static]~? ERROR the `--emit=html-non-static-files` flag is not supported with `--output-format=json` + +pub struct Foo; diff --git a/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.rs b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.rs new file mode 100644 index 0000000000000..b0f67a3b4195e --- /dev/null +++ b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -Z unstable-options --show-coverage --output-format=json --emit=html-non-static-files +//@ check-fail +//~? ERROR the `--emit=html-non-static-files` flag is not supported with `--output-format=json` + +pub struct Foo; diff --git a/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.stderr b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.stderr new file mode 100644 index 0000000000000..8d8e8c6d12281 --- /dev/null +++ b/tests/rustdoc-ui/show-coverage-json-emit-html-non-static.stderr @@ -0,0 +1,2 @@ +error: the `--emit=html-non-static-files` flag is not supported with `--output-format=json` + diff --git a/tests/ui/lint/dead-code/const-underscore-issue-101532.rs b/tests/ui/lint/dead-code/const-underscore-issue-101532.rs new file mode 100644 index 0000000000000..4dc25fbbecea9 --- /dev/null +++ b/tests/ui/lint/dead-code/const-underscore-issue-101532.rs @@ -0,0 +1,14 @@ +//@ check-pass +// Test for issue #101532 - dead code warnings should work inside const _ + +#![warn(dead_code)] + +const _: () = { + let a: (); + struct B {} //~ WARN struct `B` is never constructed + enum C {} //~ WARN enum `C` is never used + fn d() {} //~ WARN function `d` is never used + const E: () = {}; //~ WARN constant `E` is never used +}; + +fn main() {} diff --git a/tests/ui/lint/dead-code/const-underscore-issue-101532.stderr b/tests/ui/lint/dead-code/const-underscore-issue-101532.stderr new file mode 100644 index 0000000000000..d330b9e9f40a4 --- /dev/null +++ b/tests/ui/lint/dead-code/const-underscore-issue-101532.stderr @@ -0,0 +1,32 @@ +warning: struct `B` is never constructed + --> $DIR/const-underscore-issue-101532.rs:8:12 + | +LL | struct B {} + | ^ + | +note: the lint level is defined here + --> $DIR/const-underscore-issue-101532.rs:4:9 + | +LL | #![warn(dead_code)] + | ^^^^^^^^^ + +warning: enum `C` is never used + --> $DIR/const-underscore-issue-101532.rs:9:10 + | +LL | enum C {} + | ^ + +warning: function `d` is never used + --> $DIR/const-underscore-issue-101532.rs:10:8 + | +LL | fn d() {} + | ^ + +warning: constant `E` is never used + --> $DIR/const-underscore-issue-101532.rs:11:11 + | +LL | const E: () = {}; + | ^ + +warning: 4 warnings emitted + diff --git a/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr b/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr index 22fb1b945c654..b1d9c9d018744 100644 --- a/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr +++ b/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr @@ -6,7 +6,7 @@ LL | /// �test� RTL in doc in vec | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' = note: `#[deny(text_direction_codepoint_in_literal)]` on by default error: unicode codepoint changing visible direction of text present in doc comment @@ -19,7 +19,7 @@ LL | | */ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints-macros.rs:33:9 @@ -31,7 +31,7 @@ LL | | */ | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints-macros.rs:41:9 @@ -41,7 +41,7 @@ LL | /// �test� RTL in doc in proc macro | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints-macros.rs:46:9 @@ -51,7 +51,7 @@ LL | /// �test� RTL in doc in proc macro | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}', '\u{2066}' error: aborting due to 5 previous errors diff --git a/tests/ui/parser/unicode-control-codepoints.stderr b/tests/ui/parser/unicode-control-codepoints.stderr index 7978c1435f609..3b273f8212faa 100644 --- a/tests/ui/parser/unicode-control-codepoints.stderr +++ b/tests/ui/parser/unicode-control-codepoints.stderr @@ -232,7 +232,7 @@ LL | /** '�'); */fn foo() {} | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}' error: unicode codepoint changing visible direction of text present in doc comment --> $DIR/unicode-control-codepoints.rs:46:1 @@ -244,7 +244,7 @@ LL | | * '�'); */fn bar() {} | = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen = note: if their presence wasn't intentional, you can remove them - = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}' + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{202e}' error: aborting due to 20 previous errors diff --git a/tests/ui/parser/unicode-control-doc-comment-issue-153096.rs b/tests/ui/parser/unicode-control-doc-comment-issue-153096.rs new file mode 100644 index 0000000000000..a7998daa72fdc --- /dev/null +++ b/tests/ui/parser/unicode-control-doc-comment-issue-153096.rs @@ -0,0 +1,8 @@ +//@ edition: 2024 + +#[allow(unused)] +/// ⁨א⁩, ⁨ב⁩, ⁨ג⁩, ⁨ד⁩, ⁨ה⁩ +//~^ ERROR unicode codepoint changing visible direction of text present in doc comment +fn foo() {} + +fn main() {} diff --git a/tests/ui/parser/unicode-control-doc-comment-issue-153096.stderr b/tests/ui/parser/unicode-control-doc-comment-issue-153096.stderr new file mode 100644 index 0000000000000..668a7844da635 --- /dev/null +++ b/tests/ui/parser/unicode-control-doc-comment-issue-153096.stderr @@ -0,0 +1,13 @@ +error: unicode codepoint changing visible direction of text present in doc comment + --> $DIR/unicode-control-doc-comment-issue-153096.rs:4:1 + | +LL | /// �א�, �ב�, �ג�, �ד�, �ה� + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints + | + = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = note: if their presence wasn't intentional, you can remove them + = note: if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}', '\u{2068}', '\u{2069}' + = note: `#[deny(text_direction_codepoint_in_literal)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs new file mode 100644 index 0000000000000..83687f37f054b --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.rs @@ -0,0 +1,21 @@ +trait Output<'a> { + type Type; +} + +struct Wrapper; + +impl Wrapper { + fn do_something_wrapper(self, _: F) + where + for<'a> F: Output<'a>, + for<'a> O: From<>::Type>, + { + } +} + +fn main() { + let wrapper = Wrapper; + wrapper.do_something_wrapper(|value| ()); + //~^ ERROR the trait bound `for<'a> {closure@ + //~| ERROR the trait bound `for<'a> _: From<<{closure@ +} diff --git a/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr new file mode 100644 index 0000000000000..1e4cb7f1cd18b --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast-unrelated-leaf.stderr @@ -0,0 +1,47 @@ +error[E0277]: the trait bound `for<'a> {closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}: Output<'a>` is not satisfied + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:34 + | +LL | wrapper.do_something_wrapper(|value| ()); + | -------------------- ^^^^^^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | + = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}` +help: this trait has no implementations, consider adding one + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1 + | +LL | trait Output<'a> { + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `Wrapper::do_something_wrapper` + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:10:20 + | +LL | fn do_something_wrapper(self, _: F) + | -------------------- required by a bound in this associated function +LL | where +LL | for<'a> F: Output<'a>, + | ^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper` + +error[E0277]: the trait bound `for<'a> _: From<<{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41} as Output<'a>>::Type>` is not satisfied + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:18:13 + | +LL | wrapper.do_something_wrapper(|value| ()); + | ^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | + = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/explicit-reference-cast-unrelated-leaf.rs:18:34: 18:41}` +help: this trait has no implementations, consider adding one + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:1:1 + | +LL | trait Output<'a> { + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `Wrapper::do_something_wrapper` + --> $DIR/explicit-reference-cast-unrelated-leaf.rs:11:20 + | +LL | fn do_something_wrapper(self, _: F) + | -------------------- required by a bound in this associated function +... +LL | for<'a> O: From<>::Type>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.