Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d7923d4
simd_add/sub/mul/neg: document overflow behavior
RalfJung Mar 10, 2026
84a2d2a
Pass -pg to linker when using -Zinstrument-mcount
pmur Feb 10, 2026
cc2c5f9
Fix mcount name for *-windows-gnu targets
pmur Mar 12, 2026
87c2552
Link extra libraries when using mcount on *-windows-gnu targets
pmur Mar 12, 2026
fac53a0
add regression test for issue 153695
TaKO8Ki Mar 18, 2026
74909ec
fix ICE for arrays in diverging never-pattern closure bodies
TaKO8Ki Mar 18, 2026
46a9efc
Detect more cases of method shadowing with incorrect arguments
estebank Mar 9, 2026
0a5a78c
Account for inherent methods
estebank Mar 10, 2026
a72d226
Tweak output
estebank Mar 10, 2026
0bd2852
Tweak wording on "other methods available" note
estebank Mar 25, 2026
b5605cd
move many tests out of `ui/unsafe`
cyrgani Mar 26, 2026
5efde4b
Create GPU target notification group
apiraino Mar 26, 2026
fc5a707
bootstrap: force a CI LLVM stamp bump
ZuseZ4 Mar 26, 2026
93787d3
Rollup merge of #152457 - pmur:murp/mcount-link-pg, r=davidtwco
Zalathar Mar 27, 2026
1c15e3b
Rollup merge of #154031 - TaKO8Ki:fix-153695-never-pattern-array-ice,…
Zalathar Mar 27, 2026
2939bc7
Rollup merge of #154418 - cyrgani:move-unsafe, r=chenyukang
Zalathar Mar 27, 2026
7501b71
Rollup merge of #154441 - ZuseZ4:macos-bootstrap-stamp, r=Kobzol
Zalathar Mar 27, 2026
d7c9df9
Rollup merge of #153662 - estebank:suggest-fully-qualified-path, r=da…
Zalathar Mar 27, 2026
d7ae8a8
Rollup merge of #153675 - RalfJung:simd-overflow, r=scottmcm
Zalathar Mar 27, 2026
312b10e
Rollup merge of #154430 - apiraino:create-gpu-target-notif-group, r=j…
Zalathar Mar 27, 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: 4 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2767,6 +2767,10 @@ fn add_order_independent_options(
cmd.pgo_gen();
}

if sess.opts.unstable_opts.instrument_mcount {
cmd.enable_profiling();
}

if sess.opts.cg.control_flow_guard != CFGuard::Disabled {
cmd.control_flow_guard();
}
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ pub(crate) trait Linker {
fn add_no_exec(&mut self) {}
fn add_as_needed(&mut self) {}
fn reset_per_library_state(&mut self) {}
fn enable_profiling(&mut self) {}
}

impl dyn Linker + '_ {
Expand Down Expand Up @@ -732,6 +733,19 @@ impl<'a> Linker for GccLinker<'a> {
self.link_or_cc_args(&["-u", "__llvm_profile_runtime"]);
}

fn enable_profiling(&mut self) {
// This flag is also used when linking to choose target specific
// libraries needed to enable profiling.
self.cc_arg("-pg");
// On windows-gnu targets, libgmon also needs to be linked, and this
// requires readding libraries to satisfy its dependencies.
if self.sess.target.is_like_windows {
self.cc_arg("-lgmon");
self.cc_arg("-lkernel32");
self.cc_arg("-lmsvcrt");
}
}

fn control_flow_guard(&mut self) {}

fn ehcont_guard(&mut self) {}
Expand Down
102 changes: 65 additions & 37 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_errors::{Applicability, Diag, MultiSpan, listify};
use rustc_hir::def::Res;
use rustc_errors::{Applicability, Diag, MultiSpan, listify, pluralize};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, find_attr};
use rustc_infer::infer::DefineOpaqueTypes;
Expand Down Expand Up @@ -29,7 +29,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if expr_ty == expected {
return;
}
self.annotate_alternative_method_deref(err, expr, error);
self.annotate_alternative_method_deref_for_unop(err, expr, error);
self.explain_self_literal(err, expr, expected, expr_ty);

// Use `||` to give these suggestions a precedence
Expand Down Expand Up @@ -723,8 +723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Path {
res:
hir::def::Res::Def(
hir::def::DefKind::Static { .. }
| hir::def::DefKind::Const { .. },
DefKind::Static { .. } | DefKind::Const { .. },
def_id,
),
..
Expand Down Expand Up @@ -899,7 +898,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}

