Skip to content

Commit b7fd7fc

Browse files
committed
Auto merge of #147440 - Zalathar:rollup-ncjsxjb, r=Zalathar
Rollup of 8 pull requests Successful merges: - #145608 (Prevent downstream `impl DerefMut for Pin<LocalType>`) - #146865 (kcfi: only reify trait methods when dyn-compatible) - #147205 (Add a new `wasm32-wasip3` target to Rust) - #147390 (Use globals instead of metadata for std::autodiff) - #147398 (Fix; correct placement of type inference error for method calls) - #147422 (collect-license-metadata: Print a diff of the expected output) - #147431 (compiletest: Read the whole test file before parsing directives) - #147433 (Fix doc comment) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4a54b26 + d9904b8 commit b7fd7fc

File tree

59 files changed

+594
-258
lines changed

Some content is hidden

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

59 files changed

+594
-258
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ dependencies = [
686686
"anyhow",
687687
"serde",
688688
"serde_json",
689+
"similar",
689690
"spdx-rs",
690691
]
691692

compiler/rustc_codegen_llvm/src/builder/autodiff.rs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::builder::{Builder, PlaceRef, UNNAMED};
1313
use crate::context::SimpleCx;
1414
use crate::declare::declare_simple_fn;
1515
use crate::llvm;
16-
use crate::llvm::{Metadata, TRUE, Type};
16+
use crate::llvm::{TRUE, Type};
1717
use crate::value::Value;
1818

