Skip to content

Commit

Permalink
Merge branch 'rust-lang:master' into naked_asm_improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 authored Dec 13, 2024
2 parents d6b3c06 + 3da8bfb commit b8677a2
Show file tree
Hide file tree
Showing 314 changed files with 3,162 additions and 1,001 deletions.
5 changes: 0 additions & 5 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
"you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`"
);
gate_all!(let_chains, "`let` expressions in this position are unstable");
gate_all!(
async_closure,
"async closures are unstable",
"to use an async block, remove the `||`: `async {`"
);
gate_all!(
async_trait_bounds,
"`async` trait bounds are unstable",
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use super::debuginfo::{
DebugEmissionKind, DebugNameTableKind,
};

pub type Bool = c_uint;
/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
/// which has a different ABI from Rust or C++ `bool`.
pub type Bool = c_int;

pub const True: Bool = 1 as Bool;
pub const False: Bool = 0 as Bool;
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0307.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ impl Trait for Foo {
```

The nightly feature [Arbitrary self types][AST] extends the accepted
set of receiver types to also include any type that can dereference to
`Self`:
set of receiver types to also include any type that implements the
`Receiver` trait and can follow its chain of `Target` types to `Self`.
There's a blanket implementation of `Receiver` for `T: Deref`, so any
type which dereferences to `Self` can be used.

```
#![feature(arbitrary_self_types)]
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0708.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
Erroneous code example:

```edition2018
#![feature(async_closure)]
fn main() {
let add_one = async |num: u8| {
num + 1
Expand All @@ -18,8 +16,6 @@ fn main() {
version, you can use successfully by using move:

```edition2018
#![feature(async_closure)]
fn main() {
let add_one = async move |num: u8| { // ok!
num + 1
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ declare_features! (
(accepted, associated_types, "1.0.0", None),
/// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
(accepted, async_await, "1.39.0", Some(50547)),
/// Allows `async || body` closures.
(accepted, async_closure, "CURRENT_RUSTC_VERSION", Some(62290)),
/// Allows async functions to be declared, implemented, and used in traits.
(accepted, async_fn_in_trait, "1.75.0", Some(91611)),
/// Allows all literals in attribute lists and values of key-value pairs.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,8 @@ declare_features! (
(unstable, associated_const_equality, "1.58.0", Some(92827)),
/// Allows associated type defaults.
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
/// Allows `async || body` closures.
(unstable, async_closure, "1.37.0", Some(62290)),
/// Allows async functions to be called from `dyn Trait`.
(incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)),
/// Allows `#[track_caller]` on async functions.
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
/// Allows `for await` loops.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,10 @@ hir_analysis_invalid_generic_receiver_ty_help =
use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}`
.note = type of `self` must be `Self` or a type that dereferences to it
.note = type of `self` must be `Self` or some type implementing `Receiver`
hir_analysis_invalid_receiver_ty_help =
consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
hir_analysis_invalid_union_field =
field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
Expand Down
37 changes: 28 additions & 9 deletions compiler/rustc_hir_analysis/src/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub enum AutoderefKind {
/// A type which must dispatch to a `Deref` implementation.
Overloaded,
}

struct AutoderefSnapshot<'tcx> {
at_start: bool,
reached_recursion_limit: bool,
Expand All @@ -27,6 +26,10 @@ struct AutoderefSnapshot<'tcx> {
obligations: PredicateObligations<'tcx>,
}

/// Recursively dereference a type, considering both built-in
/// dereferences (`*`) and the `Deref` trait.
/// Although called `Autoderef` it can be configured to use the
/// `Receiver` trait instead of the `Deref` trait.
pub struct Autoderef<'a, 'tcx> {
// Meta infos:
infcx: &'a InferCtxt<'tcx>,
Expand All @@ -39,6 +42,7 @@ pub struct Autoderef<'a, 'tcx> {

// Configurations:
include_raw_pointers: bool,
use_receiver_trait: bool,
silence_errors: bool,
}

Expand Down Expand Up @@ -69,6 +73,10 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
}

// Otherwise, deref if type is derefable:
// NOTE: in the case of self.use_receiver_trait = true, you might think it would
// be better to skip this clause and use the Overloaded case only, since &T
// and &mut T implement Receiver. But built-in derefs apply equally to Receiver
// and Deref, and this has benefits for const and the emitted MIR.
let (kind, new_ty) =
if let Some(ty) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) {
debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty));
Expand Down Expand Up @@ -111,7 +119,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
body_def_id: LocalDefId,
span: Span,
base_ty: Ty<'tcx>,
) -> Autoderef<'a, 'tcx> {
) -> Self {
Autoderef {
infcx,
span,
Expand All @@ -125,6 +133,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
reached_recursion_limit: false,
},
include_raw_pointers: false,
use_receiver_trait: false,
silence_errors: false,
}
}
Expand All @@ -137,8 +146,13 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
return None;
}

// <ty as Deref>
let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
// <ty as Deref>, or whatever the equivalent trait is that we've been asked to walk.
let (trait_def_id, trait_target_def_id) = if self.use_receiver_trait {
(tcx.lang_items().receiver_trait()?, tcx.lang_items().receiver_target()?)
} else {
(tcx.lang_items().deref_trait()?, tcx.lang_items().deref_target()?)
};
let trait_ref = ty::TraitRef::new(tcx, trait_def_id, [ty]);
let cause = traits::ObligationCause::misc(self.span, self.body_id);
let obligation = traits::Obligation::new(
tcx,
Expand All @@ -151,11 +165,8 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
return None;
}

let (normalized_ty, obligations) = self.structurally_normalize(Ty::new_projection(
tcx,
tcx.lang_items().deref_target()?,
[ty],
))?;
let (normalized_ty, obligations) =
self.structurally_normalize(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
self.state.obligations.extend(obligations);

Expand Down Expand Up @@ -234,6 +245,14 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
self
}

/// Use `core::ops::Receiver` and `core::ops::Receiver::Target` as
/// the trait and associated type to iterate, instead of
/// `core::ops::Deref` and `core::ops::Deref::Target`
pub fn use_receiver_trait(mut self) -> Self {
self.use_receiver_trait = true;
self
}

pub fn silence_errors(mut self) -> Self {
self.silence_errors = true;
self
Expand Down
27 changes: 17 additions & 10 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1821,13 +1821,18 @@ fn receiver_is_valid<'tcx>(

let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);

// The `arbitrary_self_types` feature allows custom smart pointer
// types to be method receivers, as identified by following the Receiver<Target=T>
// chain.
if arbitrary_self_types_enabled.is_some() {
autoderef = autoderef.use_receiver_trait();
}

// The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) {
autoderef = autoderef.include_raw_pointers();
}

let receiver_trait_def_id = tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));

// Keep dereferencing `receiver_ty` until we get to `self_ty`.
while let Some((potential_self_ty, _)) = autoderef.next() {
debug!(
Expand All @@ -1849,11 +1854,13 @@ fn receiver_is_valid<'tcx>(
}

// Without `feature(arbitrary_self_types)`, we require that each step in the
// deref chain implement `receiver`.
// deref chain implement `LegacyReceiver`.
if arbitrary_self_types_enabled.is_none() {
if !receiver_is_implemented(
let legacy_receiver_trait_def_id =
tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));
if !legacy_receiver_is_implemented(
wfcx,
receiver_trait_def_id,
legacy_receiver_trait_def_id,
cause.clone(),
potential_self_ty,
) {
Expand All @@ -1866,7 +1873,7 @@ fn receiver_is_valid<'tcx>(
cause.clone(),
wfcx.param_env,
potential_self_ty,
receiver_trait_def_id,
legacy_receiver_trait_def_id,
);
}
}
Expand All @@ -1875,22 +1882,22 @@ fn receiver_is_valid<'tcx>(
Err(ReceiverValidityError::DoesNotDeref)
}

fn receiver_is_implemented<'tcx>(
fn legacy_receiver_is_implemented<'tcx>(
wfcx: &WfCheckingCtxt<'_, 'tcx>,
receiver_trait_def_id: DefId,
legacy_receiver_trait_def_id: DefId,
cause: ObligationCause<'tcx>,
receiver_ty: Ty<'tcx>,
) -> bool {
let tcx = wfcx.tcx();
let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]);
let trait_ref = ty::TraitRef::new(tcx, legacy_receiver_trait_def_id, [receiver_ty]);

let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref);

if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) {
true
} else {
debug!(
"receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
"receiver_is_implemented: type `{:?}` does not implement `LegacyReceiver` trait",
receiver_ty
);
false
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
[candidate] => format!(
"the method of the same name on {} `{}`",
match candidate.kind {
probe::CandidateKind::InherentImplCandidate(_) => "the inherent impl for",
probe::CandidateKind::InherentImplCandidate { .. } => "the inherent impl for",
_ => "trait",
},
self.tcx.def_path_str(candidate.item.container_id(self.tcx))
Expand Down
Loading

0 comments on commit b8677a2

Please sign in to comment.