Skip to content
Merged
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
d02b4c8
Improve suggestions for unconstrained parameters in `impl` blocks
TomtheCoder2 Nov 10, 2025
45adab8
Pass user-provided llvm_args after target spec llvm_args.
guybedford May 13, 2026
6bd5ab9
Emit error when self type is not specified and accessed
aerooneqq May 14, 2026
282ec28
Implement pinned drop sugar
P8L1 May 14, 2026
1b7609c
Disable `main_needs_argc_argv` for Wasm
daxpedda May 14, 2026
9faff71
actually run the temp_dir doctest
RalfJung May 12, 2026
5a12d48
Prefer tracing::instrument.
cjgillot May 14, 2026
d76d4cd
Untuple method parameters.
cjgillot May 14, 2026
6e7b089
Use DropCtxt::new_block and new_block_with_statements systematically.
cjgillot May 14, 2026
85dfeda
Correctly handle associated items in rustdoc macro expansion
GuillaumeGomez May 14, 2026
899be9f
Add regression tests for associated items in rustdoc macro expansion
GuillaumeGomez May 14, 2026
8909e79
Require UTF-8 in `Utf8Pattern::StringPattern`
qaijuang May 13, 2026
d24fd77
Make const param default test reproduce original ICE
cijiugechu May 15, 2026
5d15124
coverage: Reduce and clarify the context-mismatch test case
Zalathar May 15, 2026
860813d
Require EIIs to be defined when we compile a rust dylib
bjorn3 May 8, 2026
62c2da0
Rollup merge of #148788 - TomtheCoder2:unconstrained-parameter-fix, r…
JonathanBrouwer May 15, 2026
1a3ed2e
Rollup merge of #156319 - bjorn3:eii_dylib_require_def, r=jdonszelmann
JonathanBrouwer May 15, 2026
a29e5e1
Rollup merge of #156452 - P8L1:implement-pin-drop-sugar-upstream, r=p…
JonathanBrouwer May 15, 2026
11af4fc
Rollup merge of #156554 - guybedford:wasm-use-legacy-eh, r=alexcrichton
JonathanBrouwer May 15, 2026
e34cec6
Rollup merge of #156571 - daxpedda:wasm-main, r=alexcrichton
JonathanBrouwer May 15, 2026
df20e79
Rollup merge of #156600 - cijiugechu:false-negative-test, r=BoxyUwU
JonathanBrouwer May 15, 2026
ae98f76
Rollup merge of #156493 - RalfJung:run-temp-dir, r=ChrisDenton
JonathanBrouwer May 15, 2026
845f3d3
Rollup merge of #156556 - qaijuang:issue-156491-str-replace-utf8-patt…
JonathanBrouwer May 15, 2026
04c0c8d
Rollup merge of #156565 - aerooneqq:delegation-self-type-ice, r=petro…
JonathanBrouwer May 15, 2026
7e35a7e
Rollup merge of #156586 - cjgillot:elaborate-new-block, r=oli-obk
JonathanBrouwer May 15, 2026
6708081
Rollup merge of #156587 - GuillaumeGomez:assoc-items-macro-expansion,…
JonathanBrouwer May 15, 2026
d1da72a
Rollup merge of #156604 - Zalathar:context-mismatch, r=mu001999
JonathanBrouwer May 15, 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
13 changes: 13 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3867,6 +3867,19 @@ pub struct Fn {
pub eii_impls: ThinVec<EiiImpl>,
}

impl Fn {
pub fn is_pin_drop_sugar(&self) -> bool {
self.ident.name == sym::drop
&& self
.sig
.decl
.inputs
.first()
.and_then(|param| param.to_self())
.is_some_and(|eself| matches!(eself.node, SelfKind::Pinned(None, Mutability::Mut)))
}
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct EiiImpl {
pub node_id: NodeId,
Expand Down
73 changes: 56 additions & 17 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,52 @@ impl<'hir> LoweringContext<'_, 'hir> {
})
}

