Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cca2865
sess: `-Zbranch-protection` is a target modifier
davidtwco Jan 29, 2026
aa7d812
remove `internal_impls_macro` feature
cyrgani Mar 17, 2026
e350a56
move features into the correct section
cyrgani Feb 24, 2026
c8a2c46
bootstrap: Optionally print a backtrace if a command fails
jyn514 Mar 16, 2026
74c51ce
Don't emit `missing_doc_code_examples` on impl items
GuillaumeGomez Mar 18, 2026
6d3b780
Add more tests for rustdoc `missing_doc_code_examples` lint
GuillaumeGomez Mar 18, 2026
45b22ef
tests: Activate must_not_suspend test for MutexGuard dropped before a…
Enselic Mar 18, 2026
bef4b47
Updates derive_where and removes workaround
spirali Mar 19, 2026
74776c4
Rewrite `query_ensure_result`.
nnethercote Mar 19, 2026
cec0a68
Resolve paths for `impl` restrictions using `smart_resolve_path`
CoCo-Japan-pan Mar 19, 2026
4a60dae
Add UI tests for path resolution errors of `impl` restrictions
CoCo-Japan-pan Mar 19, 2026
082cdf7
Preserve braces around `self` in use tree pretty printing
aytey Mar 19, 2026
c777685
Fix whitespace after fragment specifiers in macro pretty printing
aytey Mar 19, 2026
e9740a4
Insert space after float literal ending with `.` in pretty printer
aytey Mar 19, 2026
caad6ee
tests: Add regression test for async closures involving HRTBs
Enselic Mar 19, 2026
88108dd
Rollup merge of #152909 - davidtwco:branch-protection-target-modifier…
JonathanBrouwer Mar 19, 2026
d99932c
Rollup merge of #153556 - CoCo-Japan-pan:impl-restriction-lowering, r…
JonathanBrouwer Mar 19, 2026
74eae37
Rollup merge of #154048 - GuillaumeGomez:missing_doc_code_examples-im…
JonathanBrouwer Mar 19, 2026
511b254
Rollup merge of #153992 - ferrocene:jyn/bootstrap-backtrace, r=jieyou…
JonathanBrouwer Mar 19, 2026
2aa5f08
Rollup merge of #154019 - cyrgani:feature-clean, r=joboet
JonathanBrouwer Mar 19, 2026
0827a4b
Rollup merge of #154059 - Enselic:dropped-mutex-guard, r=Kivooeo
JonathanBrouwer Mar 19, 2026
08c8761
Rollup merge of #154075 - nnethercote:rewrite-query_ensure_result, r=…
JonathanBrouwer Mar 19, 2026
b29a650
Rollup merge of #154082 - spirali:fix-derive-where, r=lqd
JonathanBrouwer Mar 19, 2026
f48ea33
Rollup merge of #154084 - aytey:fix-use-self-braces, r=Kivooeo
JonathanBrouwer Mar 19, 2026
b03a61d
Rollup merge of #154086 - aytey:fix-float-range-spacing, r=Kivooeo
JonathanBrouwer Mar 19, 2026
136aa2f
Rollup merge of #154087 - aytey:fix-fragment-specifier-whitespace, r=…
JonathanBrouwer Mar 19, 2026
0ab7a28
Rollup merge of #154109 - Enselic:unifying-function-types-involving-h…
JonathanBrouwer Mar 19, 2026
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
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1140,9 +1140,9 @@ version = "0.1.96"

