Skip to content

Commit 214fc33

Browse files
committed
Auto merge of #157440 - JonathanBrouwer:rollup-XlcBgjV, r=<try>
Rollup of 8 pull requests try-job: dist-various-1 try-job: test-various try-job: x86_64-gnu-aux try-job: x86_64-gnu-llvm-21-3 try-job: x86_64-msvc-1 try-job: aarch64-apple try-job: x86_64-mingw-1 try-job: i686-msvc-2
2 parents 9ae765d + b5058b6 commit 214fc33

54 files changed

Lines changed: 586 additions & 378 deletions

Some content is hidden

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

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,7 +1992,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19921992
bounds: &[GenericBound],
19931993
colon_span: Option<Span>,
19941994
parent_span: Span,
1995-
rbp: RelaxedBoundPolicy<'_>,
1995+
rbp: RelaxedBoundPolicy,
19961996
itctx: ImplTraitContext,
19971997
origin: PredicateOrigin,
19981998
) -> Option<hir::WherePredicate<'hir>> {
@@ -2067,10 +2067,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
20672067
bounded_ty,
20682068
bounds,
20692069
}) => {
2070-
let rbp = if bound_generic_params.is_empty() {
2071-
RelaxedBoundPolicy::AllowedIfOnTyParam(bounded_ty.id, params)
2070+
let rbp = if bound_generic_params.is_empty()
2071+
&& let Some(res) =
2072+
self.get_partial_res(bounded_ty.id).and_then(|r| r.full_res())
2073+
&& let Res::Def(DefKind::TyParam, def_id) = res
2074+
&& params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2075+
{
2076+
RelaxedBoundPolicy::Allowed
20722077
} else {
2073-
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope)
2078+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::WhereBound)
20742079
};
20752080
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
20762081
bound_generic_params: self.lower_generic_params(

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,8 @@ impl<'tcx> ResolverAstLowering<'tcx> {
313313
/// Relaxed bounds should only be allowed in places where we later
314314
/// (namely during HIR ty lowering) perform *sized elaboration*.
315315
#[derive(Clone, Copy, Debug)]
316-
enum RelaxedBoundPolicy<'a> {
316+
enum RelaxedBoundPolicy {
317317
Allowed,
318-
AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),
319318
Forbidden(RelaxedBoundForbiddenReason),
320319
}
321320

@@ -325,7 +324,9 @@ enum RelaxedBoundForbiddenReason {
325324
SuperTrait,
326325
TraitAlias,
327326
AssocTyBounds,
328-
LateBoundVarsInScope,
327+
/// We do not allow where bounds doing relaxed bounds,
328+
/// except if it's for generic parameters of the current item.
329+
WhereBound,
329330
}
330331

331332
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
@@ -1950,7 +1951,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19501951
fn lower_param_bound(
19511952
&mut self,
19521953
tpb: &GenericBound,
1953-
rbp: RelaxedBoundPolicy<'_>,
1954+
rbp: RelaxedBoundPolicy,
19541955
itctx: ImplTraitContext,
19551956
) -> hir::GenericBound<'hir> {
19561957
match tpb {
@@ -2188,7 +2189,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
21882189
fn lower_poly_trait_ref(
21892190
&mut self,
21902191
PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2191-
rbp: RelaxedBoundPolicy<'_>,
2192+
rbp: RelaxedBoundPolicy,
21922193
itctx: ImplTraitContext,
21932194
) -> hir::PolyTraitRef<'hir> {
21942195
let bound_generic_params =
@@ -2212,7 +2213,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
22122213
&self,
22132214
trait_ref: hir::TraitRef<'_>,
22142215
span: Span,
2215-
rbp: RelaxedBoundPolicy<'_>,
2216+
rbp: RelaxedBoundPolicy,
22162217
) {
22172218
// Even though feature `more_maybe_bounds` enables the user to relax all default bounds
22182219
// other than `Sized` in a lot more positions (thereby bypassing the given policy), we don't
@@ -2225,14 +2226,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
22252226

22262227
match rbp {
22272228
RelaxedBoundPolicy::Allowed => return,
2228-
RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2229-
if let Some(res) = self.get_partial_res(id).and_then(|r| r.full_res())
2230-
&& let Res::Def(DefKind::TyParam, def_id) = res
2231-
&& params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2232-
{
2233-
return;
2234-
}
2235-
}
22362229
RelaxedBoundPolicy::Forbidden(reason) => {
22372230
let gate = |context, subject| {
22382231
let extended = self.tcx.features().more_maybe_bounds();
@@ -2272,7 +2265,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
22722265
return;
22732266
}
22742267
RelaxedBoundForbiddenReason::AssocTyBounds
2275-
| RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2268+
| RelaxedBoundForbiddenReason::WhereBound => {}
22762269
};
22772270
}
22782271
}
@@ -2294,7 +2287,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
22942287
fn lower_param_bounds(
22952288
&mut self,
22962289
bounds: &[GenericBound],
2297-
rbp: RelaxedBoundPolicy<'_>,
2290+
rbp: RelaxedBoundPolicy,
22982291
itctx: ImplTraitContext,
22992292
) -> hir::GenericBounds<'hir> {
23002293
self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
@@ -2303,7 +2296,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
23032296
fn lower_param_bounds_mut(
23042297
&mut self,
23052298
bounds: &[GenericBound],
2306-
rbp: RelaxedBoundPolicy<'_>,
2299+
rbp: RelaxedBoundPolicy,
23072300
itctx: ImplTraitContext,
23082301
) -> impl Iterator<Item = hir::GenericBound<'hir>> {
23092302
bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Traits for parsing attributes.
2+
//!
13
//! This module defines traits for attribute parsers, little state machines that recognize and parse
24
//! attributes out of a longer list of attributes. The main trait is called [`AttributeParser`].
35
//! You can find more docs about [`AttributeParser`]s on the trait itself.
@@ -7,9 +9,11 @@
79
//! Specifically, you might not care about managing the state of your [`AttributeParser`]
810
//! state machine yourself. In this case you can choose to implement:
911
//!
10-
//! - [`SingleAttributeParser`](crate::attributes::SingleAttributeParser): makes it easy to implement an attribute which should error if it
12+
//! - [`NoArgsAttributeParser`]: used for implementing an attribute that appears only once and
13+
//! accepts no arguments
14+
//! - [`SingleAttributeParser`]: makes it easy to implement an attribute which should error if it
1115
//! appears more than once in a list of attributes
12-
//! - [`CombineAttributeParser`](crate::attributes::CombineAttributeParser): makes it easy to implement an attribute which should combine the
16+
//! - [`CombineAttributeParser`]: makes it easy to implement an attribute which should combine the
1317
//! contents of attributes, if an attribute appear multiple times in a list
1418
//!
1519
//! Attributes should be added to `crate::context::ATTRIBUTE_PARSERS` to be parsed.

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! Context given to attribute parsers when parsing.
12
use std::cell::RefCell;
23
use std::collections::BTreeMap;
34
use std::collections::btree_map::Entry;
@@ -846,6 +847,9 @@ impl ShouldEmit {
846847
}
847848
}
848849

