Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2c31b0d
check if redundant args spans belong to the same context
TaKO8Ki Jan 2, 2026
31531b3
Add regression tests for keyword-in-identifier-position recovery ICE
jieyouxu Jan 2, 2026
79c4727
Don't try to recover keyword as non-keyword identifier
jieyouxu Jan 2, 2026
308c607
remove borrowck handling for inline const patterns
dianne Jan 8, 2026
98d3026
Resolve intra-doc links to variant fields behind type aliases
camelid Jan 2, 2026
a90e041
rustdoc: Refactor `def_id_to_res` as `ty_to_res`
camelid Jan 2, 2026
945f3f9
rustdoc: Use trait as root `Res` instead of assoc item
camelid Jan 2, 2026
f503b89
rustdoc: Extract helper function for resolving assoc items on ADTs
camelid Jan 2, 2026
2c98517
Refactor out many free functions from intra-doc link code
camelid Jan 2, 2026
2b618ed
rustdoc: Correctly resolve variant and struct fields on alias
camelid Jan 2, 2026
8a8b31a
compiler: Make Externally Implementable Item (eii) macros "semiopaque"
Enselic Jan 12, 2026
467a2d2
use self instead of super
jdonszelmann Jan 11, 2026
df55233
disallow in statement position
jdonszelmann Jan 11, 2026
8dd701c
add test for rejecting EIIs in statement position
jdonszelmann Jan 11, 2026
414e00d
Clarify the docs/examples for `ProjectionElem::ConstantIndex`
Zalathar Jan 14, 2026
a9ce750
Pull array length determination out of `prefix_slice_suffix`
Zalathar Jan 14, 2026
a72083f
Avoid some more usize-to-u64 casts in `prefix_slice_suffix`
Zalathar Jan 14, 2026
2b209a6
Avoid serde dependency in build_helper when not necessary
bjorn3 Jan 14, 2026
7d80e7d
rustc_target: Remove unused Arch::PowerPC64LE
taiki-e Jan 14, 2026
c1bcae0
Fix WASI threading regression with minimal invasive change
cdmurph32 Jan 12, 2026
90e8c63
Rollup merge of #150585 - issue-149559, r=petrochenkov
JonathanBrouwer Jan 14, 2026
2be1ef4
Rollup merge of #150586 - intra-doc-assoc-alias, r=GuillaumeGomez
JonathanBrouwer Jan 14, 2026
8c2653e
Rollup merge of #150590 - ident-kw-ice, r=petrochenkov
JonathanBrouwer Jan 14, 2026
d8c4dfa
Rollup merge of #150817 - cleanup-inline-const-pat-borrowck, r=lcnr
JonathanBrouwer Jan 14, 2026
409b25e
Rollup merge of #150966 - arch-powerpc64le, r=petrochenkov
JonathanBrouwer Jan 14, 2026
4cd42e8
Rollup merge of #150971 - disallow-eii-in-statement-position, r=waffl…
JonathanBrouwer Jan 14, 2026
127ef3e
Rollup merge of #151016 - fix_wasi_threading, r=alexcrichton
JonathanBrouwer Jan 14, 2026
8d66be1
Rollup merge of #151046 - semiopaque-eii-fix, r=jdonszelmann
JonathanBrouwer Jan 14, 2026
b585b94
Rollup merge of #151103 - array-pat-len, r=Nadrieril,petrochenkov
JonathanBrouwer Jan 14, 2026
bcfe8a7
Rollup merge of #151117 - reduce_deps, r=Kobzol
JonathanBrouwer Jan 14, 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
67 changes: 9 additions & 58 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_infer::infer::{
BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin,
};
use rustc_infer::traits::PredicateObligations;
use rustc_middle::bug;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::traits::query::NoSolution;
Expand All @@ -28,7 +29,6 @@ use rustc_middle::ty::{
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions,
};
use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::move_paths::MoveData;
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::def_id::CRATE_DEF_ID;
Expand Down Expand Up @@ -387,18 +387,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn check_user_type_annotations(&mut self) {
debug!(?self.user_type_annotations);
let tcx = self.tcx();
for user_annotation in self.user_type_annotations {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
let annotation = self.instantiate_canonical(span, user_ty);
if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind
&& let DefKind::InlineConst = tcx.def_kind(def)
{
assert!(annotation.bounds.is_empty());
self.check_inline_const(inferred_ty, def.expect_local(), args, span);
} else {
self.ascribe_user_type(inferred_ty, annotation, span);
}
self.ascribe_user_type(inferred_ty, annotation, span);
}
}

Expand Down Expand Up @@ -560,36 +552,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.constraints.liveness_constraints.add_location(region, location);
}
}