[[package]]
name = "derive-where"
version = "1.6.0"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f"
checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534"
dependencies = [
"proc-macro2",
"quote",
Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,19 @@ fn print_crate_inner<'a>(
/// - #63896: `#[allow(unused,` must be printed rather than `#[allow(unused ,`
/// - #73345: `#[allow(unused)]` must be printed rather than `# [allow(unused)]`
///
/// Returns `true` if both token trees are identifier-like tokens that would
/// merge into a single token if printed without a space between them.
/// E.g. `ident` + `where` would merge into `identwhere`.
fn idents_would_merge(tt1: &TokenTree, tt2: &TokenTree) -> bool {
fn is_ident_like(tt: &TokenTree) -> bool {
matches!(
tt,
TokenTree::Token(Token { kind: token::Ident(..) | token::NtIdent(..), .. }, _,)
)
}
is_ident_like(tt1) && is_ident_like(tt2)
}

fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
use Delimiter::*;
use TokenTree::{Delimited as Del, Token as Tok};
Expand Down Expand Up @@ -811,6 +824,13 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
if let Some(next) = iter.peek() {
if spacing == Spacing::Alone && space_between(tt, next) {
self.space();
} else if spacing != Spacing::Alone && idents_would_merge(tt, next) {
// When tokens from macro `tt` captures preserve their
// original `Joint`/`JointHidden` spacing, adjacent
// identifier-like tokens can be concatenated without a
// space (e.g. `$x:identwhere`). Insert a space to
// prevent this.
self.space();
}
}
}
Expand Down
48 changes: 37 additions & 11 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,15 @@ impl<'a> State<'a> {
//
// loop { break x; }.method();
//
self.print_expr_cond_paren(
receiver,
receiver.precedence() < ExprPrecedence::Unambiguous,
fixup.leftmost_subexpression_with_dot(),
);
let needs_paren = receiver.precedence() < ExprPrecedence::Unambiguous;
self.print_expr_cond_paren(receiver, needs_paren, fixup.leftmost_subexpression_with_dot());

// If the receiver is an unsuffixed float literal like `0.`, insert
// a space so the `.` of the method call doesn't merge with the
// trailing dot: `0. .method()` instead of `0..method()`.
if !needs_paren && expr_ends_with_dot(receiver) {
self.word(" ");
}
self.word(".");
self.print_ident(segment.ident);
if let Some(args) = &segment.args {
Expand Down Expand Up @@ -658,11 +661,15 @@ impl<'a> State<'a> {
);
}
ast::ExprKind::Field(expr, ident) => {
let needs_paren = expr.precedence() < ExprPrecedence::Unambiguous;
self.print_expr_cond_paren(
expr,
expr.precedence() < ExprPrecedence::Unambiguous,
needs_paren,
fixup.leftmost_subexpression_with_dot(),
);
if !needs_paren && expr_ends_with_dot(expr) {
self.word(" ");
}
self.word(".");
self.print_ident(*ident);
}
Expand All @@ -685,11 +692,15 @@ impl<'a> State<'a> {
let fake_prec = ExprPrecedence::LOr;
if let Some(e) = start {
let start_fixup = fixup.leftmost_subexpression_with_operator(true);
self.print_expr_cond_paren(
e,
start_fixup.precedence(e) < fake_prec,
start_fixup,
);
let needs_paren = start_fixup.precedence(e) < fake_prec;
self.print_expr_cond_paren(e, needs_paren, start_fixup);
// If the start expression is a float literal ending with
// `.`, we need a space before `..` or `..=` so that the
// dots don't merge. E.g. `0. ..45.` must not become
// `0...45.`.
if !needs_paren && expr_ends_with_dot(e) {
self.word(" ");
}
}
match limits {
ast::RangeLimits::HalfOpen => self.word(".."),
Expand Down Expand Up @@ -1025,3 +1036,18 @@ fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> String
template.push('"');
template
}

/// Returns `true` if the printed representation of this expression ends with
/// a `.` character — specifically, an unsuffixed float literal like `0.` or
/// `45.`. This is used to insert whitespace before range operators (`..`,
/// `..=`) so that the dots don't merge (e.g. `0. ..45.` instead of `0...45.`).
fn expr_ends_with_dot(expr: &ast::Expr) -> bool {
match &expr.kind {
ast::ExprKind::Lit(token_lit) => {
token_lit.kind == token::Float
&& token_lit.suffix.is_none()
&& token_lit.symbol.as_str().ends_with('.')
}
_ => false,
}
}
8 changes: 7 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,13 @@ impl<'a> State<'a> {
}
if items.is_empty() {
self.word("{}");
} else if let [(item, _)] = items.as_slice() {
} else if let [(item, _)] = items.as_slice()
&& !item
.prefix
.segments
.first()
.is_some_and(|seg| seg.ident.name == rustc_span::symbol::kw::SelfLower)
{
self.print_use_tree(item);
} else {
let cb = self.cbox(INDENT_UNIT);
Expand Down
43 changes: 27 additions & 16 deletions compiler/rustc_middle/src/query/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,34 @@ where
C: QueryCache<Value = Erased<Result<T, ErrorGuaranteed>>>,
Result<T, ErrorGuaranteed>: Erasable,
{
let convert = |value: Erased<Result<T, ErrorGuaranteed>>| -> Result<(), ErrorGuaranteed> {
match erase::restore_val(value) {
Ok(_) => Ok(()),
Err(guar) => Err(guar),
}
};

match try_get_cached(tcx, &query.cache, key) {
Some(value) => erase::restore_val(value).map(drop),
None => (query.execute_query_fn)(
tcx,
DUMMY_SP,
key,
QueryMode::Ensure { ensure_mode: EnsureMode::Ok },
)
.map(erase::restore_val)
.map(|value| value.map(drop))
// Either we actually executed the query, which means we got a full `Result`,
// or we can just assume the query succeeded, because it was green in the
// incremental cache. If it is green, that means that the previous compilation
// that wrote to the incremental cache compiles successfully. That is only
// possible if the cache entry was `Ok(())`, so we emit that here, without
// actually encoding the `Result` in the cache or loading it from there.
.unwrap_or(Ok(())),
Some(value) => convert(value),
None => {
match (query.execute_query_fn)(
tcx,
DUMMY_SP,
key,
QueryMode::Ensure { ensure_mode: EnsureMode::Ok },
) {
// We executed the query. Convert the successful result.
Some(res) => convert(res),

// Reaching here means we didn't execute the query, but we can just assume the
// query succeeded, because it was green in the incremental cache. If it is green,
// that means that the previous compilation that wrote to the incremental cache
// compiles successfully. That is only possible if the cache entry was `Ok(())`, so
// we emit that here, without actually encoding the `Result` in the cache or
// loading it from there.
None => Ok(()),
}
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,10 @@ pub(crate) struct ExpectedModuleFound {
#[diag("cannot determine resolution for the visibility", code = E0578)]
pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);

#[derive(Diagnostic)]
#[diag("trait implementation can only be restricted to ancestor modules")]
pub(crate) struct RestrictionAncestorOnly(#[primary_span] pub(crate) Span);

#[derive(Diagnostic)]
#[diag("cannot use a tool module through an import")]
pub(crate) struct ToolModuleImported {
Expand Down
43 changes: 39 additions & 4 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ pub(crate) enum PathSource<'a, 'ast, 'ra> {
DefineOpaques,
/// Resolving a macro
Macro,
/// Paths for module or crate root. Used for restrictions.
Module,
}

impl PathSource<'_, '_, '_> {
Expand All @@ -460,7 +462,8 @@ impl PathSource<'_, '_, '_> {
PathSource::Type
| PathSource::Trait(_)
| PathSource::Struct(_)
| PathSource::DefineOpaques => TypeNS,
| PathSource::DefineOpaques
| PathSource::Module => TypeNS,
PathSource::Expr(..)
| PathSource::Pat
| PathSource::TupleStruct(..)
Expand All @@ -485,7 +488,8 @@ impl PathSource<'_, '_, '_> {
| PathSource::DefineOpaques
| PathSource::Delegation
| PathSource::PreciseCapturingArg(..)
| PathSource::Macro => false,
| PathSource::Macro
| PathSource::Module => false,
}
}

Expand Down Expand Up @@ -528,6 +532,7 @@ impl PathSource<'_, '_, '_> {
PathSource::ReturnTypeNotation | PathSource::Delegation => "function",
PathSource::PreciseCapturingArg(..) => "type or const parameter",
PathSource::Macro => "macro",
PathSource::Module => "module",
}
}

Expand Down Expand Up @@ -626,6 +631,7 @@ impl PathSource<'_, '_, '_> {
),
PathSource::PreciseCapturingArg(MacroNS) => false,
PathSource::Macro => matches!(res, Res::Def(DefKind::Macro(_), _)),
PathSource::Module => matches!(res, Res::Def(DefKind::Mod, _)),
}
}