850+
/// The interface for issuing argument parsing related diagnostics.
851+
///
852+
/// It can be obtained through the [`adcx`](AcceptContext::adcx) method on [`AcceptContext`].
849853
pub(crate) struct AttributeDiagnosticContext<'a, 'f, 'sess> {
850854
ctx: &'a mut AcceptContext<'f, 'sess>,
851855
custom_suggestions: Vec<Suggestion>,

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! API for other crates to parse attributes themselves.
12
use std::convert::identity;
23
#[cfg(debug_assertions)]
34
use std::sync::atomic::{AtomicBool, Ordering};

compiler/rustc_attr_parsing/src/lib.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
//!
33
//! ## Architecture
44
//! This crate is part of a series of crates and modules that handle attribute processing.
5-
//! - [rustc_hir::attrs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html): Defines the data structures that store parsed attributes
6-
//! - [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html): This crate, handles the parsing of attributes
7-
//! - (planned) rustc_attr_validation: Will handle attribute validation, logic currently handled in `rustc_passes`
5+
//! - [`rustc_hir::attrs`]: Defines the data structures that store parsed attributes
6+
//! - `rustc_attr_parsing`: This crate, handles the parsing of attributes
7+
//! - [`rustc_passes::check_attr`] handles attribute validation that cannot be done in this crate
88
//!
99
//! The separation between data structures and parsing follows the principle of separation of concerns.
1010
//! Data structures (`rustc_hir::attrs`) define what attributes look like after parsing.
@@ -13,7 +13,7 @@
1313
//! the parsing logic, making the codebase more modular and maintainable.
1414
//!
1515
//! ## Background
16-
//! Previously, the compiler had a single attribute definition (`ast::Attribute`) with parsing and
16+
//! Previously, the compiler had a single attribute definition ([`ast::Attribute`]) with parsing and
1717
//! validation scattered throughout the codebase. This was reorganized for better maintainability
1818
//! (see [#131229](https://github.com/rust-lang/rust/issues/131229)).
1919
//!
@@ -61,7 +61,7 @@
6161
//! `#[stable(...)]` and `#[unstable()]` cannot occur together, and both semantically define
6262
//! a "stability" of an item. So, the stability attribute has an
6363
//! [`AttributeParser`](attributes::AttributeParser) that recognizes both the `#[stable()]`
64-
//! and `#[unstable()]` syntactic attributes, and at the end produce a single
64+
//! and `#[unstable()]` syntactic attributes, and at the end produces a single
6565
//! [`AttributeKind::Stability`](rustc_hir::attrs::AttributeKind::Stability).
6666
//!
6767
//! When multiple instances of the same attribute are allowed, they're combined into a single
@@ -82,6 +82,9 @@
8282
//! However, sometimes an attributes' parsed form is needed before the HIR is constructed.
8383
//! This is referred to as "early" attribute parsing,
8484
//! and is performed using the `parse_limited_*` family of functions on `AttributeParser`.
85+
//!
86+
//! [`ast::Attribute`]: rustc_ast::ast::Attribute
87+
//! [`rustc_passes::check_attr`]: ../rustc_passes/check_attr/index.html
8588
8689
// tidy-alphabetical-start
8790
#![feature(decl_macro)]
@@ -91,24 +94,13 @@
9194
// tidy-alphabetical-end
9295

