Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions compiler/rustc_attr_parsing/src/attributes/cfg_select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,28 @@ pub struct CfgSelectBranches {
impl CfgSelectBranches {
/// Removes the top-most branch for which `predicate` returns `true`,
/// or the wildcard if none of the reachable branches satisfied the predicate.
pub fn pop_first_match<F>(&mut self, predicate: F) -> Option<(TokenStream, Span)>
pub fn pop_first_match<F>(&mut self, predicate: F) -> Option<(CfgEntry, TokenStream, Span)>
where
F: Fn(&CfgEntry) -> bool,
{
for (index, (cfg, _, _)) in self.reachable.iter().enumerate() {
if predicate(cfg) {
let matched = self.reachable.remove(index);
return Some((matched.1, matched.2));
return Some(self.reachable.remove(index));
}
}

self.wildcard.take().map(|(_, tts, span)| (tts, span))
self.wildcard.take().map(|(_, tts, span)| (CfgEntry::Bool(true, span), tts, span))
}

/// Consume this value and iterate over all the `TokenStream`s that it stores.
pub fn into_iter_tts(self) -> impl Iterator<Item = (TokenStream, Span)> {
let it1 = self.reachable.into_iter().map(|(_, tts, span)| (tts, span));
let it2 = self.wildcard.into_iter().map(|(_, tts, span)| (tts, span));
let it3 = self.unreachable.into_iter().map(|(_, tts, span)| (tts, span));
pub fn into_iter_tts(self) -> impl Iterator<Item = (CfgEntry, TokenStream, Span)> {
let it1 = self.reachable.into_iter();
let it2 =
self.wildcard.into_iter().map(|(_, tts, span)| (CfgEntry::Bool(true, span), tts, span));
let it3 = self
.unreachable
.into_iter()
.map(|(_, tts, span)| (CfgEntry::Bool(false, span), tts, span));

it1.chain(it2).chain(it3)
}
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_borrowck/src/region_infer/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,12 @@ impl ToElementIndex<'_> for RegionVid {

impl<'tcx> ToElementIndex<'tcx> for ty::PlaceholderRegion<'tcx> {
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool {
let placeholder: ty::PlaceholderRegion<'tcx> = self.into();
let index = values.placeholder_indices.lookup_index(placeholder);
let index = values.placeholder_indices.lookup_index(self);
values.placeholders.insert(row, index)
}

fn contained_in_row<N: Idx>(self, values: &RegionValues<'tcx, N>, row: N) -> bool {
let placeholder: ty::PlaceholderRegion<'tcx> = self.into();
let index = values.placeholder_indices.lookup_index(placeholder);
let index = values.placeholder_indices.lookup_index(self);
values.placeholders.contains(row, index)
}
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_builtin_macros/src/autodiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,8 +567,7 @@ mod llvm_enzyme {
PatKind::Ident(_, ident, _) => ecx.expr_path(ecx.path_ident(span, ident)),
_ => todo!(),
})
.collect::<ThinVec<_>>()
.into(),
.collect::<ThinVec<_>>(),
);

let enzyme_path_idents = ecx.std_path(&[sym::intrinsics, sym::autodiff]);
Expand Down
84 changes: 74 additions & 10 deletions compiler/rustc_builtin_macros/src/cfg_select.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use rustc_ast::attr::{AttrIdGenerator, mk_attr_from_item};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{Expr, ast};
use rustc_ast::{
AttrItem, AttrItemKind, EarlyParsedAttribute, Expr, Path, Safety, ast, tokenstream as tts,
};
use rustc_attr_parsing as attr;
use rustc_attr_parsing::{CfgSelectBranches, EvalConfigResult, parse_cfg_select};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult};
use rustc_expand::expand::DeclaredIdents;
use rustc_hir::attrs::CfgEntry;
use rustc_span::{Ident, Span, sym};
use smallvec::SmallVec;

Expand All @@ -17,6 +22,7 @@ struct CfgSelectResult<'cx, 'sess> {
selected_tts: TokenStream,
selected_span: Span,
other_branches: CfgSelectBranches,
cfg_entry: CfgEntry,
}

