Skip to content

Commit a9f0a72

Browse files
committed
Auto merge of #147253 - Zalathar:rollup-1yk4sc5, r=Zalathar
Rollup of 10 pull requests Successful merges: - #146281 (Support `#[rustc_align_static]` inside `thread_local!`) - #146535 (mbe: Implement `unsafe` attribute rules) - #146585 (indexing: reword help) - #147004 (Tweak handling of "struct like start" where a struct isn't supported) - #147221 (Forbid `//@ compile-flags: -Cincremental=` in tests) - #147225 (Don't enable shared memory by default with Wasm atomics) - #147227 (implement `Box::take`) - #147231 (Extending `#[rustc_force_inline]` to be applicable to inherent methods) - #147233 (Initialize llvm submodule if not already the case to run citool) - #147236 (Update books) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 42b384e + ec8a077 commit a9f0a72

File tree

76 files changed

+1591
-338
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1591
-338
lines changed

compiler/rustc_attr_parsing/src/attributes/inline.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
7272
const PATH: &'static [Symbol] = &[sym::rustc_force_inline];
7373
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
7474
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
75-
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
75+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
76+
Allow(Target::Fn),
77+
Allow(Target::Method(MethodKind::Inherent)),
78+
]);
79+
7680
const TEMPLATE: AttributeTemplate = template!(Word, List: &["reason"], NameValueStr: "reason");
7781

7882
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {

compiler/rustc_attr_parsing/src/validate_attr.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,9 @@ pub fn check_attribute_safety(
207207
}
208208
}
209209

210-
// - Normal builtin attribute, or any non-builtin attribute
211-
// - All non-builtin attributes are currently considered safe; writing `#[unsafe(..)]` is
212-
// not permitted on non-builtin attributes or normal builtin attributes
213-
(Some(AttributeSafety::Normal) | None, Safety::Unsafe(unsafe_span)) => {
210+
// - Normal builtin attribute
211+
// - Writing `#[unsafe(..)]` is not permitted on normal builtin attributes
212+
(Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => {
214213
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
215214
span: unsafe_span,
216215
name: attr_item.path.clone(),
@@ -224,9 +223,8 @@ pub fn check_attribute_safety(
224223
}
225224

226225
// - Non-builtin attribute
227-
// - No explicit `#[unsafe(..)]` written.
228-
(None, Safety::Default) => {
229-
// OK
226+
(None, Safety::Unsafe(_) | Safety::Default) => {
227+
// OK (not checked here)
230228
}
231229

232230
(

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use rustc_middle::middle::exported_symbols::{
1717
use rustc_middle::ty::TyCtxt;
1818
use rustc_session::Session;
1919
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
20-
use rustc_span::sym;
2120
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld};
2221
use tracing::{debug, warn};
2322

@@ -1324,37 +1323,7 @@ struct WasmLd<'a> {
13241323

13251324
impl<'a> WasmLd<'a> {
13261325
fn new(cmd: Command, sess: &'a Session) -> WasmLd<'a> {
1327-
// If the atomics feature is enabled for wasm then we need a whole bunch
1328-
// of flags:
1329-
//
1330-
// * `--shared-memory` - the link won't even succeed without this, flags
1331-
// the one linear memory as `shared`
1332-
//
1333-
// * `--max-memory=1G` - when specifying a shared memory this must also
1334-
// be specified. We conservatively choose 1GB but users should be able
1335-
// to override this with `-C link-arg`.
1336-
//
1337-
// * `--import-memory` - it doesn't make much sense for memory to be
1338-
// exported in a threaded module because typically you're
1339-
// sharing memory and instantiating the module multiple times. As a
1340-
// result if it were exported then we'd just have no sharing.
1341-
//
1342-
// On wasm32-unknown-unknown, we also export symbols for glue code to use:
1343-
// * `--export=*tls*` - when `#[thread_local]` symbols are used these
1344-
// symbols are how the TLS segments are initialized and configured.
1345-
let mut wasm_ld = WasmLd { cmd, sess };
1346-
if sess.target_features.contains(&sym::atomics) {
1347-
wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]);
1348-
if sess.target.os == "unknown" || sess.target.os == "none" {
1349-
wasm_ld.link_args(&[
1350-
"--export=__wasm_init_tls",
1351-
"--export=__tls_size",
1352-
"--export=__tls_align",
1353-
"--export=__tls_base",
1354-
]);
1355-
}
1356-
}
1357-
wasm_ld
1326+
WasmLd { cmd, sess }
13581327
}
13591328
}
13601329

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
1-
An attempt to use index on a type which doesn't implement the `std::ops::Index`
2-
trait was performed.
1+
Attempted to index a value whose type doesn't implement the
2+
`std::ops::Index` trait.
33

44
Erroneous code example:
55

66
```compile_fail,E0608
77
0u8[2]; // error: cannot index into a value of type `u8`
88
```
99

10-
To be able to index into a type it needs to implement the `std::ops::Index`
11-
trait. Example:
10+
Only values with types that implement the `std::ops::Index` trait
11+
can be indexed with square brackets. Example:
1212

1313
```
1414
let v: Vec<u8> = vec![0, 1, 2, 3];
1515
1616
// The `Vec` type implements the `Index` trait so you can do:
1717
println!("{}", v[2]);
1818
```
19+
20+
Tuples and structs are indexed with dot (`.`), not with brackets (`[]`),
21+
and tuple element names are their positions:
22+
```ignore(pseudo code)
23+
// this (pseudo code) expression is true for any tuple:
24+
tuple == (tuple.0, tuple.1, ...)
25+
```

compiler/rustc_expand/src/base.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_ast::attr::{AttributeExt, MarkedAttrs};
1010
use rustc_ast::token::MetaVarKind;
1111
use rustc_ast::tokenstream::TokenStream;
1212
use rustc_ast::visit::{AssocCtxt, Visitor};
13-
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
13+
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind, Safety};
1414
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1515
use rustc_data_structures::sync;
1616
use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult};
@@ -345,6 +345,21 @@ pub trait AttrProcMacro {
345345
annotation: TokenStream,
346346
annotated: TokenStream,
347347
) -> Result<TokenStream, ErrorGuaranteed>;
348+
349+
// Default implementation for safe attributes; override if the attribute can be unsafe.
350+
fn expand_with_safety<'cx>(
351+
&self,
352+
ecx: &'cx mut ExtCtxt<'_>,
353+
safety: Safety,
354+
span: Span,
355+
annotation: TokenStream,
356+
annotated: TokenStream,
357+
) -> Result<TokenStream, ErrorGuaranteed> {
358+
if let Safety::Unsafe(span) = safety {
359+
ecx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
360+
}
361+
self.expand(ecx, span, annotation, annotated)
362+
}
348363
}
349364