fn check_inline_const(
&mut self,
inferred_ty: Ty<'tcx>,
def_id: LocalDefId,
args: UserArgs<'tcx>,
span: Span,
) {
assert!(args.user_self_ty.is_none());
let tcx = self.tcx();
let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args);
if let Err(terr) =
self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring)
{
span_bug!(
span,
"bad inline const pattern: ({:?} = {:?}) {:?}",
const_ty,
inferred_ty,
terr
);
}
let args = self.infcx.resolve_vars_if_possible(args.args);
let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span));
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
Locations::All(span),
);
}
}

impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
Expand Down Expand Up @@ -1731,12 +1693,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
let def_id = uv.def;
if tcx.def_kind(def_id) == DefKind::InlineConst {
let def_id = def_id.expect_local();
let predicates = self.prove_closure_bounds(
tcx,
def_id,
uv.args,
location.to_locations(),
);
let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
Expand Down Expand Up @@ -2519,15 +2476,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// clauses on the struct.
AggregateKind::Closure(def_id, args)
| AggregateKind::CoroutineClosure(def_id, args)
| AggregateKind::Coroutine(def_id, args) => (
def_id,
self.prove_closure_bounds(
tcx,
def_id.expect_local(),
args,
location.to_locations(),
),
),
| AggregateKind::Coroutine(def_id, args) => {
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
}

AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
(CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
Expand All @@ -2546,12 +2497,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
args: GenericArgsRef<'tcx>,
locations: Locations,
location: Location,
) -> ty::InstantiatedPredicates<'tcx> {
let root_def_id = self.root_cx.root_def_id();
// We will have to handle propagated closure requirements for this closure,
// but need to defer this until the nested body has been fully borrow checked.
self.deferred_closure_requirements.push((def_id, args, locations));
self.deferred_closure_requirements.push((def_id, args, location.to_locations()));

// Equate closure args to regions inherited from `root_def_id`. Fixes #98589.
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, root_def_id);
Expand All @@ -2575,7 +2526,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Err(_) = self.eq_args(
typeck_root_args,
parent_args,
locations,
location.to_locations(),
ConstraintCategory::BoringNoLocation,
) {
span_mirbug!(
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ builtin_macros_eii_only_once = `#[{$name}]` can only be specified once

builtin_macros_eii_shared_macro_expected_function = `#[{$name}]` is only valid on functions
builtin_macros_eii_shared_macro_expected_max_one_argument = `#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]`
builtin_macros_eii_shared_macro_in_statement_position = `#[{$name}]` can only be used on functions inside a module
.label = `#[{$name}]` is used on this item, which is part of another item's local scope

builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
.cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
Expand Down
94 changes: 33 additions & 61 deletions compiler/rustc_builtin_macros/src/eii.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use rustc_ast::token::{Delimiter, TokenKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast::{
Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind,
Visibility, ast,
Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, StmtKind, Visibility, ast,
};
use rustc_ast_pretty::pprust::path_to_string;
use rustc_expand::base::{Annotatable, ExtCtxt};
Expand All @@ -12,6 +11,7 @@ use thin_vec::{ThinVec, thin_vec};
use crate::errors::{
EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe,
EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroExpectedFunction,
EiiSharedMacroInStatementPosition,
};

/// ```rust
Expand Down Expand Up @@ -55,29 +55,29 @@ fn eii_(
ecx: &mut ExtCtxt<'_>,
eii_attr_span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
orig_item: Annotatable,
impl_unsafe: bool,
) -> Vec<Annotatable> {
let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span);

let (item, wrap_item): (_, &dyn Fn(_) -> _) = if let Annotatable::Item(item) = item {
(item, &Annotatable::Item)
} else if let Annotatable::Stmt(ref stmt) = item
let item = if let Annotatable::Item(item) = orig_item {
item
} else if let Annotatable::Stmt(ref stmt) = orig_item
&& let StmtKind::Item(ref item) = stmt.kind
&& let ItemKind::Fn(ref f) = item.kind
{
(item.clone(), &|item| {
Annotatable::Stmt(Box::new(Stmt {
id: DUMMY_NODE_ID,
kind: StmtKind::Item(item),
span: eii_attr_span,
}))
})
ecx.dcx().emit_err(EiiSharedMacroInStatementPosition {
span: eii_attr_span.to(item.span),
name: path_to_string(&meta_item.path),
item_span: f.ident.span,
});
return vec![orig_item];
} else {
ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
span: eii_attr_span,
name: path_to_string(&meta_item.path),
});
return vec![item];
return vec![orig_item];
};

let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } =
Expand All @@ -87,7 +87,7 @@ fn eii_(
span: eii_attr_span,
name: path_to_string(&meta_item.path),
});
return vec![wrap_item(item)];
return vec![Annotatable::Item(item)];
};
// only clone what we need
let attrs = attrs.clone();
Expand All @@ -98,17 +98,19 @@ fn eii_(
filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path);

let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else {
return vec![wrap_item(item)];
// we don't need to wrap in Annotatable::Stmt conditionally since
// EII can't be used on items in statement position
return vec![Annotatable::Item(item)];
};

// span of the declaring item without attributes
let item_span = func.sig.span;
let foreign_item_name = func.ident;

