Skip to content

Commit fb46410

Browse files
authored
Merge pull request #4500 from RalfJung/rustup
Rustup
2 parents 0570fb4 + dea3e13 commit fb46410

File tree

573 files changed

+7326
-2976
lines changed

Some content is hidden

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

573 files changed

+7326
-2976
lines changed

Cargo.lock

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -441,20 +441,6 @@ dependencies = [
441441
"thiserror 1.0.69",
442442
]
443443

444-
[[package]]
445-
name = "cargo_metadata"
446-
version = "0.19.2"
447-
source = "registry+https://github.com/rust-lang/crates.io-index"
448-
checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
449-
dependencies = [
450-
"camino",
451-
"cargo-platform 0.1.9",
452-
"semver",
453-
"serde",
454-
"serde_json",
455-
"thiserror 2.0.12",
456-
]
457-
458444
[[package]]
459445
name = "cargo_metadata"
460446
version = "0.21.0"
@@ -1364,7 +1350,7 @@ version = "0.1.0"
13641350
dependencies = [
13651351
"anyhow",
13661352
"askama",
1367-
"cargo_metadata 0.18.1",
1353+
"cargo_metadata 0.21.0",
13681354
"serde",
13691355
"serde_json",
13701356
"thiserror 1.0.69",
@@ -4255,6 +4241,7 @@ dependencies = [
42554241
"rustc-literal-escaper",
42564242
"rustc_ast",
42574243
"rustc_ast_pretty",
4244+
"rustc_attr_parsing",
42584245
"rustc_data_structures",
42594246
"rustc_errors",
42604247
"rustc_feature",
@@ -5369,7 +5356,7 @@ name = "tidy"
53695356
version = "0.1.0"
53705357
dependencies = [
53715358
"build_helper",
5372-
"cargo_metadata 0.19.2",
5359+
"cargo_metadata 0.21.0",
53735360
"fluent-syntax",
53745361
"ignore",
53755362
"miropt-test-tools",

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2849,7 +2849,7 @@ impl InlineAsmOperand {
28492849
}
28502850
}
28512851

2852-
#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2852+
#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
28532853
pub enum AsmMacro {
28542854
/// The `asm!` macro
28552855
Asm,

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,12 +416,24 @@ pub enum AttributeKind {
416416
/// Represents `#[pointee]`
417417
Pointee(Span),
418418

419+
/// Represents `#[proc_macro]`
420+
ProcMacro(Span),
421+
422+
/// Represents `#[proc_macro_attribute]`
423+
ProcMacroAttribute(Span),
424+
425+
/// Represents `#[proc_macro_derive]`
426+
ProcMacroDerive { trait_name: Symbol, helper_attrs: ThinVec<Symbol>, span: Span },
427+
419428
/// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint).
420429
PubTransparent(Span),
421430

422431
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
423432
Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
424433

434+
/// Represents `#[rustc_builtin_macro]`.
435+
RustcBuiltinMacro { builtin_name: Option<Symbol>, helper_attrs: ThinVec<Symbol>, span: Span },
436+
425437
/// Represents `#[rustc_layout_scalar_valid_range_end]`.
426438
RustcLayoutScalarValidRangeEnd(Box<u128>, Span),
427439

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ impl AttributeKind {
6161
PassByValue(..) => Yes,
6262
Path(..) => No,
6363
Pointee(..) => No,
64+
ProcMacro(..) => No,
65+
ProcMacroAttribute(..) => No,
66+
ProcMacroDerive { .. } => No,
6467
PubTransparent(..) => Yes,
6568
Repr { .. } => No,
69+
RustcBuiltinMacro { .. } => Yes,
6670
RustcLayoutScalarValidRangeEnd(..) => Yes,
6771
RustcLayoutScalarValidRangeStart(..) => Yes,
6872
RustcObjectLifetimeDefault => No,

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub(crate) mod must_use;
4141
pub(crate) mod no_implicit_prelude;
4242
pub(crate) mod non_exhaustive;
4343
pub(crate) mod path;
44+
pub(crate) mod proc_macro_attrs;
4445
pub(crate) mod repr;
4546
pub(crate) mod rustc_internal;
4647
pub(crate) mod semantics;
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
use rustc_attr_data_structures::AttributeKind;
2+
use rustc_feature::{AttributeTemplate, template};
3+
use rustc_span::{Span, Symbol, sym};
4+
use thin_vec::ThinVec;
5+
6+
use crate::attributes::{
7+
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
8+
};
9+
use crate::context::{AcceptContext, Stage};
10+
use crate::parser::ArgParser;
11+
12+
pub(crate) struct ProcMacroParser;
13+
impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroParser {
14+
const PATH: &[Symbol] = &[sym::proc_macro];
15+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
16+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacro;
17+
}
18+
19+
pub(crate) struct ProcMacroAttributeParser;
20+
impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroAttributeParser {
21+
const PATH: &[Symbol] = &[sym::proc_macro_attribute];
22+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
23+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacroAttribute;
24+
}
25+
26+
pub(crate) struct ProcMacroDeriveParser;
27+
impl<S: Stage> SingleAttributeParser<S> for ProcMacroDeriveParser {
28+
const PATH: &[Symbol] = &[sym::proc_macro_derive];
29+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
30+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
31+
const TEMPLATE: AttributeTemplate =
32+
template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)");
33+
34+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
35+
let (trait_name, helper_attrs) = parse_derive_like(cx, args, true)?;
36+
Some(AttributeKind::ProcMacroDerive {
37+
trait_name: trait_name.expect("Trait name is mandatory, so it is present"),
38+
helper_attrs,
39+
span: cx.attr_span,
40+
})
41+
}
42+
}
43+
44+
pub(crate) struct RustcBuiltinMacroParser;
45+
impl<S: Stage> SingleAttributeParser<S> for RustcBuiltinMacroParser {
46+
const PATH: &[Symbol] = &[sym::rustc_builtin_macro];
47+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
48+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
49+
const TEMPLATE: AttributeTemplate =
50+
template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)");
51+
52+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
53+
let (builtin_name, helper_attrs) = parse_derive_like(cx, args, false)?;
54+
Some(AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, span: cx.attr_span })
55+
}
56+
}
57+
58+
fn parse_derive_like<S: Stage>(
59+
cx: &mut AcceptContext<'_, '_, S>,
60+
args: &ArgParser<'_>,
61+
trait_name_mandatory: bool,
62+
) -> Option<(Option<Symbol>, ThinVec<Symbol>)> {
63+
let Some(list) = args.list() else {
64+
// For #[rustc_builtin_macro], it is permitted to leave out the trait name
65+
if args.no_args().is_ok() && !trait_name_mandatory {
66+
return Some((None, ThinVec::new()));
67+
}
68+
cx.expected_list(cx.attr_span);
69+
return None;
70+
};
71+
let mut items = list.mixed();
72+
73+
// Parse the name of the trait that is derived.
74+
let Some(trait_attr) = items.next() else {
75+
cx.expected_at_least_one_argument(list.span);
76+
return None;
77+
};
78+
let Some(trait_attr) = trait_attr.meta_item() else {
79+
cx.unexpected_literal(trait_attr.span());
80+
return None;
81+
};
82+
let Some(trait_ident) = trait_attr.path().word() else {
83+
cx.expected_identifier(trait_attr.path().span());
84+
return None;
85+
};
86+
if !trait_ident.name.can_be_raw() {
87+
cx.expected_identifier(trait_ident.span);
88+
return None;
89+
}
90+
if let Err(e) = trait_attr.args().no_args() {
91+
cx.expected_no_args(e);
92+
return None;
93+
};
94+
95+
// Parse optional attributes
96+
let mut attributes = ThinVec::new();
97+
if let Some(attrs) = items.next() {
98+
let Some(attr_list) = attrs.meta_item() else {
99+
cx.expected_list(attrs.span());
100+
return None;
101+
};
102+
if !attr_list.path().word_is(sym::attributes) {
103+
cx.expected_specific_argument(attrs.span(), vec!["attributes"]);
104+
return None;
105+
}
106+
let Some(attr_list) = attr_list.args().list() else {
107+
cx.expected_list(attrs.span());
108+
return None;
109+
};
110+
111+
// Parse item in `attributes(...)` argument
112+
for attr in attr_list.mixed() {
113+
let Some(attr) = attr.meta_item() else {
114+
cx.expected_identifier(attr.span());
115+
return None;
116+
};
117+
if let Err(e) = attr.args().no_args() {
118+
cx.expected_no_args(e);
119+
return None;
120+
};
121+
let Some(ident) = attr.path().word() else {
122+
cx.expected_identifier(attr.path().span());
123+
return None;
124+
};
125+
if !ident.name.can_be_raw() {
126+
cx.expected_identifier(ident.span);
127+
return None;
128+
}
129+
attributes.push(ident.name);
130+
}
131+
}
132+
133+
// If anything else is specified, we should reject it
134+
if let Some(next) = items.next() {
135+
cx.expected_no_args(next.span());
136+
}
137+
138+
Some((Some(trait_ident.name), attributes))
139+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ use crate::attributes::must_use::MustUseParser;
3838
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
3939
use crate::attributes::non_exhaustive::NonExhaustiveParser;
4040
use crate::attributes::path::PathParser as PathAttributeParser;
41+
use crate::attributes::proc_macro_attrs::{
42+
ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser,
43+
};
4144
use crate::attributes::repr::{AlignParser, ReprParser};
4245
use crate::attributes::rustc_internal::{
4346
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
@@ -154,6 +157,8 @@ attribute_parsers!(
154157
Single<MustUseParser>,
155158
Single<OptimizeParser>,
156159
Single<PathAttributeParser>,
160+
Single<ProcMacroDeriveParser>,
161+
Single<RustcBuiltinMacroParser>,
157162
Single<RustcForceInlineParser>,
158163
Single<RustcLayoutScalarValidRangeEnd>,
159164
Single<RustcLayoutScalarValidRangeStart>,
@@ -186,6 +191,8 @@ attribute_parsers!(
186191
Single<WithoutArgs<ParenSugarParser>>,
187192
Single<WithoutArgs<PassByValueParser>>,
188193
Single<WithoutArgs<PointeeParser>>,
194+
Single<WithoutArgs<ProcMacroAttributeParser>>,
195+
Single<WithoutArgs<ProcMacroParser>>,
189196
Single<WithoutArgs<PubTransparentParser>>,
190197
Single<WithoutArgs<SpecializationTraitParser>>,
191198
Single<WithoutArgs<StdInternalSymbolParser>>,

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,58 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12901290
span,
12911291
format!("if `{ty}` implemented `Clone`, you could clone the value"),
12921292
);
1293+
} else if let ty::Adt(_, _) = ty.kind()
1294+
&& let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()
1295+
{
1296+
// For cases like `Option<NonClone>`, where `Option<T>: Clone` if `T: Clone`, we point
1297+
// at the types that should be `Clone`.
1298+
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
1299+
let cause = ObligationCause::misc(expr.span, self.mir_def_id());
1300+
ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait);
1301+
let errors = ocx.select_all_or_error();
1302+
if errors.iter().all(|error| {
1303+
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
1304+
Some(clause) => match clause.self_ty().skip_binder().kind() {
1305+
ty::Adt(def, _) => def.did().is_local() && clause.def_id() == clone_trait,
1306+
_ => false,
1307+
},
1308+
None => false,
1309+
}
1310+
}) {
1311+
let mut type_spans = vec![];
1312+
let mut types = FxIndexSet::default();
1313+
for clause in errors
1314+
.iter()
1315+
.filter_map(|e| e.obligation.predicate.as_clause())
1316+
.filter_map(|c| c.as_trait_clause())
1317+
{
1318+
let ty::Adt(def, _) = clause.self_ty().skip_binder().kind() else { continue };
1319+
type_spans.push(self.infcx.tcx.def_span(def.did()));
1320+
types.insert(
1321+
self.infcx
1322+
.tcx
1323+
.short_string(clause.self_ty().skip_binder(), &mut err.long_ty_path()),
1324+
);
1325+
}
1326+
let mut span: MultiSpan = type_spans.clone().into();
1327+
for sp in type_spans {
1328+
span.push_span_label(sp, "consider implementing `Clone` for this type");
1329+
}
1330+
span.push_span_label(expr.span, "you could clone this value");
1331+
let types: Vec<_> = types.into_iter().collect();
1332+
let msg = match &types[..] {
1333+
[only] => format!("`{only}`"),
1334+
[head @ .., last] => format!(
1335+
"{} and `{last}`",
1336+
head.iter().map(|t| format!("`{t}`")).collect::<Vec<_>>().join(", ")
1337+
),
1338+
[] => unreachable!(),
1339+
};
1340+
err.span_note(
1341+
span,
1342+
format!("if {msg} implemented `Clone`, you could clone the value"),
1343+
);
1344+
}
12931345
}
12941346
}
12951347

0 commit comments

Comments
 (0)