350365
impl<F> AttrProcMacro for F

compiler/rustc_expand/src/expand.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,11 +812,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
812812
_ => item.to_tokens(),
813813
};
814814
let attr_item = attr.get_normal_item();
815+
let safety = attr_item.unsafety;
815816
if let AttrArgs::Eq { .. } = attr_item.args {
816817
self.cx.dcx().emit_err(UnsupportedKeyValue { span });
817818
}
818819
let inner_tokens = attr_item.args.inner_tokens();
819-
match expander.expand(self.cx, span, inner_tokens, tokens) {
820+
match expander.expand_with_safety(self.cx, safety, span, inner_tokens, tokens) {
820821
Ok(tok_result) => {
821822
let fragment = self.parse_ast_fragment(
822823
tok_result,
@@ -840,6 +841,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
840841
Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
841842
}
842843
} else if let SyntaxExtensionKind::LegacyAttr(expander) = ext {
844+
// `LegacyAttr` is only used for builtin attribute macros, which have their
845+
// safety checked by `check_builtin_meta_item`, so we don't need to check
846+
// `unsafety` here.
843847
match validate_attr::parse_meta(&self.cx.sess.psess, &attr) {
844848
Ok(meta) => {
845849
let item_clone = macro_stats.then(|| item.clone());
@@ -882,6 +886,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
882886
}
883887
}
884888
} else if let SyntaxExtensionKind::NonMacroAttr = ext {
889+
if let ast::Safety::Unsafe(span) = attr.get_normal_item().unsafety {
890+
self.cx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
891+
}
885892
// `-Zmacro-stats` ignores these because they don't do any real expansion.
886893
self.cx.expanded_inert_attrs.mark(&attr);
887894
item.visit_attrs(|attrs| attrs.insert(pos, attr));

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_ast::token::NtPatKind::*;
88
use rustc_ast::token::TokenKind::*;
99
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind};
1010
use rustc_ast::tokenstream::{self, DelimSpan, TokenStream};
11-
use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId};
11+
use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId, Safety};
1212
use rustc_ast_pretty::pprust;
1313
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1414
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan};
@@ -131,6 +131,7 @@ pub(super) enum MacroRule {
131131
Func { lhs: Vec<MatcherLoc>, lhs_span: Span, rhs: mbe::TokenTree },
132132
/// An attr rule, for use with `#[m]`
133133
Attr {
134+
unsafe_rule: bool,
134135
args: Vec<MatcherLoc>,
135136
args_span: Span,
136137
body: Vec<MatcherLoc>,
@@ -247,8 +248,19 @@ impl TTMacroExpander for MacroRulesMacroExpander {
247248

248249
impl AttrProcMacro for MacroRulesMacroExpander {
249250
fn expand(
251+
&self,
252+
_cx: &mut ExtCtxt<'_>,
253+
_sp: Span,
254+
_args: TokenStream,
255+
_body: TokenStream,
256+
) -> Result<TokenStream, ErrorGuaranteed> {
257+
unreachable!("`expand` called on `MacroRulesMacroExpander`, expected `expand_with_safety`")
258+
}
259+
260+
fn expand_with_safety(
250261
&self,
251262
cx: &mut ExtCtxt<'_>,
263+
safety: Safety,
252264
sp: Span,
253265
args: TokenStream,
254266
body: TokenStream,
@@ -260,6 +272,7 @@ impl AttrProcMacro for MacroRulesMacroExpander {
260272
self.node_id,
261273
self.name,
262274
self.transparency,
275+
safety,
263276
args,
264277
body,
265278
&self.rules,
@@ -408,6 +421,7 @@ fn expand_macro_attr(
408421
node_id: NodeId,
409422
name: Ident,
410423
transparency: Transparency,
424+
safety: Safety,
411425
args: TokenStream,
412426
body: TokenStream,
413427
rules: &[MacroRule],
@@ -429,13 +443,26 @@ fn expand_macro_attr(
429443
// Track nothing for the best performance.
430444
match try_match_macro_attr(psess, name, &args, &body, rules, &mut NoopTracker) {
431445
Ok((i, rule, named_matches)) => {
432-
let MacroRule::Attr { rhs, .. } = rule else {
446+
let MacroRule::Attr { rhs, unsafe_rule, .. } = rule else {
433447
panic!("try_macro_match_attr returned non-attr rule");
434448
};
435449
let mbe::TokenTree::Delimited(rhs_span, _, rhs) = rhs else {
436450
cx.dcx().span_bug(sp, "malformed macro rhs");
437451
};
438452

453+
match (safety, unsafe_rule) {
454+
(Safety::Default, false) | (Safety::Unsafe(_), true) => {}
455+
(Safety::Default, true) => {
456+
cx.dcx().span_err(sp, "unsafe attribute invocation requires `unsafe`");
457+
}
458+
(Safety::Unsafe(span), false) => {
459+
cx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute invocation");
460+
}
461+
(Safety::Safe(span), _) => {
462+
cx.dcx().span_bug(span, "unexpected `safe` keyword");
463+
}
464+
}
465+
439466
let id = cx.current_expansion.id;
440467
let tts = transcribe(psess, &named_matches, rhs, *rhs_span, transparency, id)
441468
.map_err(|e| e.emit())?;
@@ -681,6 +708,11 @@ pub fn compile_declarative_macro(
681708
let mut rules = Vec::new();
682709

683710
while p.token != token::Eof {
711+
let unsafe_rule = p.eat_keyword_noexpect(kw::Unsafe);
712+
let unsafe_keyword_span = p.prev_token.span;
713+
if unsafe_rule && let Some(guar) = check_no_eof(sess, &p, "expected `attr`") {
714+
return dummy_syn_ext(guar);
715+
}
684716
let (args, is_derive) = if p.eat_keyword_noexpect(sym::attr) {
685717
kinds |= MacroKinds::ATTR;
686718
if !features.macro_attr() {
@@ -705,6 +737,10 @@ pub fn compile_declarative_macro(
705737
feature_err(sess, sym::macro_derive, span, "`macro_rules!` derives are unstable")
706738
.emit();
707739
}
740+
if unsafe_rule {
741+
sess.dcx()
742+
.span_err(unsafe_keyword_span, "`unsafe` is only supported on `attr` rules");
743+
}
708744
if let Some(guar) = check_no_eof(sess, &p, "expected `()` after `derive`") {
709745
return dummy_syn_ext(guar);
710746
}
@@ -730,6 +766,10 @@ pub fn compile_declarative_macro(
730766
(None, true)
731767
} else {
732768
kinds |= MacroKinds::BANG;
769+
if unsafe_rule {
770+
sess.dcx()
771+
.span_err(unsafe_keyword_span, "`unsafe` is only supported on `attr` rules");
772+
}
733773
(None, false)
734774
};
735775
let lhs_tt = p.parse_token_tree();
@@ -741,10 +781,10 @@ pub fn compile_declarative_macro(
741781
if let Some(guar) = check_no_eof(sess, &p, "expected right-hand side of macro rule") {
742782
return dummy_syn_ext(guar);
743783
}
744-
let rhs_tt = p.parse_token_tree();
745-
let rhs_tt = parse_one_tt(rhs_tt, RulePart::Body, sess, node_id, features, edition);
746-
check_emission(check_rhs(sess, &rhs_tt));
747-
check_emission(check_meta_variables(&sess.psess, node_id, args.as_ref(), &lhs_tt, &rhs_tt));
784+
let rhs = p.parse_token_tree();
785+
let rhs = parse_one_tt(rhs, RulePart::Body, sess, node_id, features, edition);
786+
check_emission(check_rhs(sess, &rhs));
787+
check_emission(check_meta_variables(&sess.psess, node_id, args.as_ref(), &lhs_tt, &rhs));
748788
let lhs_span = lhs_tt.span();
749789
// Convert the lhs into `MatcherLoc` form, which is better for doing the
750790
// actual matching.
@@ -760,11 +800,11 @@ pub fn compile_declarative_macro(
760800
};
761801
let args = mbe::macro_parser::compute_locs(&delimited.tts);
762802
let body_span = lhs_span;
763-
rules.push(MacroRule::Attr { args, args_span, body: lhs, body_span, rhs: rhs_tt });
803+
rules.push(MacroRule::Attr { unsafe_rule, args, args_span, body: lhs, body_span, rhs });
764804
} else if is_derive {
765-
rules.push(MacroRule::Derive { body: lhs, body_span: lhs_span, rhs: rhs_tt });
805+
rules.push(MacroRule::Derive { body: lhs, body_span: lhs_span, rhs });
766806
} else {
767-
rules.push(MacroRule::Func { lhs, lhs_span, rhs: rhs_tt });
807+
rules.push(MacroRule::Func { lhs, lhs_span, rhs });
768808
}
769809
if p.token == token::Eof {
770810
break;

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,35 +3551,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35513551
);
35523552
// Try to give some advice about indexing tuples.
35533553
if let ty::Tuple(types) = base_t.kind() {
3554-
let mut needs_note = true;
3555-
// If the index is an integer, we can show the actual
3556-
// fixed expression:
3554+
err.help(
3555+
"tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.",
3556+
);
3557+
// If index is an unsuffixed integer, show the fixed expression:
35573558
if let ExprKind::Lit(lit) = idx.kind
35583559
&& let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
3559-
&& i.get()
3560-
< types
3561-
.len()
3562-
.try_into()
3563-
.expect("expected tuple index to be < usize length")
3560+
&& i.get() < types.len().try_into().expect("tuple length fits in u128")
35643561
{
35653562
err.span_suggestion(
35663563
brackets_span,
3567-
"to access tuple elements, use",
3564+
format!("to access tuple element `{i}`, use"),
35683565
format!(".{i}"),
35693566
Applicability::MachineApplicable,
35703567
);
3571-
needs_note = false;
3572-
} else if let ExprKind::Path(..) = idx.peel_borrows().kind {
3573-
err.span_label(
3574-
idx.span,
3575-
"cannot access tuple elements at a variable index",
3576-
);
3577-
}
3578-
if needs_note {
3579-
err.help(
3580-
"to access tuple elements, use tuple indexing \
3581-
syntax (e.g., `tuple.0`)",
3582-
);
35833568
}
35843569
}
35853570

0 commit comments

Comments
 (0)