Auto merge of #137927 - matthiaskrgr:rollup-yj463ns, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #132388 (Implement `#[cfg]` in `where` clauses) - #134900 (Fix parsing of ranges after unary operators) - #136938 (Remove `:` from `stack-protector-heuristics-effect.rs` Filecheck Pattern) - #137054 (Make phantom variance markers transparent) - #137525 (Simplify parallelization in test-float-parse) - #137618 (Skip `tidy` in pre-push hook if the user is deleting a remote branch) - #137741 (Stop using `hash_raw_entry` in `CodegenCx::const_str`) - #137849 (Revert "Remove Win SDK 10.0.26100.0 from CI") - #137862 (ensure we always print all --print options in help) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2010bba886
59 changed files with 3607 additions and 411 deletions
|
@ -417,9 +417,11 @@ impl WhereClause {
|
|||
/// A single predicate in a where-clause.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct WherePredicate {
|
||||
pub attrs: AttrVec,
|
||||
pub kind: WherePredicateKind,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub is_placeholder: bool,
|
||||
}
|
||||
|
||||
/// Predicate kind in where-clause.
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::tokenstream::LazyAttrTokenStream;
|
|||
use crate::{
|
||||
Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField,
|
||||
FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind,
|
||||
Ty, Variant, Visibility,
|
||||
Ty, Variant, Visibility, WherePredicate,
|
||||
};
|
||||
|
||||
/// A utility trait to reduce boilerplate.
|
||||
|
@ -79,6 +79,7 @@ impl_has_node_id!(
|
|||
Stmt,
|
||||
Ty,
|
||||
Variant,
|
||||
WherePredicate,
|
||||
);
|
||||
|
||||
impl<T: AstDeref<Target: HasNodeId>> HasNodeId for T {
|
||||
|
@ -127,7 +128,16 @@ macro_rules! impl_has_tokens_none {
|
|||
}
|
||||
|
||||
impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility);
|
||||
impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant);
|
||||
impl_has_tokens_none!(
|
||||
Arm,
|
||||
ExprField,
|
||||
FieldDef,
|
||||
GenericParam,
|
||||
Param,
|
||||
PatField,
|
||||
Variant,
|
||||
WherePredicate
|
||||
);
|
||||
|
||||
impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
|
@ -279,6 +289,7 @@ impl_has_attrs!(
|
|||
Param,
|
||||
PatField,
|
||||
Variant,
|
||||
WherePredicate,
|
||||
);
|
||||
impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
|
||||
|
||||
|
|
|
@ -338,8 +338,11 @@ pub trait MutVisitor: Sized {
|
|||
walk_where_clause(self, where_clause);
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
|
||||
walk_where_predicate(self, where_predicate)
|
||||
fn flat_map_where_predicate(
|
||||
&mut self,
|
||||
where_predicate: WherePredicate,
|
||||
) -> SmallVec<[WherePredicate; 1]> {
|
||||
walk_flat_map_where_predicate(self, where_predicate)
|
||||
}
|
||||
|
||||
fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
|
||||
|
@ -1097,15 +1100,20 @@ fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWh
|
|||
|
||||
fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
|
||||
let WhereClause { has_where_token: _, predicates, span } = wc;
|
||||
visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
|
||||
predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
|
||||
let WherePredicate { kind, id, span } = pred;
|
||||
pub fn walk_flat_map_where_predicate<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut pred: WherePredicate,
|
||||
) -> SmallVec<[WherePredicate; 1]> {
|
||||
let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_where_predicate_kind(kind);
|
||||
vis.visit_span(span);
|
||||
smallvec![pred]
|
||||
}
|
||||
|
||||
pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
|
||||
|
|
|
@ -833,7 +833,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
|
|||
visitor: &mut V,
|
||||
predicate: &'a WherePredicate,
|
||||
) -> V::Result {
|
||||
let WherePredicate { kind, id: _, span: _ } = predicate;
|
||||
let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
visitor.visit_where_predicate_kind(kind)
|
||||
}
|
||||
|
||||
|
|
|
@ -1728,6 +1728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
|
||||
let hir_id = self.lower_node_id(pred.id);
|
||||
let span = self.lower_span(pred.span);
|
||||
self.lower_attrs(hir_id, &pred.attrs, span);
|
||||
let kind = self.arena.alloc(match &pred.kind {
|
||||
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
|
||||
bound_generic_params,
|
||||
|
|
|
@ -503,6 +503,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
|||
gate_all!(unsafe_binders, "unsafe binder types are experimental");
|
||||
gate_all!(contracts, "contracts are incomplete");
|
||||
gate_all!(contracts_internals, "contract internal machinery is for internal use only");
|
||||
gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
|
||||
|
||||
if !visitor.features.never_patterns() {
|
||||
if let Some(spans) = spans.get(&sym::never_patterns) {
|
||||
|
|
|
@ -735,7 +735,8 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
|
||||
let ast::WherePredicate { kind, id: _, span: _ } = predicate;
|
||||
let ast::WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
|
||||
self.print_outer_attributes(attrs);
|
||||
match kind {
|
||||
ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
|
||||
self.print_where_bound_predicate(where_bound_predicate);
|
||||
|
|
|
@ -300,13 +300,16 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
|||
to_ty: &s_ty,
|
||||
rewritten: false,
|
||||
};
|
||||
let mut predicate = ast::WherePredicate {
|
||||
kind: ast::WherePredicateKind::BoundPredicate(bound.clone()),
|
||||
span: predicate.span,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
};
|
||||
substitution.visit_where_predicate(&mut predicate);
|
||||
let mut kind = ast::WherePredicateKind::BoundPredicate(bound.clone());
|
||||
substitution.visit_where_predicate_kind(&mut kind);
|
||||
if substitution.rewritten {
|
||||
let predicate = ast::WherePredicate {
|
||||
attrs: predicate.attrs.clone(),
|
||||
kind,
|
||||
span: predicate.span,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
is_placeholder: false,
|
||||
};
|
||||
impl_generics.where_clause.predicates.push(predicate);
|
||||
}
|
||||
}
|
||||
|
@ -388,8 +391,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
|
||||
match &mut where_predicate.kind {
|
||||
fn visit_where_predicate_kind(&mut self, kind: &mut ast::WherePredicateKind) {
|
||||
match kind {
|
||||
rustc_ast::WherePredicateKind::BoundPredicate(bound) => {
|
||||
bound
|
||||
.bound_generic_params
|
||||
|
|
|
@ -687,9 +687,11 @@ impl<'a> TraitDef<'a> {
|
|||
// and similarly for where clauses
|
||||
where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
|
||||
ast::WherePredicate {
|
||||
attrs: clause.attrs.clone(),
|
||||
kind: clause.kind.clone(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: clause.span.with_ctxt(ctxt),
|
||||
is_placeholder: false,
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -744,8 +746,13 @@ impl<'a> TraitDef<'a> {
|
|||
};
|
||||
|
||||
let kind = ast::WherePredicateKind::BoundPredicate(predicate);
|
||||
let predicate =
|
||||
ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
|
||||
let predicate = ast::WherePredicate {
|
||||
attrs: ThinVec::new(),
|
||||
kind,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
is_placeholder: false,
|
||||
};
|
||||
where_clause.predicates.push(predicate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,13 +146,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
fn const_str(&self, s: &str) -> (RValue<'gcc>, RValue<'gcc>) {
|
||||
let str_global = *self
|
||||
.const_str_cache
|
||||
.borrow_mut()
|
||||
.raw_entry_mut()
|
||||
.from_key(s)
|
||||
.or_insert_with(|| (s.to_owned(), self.global_string(s)))
|
||||
.1;
|
||||
let mut const_str_cache = self.const_str_cache.borrow_mut();
|
||||
let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
|
||||
let g = self.global_string(s);
|
||||
const_str_cache.insert(s.to_owned(), g);
|
||||
g
|
||||
});
|
||||
let len = s.len();
|
||||
let cs = self.const_ptrcast(
|
||||
str_global.get_address(None),
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#![allow(internal_features)]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(rustdoc_internals)]
|
||||
#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains)]
|
||||
#![feature(rustc_private, decl_macro, never_type, trusted_len, let_chains)]
|
||||
#![allow(broken_intra_doc_links)]
|
||||
#![recursion_limit = "256"]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
|
|
@ -209,28 +209,24 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
|
||||
fn const_str(&self, s: &str) -> (&'ll Value, &'ll Value) {
|
||||
let str_global = *self
|
||||
.const_str_cache
|
||||
.borrow_mut()
|
||||
.raw_entry_mut()
|
||||
.from_key(s)
|
||||
.or_insert_with(|| {
|
||||
let sc = self.const_bytes(s.as_bytes());
|
||||
let sym = self.generate_local_symbol_name("str");
|
||||
let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
|
||||
bug!("symbol `{}` is already defined", sym);
|
||||
});
|
||||
llvm::set_initializer(g, sc);
|
||||
unsafe {
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
|
||||
}
|
||||
llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
|
||||
// Cast to default address space if globals are in a different addrspace
|
||||
let g = self.const_pointercast(g, self.type_ptr());
|
||||
(s.to_owned(), g)
|
||||
})
|
||||
.1;
|
||||
let mut const_str_cache = self.const_str_cache.borrow_mut();
|
||||
let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
|
||||
let sc = self.const_bytes(s.as_bytes());
|
||||
let sym = self.generate_local_symbol_name("str");
|
||||
let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
|
||||
bug!("symbol `{}` is already defined", sym);
|
||||
});
|
||||
llvm::set_initializer(g, sc);
|
||||
unsafe {
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
|
||||
}
|
||||
llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
|
||||
// Cast to default address space if globals are in a different addrspace
|
||||
let g = self.const_pointercast(g, self.type_ptr());
|
||||
const_str_cache.insert(s.to_owned(), g);
|
||||
g
|
||||
});
|
||||
let len = s.len();
|
||||
(str_global, self.const_usize(len as u64))
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#![feature(exact_size_is_empty)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(file_buffered)]
|
||||
#![feature(hash_raw_entry)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![feature(iter_intersperse)]
|
||||
|
|
|
@ -53,6 +53,7 @@ pub enum Annotatable {
|
|||
Param(ast::Param),
|
||||
FieldDef(ast::FieldDef),
|
||||
Variant(ast::Variant),
|
||||
WherePredicate(ast::WherePredicate),
|
||||
Crate(ast::Crate),
|
||||
}
|
||||
|
||||
|
@ -71,6 +72,7 @@ impl Annotatable {
|
|||
Annotatable::Param(p) => p.span,
|
||||
Annotatable::FieldDef(sf) => sf.span,
|
||||
Annotatable::Variant(v) => v.span,
|
||||
Annotatable::WherePredicate(wp) => wp.span,
|
||||
Annotatable::Crate(c) => c.spans.inner_span,
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +91,7 @@ impl Annotatable {
|
|||
Annotatable::Param(p) => p.visit_attrs(f),
|
||||
Annotatable::FieldDef(sf) => sf.visit_attrs(f),
|
||||
Annotatable::Variant(v) => v.visit_attrs(f),
|
||||
Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
|
||||
Annotatable::Crate(c) => c.visit_attrs(f),
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +110,7 @@ impl Annotatable {
|
|||
Annotatable::Param(p) => visitor.visit_param(p),
|
||||
Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
|
||||
Annotatable::Variant(v) => visitor.visit_variant(v),
|
||||
Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
|
||||
Annotatable::Crate(c) => visitor.visit_crate(c),
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +132,7 @@ impl Annotatable {
|
|||
| Annotatable::Param(..)
|
||||
| Annotatable::FieldDef(..)
|
||||
| Annotatable::Variant(..)
|
||||
| Annotatable::WherePredicate(..)
|
||||
| Annotatable::Crate(..) => panic!("unexpected annotatable"),
|
||||
}
|
||||
}
|
||||
|
@ -223,6 +228,13 @@ impl Annotatable {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expect_where_predicate(self) -> ast::WherePredicate {
|
||||
match self {
|
||||
Annotatable::WherePredicate(wp) => wp,
|
||||
_ => panic!("expected where predicate"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_crate(self) -> ast::Crate {
|
||||
match self {
|
||||
Annotatable::Crate(krate) => krate,
|
||||
|
@ -446,6 +458,10 @@ pub trait MacResult {
|
|||
None
|
||||
}
|
||||
|
||||
fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
|
||||
// Fn-like macros cannot produce a crate.
|
||||
unreachable!()
|
||||
|
|
|
@ -227,6 +227,12 @@ ast_fragments! {
|
|||
Variants(SmallVec<[ast::Variant; 1]>) {
|
||||
"variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
|
||||
}
|
||||
WherePredicates(SmallVec<[ast::WherePredicate; 1]>) {
|
||||
"where predicate";
|
||||
many fn flat_map_where_predicate;
|
||||
fn visit_where_predicate();
|
||||
fn make_where_predicates;
|
||||
}
|
||||
Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; }
|
||||
}
|
||||
|
||||
|
@ -259,7 +265,8 @@ impl AstFragmentKind {
|
|||
| AstFragmentKind::GenericParams
|
||||
| AstFragmentKind::Params
|
||||
| AstFragmentKind::FieldDefs
|
||||
| AstFragmentKind::Variants => SupportsMacroExpansion::No,
|
||||
| AstFragmentKind::Variants
|
||||
| AstFragmentKind::WherePredicates => SupportsMacroExpansion::No,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,6 +297,9 @@ impl AstFragmentKind {
|
|||
AstFragmentKind::Variants => {
|
||||
AstFragment::Variants(items.map(Annotatable::expect_variant).collect())
|
||||
}
|
||||
AstFragmentKind::WherePredicates => AstFragment::WherePredicates(
|
||||
items.map(Annotatable::expect_where_predicate).collect(),
|
||||
),
|
||||
AstFragmentKind::Items => {
|
||||
AstFragment::Items(items.map(Annotatable::expect_item).collect())
|
||||
}
|
||||
|
@ -865,7 +875,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
| Annotatable::GenericParam(..)
|
||||
| Annotatable::Param(..)
|
||||
| Annotatable::FieldDef(..)
|
||||
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
|
||||
| Annotatable::Variant(..)
|
||||
| Annotatable::WherePredicate(..) => panic!("unexpected annotatable"),
|
||||
};
|
||||
if self.cx.ecfg.features.proc_macro_hygiene() {
|
||||
return;
|
||||
|
@ -1002,7 +1013,8 @@ pub fn parse_ast_fragment<'a>(
|
|||
| AstFragmentKind::GenericParams
|
||||
| AstFragmentKind::Params
|
||||
| AstFragmentKind::FieldDefs
|
||||
| AstFragmentKind::Variants => panic!("unexpected AST fragment kind"),
|
||||
| AstFragmentKind::Variants
|
||||
| AstFragmentKind::WherePredicates => panic!("unexpected AST fragment kind"),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1414,6 +1426,19 @@ impl InvocationCollectorNode for ast::Variant {
|
|||
}
|
||||
}
|
||||
|
||||
impl InvocationCollectorNode for ast::WherePredicate {
|
||||
const KIND: AstFragmentKind = AstFragmentKind::WherePredicates;
|
||||
fn to_annotatable(self) -> Annotatable {
|
||||
Annotatable::WherePredicate(self)
|
||||
}
|
||||
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
|
||||
fragment.make_where_predicates()
|
||||
}
|
||||
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
||||
walk_flat_map_where_predicate(visitor, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl InvocationCollectorNode for ast::FieldDef {
|
||||
const KIND: AstFragmentKind = AstFragmentKind::FieldDefs;
|
||||
fn to_annotatable(self) -> Annotatable {
|
||||
|
@ -2116,6 +2141,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
self.flat_map_node(node)
|
||||
}
|
||||
|
||||
fn flat_map_where_predicate(
|
||||
&mut self,
|
||||
node: ast::WherePredicate,
|
||||
) -> SmallVec<[ast::WherePredicate; 1]> {
|
||||
self.flat_map_node(node)
|
||||
}
|
||||
|
||||
fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> {
|
||||
self.flat_map_node(node)
|
||||
}
|
||||
|
|
|
@ -188,6 +188,19 @@ pub(crate) fn placeholder(
|
|||
vis,
|
||||
is_placeholder: true,
|
||||
}]),
|
||||
AstFragmentKind::WherePredicates => {
|
||||
AstFragment::WherePredicates(smallvec![ast::WherePredicate {
|
||||
attrs: Default::default(),
|
||||
id,
|
||||
span,
|
||||
kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
|
||||
bound_generic_params: Default::default(),
|
||||
bounded_ty: ty(),
|
||||
bounds: Default::default(),
|
||||
}),
|
||||
is_placeholder: true,
|
||||
}])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +280,17 @@ impl MutVisitor for PlaceholderExpander {
|
|||
}
|
||||
}
|
||||
|
||||
fn flat_map_where_predicate(
|
||||
&mut self,
|
||||
predicate: ast::WherePredicate,
|
||||
) -> SmallVec<[ast::WherePredicate; 1]> {
|
||||
if predicate.is_placeholder {
|
||||
self.remove(predicate.id).make_where_predicates()
|
||||
} else {
|
||||
walk_flat_map_where_predicate(self, predicate)
|
||||
}
|
||||
}
|
||||
|
||||
fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||
match item.kind {
|
||||
ast::ItemKind::MacCall(_) => self.remove(item.id).make_items(),
|
||||
|
|
|
@ -661,6 +661,8 @@ declare_features! (
|
|||
(unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
|
||||
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
|
||||
(unstable, used_with_arg, "1.60.0", Some(93798)),
|
||||
/// Allows use of attributes in `where` clauses.
|
||||
(unstable, where_clause_attrs, "CURRENT_RUSTC_VERSION", Some(115590)),
|
||||
/// Allows use of x86 `AMX` target-feature attributes and intrinsics
|
||||
(unstable, x86_amx_intrinsics, "1.81.0", Some(126622)),
|
||||
/// Allows use of the `xop` target-feature
|
||||
|
|
|
@ -56,6 +56,7 @@ pub enum Target {
|
|||
Param,
|
||||
PatField,
|
||||
ExprField,
|
||||
WherePredicate,
|
||||
}
|
||||
|
||||
impl Display for Target {
|
||||
|
@ -96,7 +97,8 @@ impl Target {
|
|||
| Target::MacroDef
|
||||
| Target::Param
|
||||
| Target::PatField
|
||||
| Target::ExprField => false,
|
||||
| Target::ExprField
|
||||
| Target::WherePredicate => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,6 +219,7 @@ impl Target {
|
|||
Target::Param => "function param",
|
||||
Target::PatField => "pattern field",
|
||||
Target::ExprField => "struct field",
|
||||
Target::WherePredicate => "where predicate",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2386,6 +2386,7 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
|
||||
self.print_attrs_as_outer(self.attrs(predicate.hir_id));
|
||||
match *predicate.kind {
|
||||
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
|
||||
bound_generic_params,
|
||||
|
|
|
@ -567,7 +567,11 @@ impl<'a> Parser<'a> {
|
|||
fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
|
||||
self.bump();
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let expr = self.parse_expr_prefix(attrs)?;
|
||||
let expr = if self.token.is_range_separator() {
|
||||
self.parse_expr_prefix_range(attrs)
|
||||
} else {
|
||||
self.parse_expr_prefix(attrs)
|
||||
}?;
|
||||
let span = self.interpolated_or_expr_span(&expr);
|
||||
Ok((lo.to(span), expr))
|
||||
}
|
||||
|
|
|
@ -367,34 +367,47 @@ impl<'a> Parser<'a> {
|
|||
|
||||
loop {
|
||||
let where_sp = where_lo.to(self.prev_token.span);
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let pred_lo = self.token.span;
|
||||
let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
|
||||
let lifetime = self.expect_lifetime();
|
||||
// Bounds starting with a colon are mandatory, but possibly empty.
|
||||
self.expect(exp!(Colon))?;
|
||||
let bounds = self.parse_lt_param_bounds();
|
||||
ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
|
||||
lifetime,
|
||||
bounds,
|
||||
})
|
||||
} else if self.check_type() {
|
||||
match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
|
||||
struct_, pred_lo, where_sp,
|
||||
)? {
|
||||
PredicateKindOrStructBody::PredicateKind(kind) => kind,
|
||||
PredicateKindOrStructBody::StructBody(body) => {
|
||||
tuple_struct_body = Some(body);
|
||||
break;
|
||||
}
|
||||
let predicate = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
|
||||
for attr in &attrs {
|
||||
self.psess.gated_spans.gate(sym::where_clause_attrs, attr.span);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
where_clause.predicates.push(ast::WherePredicate {
|
||||
kind,
|
||||
id: DUMMY_NODE_ID,
|
||||
span: pred_lo.to(self.prev_token.span),
|
||||
});
|
||||
let kind = if this.check_lifetime() && this.look_ahead(1, |t| !t.is_like_plus()) {
|
||||
let lifetime = this.expect_lifetime();
|
||||
// Bounds starting with a colon are mandatory, but possibly empty.
|
||||
this.expect(exp!(Colon))?;
|
||||
let bounds = this.parse_lt_param_bounds();
|
||||
Some(ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
|
||||
lifetime,
|
||||
bounds,
|
||||
}))
|
||||
} else if this.check_type() {
|
||||
match this.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
|
||||
struct_, pred_lo, where_sp,
|
||||
)? {
|
||||
PredicateKindOrStructBody::PredicateKind(kind) => Some(kind),
|
||||
PredicateKindOrStructBody::StructBody(body) => {
|
||||
tuple_struct_body = Some(body);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let predicate = kind.map(|kind| ast::WherePredicate {
|
||||
attrs,
|
||||
kind,
|
||||
id: DUMMY_NODE_ID,
|
||||
span: pred_lo.to(this.prev_token.span),
|
||||
is_placeholder: false,
|
||||
});
|
||||
Ok((predicate, Trailing::No, UsePreAttrPos::No))
|
||||
})?;
|
||||
match predicate {
|
||||
Some(predicate) => where_clause.predicates.push(predicate),
|
||||
None => break,
|
||||
}
|
||||
|
||||
let prev_token = self.prev_token.span;
|
||||
let ate_comma = self.eat(exp!(Comma));
|
||||
|
|
|
@ -779,6 +779,10 @@ passes_unstable_attr_for_already_stable_feature =
|
|||
.item = the stability attribute annotates this item
|
||||
.help = consider removing the attribute
|
||||
|
||||
passes_unsupported_attributes_in_where =
|
||||
most attributes are not supported in `where` clauses
|
||||
.help = only `#[cfg]` and `#[cfg_attr]` are supported
|
||||
|
||||
passes_unused =
|
||||
unused attribute
|
||||
.suggestion = remove this attribute
|
||||
|
|
|
@ -919,7 +919,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| Target::Arm
|
||||
| Target::ForeignMod
|
||||
| Target::Closure
|
||||
| Target::Impl => Some(target.name()),
|
||||
| Target::Impl
|
||||
| Target::WherePredicate => Some(target.name()),
|
||||
Target::ExternCrate
|
||||
| Target::Use
|
||||
| Target::Static
|
||||
|
@ -2614,6 +2615,32 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
|||
intravisit::walk_item(self, item)
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) {
|
||||
// FIXME(where_clause_attrs): Currently, as the following check shows,
|
||||
// only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
|
||||
// if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
|
||||
// in where clauses. After that, only `self.check_attributes` should be enough.
|
||||
const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr];
|
||||
let spans = self
|
||||
.tcx
|
||||
.hir()
|
||||
.attrs(where_predicate.hir_id)
|
||||
.iter()
|
||||
.filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym)))
|
||||
.map(|attr| attr.span())
|
||||
.collect::<Vec<_>>();
|
||||
if !spans.is_empty() {
|
||||
self.tcx.dcx().emit_err(errors::UnsupportedAttributesInWhere { span: spans.into() });
|
||||
}
|
||||
self.check_attributes(
|
||||
where_predicate.hir_id,
|
||||
where_predicate.span,
|
||||
Target::WherePredicate,
|
||||
None,
|
||||
);
|
||||
intravisit::walk_where_predicate(self, where_predicate)
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) {
|
||||
let target = Target::from_generic_param(generic_param);
|
||||
self.check_attributes(generic_param.hir_id, generic_param.span, target, None);
|
||||
|
|
|
@ -1909,3 +1909,11 @@ pub(crate) struct RustcConstStableIndirectPairing {
|
|||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_unsupported_attributes_in_where)]
|
||||
#[help]
|
||||
pub(crate) struct UnsupportedAttributesInWhere {
|
||||
#[primary_span]
|
||||
pub span: MultiSpan,
|
||||
}
|
||||
|
|
|
@ -1529,6 +1529,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
visit::walk_variant(self, variant);
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
|
||||
if p.is_placeholder {
|
||||
self.visit_invoc(p.id);
|
||||
} else {
|
||||
visit::walk_where_predicate(self, p);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_crate(&mut self, krate: &'a ast::Crate) {
|
||||
if krate.is_placeholder {
|
||||
self.visit_invoc_in_module(krate.id);
|
||||
|
|
|
@ -285,6 +285,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, pred: &'a WherePredicate) {
|
||||
if pred.is_placeholder {
|
||||
self.visit_macro_invoc(pred.id)
|
||||
} else {
|
||||
visit::walk_where_predicate(self, pred)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self, data: &'a VariantData) {
|
||||
// The assumption here is that non-`cfg` macro expansion cannot change field indices.
|
||||
// It currently holds because only inert attributes are accepted on fields,
|
||||
|
|
|
@ -42,6 +42,32 @@ mod cfg;
|
|||
mod native_libs;
|
||||
pub mod sigpipe;
|
||||
|
||||
pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
|
||||
// tidy-alphabetical-start
|
||||
("all-target-specs-json", PrintKind::AllTargetSpecs),
|
||||
("calling-conventions", PrintKind::CallingConventions),
|
||||
("cfg", PrintKind::Cfg),
|
||||
("check-cfg", PrintKind::CheckCfg),
|
||||
("code-models", PrintKind::CodeModels),
|
||||
("crate-name", PrintKind::CrateName),
|
||||
("deployment-target", PrintKind::DeploymentTarget),
|
||||
("file-names", PrintKind::FileNames),
|
||||
("host-tuple", PrintKind::HostTuple),
|
||||
("link-args", PrintKind::LinkArgs),
|
||||
("native-static-libs", PrintKind::NativeStaticLibs),
|
||||
("relocation-models", PrintKind::RelocationModels),
|
||||
("split-debuginfo", PrintKind::SplitDebuginfo),
|
||||
("stack-protector-strategies", PrintKind::StackProtectorStrategies),
|
||||
("sysroot", PrintKind::Sysroot),
|
||||
("target-cpus", PrintKind::TargetCPUs),
|
||||
("target-features", PrintKind::TargetFeatures),
|
||||
("target-libdir", PrintKind::TargetLibdir),
|
||||
("target-list", PrintKind::TargetList),
|
||||
("target-spec-json", PrintKind::TargetSpec),
|
||||
("tls-models", PrintKind::TlsModels),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
/// The different settings that the `-C strip` flag can have.
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
||||
pub enum Strip {
|
||||
|
@ -1508,6 +1534,13 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE
|
|||
)
|
||||
});
|
||||
|
||||
static PRINT_KINDS_STRING: LazyLock<String> = LazyLock::new(|| {
|
||||
format!(
|
||||
"[{}]",
|
||||
PRINT_KINDS.iter().map(|(name, _)| format!("{name}")).collect::<Vec<_>>().join("|")
|
||||
)
|
||||
});
|
||||
|
||||
/// Returns all rustc command line options, including metadata for
|
||||
/// each option, such as whether the option is stable.
|
||||
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
||||
|
@ -1568,10 +1601,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
|||
"",
|
||||
"print",
|
||||
"Compiler information to print on stdout",
|
||||
"[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
|
||||
target-list|target-cpus|target-features|relocation-models|code-models|\
|
||||
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
|
||||
stack-protector-strategies|link-args|deployment-target]",
|
||||
&PRINT_KINDS_STRING,
|
||||
),
|
||||
opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
|
||||
opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
|
||||
|
@ -1999,32 +2029,6 @@ fn collect_print_requests(
|
|||
cg.target_feature = String::new();
|
||||
}
|
||||
|
||||
const PRINT_KINDS: &[(&str, PrintKind)] = &[
|
||||
// tidy-alphabetical-start
|
||||
("all-target-specs-json", PrintKind::AllTargetSpecs),
|
||||
("calling-conventions", PrintKind::CallingConventions),
|
||||
("cfg", PrintKind::Cfg),
|
||||
("check-cfg", PrintKind::CheckCfg),
|
||||
("code-models", PrintKind::CodeModels),
|
||||
("crate-name", PrintKind::CrateName),
|
||||
("deployment-target", PrintKind::DeploymentTarget),
|
||||
("file-names", PrintKind::FileNames),
|
||||
("host-tuple", PrintKind::HostTuple),
|
||||
("link-args", PrintKind::LinkArgs),
|
||||
("native-static-libs", PrintKind::NativeStaticLibs),
|
||||
("relocation-models", PrintKind::RelocationModels),
|
||||
("split-debuginfo", PrintKind::SplitDebuginfo),
|
||||
("stack-protector-strategies", PrintKind::StackProtectorStrategies),
|
||||
("sysroot", PrintKind::Sysroot),
|
||||
("target-cpus", PrintKind::TargetCPUs),
|
||||
("target-features", PrintKind::TargetFeatures),
|
||||
("target-libdir", PrintKind::TargetLibdir),
|
||||
("target-list", PrintKind::TargetList),
|
||||
("target-spec-json", PrintKind::TargetSpec),
|
||||
("tls-models", PrintKind::TlsModels),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
// We disallow reusing the same path in multiple prints, such as `--print
|
||||
// cfg=output.txt --print link-args=output.txt`, because outputs are printed
|
||||
// by disparate pieces of the compiler, and keeping track of which files
|
||||
|
|
|
@ -2234,6 +2234,7 @@ symbols! {
|
|||
wasm_abi,
|
||||
wasm_import_module,
|
||||
wasm_target_feature,
|
||||
where_clause_attrs,
|
||||
while_let,
|
||||
windows,
|
||||
windows_subsystem,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue