mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-16 21:15:18 +03:00
Auto merge of #156305 - JonathanBrouwer:rollup-xjiYS62, r=JonathanBrouwer
Rollup of 7 pull requests Successful merges: - rust-lang/rust#156236 (resolve: Remove `MacroData`) - rust-lang/rust#156298 (Rename the unstable integer `extend` function to `widen`) - rust-lang/rust#154498 (turn some long-deprecated -C options into errors) - rust-lang/rust#155734 (Reject outer attributes on `cfg_select` branches) - rust-lang/rust#156123 (Simplify the creation of synthetic HIR.) - rust-lang/rust#156175 (Dep graph cleanups) - rust-lang/rust#156214 (Do not cache `lints_that_dont_need_to_run` across sessions)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::{AttrStyle, NodeId, token};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_errors::{Diagnostic, MultiSpan};
|
||||
use rustc_feature::{AttributeTemplate, Features};
|
||||
use rustc_hir::attrs::CfgEntry;
|
||||
use rustc_hir::{AttrPath, Target};
|
||||
@@ -76,8 +76,11 @@ pub fn parse_cfg_select(
|
||||
lint_node_id: NodeId,
|
||||
) -> Result<CfgSelectBranches, ErrorGuaranteed> {
|
||||
let mut branches = CfgSelectBranches::default();
|
||||
let mut branch_attr_error: Option<ErrorGuaranteed> = None;
|
||||
|
||||
while p.token != token::Eof {
|
||||
reject_branch_outer_attrs(p, &mut branch_attr_error)?;
|
||||
|
||||
if p.eat_keyword(exp!(Underscore)) {
|
||||
let underscore = p.prev_token;
|
||||
p.expect(exp!(FatArrow)).map_err(|e| e.emit())?;
|
||||
@@ -131,6 +134,10 @@ pub fn parse_cfg_select(
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(guar) = branch_attr_error {
|
||||
return Err(guar);
|
||||
}
|
||||
|
||||
let it = branches
|
||||
.reachable
|
||||
.iter()
|
||||
@@ -143,6 +150,27 @@ pub fn parse_cfg_select(
|
||||
Ok(branches)
|
||||
}
|
||||
|
||||
fn reject_branch_outer_attrs(
|
||||
p: &mut Parser<'_>,
|
||||
branch_attr_error: &mut Option<ErrorGuaranteed>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let Some(spans) = p.parse_cfg_select_branch_outer_attrs().map_err(|e| e.emit())? else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
for (spans, msg) in [
|
||||
(spans.doc_comments, "doc comments are not allowed on `cfg_select` branches"),
|
||||
(spans.attrs, "attributes are not allowed on `cfg_select` branches"),
|
||||
] {
|
||||
if !spans.is_empty() {
|
||||
branch_attr_error
|
||||
.get_or_insert(p.dcx().struct_span_err(MultiSpan::from_spans(spans), msg).emit());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn lint_unreachable(
|
||||
p: &mut Parser<'_>,
|
||||
predicates: impl Iterator<Item = CfgSelectPredicate>,
|
||||
|
||||
@@ -170,6 +170,7 @@ pub struct MacroRulesMacroExpander {
|
||||
transparency: Transparency,
|
||||
kinds: MacroKinds,
|
||||
rules: Vec<MacroRule>,
|
||||
macro_rules: bool,
|
||||
}
|
||||
|
||||
impl MacroRulesMacroExpander {
|
||||
@@ -189,6 +190,14 @@ pub fn kinds(&self) -> MacroKinds {
|
||||
self.kinds
|
||||
}
|
||||
|
||||
pub fn nrules(&self) -> usize {
|
||||
self.rules.len()
|
||||
}
|
||||
|
||||
pub fn is_macro_rules(&self) -> bool {
|
||||
self.macro_rules
|
||||
}
|
||||
|
||||
pub fn expand_derive(
|
||||
&self,
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
@@ -714,13 +723,12 @@ pub fn compile_declarative_macro(
|
||||
span: Span,
|
||||
node_id: NodeId,
|
||||
edition: Edition,
|
||||
) -> (SyntaxExtension, usize) {
|
||||
) -> SyntaxExtension {
|
||||
let mk_syn_ext = |kind| {
|
||||
let is_local = is_defined_in_current_crate(node_id);
|
||||
SyntaxExtension::new(sess, kind, span, Vec::new(), edition, ident.name, attrs, is_local)
|
||||
};
|
||||
let dummy_syn_ext =
|
||||
|guar| (mk_syn_ext(SyntaxExtensionKind::Bang(Arc::new(DummyBang(guar)))), 0);
|
||||
let dummy_syn_ext = |guar| mk_syn_ext(SyntaxExtensionKind::Bang(Arc::new(DummyBang(guar))));
|
||||
|
||||
let macro_rules = macro_def.macro_rules;
|
||||
let exp_sep = if macro_rules { exp!(Semi) } else { exp!(Comma) };
|
||||
@@ -857,9 +865,6 @@ pub fn compile_declarative_macro(
|
||||
return dummy_syn_ext(guar);
|
||||
}
|
||||
|
||||
// Return the number of rules for unused rule linting, if this is a local macro.
|
||||
let nrules = if is_defined_in_current_crate(node_id) { rules.len() } else { 0 };
|
||||
|
||||
let on_unmatch_args = find_attr!(
|
||||
attrs,
|
||||
OnUnmatchArgs { directive, .. } => directive.clone()
|
||||
@@ -875,8 +880,9 @@ pub fn compile_declarative_macro(
|
||||
on_unmatch_args,
|
||||
transparency,
|
||||
rules,
|
||||
macro_rules,
|
||||
};
|
||||
(mk_syn_ext(SyntaxExtensionKind::MacroRules(Arc::new(exp))), nrules)
|
||||
mk_syn_ext(SyntaxExtensionKind::MacroRules(Arc::new(exp)))
|
||||
}
|
||||
|
||||
fn check_no_eof(sess: &Session, p: &Parser<'_>, msg: &'static str) -> Option<ErrorGuaranteed> {
|
||||
|
||||
@@ -1595,6 +1595,20 @@ pub fn node(&self) -> OwnerNode<'tcx> {
|
||||
// Indexing must ensure it is an OwnerNode.
|
||||
self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
|
||||
}
|
||||
|
||||
/// Return an instance of `OwnerNodes` suitable for definitions that have no corresponding AST.
|
||||
pub fn synthetic() -> OwnerNodes<'tcx> {
|
||||
OwnerNodes {
|
||||
// There is no reason to bother computing a hash for a synthetic body.
|
||||
// Just use a constant value.
|
||||
opt_hash_including_bodies: Some(Fingerprint::ZERO),
|
||||
nodes: IndexVec::from_elem_n(
|
||||
ParentedNode { parent: ItemLocalId::INVALID, node: OwnerNode::Synthetic.into() },
|
||||
1,
|
||||
),
|
||||
bodies: SortedMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for OwnerNodes<'_> {
|
||||
|
||||
@@ -578,19 +578,16 @@ macro_rules! untracked {
|
||||
|
||||
// Make sure that changing an [UNTRACKED] option leaves the hash unchanged.
|
||||
// tidy-alphabetical-start
|
||||
untracked!(ar, String::from("abc"));
|
||||
untracked!(codegen_units, Some(42));
|
||||
untracked!(default_linker_libraries, true);
|
||||
untracked!(dlltool, Some(PathBuf::from("custom_dlltool.exe")));
|
||||
untracked!(extra_filename, String::from("extra-filename"));
|
||||
untracked!(incremental, Some(String::from("abc")));
|
||||
untracked!(inline_threshold, Some(0xf007ba11));
|
||||
// `link_arg` is omitted because it just forwards to `link_args`.
|
||||
untracked!(link_args, vec![String::from("abc"), String::from("def")]);
|
||||
untracked!(link_self_contained, LinkSelfContained::on());
|
||||
untracked!(linker, Some(PathBuf::from("linker")));
|
||||
untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc));
|
||||
untracked!(no_stack_check, true);
|
||||
untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")]));
|
||||
untracked!(rpath, true);
|
||||
untracked!(save_temps, true);
|
||||
|
||||
@@ -331,16 +331,15 @@ pub fn with_task<'tcx, OP, R>(
|
||||
format!("forcing query with already existing `DepNode`: {dep_node:?}")
|
||||
});
|
||||
|
||||
let with_deps = |task_deps| with_deps(task_deps, op);
|
||||
let (result, edges) = if tcx.is_eval_always(dep_node.kind) {
|
||||
(with_deps(TaskDepsRef::EvalAlways), EdgesVec::new())
|
||||
(with_deps(TaskDepsRef::EvalAlways, op), EdgesVec::new())
|
||||
} else {
|
||||
let task_deps = Lock::new(TaskDeps::new(
|
||||
#[cfg(debug_assertions)]
|
||||
Some(dep_node),
|
||||
0,
|
||||
));
|
||||
(with_deps(TaskDepsRef::Allow(&task_deps)), task_deps.into_inner().reads)
|
||||
(with_deps(TaskDepsRef::Allow(&task_deps), op), task_deps.into_inner().reads)
|
||||
};
|
||||
|
||||
let dep_node_index =
|
||||
@@ -396,10 +395,10 @@ fn with_anon_task_inner<'tcx, OP, R>(
|
||||
}
|
||||
_ => {
|
||||
// The dep node indices are hashed here instead of hashing the dep nodes of the
|
||||
// dependencies. These indices may refer to different nodes per session, but this isn't
|
||||
// a problem here because we that ensure the final dep node hash is per session only by
|
||||
// combining it with the per session random number `anon_id_seed`. This hash only need
|
||||
// to map the dependencies to a single value on a per session basis.
|
||||
// dependencies. These indices may refer to different nodes per session, but this
|
||||
// isn't a problem here because we that ensure the final dep node hash is per
|
||||
// session only by combining it with the per session `anon_id_seed`. This hash only
|
||||
// need to map the dependencies to a single value on a per session basis.
|
||||
let mut hasher = StableHasher::new();
|
||||
reads.hash(&mut hasher);
|
||||
|
||||
@@ -1223,13 +1222,14 @@ pub struct TaskDeps {
|
||||
#[cfg(debug_assertions)]
|
||||
node: Option<DepNode>,
|
||||
|
||||
/// A vector of `DepNodeIndex`, basically.
|
||||
/// A vector of `DepNodeIndex`, basically. Contains no duplicates.
|
||||
reads: EdgesVec,
|
||||
|
||||
/// When adding new edges to `reads` in `DepGraph::read_index` we need to determine if the edge
|
||||
/// has been seen before. If the number of elements in `reads` is small, we just do a linear
|
||||
/// scan. If the number is higher, a hashset has better perf. This field is that hashset. It's
|
||||
/// only used if the number of elements in `reads` exceeds `LINEAR_SCAN_MAX`.
|
||||
/// When adding a new edge to `reads` in `DepGraph::read_index` we must determine if the edge
|
||||
/// has been seen before. We just do a linear scan of `reads` if its length is less than or
|
||||
/// equal to `LINEAR_SCAN_MAX`. Otherwise, we use this hashset for better performance. Note:
|
||||
/// `reads` is always the canonical edges representation; this field is just to speed up the
|
||||
/// seen-before test.
|
||||
read_set: FxHashSet<DepNodeIndex>,
|
||||
}
|
||||
|
||||
|
||||
@@ -565,6 +565,9 @@
|
||||
|
||||
query lints_that_dont_need_to_run(_: ()) -> &'tcx UnordSet<LintId> {
|
||||
arena_cache
|
||||
// This depends on the lint store, which includes internal lints when the
|
||||
// untracked `-Zunstable-options` flag is set.
|
||||
eval_always
|
||||
desc { "Computing all lints that are explicitly enabled or with a default level greater than Allow" }
|
||||
}
|
||||
|
||||
|
||||
@@ -627,23 +627,8 @@ pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
|
||||
// Fills in all the important parts needed by HIR queries
|
||||
pub fn feed_hir(&self) {
|
||||
self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
|
||||
|
||||
let node = hir::OwnerNode::Synthetic;
|
||||
let bodies = Default::default();
|
||||
let attrs = hir::AttributeMap::EMPTY;
|
||||
|
||||
let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
|
||||
self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
|
||||
let node = node.into();
|
||||
self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
|
||||
opt_hash_including_bodies,
|
||||
nodes: IndexVec::from_elem_n(
|
||||
hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
|
||||
1,
|
||||
),
|
||||
bodies,
|
||||
})));
|
||||
self.feed_owner_id().hir_attr_map(attrs);
|
||||
self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes::synthetic())));
|
||||
self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::{AttrKind, token};
|
||||
use rustc_errors::PResult;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::exp;
|
||||
use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CfgSelectBranchAttrSpans {
|
||||
pub attrs: Vec<Span>,
|
||||
pub doc_comments: Vec<Span>,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
/// Parses a `TokenTree` consisting either of `{ /* ... */ }` optionally followed by a comma
|
||||
/// (and strip the braces and the optional comma) or an expression followed by a comma
|
||||
@@ -36,4 +43,33 @@ pub fn parse_delimited_token_tree(&mut self) -> PResult<'a, TokenStream> {
|
||||
}
|
||||
Ok(TokenStream::from_ast(&expr))
|
||||
}
|
||||
|
||||
/// Parses outer attributes before a `cfg_select!` branch for recovery.
|
||||
pub fn parse_cfg_select_branch_outer_attrs(
|
||||
&mut self,
|
||||
) -> PResult<'a, Option<CfgSelectBranchAttrSpans>> {
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
if attrs.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mut spans = CfgSelectBranchAttrSpans::default();
|
||||
for attr in attrs.take_for_recovery(self.psess) {
|
||||
match attr.kind {
|
||||
AttrKind::Normal(..) => spans.attrs.push(attr.span),
|
||||
// `parse_outer_attributes` already emitted E0753 for inner doc comments before
|
||||
// recovering them as outer doc-comment attributes.
|
||||
AttrKind::DocComment(comment_kind, _)
|
||||
if self.span_to_snippet(attr.span).ok().is_some_and(
|
||||
|snippet| match comment_kind {
|
||||
token::CommentKind::Line => snippet.starts_with("//!"),
|
||||
token::CommentKind::Block => snippet.starts_with("/*!"),
|
||||
},
|
||||
) => {}
|
||||
AttrKind::DocComment(..) => spans.doc_comments.push(attr.span),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Some(spans))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
TyAlias,
|
||||
};
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
use rustc_expand::base::ResolverExpand;
|
||||
use rustc_expand::base::{ResolverExpand, SyntaxExtension, SyntaxExtensionKind};
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_hir::attrs::{AttributeKind, MacroUseArgs};
|
||||
use rustc_hir::def::{self, *};
|
||||
@@ -37,9 +37,8 @@
|
||||
use crate::ref_mut::CmCell;
|
||||
use crate::{
|
||||
BindingKey, Decl, DeclData, DeclKind, DelayedVisResolutionError, ExternModule,
|
||||
ExternPreludeEntry, Finalize, IdentKey, LocalModule, MacroData, Module, ModuleKind,
|
||||
ModuleOrUniformRoot, ParentScope, PathResult, Res, Resolver, Segment, SyntaxExtension, Used,
|
||||
VisResolutionError, errors,
|
||||
ExternPreludeEntry, Finalize, IdentKey, LocalModule, Module, ModuleKind, ModuleOrUniformRoot,
|
||||
ParentScope, PathResult, Res, Resolver, Segment, Used, VisResolutionError, errors,
|
||||
};
|
||||
|
||||
impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
@@ -208,28 +207,28 @@ pub(crate) fn macro_def_scope(&self, def_id: DefId) -> Module<'ra> {
|
||||
}
|
||||
|
||||
/// Gets the `SyntaxExtension` corresponding to `res`.
|
||||
pub(crate) fn get_macro(&self, res: Res) -> Option<&Arc<SyntaxExtension>> {
|
||||
pub(crate) fn get_macro(&self, res: Res) -> Option<&'ra Arc<SyntaxExtension>> {
|
||||
match res {
|
||||
Res::Def(DefKind::Macro(..), def_id) => Some(&self.get_macro_by_def_id(def_id).ext),
|
||||
Res::NonMacroAttr(_) => Some(&self.non_macro_attr),
|
||||
Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
|
||||
Res::NonMacroAttr(_) => Some(self.non_macro_attr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra MacroData {
|
||||
pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra Arc<SyntaxExtension> {
|
||||
// Local macros are always compiled.
|
||||
match def_id.as_local() {
|
||||
Some(local_def_id) => self.local_macro_map[&local_def_id],
|
||||
None => *self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| {
|
||||
None => self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| {
|
||||
let loaded_macro = self.cstore().load_macro_untracked(self.tcx, def_id);
|
||||
let macro_data = match loaded_macro {
|
||||
let ext = match loaded_macro {
|
||||
LoadedMacro::MacroDef { def, ident, attrs, span, edition } => {
|
||||
self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition)
|
||||
}
|
||||
LoadedMacro::ProcMacro(ext) => MacroData::new(Arc::new(ext)),
|
||||
LoadedMacro::ProcMacro(ext) => ext,
|
||||
};
|
||||
|
||||
self.arenas.alloc_macro(macro_data)
|
||||
self.arenas.alloc_macro(ext)
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -1277,8 +1276,10 @@ fn proc_macro_stub(
|
||||
fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) {
|
||||
if !ident.as_str().starts_with('_') {
|
||||
self.r.unused_macros.insert(def_id, (node_id, ident));
|
||||
let nrules = self.r.local_macro_map[&def_id].nrules;
|
||||
self.r.unused_macro_rules.insert(node_id, (def_id, DenseBitSet::new_filled(nrules)));
|
||||
if let SyntaxExtensionKind::MacroRules(mr) = &self.r.local_macro_map[&def_id].kind {
|
||||
let value = (def_id, DenseBitSet::new_filled(mr.nrules()));
|
||||
self.r.unused_macro_rules.insert(node_id, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,8 +1300,7 @@ fn define_macro(
|
||||
Some((macro_kind, ident, span)) => {
|
||||
let macro_kinds = macro_kind.into();
|
||||
let res = Res::Def(DefKind::Macro(macro_kinds), def_id.to_def_id());
|
||||
let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
|
||||
self.r.new_local_macro(def_id, macro_data);
|
||||
self.r.local_macro_map.insert(def_id, self.r.dummy_ext(macro_kind));
|
||||
self.r.proc_macro_stubs.insert(def_id);
|
||||
(res, ident, span, false)
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
||||
fn visit_item(&mut self, i: &'a Item) {
|
||||
// Pick the def data. This need not be unique, but the more
|
||||
// information we encapsulate into, the better
|
||||
let mut opt_macro_data = None;
|
||||
let mut opt_syn_ext = None;
|
||||
let def_kind = match &i.kind {
|
||||
ItemKind::Impl(i) => DefKind::Impl { of_trait: i.of_trait.is_some() },
|
||||
ItemKind::ForeignMod(..) => DefKind::ForeignMod,
|
||||
@@ -165,9 +165,9 @@ fn visit_item(&mut self, i: &'a Item) {
|
||||
},
|
||||
);
|
||||
|
||||
let macro_data = self.r.compile_macro(def, *ident, &attrs, i.span, i.id, edition);
|
||||
let macro_kinds = macro_data.ext.macro_kinds();
|
||||
opt_macro_data = Some(macro_data);
|
||||
let ext = self.r.compile_macro(def, *ident, &attrs, i.span, i.id, edition);
|
||||
let macro_kinds = ext.macro_kinds();
|
||||
opt_syn_ext = Some(ext);
|
||||
DefKind::Macro(macro_kinds)
|
||||
}
|
||||
ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
|
||||
@@ -185,8 +185,8 @@ fn visit_item(&mut self, i: &'a Item) {
|
||||
};
|
||||
let feed = self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span);
|
||||
|
||||
if let Some(macro_data) = opt_macro_data {
|
||||
self.r.new_local_macro(feed.def_id(), macro_data);
|
||||
if let Some(ext) = opt_syn_ext {
|
||||
self.r.local_macro_map.insert(feed.def_id(), self.r.arenas.alloc_macro(ext));
|
||||
}
|
||||
|
||||
self.with_parent(feed.def_id(), |this| {
|
||||
|
||||
@@ -1742,7 +1742,7 @@ pub(crate) fn unresolved_macro_suggestions(
|
||||
if let Some((def_id, unused_ident)) = unused_macro {
|
||||
let scope = self.local_macro_def_scopes[&def_id];
|
||||
let parent_nearest = parent_scope.module.nearest_parent_mod();
|
||||
let unused_macro_kinds = self.local_macro_map[def_id].ext.macro_kinds();
|
||||
let unused_macro_kinds = self.local_macro_map[def_id].macro_kinds();
|
||||
if !unused_macro_kinds.contains(macro_kind.into()) {
|
||||
match macro_kind {
|
||||
MacroKind::Bang => {
|
||||
@@ -1860,13 +1860,13 @@ fn detect_derive_attribute(
|
||||
let mut all_attrs: UnordMap<Symbol, Vec<_>> = UnordMap::default();
|
||||
// We're collecting these in a hashmap, and handle ordering the output further down.
|
||||
#[allow(rustc::potential_query_instability)]
|
||||
for (def_id, data) in self
|
||||
for (def_id, ext) in self
|
||||
.local_macro_map
|
||||
.iter()
|
||||
.map(|(local_id, data)| (local_id.to_def_id(), data))
|
||||
.map(|(local_id, ext)| (local_id.to_def_id(), ext))
|
||||
.chain(self.extern_macro_map.borrow().iter().map(|(id, d)| (*id, d)))
|
||||
{
|
||||
for helper_attr in &data.ext.helper_attrs {
|
||||
for helper_attr in &ext.helper_attrs {
|
||||
let item_name = self.tcx.item_name(def_id);
|
||||
all_attrs.entry(*helper_attr).or_default().push(item_name);
|
||||
if helper_attr == &ident.name {
|
||||
|
||||
@@ -271,7 +271,7 @@ fn hygienic_lexical_parent(
|
||||
// The macro is a proc macro derive
|
||||
&& let Some(def_id) = module.expansion.expn_data().macro_def_id
|
||||
{
|
||||
let ext = &self.get_macro_by_def_id(def_id).ext;
|
||||
let ext = self.get_macro_by_def_id(def_id);
|
||||
if ext.builtin_name.is_none()
|
||||
&& ext.macro_kinds() == MacroKinds::DERIVE
|
||||
&& parent.expansion.outer_expn_is_descendant_of(**ctxt)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
use rustc_errors::{
|
||||
Applicability, BufferedEarlyLint, Diagnostic, MultiSpan, pluralize, struct_span_code_err,
|
||||
};
|
||||
use rustc_expand::base::SyntaxExtensionKind;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs};
|
||||
@@ -1656,7 +1657,9 @@ fn report_cannot_reexport(
|
||||
match decl.kind {
|
||||
// exclude decl_macro
|
||||
DeclKind::Def(Res::Def(DefKind::Macro(_), def_id))
|
||||
if self.get_macro_by_def_id(def_id).macro_rules =>
|
||||
if let SyntaxExtensionKind::MacroRules(mr) =
|
||||
&self.get_macro_by_def_id(def_id).kind
|
||||
&& mr.is_macro_rules() =>
|
||||
{
|
||||
err.subdiagnostic(ConsiderAddingMacroExport { span: decl.span });
|
||||
err.subdiagnostic(ConsiderMarkingAsPubCrate { vis_span: import.vis_span });
|
||||
|
||||
@@ -1265,18 +1265,6 @@ struct DeriveData {
|
||||
has_derive_copy: bool,
|
||||
}
|
||||
|
||||
struct MacroData {
|
||||
ext: Arc<SyntaxExtension>,
|
||||
nrules: usize,
|
||||
macro_rules: bool,
|
||||
}
|
||||
|
||||
impl MacroData {
|
||||
fn new(ext: Arc<SyntaxExtension>) -> MacroData {
|
||||
MacroData { ext, nrules: 0, macro_rules: false }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ResolverOutputs<'tcx> {
|
||||
pub global_ctxt: ResolverGlobalCtxt,
|
||||
pub ast_lowering: ResolverAstLowering<'tcx>,
|
||||
@@ -1396,12 +1384,12 @@ pub struct Resolver<'ra, 'tcx> {
|
||||
registered_tools: &'tcx RegisteredTools,
|
||||
macro_use_prelude: FxIndexMap<Symbol, Decl<'ra>>,
|
||||
/// Eagerly populated map of all local macro definitions.
|
||||
local_macro_map: FxHashMap<LocalDefId, &'ra MacroData> = default::fx_hash_map(),
|
||||
local_macro_map: FxHashMap<LocalDefId, &'ra Arc<SyntaxExtension>> = default::fx_hash_map(),
|
||||
/// Lazily populated cache of macro definitions loaded from external crates.
|
||||
extern_macro_map: CacheRefCell<FxHashMap<DefId, &'ra MacroData>>,
|
||||
dummy_ext_bang: Arc<SyntaxExtension>,
|
||||
dummy_ext_derive: Arc<SyntaxExtension>,
|
||||
non_macro_attr: Arc<SyntaxExtension>,
|
||||
extern_macro_map: CacheRefCell<FxHashMap<DefId, &'ra Arc<SyntaxExtension>>>,
|
||||
dummy_ext_bang: &'ra Arc<SyntaxExtension>,
|
||||
dummy_ext_derive: &'ra Arc<SyntaxExtension>,
|
||||
non_macro_attr: &'ra Arc<SyntaxExtension>,
|
||||
local_macro_def_scopes: FxHashMap<LocalDefId, LocalModule<'ra>> = default::fx_hash_map(),
|
||||
ast_transform_scopes: FxHashMap<LocalExpnId, LocalModule<'ra>> = default::fx_hash_map(),
|
||||
unused_macros: FxIndexMap<LocalDefId, (NodeId, Ident)>,
|
||||
@@ -1520,7 +1508,7 @@ pub struct ResolverArenas<'ra> {
|
||||
imports: TypedArena<ImportData<'ra>>,
|
||||
name_resolutions: TypedArena<CmRefCell<NameResolution<'ra>>>,
|
||||
ast_paths: TypedArena<ast::Path>,
|
||||
macros: TypedArena<MacroData>,
|
||||
macros: TypedArena<Arc<SyntaxExtension>>,
|
||||
dropless: DroplessArena,
|
||||
}
|
||||
|
||||
@@ -1599,8 +1587,8 @@ fn alloc_macro_rules_decl(&'ra self, decl: MacroRulesDecl<'ra>) -> &'ra MacroRul
|
||||
fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] {
|
||||
self.ast_paths.alloc_from_iter(paths.iter().cloned())
|
||||
}
|
||||
fn alloc_macro(&'ra self, macro_data: MacroData) -> &'ra MacroData {
|
||||
self.macros.alloc(macro_data)
|
||||
fn alloc_macro(&'ra self, ext: SyntaxExtension) -> &'ra Arc<SyntaxExtension> {
|
||||
self.macros.alloc(Arc::new(ext))
|
||||
}
|
||||
fn alloc_pattern_spans(&'ra self, spans: impl Iterator<Item = Span>) -> &'ra [Span] {
|
||||
self.dropless.alloc_from_iter(spans)
|
||||
@@ -1819,9 +1807,9 @@ pub fn new(
|
||||
registered_tools,
|
||||
macro_use_prelude: Default::default(),
|
||||
extern_macro_map: Default::default(),
|
||||
dummy_ext_bang: Arc::new(SyntaxExtension::dummy_bang(edition)),
|
||||
dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)),
|
||||
non_macro_attr: Arc::new(SyntaxExtension::non_macro_attr(edition)),
|
||||
dummy_ext_bang: arenas.alloc_macro(SyntaxExtension::dummy_bang(edition)),
|
||||
dummy_ext_derive: arenas.alloc_macro(SyntaxExtension::dummy_derive(edition)),
|
||||
non_macro_attr: arenas.alloc_macro(SyntaxExtension::non_macro_attr(edition)),
|
||||
unused_macros: Default::default(),
|
||||
unused_macro_rules: Default::default(),
|
||||
single_segment_macro_resolutions: Default::default(),
|
||||
@@ -1888,12 +1876,6 @@ fn new_extern_module(
|
||||
module
|
||||
}
|
||||
|
||||
fn new_local_macro(&mut self, def_id: LocalDefId, macro_data: MacroData) -> &'ra MacroData {
|
||||
let mac = self.arenas.alloc_macro(macro_data);
|
||||
self.local_macro_map.insert(def_id, mac);
|
||||
mac
|
||||
}
|
||||
|
||||
fn next_node_id(&mut self) -> NodeId {
|
||||
let start = self.next_node_id;
|
||||
let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
|
||||
@@ -1988,11 +1970,11 @@ fn cstore_mut(&self) -> FreezeWriteGuard<'_, CStore> {
|
||||
CStore::from_tcx_mut(self.tcx)
|
||||
}
|
||||
|
||||
fn dummy_ext(&self, macro_kind: MacroKind) -> Arc<SyntaxExtension> {
|
||||
fn dummy_ext(&self, macro_kind: MacroKind) -> &'ra Arc<SyntaxExtension> {
|
||||
match macro_kind {
|
||||
MacroKind::Bang => Arc::clone(&self.dummy_ext_bang),
|
||||
MacroKind::Derive => Arc::clone(&self.dummy_ext_derive),
|
||||
MacroKind::Attr => Arc::clone(&self.non_macro_attr),
|
||||
MacroKind::Bang => self.dummy_ext_bang,
|
||||
MacroKind::Derive => self.dummy_ext_derive,
|
||||
MacroKind::Attr => self.non_macro_attr,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
use crate::imports::Import;
|
||||
use crate::{
|
||||
BindingKey, CacheCell, CmResolver, Decl, DeclKind, DeriveData, Determinacy, Finalize, IdentKey,
|
||||
InvocationParent, MacroData, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, Res,
|
||||
InvocationParent, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, Res,
|
||||
ResolutionError, Resolver, ScopeSet, Segment, Used,
|
||||
};
|
||||
|
||||
@@ -335,7 +335,7 @@ fn resolve_macro_invocation(
|
||||
)
|
||||
});
|
||||
|
||||
Ok(ext)
|
||||
Ok(Arc::clone(ext))
|
||||
}
|
||||
|
||||
fn record_macro_rule_usage(&mut self, id: NodeId, rule_i: usize) {
|
||||
@@ -360,8 +360,8 @@ fn check_unused_macros(&mut self) {
|
||||
if unused_arms.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let m = &self.local_macro_map[&def_id];
|
||||
let SyntaxExtensionKind::MacroRules(ref m) = m.ext.kind else {
|
||||
let ext = self.local_macro_map[&def_id];
|
||||
let SyntaxExtensionKind::MacroRules(ref m) = ext.kind else {
|
||||
continue;
|
||||
};
|
||||
for arm_i in unused_arms.iter() {
|
||||
@@ -404,7 +404,7 @@ fn resolve_derives(
|
||||
let parent_scope = self.invocation_parent_scopes[&expn_id];
|
||||
for (i, resolution) in entry.resolutions.iter_mut().enumerate() {
|
||||
if resolution.exts.is_none() {
|
||||
resolution.exts = Some(
|
||||
resolution.exts = Some(Arc::clone(
|
||||
match self.cm().resolve_derive_macro_path(
|
||||
&resolution.path,
|
||||
&parent_scope,
|
||||
@@ -431,7 +431,7 @@ fn resolve_derives(
|
||||
return Err(Indeterminate);
|
||||
}
|
||||
},
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
// Sort helpers in a stable way independent from the derive resolution order.
|
||||
@@ -573,7 +573,7 @@ fn smart_resolve_macro_path(
|
||||
deleg_impl: Option<(LocalDefId, Span)>,
|
||||
invoc_in_mod_inert_attr: Option<LocalDefId>,
|
||||
suggestion_span: Option<Span>,
|
||||
) -> Result<(Arc<SyntaxExtension>, Res), Indeterminate> {
|
||||
) -> Result<(&'ra Arc<SyntaxExtension>, Res), Indeterminate> {
|
||||
let (ext, res) = match self.cm().resolve_macro_or_delegation_path(
|
||||
path,
|
||||
kind,
|
||||
@@ -765,7 +765,7 @@ pub(crate) fn resolve_derive_macro_path<'r>(
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
force: bool,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<(Option<Arc<SyntaxExtension>>, Res), Determinacy> {
|
||||
) -> Result<(Option<&'r Arc<SyntaxExtension>>, Res), Determinacy> {
|
||||
self.resolve_macro_or_delegation_path(
|
||||
path,
|
||||
MacroKind::Derive,
|
||||
@@ -788,7 +788,7 @@ fn resolve_macro_or_delegation_path<'r>(
|
||||
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
suggestion_span: Option<Span>,
|
||||
) -> Result<(Option<Arc<SyntaxExtension>>, Res), Determinacy> {
|
||||
) -> Result<(Option<&'ra Arc<SyntaxExtension>>, Res), Determinacy> {
|
||||
let path_span = ast_path.span;
|
||||
let mut path = Segment::from_path(ast_path);
|
||||
|
||||
@@ -872,7 +872,7 @@ fn resolve_macro_or_delegation_path<'r>(
|
||||
Some((impl_def_id, star_span)) => match res {
|
||||
Res::Def(DefKind::Trait, def_id) => {
|
||||
let edition = self.tcx.sess.edition();
|
||||
Some(Arc::new(SyntaxExtension::glob_delegation(
|
||||
Some(self.arenas.alloc_macro(SyntaxExtension::glob_delegation(
|
||||
def_id,
|
||||
impl_def_id,
|
||||
star_span,
|
||||
@@ -881,7 +881,7 @@ fn resolve_macro_or_delegation_path<'r>(
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
None => self.get_macro(res).map(Arc::clone),
|
||||
None => self.get_macro(res),
|
||||
};
|
||||
Ok((ext, res))
|
||||
}
|
||||
@@ -1229,8 +1229,8 @@ pub(crate) fn compile_macro(
|
||||
span: Span,
|
||||
node_id: NodeId,
|
||||
edition: Edition,
|
||||
) -> MacroData {
|
||||
let (mut ext, mut nrules) = compile_declarative_macro(
|
||||
) -> SyntaxExtension {
|
||||
let mut ext = compile_declarative_macro(
|
||||
self.tcx.sess,
|
||||
self.tcx.features(),
|
||||
macro_def,
|
||||
@@ -1247,13 +1247,12 @@ pub(crate) fn compile_macro(
|
||||
// The macro is a built-in, replace its expander function
|
||||
// while still taking everything else from the source code.
|
||||
ext.kind = builtin_ext_kind.clone();
|
||||
nrules = 0;
|
||||
} else {
|
||||
self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident });
|
||||
}
|
||||
}
|
||||
|
||||
MacroData { ext: Arc::new(ext), nrules, macro_rules: macro_def.macro_rules }
|
||||
ext
|
||||
}
|
||||
|
||||
fn path_accessible(
|
||||
|
||||
@@ -653,6 +653,7 @@ macro_rules! redirect_field {
|
||||
|
||||
/// Indicates whether a removed option should warn or error.
|
||||
enum RemovedOption {
|
||||
#[allow(unused)] // we might want deprecated options that warn again in the future
|
||||
Warn,
|
||||
Err,
|
||||
}
|
||||
@@ -2038,10 +2039,9 @@ pub(crate) fn parse_assert_incr_state(
|
||||
// - src/doc/rustc/src/codegen-options/index.md
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
|
||||
ar: String = (String::new(), parse_string, [UNTRACKED],
|
||||
"this option is deprecated and does nothing",
|
||||
removed: Warn),
|
||||
ar: () = ((), parse_ignore, [UNTRACKED],
|
||||
"this option has been removed",
|
||||
removed: Err),
|
||||
#[rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field")]
|
||||
code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED],
|
||||
"choose the code model to use (`rustc --print code-models` for details)"),
|
||||
@@ -2076,11 +2076,10 @@ pub(crate) fn parse_assert_incr_state(
|
||||
help: bool = (false, parse_no_value, [UNTRACKED], "Print codegen options"),
|
||||
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
||||
"enable incremental compilation"),
|
||||
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
|
||||
inline_threshold: Option<u32> = (None, parse_opt_number, [UNTRACKED],
|
||||
"this option is deprecated and does nothing \
|
||||
inline_threshold: () = ((), parse_ignore, [UNTRACKED],
|
||||
"this option has been removed \
|
||||
(consider using `-Cllvm-args=--inline-threshold=...`)",
|
||||
removed: Warn),
|
||||
removed: Err),
|
||||
#[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
|
||||
instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED],
|
||||
"instrument the generated code to support LLVM source-based code coverage reports \
|
||||
@@ -2118,10 +2117,9 @@ pub(crate) fn parse_assert_incr_state(
|
||||
"give an empty list of passes to the pass manager"),
|
||||
no_redzone: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"disable the use of the redzone"),
|
||||
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
|
||||
no_stack_check: bool = (false, parse_no_value, [UNTRACKED],
|
||||
"this option is deprecated and does nothing",
|
||||
removed: Warn),
|
||||
no_stack_check: () = ((), parse_ignore, [UNTRACKED],
|
||||
"this option has been removed",
|
||||
removed: Err),
|
||||
no_vectorize_loops: bool = (false, parse_no_value, [TRACKED],
|
||||
"disable loop vectorization optimization passes"),
|
||||
no_vectorize_slp: bool = (false, parse_no_value, [TRACKED],
|
||||
@@ -2155,7 +2153,6 @@ pub(crate) fn parse_assert_incr_state(
|
||||
"set rpath values in libs/exes (default: no)"),
|
||||
save_temps: bool = (false, parse_bool, [UNTRACKED],
|
||||
"save all temporary output files during compilation (default: no)"),
|
||||
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
|
||||
soft_float: () = ((), parse_ignore, [UNTRACKED],
|
||||
"this option has been removed \
|
||||
(use a corresponding *eabi target instead)",
|
||||
|
||||
@@ -4036,14 +4036,14 @@ pub fn clamp_magnitude(self, limit: $UnsignedT) -> Self {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(120i8, 120", stringify!($SelfT), ".truncate());")]
|
||||
#[doc = concat!("assert_eq!(-120i8, (-120", stringify!($SelfT), ").truncate());")]
|
||||
/// assert_eq!(120i8, 376i32.truncate());
|
||||
/// ```
|
||||
#[must_use = "this returns the truncated value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn truncate<Target>(self) -> Target
|
||||
where Self: [const] traits::TruncateTarget<Target>
|
||||
@@ -4057,15 +4057,15 @@ pub const fn truncate<Target>(self) -> Target
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(120i8, 120", stringify!($SelfT), ".saturating_truncate());")]
|
||||
#[doc = concat!("assert_eq!(-120i8, (-120", stringify!($SelfT), ").saturating_truncate());")]
|
||||
/// assert_eq!(127i8, 376i32.saturating_truncate());
|
||||
/// assert_eq!(-128i8, (-1000i32).saturating_truncate());
|
||||
/// ```
|
||||
#[must_use = "this returns the truncated value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn saturating_truncate<Target>(self) -> Target
|
||||
where Self: [const] traits::TruncateTarget<Target>
|
||||
@@ -4079,15 +4079,15 @@ pub const fn saturating_truncate<Target>(self) -> Target
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(Some(120i8), 120", stringify!($SelfT), ".checked_truncate());")]
|
||||
#[doc = concat!("assert_eq!(Some(-120i8), (-120", stringify!($SelfT), ").checked_truncate());")]
|
||||
/// assert_eq!(None, 376i32.checked_truncate::<i8>());
|
||||
/// assert_eq!(None, (-1000i32).checked_truncate::<i8>());
|
||||
/// ```
|
||||
#[must_use = "this returns the truncated value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn checked_truncate<Target>(self) -> Option<Target>
|
||||
where Self: [const] traits::TruncateTarget<Target>
|
||||
@@ -4095,23 +4095,23 @@ pub const fn checked_truncate<Target>(self) -> Option<Target>
|
||||
traits::TruncateTarget::internal_checked_truncate(self)
|
||||
}
|
||||
|
||||
/// Extend to an integer of the same size or larger, preserving its value.
|
||||
/// Widen to an integer of the same size or larger, preserving its value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
#[doc = concat!("assert_eq!(120i128, 120i8.extend());")]
|
||||
#[doc = concat!("assert_eq!(-120i128, (-120i8).extend());")]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(120i128, 120i8.widen());")]
|
||||
#[doc = concat!("assert_eq!(-120i128, (-120i8).widen());")]
|
||||
/// ```
|
||||
#[must_use = "this returns the extended value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[must_use = "this returns the widened value and does not modify the original"]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn extend<Target>(self) -> Target
|
||||
where Self: [const] traits::ExtendTarget<Target>
|
||||
pub const fn widen<Target>(self) -> Target
|
||||
where Self: [const] traits::WidenTarget<Target>
|
||||
{
|
||||
traits::ExtendTarget::internal_extend(self)
|
||||
traits::WidenTarget::internal_widen(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/// Trait for types that this type can be truncated to
|
||||
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
pub const trait TruncateTarget<Target>: crate::sealed::Sealed {
|
||||
#[doc(hidden)]
|
||||
fn internal_truncate(self) -> Target;
|
||||
@@ -15,12 +15,12 @@ pub const trait TruncateTarget<Target>: crate::sealed::Sealed {
|
||||
fn internal_checked_truncate(self) -> Option<Target>;
|
||||
}
|
||||
|
||||
/// Trait for types that this type can be truncated to
|
||||
/// Trait for types that this type can be widened to
|
||||
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
pub const trait ExtendTarget<Target>: crate::sealed::Sealed {
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
pub const trait WidenTarget<Target>: crate::sealed::Sealed {
|
||||
#[doc(hidden)]
|
||||
fn internal_extend(self) -> Target;
|
||||
fn internal_widen(self) -> Target;
|
||||
}
|
||||
|
||||
macro_rules! impl_truncate {
|
||||
@@ -40,7 +40,7 @@ macro_rules! impl_truncate {
|
||||
);
|
||||
|
||||
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
impl const TruncateTarget<$to> for $from {
|
||||
#[inline]
|
||||
fn internal_truncate(self) -> $to {
|
||||
@@ -70,12 +70,12 @@ fn internal_checked_truncate(self) -> Option<$to> {
|
||||
)+)*};
|
||||
}
|
||||
|
||||
macro_rules! impl_extend {
|
||||
macro_rules! impl_widen {
|
||||
($($from:ty => $($to:ty),+;)*) => {$($(
|
||||
const _: () = assert!(
|
||||
size_of::<$from>() <= size_of::<$to>(),
|
||||
concat!(
|
||||
"cannot extend ",
|
||||
"cannot widen ",
|
||||
stringify!($from),
|
||||
" to ",
|
||||
stringify!($to),
|
||||
@@ -87,9 +87,9 @@ macro_rules! impl_extend {
|
||||
);
|
||||
|
||||
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
impl const ExtendTarget<$to> for $from {
|
||||
fn internal_extend(self) -> $to {
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
impl const WidenTarget<$to> for $from {
|
||||
fn internal_widen(self) -> $to {
|
||||
self as _
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ fn internal_extend(self) -> $to {
|
||||
isize => isize, i16, i8;
|
||||
}
|
||||
|
||||
impl_extend! {
|
||||
impl_widen! {
|
||||
u8 => u8, u16, u32, u64, u128, usize;
|
||||
u16 => u16, u32, u64, u128, usize;
|
||||
u32 => u32, u64, u128;
|
||||
|
||||
@@ -4220,13 +4220,13 @@ pub const fn max_value() -> Self { Self::MAX }
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(120u8, 120", stringify!($SelfT), ".truncate());")]
|
||||
/// assert_eq!(120u8, 376u32.truncate());
|
||||
/// ```
|
||||
#[must_use = "this returns the truncated value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn truncate<Target>(self) -> Target
|
||||
where Self: [const] traits::TruncateTarget<Target>
|
||||
@@ -4240,13 +4240,13 @@ pub const fn truncate<Target>(self) -> Target
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(120u8, 120", stringify!($SelfT), ".saturating_truncate());")]
|
||||
/// assert_eq!(255u8, 376u32.saturating_truncate());
|
||||
/// ```
|
||||
#[must_use = "this returns the truncated value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn saturating_truncate<Target>(self) -> Target
|
||||
where Self: [const] traits::TruncateTarget<Target>
|
||||
@@ -4260,13 +4260,13 @@ pub const fn saturating_truncate<Target>(self) -> Target
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(Some(120u8), 120", stringify!($SelfT), ".checked_truncate());")]
|
||||
/// assert_eq!(None, 376u32.checked_truncate::<u8>());
|
||||
/// ```
|
||||
#[must_use = "this returns the truncated value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn checked_truncate<Target>(self) -> Option<Target>
|
||||
where Self: [const] traits::TruncateTarget<Target>
|
||||
@@ -4274,22 +4274,22 @@ pub const fn checked_truncate<Target>(self) -> Option<Target>
|
||||
traits::TruncateTarget::internal_checked_truncate(self)
|
||||
}
|
||||
|
||||
/// Extend to an integer of the same size or larger, preserving its value.
|
||||
/// Widen to an integer of the same size or larger, preserving its value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(integer_extend_truncate)]
|
||||
#[doc = concat!("assert_eq!(120u128, 120u8.extend());")]
|
||||
/// #![feature(integer_widen_truncate)]
|
||||
#[doc = concat!("assert_eq!(120u128, 120u8.widen());")]
|
||||
/// ```
|
||||
#[must_use = "this returns the extended value and does not modify the original"]
|
||||
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_extend_truncate", issue = "154330")]
|
||||
#[must_use = "this returns the widened value and does not modify the original"]
|
||||
#[unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[rustc_const_unstable(feature = "integer_widen_truncate", issue = "154330")]
|
||||
#[inline]
|
||||
pub const fn extend<Target>(self) -> Target
|
||||
where Self: [const] traits::ExtendTarget<Target>
|
||||
pub const fn widen<Target>(self) -> Target
|
||||
where Self: [const] traits::WidenTarget<Target>
|
||||
{
|
||||
traits::ExtendTarget::internal_extend(self)
|
||||
traits::WidenTarget::internal_widen(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
All of these options are passed to `rustc` via the `-C` flag, short for "codegen." You can see
|
||||
a version of this list for your exact compiler by running `rustc -C help`.
|
||||
|
||||
## ar
|
||||
|
||||
This option is deprecated and does nothing.
|
||||
|
||||
## code-model
|
||||
|
||||
This option lets you choose which code model to use. \
|
||||
@@ -194,12 +190,6 @@ incremental files will be stored.
|
||||
|
||||
Using incremental compilation inhibits certain optimizations (for example by increasing the amount of codegen units) and is therefore not recommended for release builds.
|
||||
|
||||
## inline-threshold
|
||||
|
||||
This option is deprecated and does nothing.
|
||||
|
||||
Consider using `-Cllvm-args=--inline-threshold=...`.
|
||||
|
||||
## instrument-coverage
|
||||
|
||||
This option enables instrumentation-based code coverage support. See the
|
||||
@@ -443,10 +433,6 @@ of the following values:
|
||||
|
||||
The default behaviour, if the flag is not specified, depends on the target.
|
||||
|
||||
## no-stack-check
|
||||
|
||||
This option is deprecated and does nothing.
|
||||
|
||||
## no-vectorize-loops
|
||||
|
||||
This flag disables [loop
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Test that changing a tracked commandline argument invalidates
|
||||
// the cache while changing an untracked one doesn't.
|
||||
|
||||
//@ revisions:rpass1 rpass2 rpass3 rpass4
|
||||
//@ revisions:rpass1 rpass2 rpass3 rpass4 rpass5
|
||||
//@ compile-flags: -Z query-dep-graph
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
@@ -9,6 +9,7 @@
|
||||
#![rustc_partition_codegened(module="commandline_args", cfg="rpass2")]
|
||||
#![rustc_partition_reused(module="commandline_args", cfg="rpass3")]
|
||||
#![rustc_partition_codegened(module="commandline_args", cfg="rpass4")]
|
||||
#![rustc_partition_reused(module="commandline_args", cfg="rpass5")]
|
||||
|
||||
// Between revisions 1 and 2, we are changing the debuginfo-level, which should
|
||||
// invalidate the cache. Between revisions 2 and 3, we are adding `--diagnostic-width`
|
||||
@@ -18,6 +19,10 @@
|
||||
//@[rpass2] compile-flags: -C debuginfo=2
|
||||
//@[rpass3] compile-flags: -C debuginfo=2 --diagnostic-width=80
|
||||
//@[rpass4] compile-flags: -C debuginfo=2 --diagnostic-width=80 --remap-path-prefix=/home/bors/r=src
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/156182.
|
||||
// `-Zunstable-options` enables internal lints, so the lint store changes without
|
||||
// changing the incremental command-line hash.
|
||||
//@[rpass5] compile-flags: -C debuginfo=2 --diagnostic-width=80 --remap-path-prefix=/home/bors/r=src -Zunstable-options
|
||||
//@ ignore-backends: gcc
|
||||
|
||||
pub fn main() {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
//@ compile-flags: -Car=foo
|
||||
|
||||
fn main() {}
|
||||
|
||||
//~? ERROR `-C ar`: this option has been removed
|
||||
@@ -0,0 +1,2 @@
|
||||
error: `-C ar`: this option has been removed
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
//@ check-pass
|
||||
//@ compile-flags: -Car=foo
|
||||
|
||||
fn main() {}
|
||||
|
||||
//~? WARN `-C ar`: this option is deprecated and does nothing
|
||||
@@ -1,2 +0,0 @@
|
||||
warning: `-C ar`: this option is deprecated and does nothing
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
warning: `-C inline-threshold`: this option is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)
|
||||
|
||||
error: incorrect value `asd` for codegen option `inline-threshold` - a number was expected
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
warning: `-C inline-threshold`: this option is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
warning: `-C inline-threshold`: this option is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)
|
||||
|
||||
error: codegen option `inline-threshold` requires a number (`-C inline-threshold=<value>`)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
//@ revisions: good_val bad_val no_val
|
||||
//
|
||||
//@[good_val] compile-flags: -Cinline-threshold=666
|
||||
//@[good_val] check-pass
|
||||
//@[bad_val] compile-flags: -Cinline-threshold=asd
|
||||
//@[no_val] compile-flags: -Cinline-threshold
|
||||
|
||||
fn main() {}
|
||||
|
||||
//[good_val]~? WARN `-C inline-threshold`: this option is deprecated and does nothing
|
||||
//[bad_val]~? WARN `-C inline-threshold`: this option is deprecated and does nothing
|
||||
//[bad_val]~? ERROR incorrect value `asd` for codegen option `inline-threshold`
|
||||
//[no_val]~? WARN `-C inline-threshold`: this option is deprecated and does nothing
|
||||
//[no_val]~? ERROR codegen option `inline-threshold` requires a number
|
||||
@@ -1,6 +0,0 @@
|
||||
#![deny(warnings)]
|
||||
#![feature(no_stack_check)]
|
||||
//~^ ERROR: feature has been removed [E0557]
|
||||
fn main() {
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
error[E0557]: feature has been removed
|
||||
--> $DIR/deprecated_no_stack_check.rs:2:12
|
||||
|
|
||||
LL | #![feature(no_stack_check)]
|
||||
| ^^^^^^^^^^^^^^ feature has been removed
|
||||
|
|
||||
= note: removed in 1.0.0; see <https://github.com/rust-lang/rust/pull/40110> for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0557`.
|
||||
@@ -1,6 +0,0 @@
|
||||
//@ check-pass
|
||||
//@ compile-flags: -Cno-stack-check
|
||||
|
||||
fn main() {}
|
||||
|
||||
//~? WARN `-C no-stack-check`: this option is deprecated and does nothing
|
||||
@@ -1,2 +0,0 @@
|
||||
warning: `-C no-stack-check`: this option is deprecated and does nothing
|
||||
|
||||
@@ -5,17 +5,13 @@ LL | fn ext(&self) {}
|
||||
| --- the method is available for `u8` here
|
||||
...
|
||||
LL | a.ext();
|
||||
| ^^^
|
||||
| ^^^ method not found in `u8`
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
help: trait `SettingsExt` which provides `ext` is implemented but not in scope; perhaps you want to import it
|
||||
|
|
||||
LL + use auto::SettingsExt;
|
||||
|
|
||||
help: there is a method `extend` with a similar name
|
||||
|
|
||||
LL | a.extend();
|
||||
| +++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -202,3 +202,52 @@ fn b() {}
|
||||
//~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `!`
|
||||
//~| WARN unexpected `cfg` condition name
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/155701.
|
||||
cfg_select! {
|
||||
/// doc comment
|
||||
//~^ ERROR doc comments are not allowed on `cfg_select` branches
|
||||
debug_assertions => {}
|
||||
/// doc comment
|
||||
//~^ ERROR doc comments are not allowed on `cfg_select` branches
|
||||
_ => {}
|
||||
}
|
||||
|
||||
cfg_select! {
|
||||
#[cfg(false)]
|
||||
//~^ ERROR attributes are not allowed on `cfg_select` branches
|
||||
debug_assertions => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
cfg_select! {
|
||||
#![cfg(false)]
|
||||
//~^ ERROR an inner attribute is not permitted in this context
|
||||
debug_assertions => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
cfg_select! {
|
||||
//! inner doc comment
|
||||
//~^ ERROR expected outer doc comment
|
||||
debug_assertions => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
cfg_select! {
|
||||
debug_assertions => {}
|
||||
/// line1
|
||||
//~^ ERROR doc comments are not allowed on `cfg_select` branches
|
||||
// line2
|
||||
/// line3
|
||||
_ => {}
|
||||
}
|
||||
|
||||
cfg_select! {
|
||||
/// outer doc comment
|
||||
//~^ ERROR doc comments are not allowed on `cfg_select` branches
|
||||
//! inner doc comment
|
||||
//~^ ERROR expected outer doc comment
|
||||
debug_assertions => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,74 @@ error: expected one of `(`, `::`, `=>`, or `=`, found `!`
|
||||
LL | cfg!() => {}
|
||||
| ^ expected one of `(`, `::`, `=>`, or `=`
|
||||
|
||||
error: doc comments are not allowed on `cfg_select` branches
|
||||
--> $DIR/cfg_select.rs:208:5
|
||||
|
|
||||
LL | /// doc comment
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: doc comments are not allowed on `cfg_select` branches
|
||||
--> $DIR/cfg_select.rs:211:5
|
||||
|
|
||||
LL | /// doc comment
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: attributes are not allowed on `cfg_select` branches
|
||||
--> $DIR/cfg_select.rs:217:5
|
||||
|
|
||||
LL | #[cfg(false)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/cfg_select.rs:224:5
|
||||
|
|
||||
LL | #![cfg(false)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
|
||||
= note: outer attributes, like `#[test]`, annotate the item following them
|
||||
|
||||
error[E0753]: expected outer doc comment
|
||||
--> $DIR/cfg_select.rs:231:5
|
||||
|
|
||||
LL | //! inner doc comment
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
|
||||
help: you might have meant to write a regular comment
|
||||
|
|
||||
LL - //! inner doc comment
|
||||
LL + // inner doc comment
|
||||
|
|
||||
|
||||
error: doc comments are not allowed on `cfg_select` branches
|
||||
--> $DIR/cfg_select.rs:239:5
|
||||
|
|
||||
LL | /// line1
|
||||
| ^^^^^^^^^
|
||||
...
|
||||
LL | /// line3
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0753]: expected outer doc comment
|
||||
--> $DIR/cfg_select.rs:249:5
|
||||
|
|
||||
LL | //! inner doc comment
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
|
||||
help: you might have meant to write a regular comment
|
||||
|
|
||||
LL - //! inner doc comment
|
||||
LL + // inner doc comment
|
||||
|
|
||||
|
||||
error: doc comments are not allowed on `cfg_select` branches
|
||||
--> $DIR/cfg_select.rs:247:5
|
||||
|
|
||||
LL | /// outer doc comment
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unreachable configuration predicate
|
||||
--> $DIR/cfg_select.rs:136:5
|
||||
|
|
||||
@@ -115,7 +183,7 @@ LL | cfg!() => {}
|
||||
= help: to expect this configuration use `--check-cfg=cfg(cfg)`
|
||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
error: aborting due to 9 previous errors; 7 warnings emitted
|
||||
error: aborting due to 17 previous errors; 7 warnings emitted
|
||||
|
||||
Some errors have detailed explanations: E0537, E0539.
|
||||
Some errors have detailed explanations: E0537, E0539, E0753.
|
||||
For more information about an error, try `rustc --explain E0537`.
|
||||
|
||||
Reference in New Issue
Block a user