fn tts_to_mac_result<'cx, 'sess>(
Expand All @@ -33,23 +39,78 @@ fn tts_to_mac_result<'cx, 'sess>(
}

macro_rules! forward_to_parser_any_macro {
($method_name:ident, $ret_ty:ty) => {
($method_name:ident, $ret_ty:ty, $other:expr, $selected:expr) => {
fn $method_name(self: Box<Self>) -> Option<$ret_ty> {
let CfgSelectResult { ecx, site_span, selected_tts, selected_span, .. } = *self;
let CfgSelectResult { ecx, site_span, selected_tts, selected_span, cfg_entry, .. } =
*self;

for (tts, span) in self.other_branches.into_iter_tts() {
let _ = tts_to_mac_result(ecx, site_span, tts, span).$method_name();
for (cfg_entry, tts, span) in self.other_branches.into_iter_tts() {
let result = tts_to_mac_result(ecx, site_span, tts, span).$method_name();
$other(&mut *ecx, cfg_entry, span, result);
}

tts_to_mac_result(ecx, site_span, selected_tts, selected_span).$method_name()
tts_to_mac_result(ecx, site_span, selected_tts, selected_span)
.$method_name()
.map(|elements| $selected(&mut *ecx, cfg_entry, elements))
}
};

($method_name:ident, $ret_ty:ty) => {
forward_to_parser_any_macro!($method_name, $ret_ty, |_, _, _, _| {}, |_, _, elements| {
elements
});
};
}

/// Construct a `#[<cfg_trace>]` attribute from a `CfgEntry`. This allows us to keep track of items
/// that were behind a `cfg_select!`, which is relevant for some diagnostics.
fn mk_attr(g: &AttrIdGenerator, cfg_entry: CfgEntry) -> ast::Attribute {
let cfg_span = cfg_entry.span();
let args = AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg_entry));
// This makes the trace attributes unobservable to token-based proc macros.
let tokens = Some(tts::LazyAttrTokenStream::new_direct(tts::AttrTokenStream::default()));
let attr_item = AttrItem {
unsafety: Safety::Default,
path: Path::from_ident(Ident::new(sym::cfg_trace, cfg_span)),
args,
tokens: None,
};
mk_attr_from_item(g, attr_item, tokens, ast::AttrStyle::Outer, cfg_span)
}

impl<'cx, 'sess> MacResult for CfgSelectResult<'cx, 'sess> {
forward_to_parser_any_macro!(make_expr, Box<Expr>);
forward_to_parser_any_macro!(make_stmts, SmallVec<[ast::Stmt; 1]>);
forward_to_parser_any_macro!(make_items, SmallVec<[Box<ast::Item>; 1]>);
forward_to_parser_any_macro!(
make_items,
SmallVec<[Box<ast::Item>; 1]>,
|ecx: &mut ExtCtxt<'_>,
cfg_entry: CfgEntry,
span: Span,
items: Option<SmallVec<[Box<ast::Item>; 1]>>| if let Some(items) = items {
// Register item names that were not selected for error reporting. We do this
// for `#[cfg]` too.
for item in items {
for name in item.declared_idents() {
ecx.resolver.append_stripped_cfg_item(
ecx.current_expansion.lint_node_id,
name,
cfg_entry.clone(),
span,
);
}
}
},
|ecx: &mut ExtCtxt<'_>, cfg_entry: CfgEntry, items: SmallVec<[Box<ast::Item>; 1]>| {
items
.into_iter()
.map(|mut item| {
item.attrs.push(mk_attr(&ecx.sess.psess.attr_id_generator, cfg_entry.clone()));
item
})
.collect()
}
);

forward_to_parser_any_macro!(make_impl_items, SmallVec<[Box<ast::AssocItem>; 1]>);
forward_to_parser_any_macro!(make_trait_impl_items, SmallVec<[Box<ast::AssocItem>; 1]>);
Expand All @@ -73,15 +134,18 @@ pub(super) fn expand_cfg_select<'cx>(
ecx.current_expansion.lint_node_id,
) {
Ok(mut branches) => {
if let Some((selected_tts, selected_span)) = branches.pop_first_match(|cfg| {
matches!(attr::eval_config_entry(&ecx.sess, cfg), EvalConfigResult::True)
}) {
if let Some((cfg_entry, selected_tts, selected_span)) =
branches.pop_first_match(|cfg| {
matches!(attr::eval_config_entry(&ecx.sess, cfg), EvalConfigResult::True)
})
{
let mac = CfgSelectResult {
ecx,
selected_tts,
selected_span,
other_branches: branches,
site_span: sp,
cfg_entry,
};
return ExpandResult::Ready(Box::new(mac));
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
}

for i in 0..lane_count {
let ret_lane = ret.place_lane(fx, i.into());
let ret_lane = ret.place_lane(fx, i);
ret_lane.write_cvalue(fx, value);
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
_ => return interp_ok(false),
}

trace!("{:?}", self.dump_place(&dest.clone().into()));
trace!("{:?}", self.dump_place(&dest));
self.return_to_block(ret)?;
interp_ok(true)
}
Expand Down
45 changes: 39 additions & 6 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ enum AddSemicolon {

/// A trait implemented for all `AstFragment` nodes and providing all pieces
/// of functionality used by `InvocationCollector`.
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized + DeclaredIdents {
type OutputTy = SmallVec<[Self; 1]>;
type ItemKind = ItemKind;
const KIND: AstFragmentKind;
Expand Down Expand Up @@ -1302,13 +1302,43 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
collector.cx.dcx().emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
}

fn as_target(&self) -> Target;
}

pub trait DeclaredIdents {
/// All of the identifiers (items) declared by this node.
/// This is an approximation and should only be used for diagnostics.
fn declared_idents(&self) -> Vec<Ident> {
vec![]
}
}

fn as_target(&self) -> Target;
macro_rules! declared_idents {
($($ty:ty),*) => {
$(impl DeclaredIdents for $ty {})*
};
}

// Use the default "empty" list of idents for the following:
declared_idents! {
AstNodeWrapper<Box<ast::AssocItem>, TraitItemTag>,
AstNodeWrapper<Box<ast::AssocItem>, ImplItemTag>,
AstNodeWrapper<Box<ast::AssocItem>, TraitImplItemTag>,
Box<ast::ForeignItem>,
ast::Variant,
ast::WherePredicate,
ast::FieldDef,
ast::PatField,
ast::ExprField,
ast::Param,
ast::GenericParam,
ast::Arm,
ast::Stmt,
ast::Crate,
ast::Ty,
ast::Pat,
ast::Expr,
AstNodeWrapper<Box<ast::Expr>, OptExprTag>
}

impl InvocationCollectorNode for Box<ast::Item> {
Expand Down Expand Up @@ -1440,6 +1470,12 @@ impl InvocationCollectorNode for Box<ast::Item> {
res
}

fn as_target(&self) -> Target {
Target::from_ast_item(self)
}
}

impl DeclaredIdents for Box<ast::Item> {
fn declared_idents(&self) -> Vec<Ident> {
if let ItemKind::Use(ut) = &self.kind {
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
Expand All @@ -1460,10 +1496,6 @@ impl InvocationCollectorNode for Box<ast::Item> {
self.kind.ident().into_iter().collect()
}
}

fn as_target(&self) -> Target {
Target::from_ast_item(self)
}
}

struct TraitItemTag;
Expand Down Expand Up @@ -2005,6 +2037,7 @@ impl InvocationCollectorNode for AstNodeWrapper<Box<ast::Expr>, OptExprTag> {
/// It can be removed once that feature is stabilized.
struct MethodReceiverTag;

impl DeclaredIdents for AstNodeWrapper<ast::Expr, MethodReceiverTag> {}
impl InvocationCollectorNode for AstNodeWrapper<ast::Expr, MethodReceiverTag> {
type OutputTy = AstNodeWrapper<Box<ast::Expr>, MethodReceiverTag>;
const KIND: AstFragmentKind = AstFragmentKind::MethodReceiverExpr;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/snapshot/undo_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ macro_rules! impl_from {
$(
impl<'tcx> From<$ty> for UndoLog<'tcx> {
fn from(x: $ty) -> Self {
#[cfg_attr(not(bootstrap), allow(self_type_conversion))]
UndoLog::$ctor(x.into())
}
}
Expand Down
Loading
Loading