fn annotate_alternative_method_deref(
fn annotate_alternative_method_deref_for_unop(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
Expand All @@ -919,7 +918,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::ExprKind::Unary(hir::UnOp::Deref, deref) = lhs.kind else {
return;
};
let hir::ExprKind::MethodCall(path, base, args, _) = deref.kind else {
self.annotate_alternative_method_deref(err, deref, Some(expected))
}

#[tracing::instrument(skip(self, err), level = "debug")]
pub(crate) fn annotate_alternative_method_deref(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
expected: Option<Ty<'tcx>>,
) {
let hir::ExprKind::MethodCall(path, base, args, _) = expr.kind else {
return;
};
let Some(self_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(base) else {
Expand All @@ -929,7 +938,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Ok(pick) = self.lookup_probe_for_diagnostic(
path.ident,
self_ty,
deref,
expr,
probe::ProbeScope::TraitsInScope,
None,
) else {
Expand All @@ -939,10 +948,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Ok(in_scope_methods) = self.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
expected,
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
expr.hir_id,
probe::ProbeScope::TraitsInScope,
) else {
return;
Expand All @@ -954,45 +963,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Ok(all_methods) = self.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
expected,
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
expr.hir_id,
probe::ProbeScope::AllTraits,
) else {
return;
};

let suggestions: Vec<_> = all_methods
.into_iter()
.filter(|c| c.item.def_id != pick.item.def_id)
.map(|c| {
.filter_map(|c| {
if c.item.def_id == pick.item.def_id {
return None;
}
let m = c.item;
let generic_args = ty::GenericArgs::for_item(self.tcx, m.def_id, |param, _| {
self.var_for_def(deref.span, param)
self.var_for_def(expr.span, param)
});
let mutability =
match self.tcx.fn_sig(m.def_id).skip_binder().input(0).skip_binder().kind() {
ty::Ref(_, _, hir::Mutability::Mut) => "&mut ",
ty::Ref(_, _, _) => "&",
_ => "",
};
vec![
(
deref.span.until(base.span),
format!(
"{}({}",
with_no_trimmed_paths!(
self.tcx.def_path_str_with_args(m.def_id, generic_args,)
),
mutability,
),
),
let fn_sig = self.tcx.fn_sig(m.def_id);
if fn_sig.skip_binder().inputs().skip_binder().len() != args.len() + 1 {
return None;
}
let rcvr_ty = fn_sig.skip_binder().input(0).skip_binder();
let (mutability, ty) = match rcvr_ty.kind() {
ty::Ref(_, ty, hir::Mutability::Mut) => ("&mut ", ty),
ty::Ref(_, ty, _) => ("&", ty),
_ => ("", &rcvr_ty),
};
let path = match self.tcx.assoc_parent(m.def_id) {
Some((_, DefKind::Impl { of_trait: true })) => {
// We have `impl Trait for T {}`, suggest `<T as Trait>::method`.
self.tcx.def_path_str_with_args(m.def_id, generic_args).to_string()
}
Some((_, DefKind::Impl { of_trait: false })) => {
if let ty::Adt(def, _) = ty.kind() {
// We have `impl T {}`, suggest `T::method`.
format!("{}::{}", self.tcx.def_path_str(def.did()), path.ident)
} else {
// This should be unreachable, as `impl &'a T {}` is invalid.
format!("{ty}::{}", path.ident)
}
}
// Fallback for arbitrary self types.
_ => with_no_trimmed_paths!(
self.tcx.def_path_str_with_args(m.def_id, generic_args)
)
.to_string(),
};
Some(vec![
(expr.span.until(base.span), format!("{path}({}", mutability)),
match &args {
[] => (base.span.shrink_to_hi().with_hi(deref.span.hi()), ")".to_string()),
[] => (base.span.shrink_to_hi().with_hi(expr.span.hi()), ")".to_string()),
[first, ..] => (base.span.between(first.span), ", ".to_string()),
},
]
])
})
.collect();
if suggestions.is_empty() {
Expand Down Expand Up @@ -1046,9 +1072,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
if suggestions.len() > other_methods_in_scope.len() {
let n = suggestions.len() - other_methods_in_scope.len();
err.note(format!(
"additionally, there are {} other available methods that aren't in scope",
suggestions.len() - other_methods_in_scope.len()
"additionally, there {are} {n} other available method{s} that {are}n't in scope",
are = pluralize!("is", n),
s = pluralize!(n),
));
}
err.multipart_suggestions(
Expand Down Expand Up @@ -1263,7 +1291,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::def::Res::Def(kind, def_id) = path.res else {
return;
};
let callable_kind = if matches!(kind, hir::def::DefKind::Ctor(_, _)) {
let callable_kind = if matches!(kind, DefKind::Ctor(_, _)) {
CallableKind::Constructor
} else {
CallableKind::Function
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1660,14 +1660,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> {
let element_ty = if !args.is_empty() {
// This shouldn't happen unless there's another error
// (e.g., never patterns in inappropriate contexts).
if self.diverges.get() != Diverges::Maybe {
self.dcx()
.struct_span_err(expr.span, "unexpected divergence state in checking array")
.delay_as_bug();
}

let coerce_to = expected
.to_option(self)
.and_then(|uty| {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2853,6 +2853,8 @@ impl<'a, 'b, 'tcx> ArgMatchingCtxt<'a, 'b, 'tcx> {
);
return;
}

self.annotate_alternative_method_deref(err, self.call_expr, None);
}

/// A "softer" version of the `demand_compatible`, which checks types without persisting them,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/base/windows_gnu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub(crate) fn opts() -> TargetOptions {
// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
// output DWO, despite using DWARF, doesn't use ELF..
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
mcount: "_mcount".into(),
..Default::default()
}
}
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/base/windows_gnullvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub(crate) fn opts() -> TargetOptions {
// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
// output DWO, despite using DWARF, doesn't use ELF..
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
mcount: "_mcount".into(),
..Default::default()
}
}
6 changes: 4 additions & 2 deletions library/core/src/intrinsics/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,23 @@ pub const unsafe fn simd_splat<T, U>(value: U) -> T;
/// Adds two simd vectors elementwise.
///
/// `T` must be a vector of integers or floats.
/// For integers, wrapping arithmetic is used.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const unsafe fn simd_add<T>(x: T, y: T) -> T;

/// Subtracts `rhs` from `lhs` elementwise.
///
/// `T` must be a vector of integers or floats.
/// For integers, wrapping arithmetic is used.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const unsafe fn simd_sub<T>(lhs: T, rhs: T) -> T;

/// Multiplies two simd vectors elementwise.
///
/// `T` must be a vector of integers or floats.
/// For integers, wrapping arithmetic is used.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const unsafe fn simd_mul<T>(x: T, y: T) -> T;
Expand Down Expand Up @@ -233,8 +236,7 @@ pub const unsafe fn simd_as<T, U>(x: T) -> U;
/// Negates a vector elementwise.
///
/// `T` must be a vector of integers or floats.
///
/// Rust panics for `-<int>::Min` due to overflow, but it is not UB with this intrinsic.
/// For integers, wrapping arithmetic is used.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const unsafe fn simd_neg<T>(x: T) -> T;
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/download-ci-llvm-stamp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Change this file to make users of the `download-ci-llvm` configuration download
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.

Last change is for: https://github.com/rust-lang/rust/pull/153179
Last change is for: https://github.com/rust-lang/rust/pull/151063
3 changes: 3 additions & 0 deletions tests/run-make/instrument-mcount-link-pg/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello World!");
}
19 changes: 19 additions & 0 deletions tests/run-make/instrument-mcount-link-pg/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// When building a binary instrumented with mcount, verify the
// binary is linked with the correct crt to enable profiling.
//
//@ only-gnu
//@ ignore-cross-compile

use run_make_support::{path, run, rustc};

fn main() {
// Compile instrumentation enabled binary, and verify -pg is passed
let link_args =
rustc().input("main.rs").arg("-Zinstrument-mcount").print("link-args").run().stdout_utf8();
assert!(link_args.contains("\"-pg\""));

// Run it, and verify gmon.out is created
assert!(!path("gmon.out").exists());
run("main");
assert!(path("gmon.out").exists());
}
37 changes: 37 additions & 0 deletions tests/ui/methods/shadowed-intrinsic-method.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Can't use rustfix because we provide two suggestions:
// to remove the arg for `Borrow::borrow` or to call `Type::borrow`.
use std::borrow::Borrow;

struct A;

impl A { fn borrow(&mut self, _: ()) {} }

struct B;

fn main() {
// The fully-qualified path for items within functions is unnameable from outside that function.
impl B { fn borrow(&mut self, _: ()) {} }

struct C;
// The fully-qualified path for items within functions is unnameable from outside that function.
impl C { fn borrow(&mut self, _: ()) {} }

let mut a = A;
a.borrow(()); //~ ERROR E0061
// A::borrow(&mut a, ());
let mut b = B;
b.borrow(()); //~ ERROR E0061
// This currently suggests `main::<impl B>::borrow`, which is not correct, it should be
// B::borrow(&mut b, ());
let mut c = C;
c.borrow(()); //~ ERROR E0061
// This currently suggests `main::C::borrow`, which is not correct, it should be
// C::borrow(&mut c, ());
}

fn foo() {
let mut b = B;
b.borrow(()); //~ ERROR E0061
// This currently suggests `main::<impl B>::borrow`, which is not correct, it should be
// B::borrow(&mut b, ());
}
Loading
Loading