fn resolve_pin_drop_sugar_impl_item(
&self,
i: &AssocItem,
ident: Ident,
span: Span,
) -> (Ident, Result<DefId, ErrorGuaranteed>) {
let trait_item_def_id = self
.get_partial_res(i.id)
.and_then(|r| r.expect_full_res().opt_def_id())
.ok_or_else(|| {
self.dcx().span_delayed_bug(span, "could not resolve trait item being implemented")
});

let is_pin_drop_sugar = match &i.kind {
AssocItemKind::Fn(fn_kind) => fn_kind.is_pin_drop_sugar(),
_ => false,
};
let def_id = match trait_item_def_id {
Ok(def_id) => def_id,
Err(guar) => return (ident, Err(guar)),
};
if !is_pin_drop_sugar {
return (ident, Ok(def_id));
}

let is_drop_pin_drop = self
.tcx
.lang_items()
.drop_trait()
.is_some_and(|drop_trait| self.tcx.parent(def_id) == drop_trait);
if is_drop_pin_drop {
// Associated item collection still derives the impl item's name from HIR.
return (Ident::new(sym::pin_drop, ident.span), Ok(def_id));
}

let guar = self
.dcx()
.struct_span_err(
i.span,
"method `drop` with `&pin mut self` is only supported for the `Drop` trait",
)
.with_span_label(i.span, "not a `Drop::pin_drop` implementation")
.emit();
(ident, Err(guar))
}

fn lower_impl_item(
&mut self,
i: &AssocItem,
Expand Down Expand Up @@ -1309,26 +1355,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
};

let span = self.lower_span(i.span);
let (effective_ident, impl_kind) = if is_in_trait_impl {
let (effective_ident, trait_item_def_id) =
self.resolve_pin_drop_sugar_impl_item(i, ident, span);
(effective_ident, ImplItemImplKind::Trait { defaultness, trait_item_def_id })
} else {
(ident, ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) })
};

let item = hir::ImplItem {
owner_id: hir_id.expect_owner(),
ident: self.lower_ident(ident),
ident: self.lower_ident(effective_ident),
generics,
impl_kind: if is_in_trait_impl {
ImplItemImplKind::Trait {
defaultness,
trait_item_def_id: self
.get_partial_res(i.id)
.and_then(|r| r.expect_full_res().opt_def_id())
.ok_or_else(|| {
self.dcx().span_delayed_bug(
span,
"could not resolve trait item being implemented",
)
}),
}
} else {
ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }
},
impl_kind,
kind,
span,
has_delayed_lints: !self.delayed_lints.is_empty(),
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ unsafe fn configure_llvm(sess: &Session) {

let cg_opts = sess.opts.cg.llvm_args.iter().map(AsRef::as_ref);
let tg_opts = sess.target.llvm_args.iter().map(AsRef::as_ref);
let sess_args = cg_opts.chain(tg_opts);
// Target-spec args are passed to LLVM before user `-Cllvm-args`. LLVM's
// `cl::opt` parser is last-wins, so this lets `-Cllvm-args=...` override
// a value already set in the target spec (e.g. `-wasm-use-legacy-eh`).
let sess_args = tg_opts.chain(cg_opts);

let user_specified_args: FxHashSet<_> =
sess_args.clone().map(|s| llvm_arg_to_arg_name(s)).filter(|s| !s.is_empty()).collect();
Expand Down
87 changes: 87 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,93 @@ impl<'hir> Generics<'hir> {
bound_span.with_lo(bounds[bound_pos - 1].span().hi())
}
}