let mut return_items = Vec::new();
let mut module_items = Vec::new();

if func.body.is_some() {
return_items.push(generate_default_impl(
module_items.push(generate_default_impl(
ecx,
&func,
impl_unsafe,
Expand All @@ -119,15 +121,15 @@ fn eii_(
))
}

return_items.push(generate_foreign_item(
module_items.push(generate_foreign_item(
ecx,
eii_attr_span,
item_span,
func,
vis,
&attrs_from_decl,
));
return_items.push(generate_attribute_macro_to_implement(
module_items.push(generate_attribute_macro_to_implement(
ecx,
eii_attr_span,
macro_name,
Expand All @@ -136,7 +138,9 @@ fn eii_(
&attrs_from_decl,
));

return_items.into_iter().map(wrap_item).collect()
// we don't need to wrap in Annotatable::Stmt conditionally since
// EII can't be used on items in statement position
module_items.into_iter().map(Annotatable::Item).collect()
}

/// Decide on the name of the macro that can be used to implement the EII.
Expand Down Expand Up @@ -213,29 +217,14 @@ fn generate_default_impl(
known_eii_macro_resolution: Some(ast::EiiDecl {
foreign_item: ecx.path(
foreign_item_name.span,
// prefix super to escape the `dflt` module generated below
vec![Ident::from_str_and_span("super", foreign_item_name.span), foreign_item_name],
// prefix self to explicitly escape the const block generated below
// NOTE: this is why EIIs can't be used on statements
vec![Ident::from_str_and_span("self", foreign_item_name.span), foreign_item_name],
),
impl_unsafe,
}),
});

let item_mod = |span: Span, name: Ident, items: ThinVec<Box<ast::Item>>| {
ecx.item(
item_span,
ThinVec::new(),
ItemKind::Mod(
ast::Safety::Default,
name,
ast::ModKind::Loaded(
items,
ast::Inline::Yes,
ast::ModSpans { inner_span: span, inject_use_span: span },
),
),
)
};

let anon_mod = |span: Span, stmts: ThinVec<ast::Stmt>| {
let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new()));
let underscore = Ident::new(kw::Underscore, item_span);
Expand All @@ -248,33 +237,13 @@ fn generate_default_impl(
};

// const _: () = {
// mod dflt {
// use super::*;
// <orig fn>
// }
// <orig fn>
// }
anon_mod(
item_span,
thin_vec![ecx.stmt_item(
item_span,
item_mod(
item_span,
Ident::from_str_and_span("dflt", item_span),
thin_vec![
ecx.item(
item_span,
thin_vec![ecx.attr_nested_word(sym::allow, sym::unused_imports, item_span)],
ItemKind::Use(ast::UseTree {
prefix: ast::Path::from_ident(Ident::from_str_and_span(
"super", item_span,
)),
kind: ast::UseTreeKind::Glob,
span: item_span,
})
),
ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
]
)
ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
),],
)
}
Expand Down Expand Up @@ -366,6 +335,9 @@ fn generate_attribute_macro_to_implement(
// errors for eii's in std.
macro_attrs.extend_from_slice(attrs_from_decl);

// Avoid "missing stability attribute" errors for eiis in std. See #146993.
macro_attrs.push(ecx.attr_name_value_str(sym::rustc_macro_transparency, sym::semiopaque, span));

// #[builtin_macro(eii_shared_macro)]
macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span));

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,16 @@ pub(crate) struct EiiSharedMacroExpectedFunction {
pub name: String,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_eii_shared_macro_in_statement_position)]
pub(crate) struct EiiSharedMacroInStatementPosition {
#[primary_span]
pub span: Span,
pub name: String,
#[label]
pub item_span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_eii_only_once)]
pub(crate) struct EiiOnlyOnce {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl CodegenCx<'_, '_> {
}

// PowerPC64 prefers TOC indirection to avoid copy relocations.
if matches!(self.tcx.sess.target.arch, Arch::PowerPC64 | Arch::PowerPC64LE) {
if self.tcx.sess.target.arch == Arch::PowerPC64 {
return false;
}

Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_codegen_llvm/src/va_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,15 +1064,6 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
AllowHigherAlign::Yes,
ForceRightAdjust::Yes,
),
Arch::PowerPC64LE => emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes8,
AllowHigherAlign::Yes,
ForceRightAdjust::No,
),
Arch::LoongArch32 => emit_ptr_va_arg(
bx,
addr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
gen_arg_spans[self.num_expected_type_or_const_args() - 1]
};
let span_hi_redundant_type_or_const_args = gen_arg_spans[gen_arg_spans.len() - 1];
if !span_lo_redundant_type_or_const_args.eq_ctxt(span_hi_redundant_type_or_const_args) {
return;
}
let span_redundant_type_or_const_args = span_lo_redundant_type_or_const_args
.shrink_to_hi()
.to(span_hi_redundant_type_or_const_args);
Expand Down
Loading
Loading