Expand All @@ -646,6 +652,12 @@ impl PathSource<'_, '_, '_> {
(PathSource::PreciseCapturingArg(..), true) => E0799,
(PathSource::PreciseCapturingArg(..), false) => E0800,
(PathSource::Macro, _) => E0425,
// FIXME: There is no dedicated error code for this case yet.
// E0577 already covers the same situation for visibilities,
// so we reuse it here for now. It may make sense to generalize
// it for restrictions in the future.
(PathSource::Module, true) => E0577,
(PathSource::Module, false) => E0433,
}
}
}
Expand Down Expand Up @@ -2174,7 +2186,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
| PathSource::Type
| PathSource::PreciseCapturingArg(..)
| PathSource::ReturnTypeNotation
| PathSource::Macro => false,
| PathSource::Macro
| PathSource::Module => false,
PathSource::Expr(..)
| PathSource::Pat
| PathSource::Struct(_)
Expand Down Expand Up @@ -2800,7 +2813,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.diag_metadata.current_impl_items = None;
}

ItemKind::Trait(box Trait { generics, bounds, items, .. }) => {
ItemKind::Trait(box Trait { generics, bounds, items, impl_restriction, .. }) => {
// resolve paths for `impl` restrictions
self.resolve_impl_restriction_path(impl_restriction);

// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
&generics.params,
Expand Down Expand Up @@ -4389,6 +4405,25 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
}
}