9396
#[macro_use]
94-
/// All the individual attribute parsers for each of rustc's built-in attributes.
9597
mod attributes;
96-
97-
/// All the important types given to attribute parsers when parsing
98-
pub(crate) mod context;
99-
100-
/// Code that other crates interact with, to actually parse a list (or sometimes single)
101-
/// attribute.
102-
mod interface;
103-
104-
/// Despite this entire module called attribute parsing and the term being a little overloaded,
105-
/// in this module the code lives that actually breaks up tokenstreams into semantic pieces of attributes,
106-
/// like lists or name-value pairs.
107-
pub mod parser;
108-
10998
mod check_cfg;
99+
mod context;
110100
mod early_parsed;
111101
mod errors;
102+
mod interface;
103+
pub mod parser;
112104
mod safety;
113105
mod session_diagnostics;
114106
mod stability;

compiler/rustc_attr_parsing/src/parser.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
//! Parsing of attribute arguments.
2+
//!
3+
//! Depending on the attribute parser, an [`ArgParser`] can be used to parse the arguments given to
4+
//! an attribute. See its documentation for more information.
5+
//!
16
//! This is in essence an (improved) duplicate of `rustc_ast/attr/mod.rs`.
27
//! That module is intended to be deleted in its entirety.
38
//!
@@ -89,6 +94,12 @@ impl<P: Borrow<Path>> Display for PathParser<P> {
8994
}
9095
}
9196