1919
pub(crate) fn adjust_activity_to_abi<'tcx>(
@@ -159,32 +159,36 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>(
159159
let mut outer_pos: usize = 0;
160160
let mut activity_pos = 0;
161161

162-
let enzyme_const = cx.create_metadata(b"enzyme_const");
163-
let enzyme_out = cx.create_metadata(b"enzyme_out");
164-
let enzyme_dup = cx.create_metadata(b"enzyme_dup");
165-
let enzyme_dupv = cx.create_metadata(b"enzyme_dupv");
166-
let enzyme_dupnoneed = cx.create_metadata(b"enzyme_dupnoneed");
167-
let enzyme_dupnoneedv = cx.create_metadata(b"enzyme_dupnoneedv");
162+
// We used to use llvm's metadata to instruct enzyme how to differentiate a function.
163+
// In debug mode we would use incremental compilation which caused the metadata to be
164+
// dropped. This is prevented by now using named globals, which are also understood
165+
// by Enzyme.
166+
let global_const = cx.declare_global("enzyme_const", cx.type_ptr());
167+
let global_out = cx.declare_global("enzyme_out", cx.type_ptr());
168+
let global_dup = cx.declare_global("enzyme_dup", cx.type_ptr());
169+
let global_dupv = cx.declare_global("enzyme_dupv", cx.type_ptr());
170+
let global_dupnoneed = cx.declare_global("enzyme_dupnoneed", cx.type_ptr());
171+
let global_dupnoneedv = cx.declare_global("enzyme_dupnoneedv", cx.type_ptr());
168172

169173
while activity_pos < inputs.len() {
170174
let diff_activity = inputs[activity_pos as usize];
171175
// Duplicated arguments received a shadow argument, into which enzyme will write the
172176
// gradient.
173-
let (activity, duplicated): (&Metadata, bool) = match diff_activity {
177+
let (activity, duplicated): (&llvm::Value, bool) = match diff_activity {
174178
DiffActivity::None => panic!("not a valid input activity"),
175-
DiffActivity::Const => (enzyme_const, false),
176-
DiffActivity::Active => (enzyme_out, false),
177-
DiffActivity::ActiveOnly => (enzyme_out, false),
178-
DiffActivity::Dual => (enzyme_dup, true),
179-
DiffActivity::Dualv => (enzyme_dupv, true),
180-
DiffActivity::DualOnly => (enzyme_dupnoneed, true),
181-
DiffActivity::DualvOnly => (enzyme_dupnoneedv, true),
182-
DiffActivity::Duplicated => (enzyme_dup, true),
183-
DiffActivity::DuplicatedOnly => (enzyme_dupnoneed, true),
184-
DiffActivity::FakeActivitySize(_) => (enzyme_const, false),
179+
DiffActivity::Const => (global_const, false),
180+
DiffActivity::Active => (global_out, false),
181+
DiffActivity::ActiveOnly => (global_out, false),
182+
DiffActivity::Dual => (global_dup, true),
183+
DiffActivity::Dualv => (global_dupv, true),
184+
DiffActivity::DualOnly => (global_dupnoneed, true),
185+
DiffActivity::DualvOnly => (global_dupnoneedv, true),
186+
DiffActivity::Duplicated => (global_dup, true),
187+
DiffActivity::DuplicatedOnly => (global_dupnoneed, true),
188+
DiffActivity::FakeActivitySize(_) => (global_const, false),
185189
};
186190
let outer_arg = outer_args[outer_pos];
187-
args.push(cx.get_metadata_value(activity));
191+
args.push(activity);
188192
if matches!(diff_activity, DiffActivity::Dualv) {
189193
let next_outer_arg = outer_args[outer_pos + 1];
190194
let elem_bytes_size: u64 = match inputs[activity_pos + 1] {
@@ -244,7 +248,7 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>(
244248
assert_eq!(cx.type_kind(next_outer_ty3), TypeKind::Integer);
245249
args.push(next_outer_arg2);
246250
}
247-
args.push(cx.get_metadata_value(enzyme_const));
251+
args.push(global_const);
248252
args.push(next_outer_arg);
249253
outer_pos += 2 + 2 * iterations;
250254
activity_pos += 2;
@@ -353,13 +357,13 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
353357
let mut args = Vec::with_capacity(num_args as usize + 1);
354358
args.push(fn_to_diff);
355359

356-
let enzyme_primal_ret = cx.create_metadata(b"enzyme_primal_return");
360+
let global_primal_ret = cx.declare_global("enzyme_primal_return", cx.type_ptr());
357361
if matches!(attrs.ret_activity, DiffActivity::Dual | DiffActivity::Active) {
358-
args.push(cx.get_metadata_value(enzyme_primal_ret));
362+
args.push(global_primal_ret);
359363
}
360364
if attrs.width > 1 {
361-
let enzyme_width = cx.create_metadata(b"enzyme_width");
362-
args.push(cx.get_metadata_value(enzyme_width));
365+
let global_width = cx.declare_global("enzyme_width", cx.type_ptr());
366+
args.push(global_width);
363367
args.push(cx.get_const_int(cx.type_i64(), attrs.width as u64));
364368
}
365369

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ use rustc_attr_parsing::is_doc_alias_attrs_contain_symbol;
77
use rustc_data_structures::fx::FxHashSet;
88
use rustc_data_structures::sso::SsoHashSet;
99
use rustc_errors::Applicability;
10-
use rustc_hir as hir;
11-
use rustc_hir::HirId;
1210
use rustc_hir::def::DefKind;
11+
use rustc_hir::{self as hir, ExprKind, HirId, Node};
1312
use rustc_hir_analysis::autoderef::{self, Autoderef};
1413
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
1514
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt};
@@ -486,13 +485,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
486485
let ty = self.resolve_vars_if_possible(ty.value);
487486
let guar = match *ty.kind() {
488487
ty::Infer(ty::TyVar(_)) => {
488+
// We want to get the variable name that the method
489+
// is being called on. If it is a method call.
490+
let err_span = match (mode, self.tcx.hir_node(scope_expr_id)) {
491+
(
492+
Mode::MethodCall,
493+
Node::Expr(hir::Expr {
494+
kind: ExprKind::MethodCall(_, recv, ..),
495+
..
496+
}),
497+
) => recv.span,
498+
_ => span,
499+
};
500+
489501
let raw_ptr_call = bad_ty.reached_raw_pointer
490502
&& !self.tcx.features().arbitrary_self_types();
491-
// FIXME: Ideally we'd use the span of the self-expr here,
492-
// not of the method path.
503+
493504
let mut err = self.err_ctxt().emit_inference_failure_err(
494505
self.body_id,
495-
span,
506+
err_span,
496507
ty.into(),
497508
TypeAnnotationNeeded::E0282,
498509
!raw_ptr_call,

compiler/rustc_middle/src/thir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ pub enum PatKind<'tcx> {
839839
/// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
840840
/// much simpler.
841841
/// * raw pointers derived from integers, other raw pointers will have already resulted in an
842-
// error.
842+
/// error.
843843
/// * `String`, if `string_deref_patterns` is enabled.
844844
Constant {
845845
value: ty::Value<'tcx>,

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,11 +618,11 @@ impl<'tcx> Instance<'tcx> {
618618
// be directly reified because it's closure-like. The reify can handle the
619619
// unresolved instance.
620620
resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
621-
// Reify `Trait::method` implementations
622-
// FIXME(maurer) only reify it if it is a vtable-safe function
621+
// Reify `Trait::method` implementations if the trait is dyn-compatible.
623622
} else if let Some(assoc) = tcx.opt_associated_item(def_id)
624623
&& let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) =
625624
assoc.container
625+
&& tcx.is_dyn_compatible(assoc.container_id(tcx))
626626
{
627627
// If this function could also go in a vtable, we need to `ReifyShim` it with
628628
// KCFI because it can only attach one type per function.

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ symbols! {
309309
PathBuf,
310310
Pending,
311311
PinCoerceUnsized,
312+
PinDerefMutHelper,
312313
Pointer,
313314
Poll,
314315
ProcMacro,

compiler/rustc_target/src/spec/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,7 @@ supported_targets! {
16241624
("wasm32v1-none", wasm32v1_none),
16251625
("wasm32-wasip1", wasm32_wasip1),
16261626
("wasm32-wasip2", wasm32_wasip2),
1627+
("wasm32-wasip3", wasm32_wasip3),
16271628
("wasm32-wasip1-threads", wasm32_wasip1_threads),
16281629
("wasm32-wali-linux-musl", wasm32_wali_linux_musl),
16291630
("wasm64-unknown-unknown", wasm64_unknown_unknown),
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//! The `wasm32-wasip3` target is the next in the chain of `wasm32-wasip1`, then
2+
//! `wasm32-wasip2`, then WASIp3. The main feature of WASIp3 is native async
3+
//! support in the component model itself.
4+
//!
5+
//! Like `wasm32-wasip2` this target produces a component by default. Support
6+
//! for `wasm32-wasip3` is very early as of the time of this writing so
7+
//! components produced will still import WASIp2 APIs, but that's ok since it's
8+
//! all component-model-level imports anyway. Over time the imports of the
9+
//! standard library will change to WASIp3.
10+
11+
use crate::spec::Target;
12+
13+
pub(crate) fn target() -> Target {
14+
// As of now WASIp3 is a lightly edited wasip2 target, so start with that
15+
// and this may grow over time as more features are supported.
16+
let mut target = super::wasm32_wasip2::target();
17+
target.llvm_target = "wasm32-wasip3".into();
18+
target.options.env = "p3".into();
19+
target
20+
}

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3476,6 +3476,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
34763476
// can do about it. As far as they are concerned, `?` is compiler magic.
34773477
return;
34783478
}
3479+
if tcx.is_diagnostic_item(sym::PinDerefMutHelper, parent_def_id) {
3480+
let parent_predicate =
3481+
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
3482+
3483+
// Skip PinDerefMutHelper in suggestions, but still show downstream suggestions.
3484+
ensure_sufficient_stack(|| {
3485+
self.note_obligation_cause_code(
3486+
body_id,
3487+
err,
3488+
parent_predicate,
3489+
param_env,
3490+
&data.derived.parent_code,
3491+
obligated_types,
3492+
seen_requirements,
3493+
)
3494+
});
3495+
return;
3496+
}
34793497
let self_ty_str =
34803498
tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
34813499
let trait_name = tcx.short_string(

library/core/src/pin.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1689,9 +1689,89 @@ impl<Ptr: [const] Deref> const Deref for Pin<Ptr> {
16891689
}
16901690
}
16911691

1692+
mod helper {
1693+
/// Helper that prevents downstream crates from implementing `DerefMut` for `Pin`.
1694+
///
1695+
/// The `Pin` type implements the unsafe trait `PinCoerceUnsized`, which essentially requires
1696+
/// that the type does not have a malicious `Deref` or `DerefMut` impl. However, without this
1697+
/// helper module, downstream crates are able to write `impl DerefMut for Pin<LocalType>` as
1698+
/// long as it does not overlap with the impl provided by stdlib. This is because `Pin` is
1699+
/// `#[fundamental]`, so stdlib promises to never implement traits for `Pin` that it does not
1700+
/// implement today.
1701+
///
1702+
/// However, this is problematic. Downstream crates could implement `DerefMut` for
1703+
/// `Pin<&LocalType>`, and they could do so maliciously. To prevent this, the implementation for
1704+
/// `Pin` delegates to this helper module. Since `helper::Pin` is not `#[fundamental]`, the
1705+
/// orphan rules assume that stdlib might implement `helper::DerefMut` for `helper::Pin<&_>` in
1706+
/// the future. Because of this, downstream crates can no longer provide an implementation of
1707+
/// `DerefMut` for `Pin<&_>`, as it might overlap with a trait impl that, according to the
1708+
/// orphan rules, the stdlib could introduce without a breaking change in a future release.
1709+
///
1710+
/// See <https://github.com/rust-lang/rust/issues/85099> for the issue this fixes.
1711+
#[repr(transparent)]
1712+
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1713+
#[allow(missing_debug_implementations)]
1714+
pub struct PinHelper<Ptr> {
1715+
pointer: Ptr,
1716+
}
1717+
1718+
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1719+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1720+
#[rustc_diagnostic_item = "PinDerefMutHelper"]
1721+
pub const trait PinDerefMutHelper {
1722+
type Target: ?Sized;
1723+
fn deref_mut(&mut self) -> &mut Self::Target;
1724+
}
1725+
1726+
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1727+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1728+
impl<Ptr: [const] super::DerefMut> const PinDerefMutHelper for PinHelper<Ptr>
1729+
where
1730+
Ptr::Target: crate::marker::Unpin,
1731+
{
1732+
type Target = Ptr::Target;
1733+
1734+
#[inline(always)]
1735+
fn deref_mut(&mut self) -> &mut Ptr::Target {
1736+
&mut self.pointer
1737+
}
1738+
}
1739+
}
1740+
16921741
#[stable(feature = "pin", since = "1.33.0")]
16931742
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1694-
impl<Ptr: [const] DerefMut<Target: Unpin>> const DerefMut for Pin<Ptr> {
1743+
#[cfg(not(doc))]
1744+
impl<Ptr> const DerefMut for Pin<Ptr>
1745+
where
1746+
Ptr: [const] Deref,
1747+
helper::PinHelper<Ptr>: [const] helper::PinDerefMutHelper<Target = Self::Target>,
1748+
{
1749+
#[inline]
1750+
fn deref_mut(&mut self) -> &mut Ptr::Target {
1751+
// SAFETY: Pin and PinHelper have the same layout, so this is equivalent to
1752+
// `&mut self.pointer` which is safe because `Target: Unpin`.
1753+
helper::PinDerefMutHelper::deref_mut(unsafe {
1754+
&mut *(self as *mut Pin<Ptr> as *mut helper::PinHelper<Ptr>)
1755+
})
1756+
}
1757+
}
1758+
1759+
/// The `Target` type is restricted to `Unpin` types as it's not safe to obtain a mutable reference
1760+
/// to a pinned value.
1761+
///
1762+
/// For soundness reasons, implementations of `DerefMut` for `Pin<T>` are rejected even when `T` is
1763+
/// a local type not covered by this impl block. (Since `Pin` is [fundamental], such implementations
1764+
/// would normally be possible.)
1765+
///
1766+
/// [fundamental]: ../../reference/items/implementations.html#r-items.impl.trait.fundamental
1767+
#[stable(feature = "pin", since = "1.33.0")]
1768+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1769+
#[cfg(doc)]
1770+
impl<Ptr> const DerefMut for Pin<Ptr>
1771+
where
1772+
Ptr: [const] DerefMut,
1773+
<Ptr as Deref>::Target: Unpin,
1774+
{
16951775
fn deref_mut(&mut self) -> &mut Ptr::Target {
16961776
Pin::get_mut(Pin::as_mut(self))
16971777
}

0 commit comments

Comments
 (0)