/// Computes the span representing the removal of a generic parameter at `param_index`.
///
/// This function identifies the correct slice of source code to delete so that the
/// remaining generic list remains syntactically valid (handling commas and brackets).
///
/// ### Examples
///
/// 1. **With a following parameter:** (Includes the trailing comma)
/// - Input: `<T, U>` (index 0)
/// - Produces span for: `T, `
///
/// 2. **With a previous parameter:** (Includes the leading comma and bounds)
/// - Input: `<T: Clone, U>` (index 1)
/// - Produces span for: `, U`
///
/// 3. **The only parameter:** (Includes the angle brackets)
/// - Input: `<T>` (index 0)
/// - Produces span for: `<T>`
///
/// 4. **Parameter with where-clause bounds:**
/// - Input: `fn foo<T, U>() where T: Copy` (index 0)
/// - Produces span for: `T, ` (The where-clause remains for other logic to handle).
pub fn span_for_param_removal(&self, param_index: usize) -> Span {
if param_index >= self.params.len() {
return self.span.shrink_to_hi();
}

let is_param_explicit = |par: &&GenericParam<'_>| match par.kind {
GenericParamKind::Type { .. }
| GenericParamKind::Const { .. }
| GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit } => true,
_ => false,
};

// Find the span of the type parameter.
if let Some(next) = self.params[param_index + 1..].iter().find(is_param_explicit) {
self.params[param_index].span.until(next.span)
} else if let Some(prev) = self.params[..param_index].iter().rfind(is_param_explicit) {
let mut prev_span = prev.span;
// Consider the span of the bounds with the previous generic parameter when there is.
if let Some(prev_bounds_span) = self.span_for_param_bounds(prev) {
prev_span = prev_span.to(prev_bounds_span);
}

// Consider the span of the bounds with the current generic parameter when there is.
prev_span.shrink_to_hi().to(
if let Some(cur_bounds_span) = self.span_for_param_bounds(&self.params[param_index])
{
cur_bounds_span
} else {
self.params[param_index].span
},
)
} else {
// Remove also angle brackets <> when there is just ONE generic parameter.
self.span
}
}

/// Returns the span of the `WherePredicate` associated with the given `GenericParam`, if any.
///
/// This looks specifically for predicates in the `where` clause that were generated
/// from the parameter definition (e.g., `T` in `where T: Bound`).
///
/// ### Example
///
/// - Input: `param` representing `T`
/// - Context: `where T: Clone + Default, U: Copy`
/// - Returns: Span of `T: Clone + Default`
fn span_for_param_bounds(&self, param: &GenericParam<'hir>) -> Option<Span> {
self.predicates
.iter()
.find(|pred| {
if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
origin: PredicateOrigin::GenericParam,
bounded_ty,
..
}) = pred.kind
{
bounded_ty.span == param.span
} else {
false
}
})
.map(|pred| pred.span)
}
}

/// A single predicate in a where-clause.
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustc_middle::ty::{
use rustc_span::{ErrorGuaranteed, Span, kw};

use crate::collect::ItemCtxt;
use crate::errors::DelegationSelfTypeNotSpecified;
use crate::hir_ty_lowering::HirTyLowerer;

type RemapTable = FxHashMap<u32, u32>;
Expand Down Expand Up @@ -284,6 +285,12 @@ fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) ->
ctx.lower_ty(tcx.hir_node(id).expect_ty())
})
.unwrap_or_else(|| {
// It is possible to attempt to get self type when it is used in signature
// (i.e., `fn default() -> Self`), so emit error here in addition to possible
// `mismatched types` error (see #156388).
let err = DelegationSelfTypeNotSpecified { span: tcx.def_span(delegation_id) };
tcx.dcx().emit_err(err);

Ty::new_error_with_message(
tcx,
tcx.def_span(delegation_id),
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub(crate) mod wrong_number_of_generic_args;
mod precise_captures;
pub(crate) use precise_captures::*;

pub(crate) mod remove_or_use_generic;

#[derive(Diagnostic)]
#[diag("ambiguous associated {$assoc_kind} `{$assoc_ident}` in bounds of `{$qself}`")]
pub(crate) struct AmbiguousAssocItem<'a> {
Expand Down Expand Up @@ -1670,6 +1672,14 @@ pub(crate) struct UnsupportedDelegation<'a> {
pub callee_span: Span,
}

#[derive(Diagnostic)]
#[diag("delegation self type is not specified")]
#[help("consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`")]
pub(crate) struct DelegationSelfTypeNotSpecified {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("method should be `async` or return a future, but it is synchronous")]
pub(crate) struct MethodShouldReturnFuture {
Expand Down
Loading
Loading