97+
/// Used for parsing attribute arguments.
98+
///
99+
/// See also [`AttributeDiagnosticContext`], which is the preferred interface for issuing argument
100+
/// parsing related diagnostics.
101+
///
102+
/// [`AttributeDiagnosticContext`]: crate::context::AttributeDiagnosticContext
92103
#[derive(Debug)]
93104
#[must_use]
94105
pub enum ArgParser {

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,12 @@ impl RegionName {
111111
| RegionNameSource::NamedEarlyParamRegion(span) => {
112112
diag.span_label(*span, format!("lifetime `{self}` defined here"));
113113
}
114-
RegionNameSource::SynthesizedFreeEnvRegion(span, note) => {
114+
RegionNameSource::SynthesizedFreeEnvRegion(span, closure_trait) => {
115115
diag.span_label(*span, format!("lifetime `{self}` represents this closure's body"));
116-
diag.note(*note);
116+
diag.note(format!(
117+
"closure implements `{closure_trait}`, so references to captured variables \
118+
can't escape the closure"
119+
));
117120
}
118121
RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::CannotMatchHirTy(
119122
span,
@@ -326,9 +329,15 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
326329
ty::LateParamRegionKind::ClosureEnv => {
327330
let def_ty = self.regioncx.universal_regions().defining_ty;
328331

329-
let closure_kind = match def_ty {
330-
DefiningTy::Closure(_, args) => args.as_closure().kind(),
331-
DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().kind(),
332+
let (is_lending_coroutine_closure, closure_kind) = match def_ty {
333+
DefiningTy::Closure(_, args) => (false, args.as_closure().kind()),
334+
DefiningTy::CoroutineClosure(_, args) => {
335+
let args = args.as_coroutine_closure();
336+
(
337+
!args.tupled_upvars_ty().is_ty_var() && args.has_self_borrows(),
338+
args.kind(),
339+
)
340+
}
332341
_ => {
333342
// Can't have BrEnv in functions, constants or coroutines.
334343
bug!("BrEnv outside of closure.");
@@ -340,23 +349,19 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
340349
bug!("Closure is not defined by a closure expr");
341350
};
342351
let region_name = self.synthesize_region_name();
343-
let note = match closure_kind {
344-
ty::ClosureKind::Fn => {
345-
"closure implements `Fn`, so references to captured variables \
346-
can't escape the closure"
347-
}
348-
ty::ClosureKind::FnMut => {
349-
"closure implements `FnMut`, so references to captured variables \
350-
can't escape the closure"
351-
}
352-
ty::ClosureKind::FnOnce => {
353-
bug!("BrEnv in a `FnOnce` closure");
354-
}
352+
let closure_trait = match (is_lending_coroutine_closure, closure_kind) {
353+
(false, kind) => kind.as_str(),
354+
(true, ty::ClosureKind::Fn) => "AsyncFn",
355+
(true, ty::ClosureKind::FnMut) => "AsyncFnMut",
356+
(true, ty::ClosureKind::FnOnce) => "AsyncFnOnce",
355357
};
356358

357359
Some(RegionName {
358360
name: region_name,
359-
source: RegionNameSource::SynthesizedFreeEnvRegion(fn_decl_span, note),
361+
source: RegionNameSource::SynthesizedFreeEnvRegion(
362+
fn_decl_span,
363+
closure_trait,
364+
),
360365
})
361366
}
362367

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@ trait ArgAttributesExt {
3838
const ABI_AFFECTING_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 1] =
3939
[(ArgAttribute::InReg, llvm::AttributeKind::InReg)];
4040

41-
const OPTIMIZATION_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 5] = [
41+
const OPTIMIZATION_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 6] = [
4242
(ArgAttribute::NoAlias, llvm::AttributeKind::NoAlias),
4343
(ArgAttribute::NonNull, llvm::AttributeKind::NonNull),
4444
(ArgAttribute::ReadOnly, llvm::AttributeKind::ReadOnly),
4545
(ArgAttribute::NoUndef, llvm::AttributeKind::NoUndef),
4646
(ArgAttribute::Writable, llvm::AttributeKind::Writable),
47+
// Our internal NoFree attribute still allows deallocation of zero-size allocations. However,
48+
// these don't render any bytes non-dereferenceable, so it's still fine to apply LLVM NoFree
49+
// for them.
50+
(ArgAttribute::NoFree, llvm::AttributeKind::NoFree),
4751
];
4852

4953
const CAPTURES_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 3] = [
@@ -75,7 +79,9 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
7579
// Only apply remaining attributes when optimizing
7680
if cx.sess().opts.optimize != config::OptLevel::No {
7781
let deref = this.pointee_size.bytes();
78-
if deref != 0 {
82+
// dereferenceable in LLVM currently implies nofree, so only emit dereferenceable if nofree
83+
// is also set.
84+
if deref != 0 && regular.contains(ArgAttribute::NoFree) {
7985
if regular.contains(ArgAttribute::NonNull) {
8086
attrs.push(llvm::CreateDereferenceableAttr(cx.llcx, deref));
8187
} else {

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ pub(crate) enum AttributeKind {
318318
SanitizeRealtimeNonblocking = 47,
319319
SanitizeRealtimeBlocking = 48,
320320
Convergent = 49,
321+
NoFree = 50,
321322
}
322323

323324
/// LLVMIntPredicate

0 commit comments

Comments
 (0)