fn resolve_impl_restriction_path(&mut self, restriction: &'ast ast::ImplRestriction) {
match &restriction.kind {
ast::RestrictionKind::Unrestricted => (),
ast::RestrictionKind::Restricted { path, id, shorthand: _ } => {
self.smart_resolve_path(*id, &None, path, PathSource::Module);
if let Some(res) = self.r.partial_res_map[&id].full_res()
&& let Some(def_id) = res.opt_def_id()
{
if !self.r.is_accessible_from(
Visibility::Restricted(def_id),
self.parent_scope.module,
) {
self.r.dcx().create_err(errors::RestrictionAncestorOnly(path.span)).emit();
}
}
}
}
}

// High-level and context dependent path resolution routine.
// Resolves the path and records the resolution into definition map.
// If resolution fails tries several techniques to find likely
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2240,7 +2240,7 @@ options! {
(default: no)"),
box_noalias: bool = (true, parse_bool, [TRACKED],
"emit noalias metadata for box (default: yes)"),
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED TARGET_MODIFIER],
"set options for branch target identification and pointer authentication on AArch64"),
build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED],
"whether the stable interface is being built"),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2024"
# tidy-alphabetical-start
arrayvec = { version = "0.7", default-features = false }
bitflags = "2.4.1"
derive-where = "1.2.7"
derive-where = "1.6.1"
ena = "0.14.4"
indexmap = "2.0.0"
rustc-hash = "2.0.0"
Expand Down
20 changes: 3 additions & 17 deletions compiler/rustc_type_ir/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex};
/// for more details.
///
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
// FIXME(derive-where#136): Need to use separate `derive_where` for
// `Copy` and `Ord` to prevent the emitted `Clone` and `PartialOrd`
// impls from incorrectly relying on `T: Copy` and `T: Ord`.
#[derive_where(Copy; I: Interner, T: Copy)]
#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, T)]
#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner, T)]
#[derive(GenericTypeVisitable)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
pub struct Binder<I: Interner, T> {
Expand Down Expand Up @@ -365,12 +361,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
/// `instantiate`.
///
/// See <https://rustc-dev-guide.rust-lang.org/ty_module/early_binder.html> for more details.
// FIXME(derive-where#136): Need to use separate `derive_where` for
// `Copy` and `Ord` to prevent the emitted `Clone` and `PartialOrd`
// impls from incorrectly relying on `T: Copy` and `T: Ord`.
#[derive_where(Ord; I: Interner, T: Ord)]
#[derive_where(Copy; I: Interner, T: Copy)]
#[derive_where(Clone, PartialOrd, PartialEq, Hash, Debug; I: Interner, T)]
#[derive_where(Clone, Copy, PartialOrd, Ord, PartialEq, Hash, Debug; I: Interner, T)]
#[derive(GenericTypeVisitable)]
#[cfg_attr(
feature = "nightly",
Expand Down Expand Up @@ -964,12 +955,7 @@ pub enum BoundVarIndexKind {
/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
/// identified by both a universe, as well as a name residing within that universe. Distinct bound
/// regions/types/consts within the same universe simply have an unknown relationship to one
// FIXME(derive-where#136): Need to use separate `derive_where` for
// `Copy` and `Ord` to prevent the emitted `Clone` and `PartialOrd`
// impls from incorrectly relying on `T: Copy` and `T: Ord`.
#[derive_where(Ord; I: Interner, T: Ord)]
#[derive_where(Copy; I: Interner, T: Copy)]
#[derive_where(Clone, PartialOrd, PartialEq, Eq, Hash; I: Interner, T)]
#[derive_where(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash; I: Interner, T)]
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
#[cfg_attr(
feature = "nightly",
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@
#![feature(core_intrinsics)]
#![feature(coverage_attribute)]
#![feature(disjoint_bitor)]
#![feature(internal_impls_macro)]
#![feature(link_cfg)]
#![feature(offset_of_enum)]
#![feature(panic_internals)]
#![feature(pattern_type_macro)]
Expand Down Expand Up @@ -144,6 +142,7 @@
#![feature(intra_doc_pointers)]
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(link_cfg)]
#![feature(link_llvm_intrinsics)]
#![feature(macro_metavar_expr)]
#![feature(macro_metavar_expr_concat)]
Expand Down
3 changes: 0 additions & 3 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ use crate::pin::UnsafePinned;
/// u32,
/// }
/// ```
#[unstable(feature = "internal_impls_macro", issue = "none")]
// Allow implementations of `UnsizedConstParamTy` even though std cannot use that feature.
#[allow_internal_unstable(const_param_ty_trait)]
macro marker_impls {
( $(#[$($meta:tt)*])* $Trait:ident for $({$($bounds:tt)*})? $T:ty $(, $($rest:tt)*)? ) => {
$(#[$($meta)*])* impl< $($($bounds)*)? > $Trait for $T {}
Expand Down
Loading
Loading