Skip to content

Rollup of 6 pull requests #106025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Dec 22, 2022
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4042f55
Don't ICE in check_must_not_suspend_ty for mismatched tuple arity
compiler-errors Dec 17, 2022
55c4164
Correct ModFlagBehavior for Aarch64 on LLVM-15
MasterAwesome Dec 20, 2022
872a6da
Remove an unused function
oli-obk Oct 6, 2022
c787de3
Fix some `~const` usage in libcore
oli-obk Oct 11, 2022
b0ed631
Some hir cleanups
oli-obk Nov 10, 2022
b2b859b
Some track_caller additions
oli-obk Oct 12, 2022
fedcc73
tracing: make flag checking less noisy
oli-obk Oct 11, 2022
ed61be6
Some ICE debugging aids
oli-obk Sep 21, 2022
5480ac5
Use `Error` behavior for LLVM versions prior to 15
MasterAwesome Dec 20, 2022
c8ebff6
Remove some unnecessary try_map_bound
compiler-errors Dec 21, 2022
0c09e2b
Substitute things correctly
compiler-errors Dec 21, 2022
978dd2e
Rename things to be a bit clearer
compiler-errors Dec 21, 2022
c6ef534
CollectAllMismatches relation should respect int/float infer vars
compiler-errors Dec 21, 2022
85a9d85
Don't call typeck if we have no typeck results
compiler-errors Dec 21, 2022
b60281f
Test that async blocks are UnwindSafe
Swatinem Dec 21, 2022
cb2c7bb
Clarify that raw retags are not permitted in Mir
JakobDegen Dec 21, 2022
7c4c620
Forbid `RetagKind::TwoPhase` as well
JakobDegen Dec 21, 2022
3eccc29
Rollup merge of #105837 - compiler-errors:issue-105728, r=estebank
matthiaskrgr Dec 22, 2022
924a1d4
Rollup merge of #105932 - MasterAwesome:aarch64-bti-llvm-15, r=nikic
matthiaskrgr Dec 22, 2022
ec7eb5b
Rollup merge of #105960 - oli-obk:effect_cleanup, r=fee1-dead
matthiaskrgr Dec 22, 2022
66544b5
Rollup merge of #105985 - compiler-errors:method-chain-nitpicks, r=es…
matthiaskrgr Dec 22, 2022
f340e68
Rollup merge of #105996 - Swatinem:async-is-unwindsafe, r=petrochenkov
matthiaskrgr Dec 22, 2022
d0d0ccd
Rollup merge of #106012 - JakobDegen:retag-raw, r=RalfJung
matthiaskrgr Dec 22, 2022
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
14 changes: 10 additions & 4 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
@@ -280,29 +280,35 @@ pub unsafe fn create_module<'ll>(
}

if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
let behavior = if llvm_version >= (15, 0, 0) {
llvm::LLVMModFlagBehavior::Min
} else {
llvm::LLVMModFlagBehavior::Error
};

if sess.target.arch == "aarch64" {
llvm::LLVMRustAddModuleFlag(
llmod,
llvm::LLVMModFlagBehavior::Error,
behavior,
"branch-target-enforcement\0".as_ptr().cast(),
bti.into(),
);
llvm::LLVMRustAddModuleFlag(
llmod,
llvm::LLVMModFlagBehavior::Error,
behavior,
"sign-return-address\0".as_ptr().cast(),
pac_ret.is_some().into(),
);
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
llvm::LLVMRustAddModuleFlag(
llmod,
llvm::LLVMModFlagBehavior::Error,
behavior,
"sign-return-address-all\0".as_ptr().cast(),
pac_opts.leaf.into(),
);
llvm::LLVMRustAddModuleFlag(
llmod,
llvm::LLVMModFlagBehavior::Error,
behavior,
"sign-return-address-with-bkey\0".as_ptr().cast(),
u32::from(pac_opts.key == PAuthKey::B),
);
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -79,6 +79,7 @@ pub enum LLVMModFlagBehavior {
Append = 5,
AppendUnique = 6,
Max = 7,
Min = 8,
}

// Consts for the LLVM CallConv type, pre-cast to usize.
9 changes: 6 additions & 3 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{
traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping,
Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef,
ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
TerminatorKind, UnOp, START_BLOCK,
ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
Terminator, TerminatorKind, UnOp, START_BLOCK,
};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
use rustc_mir_dataflow::impls::MaybeStorageLive;
@@ -667,10 +667,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.fail(location, "`Deinit`is not allowed until deaggregation");
}
}
StatementKind::Retag(_, _) => {
StatementKind::Retag(kind, _) => {
// FIXME(JakobDegen) The validator should check that `self.mir_phase <
// DropsLowered`. However, this causes ICEs with generation of drop shims, which
// seem to fail to set their `MirPhase` correctly.
if *kind == RetagKind::Raw || *kind == RetagKind::TwoPhase {
self.fail(location, format!("explicit `{:?}` is forbidden", kind));
}
}
StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
5 changes: 1 addition & 4 deletions compiler/rustc_hir_typeck/src/generator_interior/mod.rs
Original file line number Diff line number Diff line change
@@ -607,10 +607,7 @@ fn check_must_not_suspend_ty<'tcx>(
ty::Tuple(fields) => {
let mut has_emitted = false;
let comps = match data.expr.map(|e| &e.kind) {
Some(hir::ExprKind::Tup(comps)) => {
debug_assert_eq!(comps.len(), fields.len());
Some(comps)
}
Some(hir::ExprKind::Tup(comps)) if comps.len() == fields.len() => Some(comps),
_ => None,
};
for (i, ty) in fields.iter().enumerate() {
12 changes: 10 additions & 2 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -170,6 +170,7 @@ impl<'hir> Map<'hir> {
}

#[inline]
#[track_caller]
pub fn local_def_id(self, hir_id: HirId) -> LocalDefId {
self.opt_local_def_id(hir_id).unwrap_or_else(|| {
bug!(
@@ -310,6 +311,7 @@ impl<'hir> Map<'hir> {
}
}

#[track_caller]
pub fn get_parent_node(self, hir_id: HirId) -> HirId {
self.find_parent_node(hir_id)
.unwrap_or_else(|| bug!("No parent for node {:?}", self.node_to_string(hir_id)))
@@ -334,12 +336,14 @@ impl<'hir> Map<'hir> {
}

/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
#[track_caller]
pub fn get(self, id: HirId) -> Node<'hir> {
self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id))
}

/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
#[inline]
#[track_caller]
pub fn get_by_def_id(self, id: LocalDefId) -> Node<'hir> {
self.find_by_def_id(id).unwrap_or_else(|| bug!("couldn't find {:?} in the HIR map", id))
}
@@ -377,6 +381,7 @@ impl<'hir> Map<'hir> {
self.tcx.hir_owner_nodes(id.hir_id.owner).unwrap().bodies[&id.hir_id.local_id]
}

#[track_caller]
pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
if let Some(node) = self.find(hir_id) {
node.fn_decl()
@@ -385,6 +390,7 @@ impl<'hir> Map<'hir> {
}
}

#[track_caller]
pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
if let Some(node) = self.find(hir_id) {
node.fn_sig()
@@ -393,6 +399,7 @@ impl<'hir> Map<'hir> {
}
}

#[track_caller]
pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId {
for (_, node) in self.parent_iter(hir_id) {
if let Some(body) = associated_body(node) {
@@ -408,7 +415,7 @@ impl<'hir> Map<'hir> {
/// item (possibly associated), a closure, or a `hir::AnonConst`.
pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
let parent = self.get_parent_node(hir_id);
assert!(self.find(parent).map_or(false, |n| is_body_owner(n, hir_id)));
assert!(self.find(parent).map_or(false, |n| is_body_owner(n, hir_id)), "{hir_id:?}");
parent
}

@@ -419,10 +426,11 @@ impl<'hir> Map<'hir> {
/// Given a `LocalDefId`, returns the `BodyId` associated with it,
/// if the node is a body owner, otherwise returns `None`.
pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<BodyId> {
self.get_if_local(id.to_def_id()).map(associated_body).flatten()
self.find_by_def_id(id).and_then(associated_body)
}

/// Given a body owner's id, returns the `BodyId` associated with it.
#[track_caller]
pub fn body_owned_by(self, id: LocalDefId) -> BodyId {
self.maybe_body_owned_by(id).unwrap_or_else(|| {
let hir_id = self.local_def_id_to_hir_id(id);
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
@@ -320,8 +320,10 @@ pub enum StatementKind<'tcx> {
/// <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/> for
/// more details.
///
/// For code that is not specific to stacked borrows, you should consider retags to read
/// and modify the place in an opaque way.
/// For code that is not specific to stacked borrows, you should consider retags to read and
/// modify the place in an opaque way.
///
/// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted.
Retag(RetagKind, Box<Place<'tcx>>),

/// Encodes a user's type ascription. These need to be preserved
8 changes: 0 additions & 8 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
@@ -70,14 +70,6 @@ impl GenericParamDef {
}
}

pub fn has_default(&self) -> bool {
match self.kind {
GenericParamDefKind::Type { has_default, .. }
| GenericParamDefKind::Const { has_default } => has_default,
GenericParamDefKind::Lifetime => false,
}
}

pub fn is_anonymous_lifetime(&self) -> bool {
match self.kind {
GenericParamDefKind::Lifetime => {
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/subst.rs
Original file line number Diff line number Diff line change
@@ -348,7 +348,7 @@ impl<'tcx> InternalSubsts<'tcx> {
substs.reserve(defs.params.len());
for param in &defs.params {
let kind = mk_kind(param, substs);
assert_eq!(param.index as usize, substs.len());
assert_eq!(param.index as usize, substs.len(), "{substs:#?}, {defs:#?}");
substs.push(kind);
}
}
18 changes: 4 additions & 14 deletions compiler/rustc_middle/src/ty/visit.rs
Original file line number Diff line number Diff line change
@@ -88,9 +88,11 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone {
self.has_vars_bound_at_or_above(ty::INNERMOST)
}

#[instrument(level = "trace", ret)]
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags)
let res =
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
trace!(?self, ?flags, ?res, "has_type_flags");
res
}
fn has_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PROJECTION)
@@ -560,10 +562,8 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
type BreakTy = FoundFlags;

#[inline]
#[instrument(skip(self), level = "trace", ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = t.flags();
trace!(t.flags=?t.flags());
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
@@ -572,10 +572,8 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}

#[inline]
#[instrument(skip(self), level = "trace", ret)]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = r.type_flags();
trace!(r.flags=?flags);
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
@@ -584,7 +582,6 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}

#[inline]
#[instrument(level = "trace", ret)]
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
let flags = FlagComputation::for_const(c);
trace!(r.flags=?flags);
@@ -596,14 +593,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}

#[inline]
#[instrument(level = "trace", ret)]
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
debug!(
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
predicate,
predicate.flags(),
self.flags
);
if predicate.flags().intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
Original file line number Diff line number Diff line change
@@ -15,9 +15,6 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
@call("mir_retag", args) => {
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
},
@call("mir_retag_raw", args) => {
Ok(StatementKind::Retag(RetagKind::Raw, Box::new(self.parse_place(args[0])?)))
},
@call("mir_set_discriminant", args) => {
let place = self.parse_place(args[0])?;
let var = self.parse_integer_literal(args[1])? as u32;
Original file line number Diff line number Diff line change
@@ -14,21 +14,27 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
fn tag(&self) -> &'static str {
"CollectAllMismatches"
}

fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}

fn intercrate(&self) -> bool {
false
}

fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.param_env
}

fn a_is_expected(&self) -> bool {
true
} // irrelevant
}

fn mark_ambiguous(&mut self) {
bug!()
}

fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_: ty::Variance,
@@ -38,22 +44,28 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
) -> RelateResult<'tcx, T> {
self.relate(a, b)
}

fn regions(
&mut self,
a: ty::Region<'tcx>,
_b: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> {
Ok(a)
}

fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
if a == b || matches!(a.kind(), ty::Infer(_)) || matches!(b.kind(), ty::Infer(_)) {
return Ok(a);
}
relate::super_relate_tys(self, a, b).or_else(|e| {
self.errors.push(e);
Ok(a)
self.infcx.probe(|_| {
if a.is_ty_infer() || b.is_ty_infer() {
Ok(a)
} else {
self.infcx.super_combine_tys(self, a, b).or_else(|e| {
self.errors.push(e);
Ok(a)
})
}
})
}

fn consts(
&mut self,
a: ty::Const<'tcx>,
@@ -64,6 +76,7 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
}
relate::super_relate_consts(self, a, b) // could do something similar here for constants!
}

fn binders<T: Relate<'tcx>>(
&mut self,
a: ty::Binder<'tcx, T>,
Original file line number Diff line number Diff line change
@@ -335,7 +335,7 @@ pub trait TypeErrCtxtExt<'tcx> {
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
);
fn function_argument_obligation(
fn note_function_argument_obligation(
&self,
arg_hir_id: HirId,
err: &mut Diagnostic,
@@ -2909,7 +2909,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ref parent_code,
..
} => {
self.function_argument_obligation(
self.note_function_argument_obligation(
arg_hir_id,
err,
parent_code,
@@ -3141,23 +3141,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
}
}
fn function_argument_obligation(
fn note_function_argument_obligation(
&self,
arg_hir_id: HirId,
err: &mut Diagnostic,
parent_code: &ObligationCauseCode<'tcx>,
param_env: ty::ParamEnv<'tcx>,
predicate: ty::Predicate<'tcx>,
failed_pred: ty::Predicate<'tcx>,
call_hir_id: HirId,
) {
let tcx = self.tcx;
let hir = tcx.hir();
if let Some(Node::Expr(expr)) = hir.find(arg_hir_id) {
let parent_id = hir.get_parent_item(arg_hir_id);
let typeck_results: &TypeckResults<'tcx> = match &self.typeck_results {
Some(t) if t.hir_owner == parent_id => t,
_ => self.tcx.typeck(parent_id.def_id),
};
if let Some(Node::Expr(expr)) = hir.find(arg_hir_id)
&& let Some(typeck_results) = &self.typeck_results
{
if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr {
let expr = expr.peel_blocks();
let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error());
@@ -3182,37 +3179,29 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut type_diffs = vec![];

if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref()
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
&& let Some(pred) = predicates.predicates.get(*idx)
&& let Some(node_substs) = typeck_results.node_substs_opt(call_hir_id)
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_substs)
&& let Some(where_pred) = where_clauses.predicates.get(*idx)
{
if let Ok(trait_pred) = pred.kind().try_map_bound(|pred| match pred {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => Ok(trait_pred),
_ => Err(()),
})
&& let Ok(trait_predicate) = predicate.kind().try_map_bound(|pred| match pred {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => Ok(trait_pred),
_ => Err(()),
})
if let Some(where_pred) = where_pred.to_opt_poly_trait_pred()
&& let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
{
let mut c = CollectAllMismatches {
infcx: self.infcx,
param_env,
errors: vec![],
};
if let Ok(_) = c.relate(trait_pred, trait_predicate) {
if let Ok(_) = c.relate(where_pred, failed_pred) {
type_diffs = c.errors;
}
} else if let ty::PredicateKind::Clause(
ty::Clause::Projection(proj)
) = pred.kind().skip_binder()
&& let ty::PredicateKind::Clause(
ty::Clause::Projection(projection)
) = predicate.kind().skip_binder()
} else if let Some(where_pred) = where_pred.to_opt_poly_projection_pred()
&& let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred()
&& let Some(found) = failed_pred.skip_binder().term.ty()
{
type_diffs = vec![
Sorts(ty::error::ExpectedFound {
expected: self.tcx.mk_ty(ty::Alias(ty::Projection, proj.projection_ty)),
found: projection.term.ty().unwrap(),
expected: self.tcx.mk_ty(ty::Alias(ty::Projection, where_pred.skip_binder().projection_ty)),
found,
}),
];
}
@@ -3227,9 +3216,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// If the expression we're calling on is a binding, we want to point at the
// `let` when talking about the type. Otherwise we'll point at every part
// of the method chain with the type.
self.point_at_chain(binding_expr, typeck_results, type_diffs, param_env, err);
self.point_at_chain(binding_expr, &typeck_results, type_diffs, param_env, err);
} else {
self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
self.point_at_chain(expr, &typeck_results, type_diffs, param_env, err);
}
}
let call_node = hir.find(call_hir_id);
4 changes: 2 additions & 2 deletions library/core/src/const_closure.rs
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ macro_rules! impl_fn_mut_tuple {
impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
where
Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue + ~const Destruct,
{
type Output = ClosureReturnValue;

@@ -64,7 +64,7 @@ macro_rules! impl_fn_mut_tuple {
impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
where
Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue + ~const Destruct,
{
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
#[allow(non_snake_case)]
4 changes: 2 additions & 2 deletions library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ pub trait Hash {
/// println!("Hash is {:x}!", hasher.finish());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn hash<H: Hasher>(&self, state: &mut H);
fn hash<H: ~const Hasher>(&self, state: &mut H);

/// Feeds a slice of this type into the given [`Hasher`].
///
@@ -980,7 +980,7 @@ mod impls {
#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
impl<T: ?Sized + ~const Hash> const Hash for &mut T {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
fn hash<H: ~const Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
1 change: 0 additions & 1 deletion library/core/src/intrinsics/mir.rs
Original file line number Diff line number Diff line change
@@ -259,7 +259,6 @@ define!("mir_drop", fn Drop<T>(place: T, goto: BasicBlock));
define!("mir_drop_and_replace", fn DropAndReplace<T>(place: T, value: T, goto: BasicBlock));
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
define!("mir_retag", fn Retag<T>(place: T));
define!("mir_retag_raw", fn RetagRaw<T>(place: T));
define!("mir_move", fn Move<T>(place: T) -> T);
define!("mir_static", fn Static<T>(s: T) -> &'static T);
define!("mir_static_mut", fn StaticMut<T>(s: T) -> *mut T);
2 changes: 1 addition & 1 deletion library/core/src/ops/index.rs
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
#[doc(alias = "]")]
#[doc(alias = "[]")]
#[const_trait]
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> {
/// Performs the mutable indexing (`container[index]`) operation.
///
/// # Panics
Original file line number Diff line number Diff line change
@@ -6,9 +6,8 @@ fn immut_ref(_1: &i32) -> &i32 {

bb0: {
_2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:29
Retag([raw] _2); // scope 0 at $DIR/references.rs:+6:13: +6:24
_0 = &(*_2); // scope 0 at $DIR/references.rs:+7:13: +7:23
Retag(_0); // scope 0 at $DIR/references.rs:+8:13: +8:23
return; // scope 0 at $DIR/references.rs:+9:13: +9:21
_0 = &(*_2); // scope 0 at $DIR/references.rs:+6:13: +6:23
Retag(_0); // scope 0 at $DIR/references.rs:+7:13: +7:23
return; // scope 0 at $DIR/references.rs:+8:13: +8:21
}
}
Original file line number Diff line number Diff line change
@@ -6,9 +6,8 @@ fn mut_ref(_1: &mut i32) -> &mut i32 {

bb0: {
_2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:33
Retag([raw] _2); // scope 0 at $DIR/references.rs:+6:13: +6:24
_0 = &mut (*_2); // scope 0 at $DIR/references.rs:+7:13: +7:26
Retag(_0); // scope 0 at $DIR/references.rs:+8:13: +8:23
return; // scope 0 at $DIR/references.rs:+9:13: +9:21
_0 = &mut (*_2); // scope 0 at $DIR/references.rs:+6:13: +6:26
Retag(_0); // scope 0 at $DIR/references.rs:+7:13: +7:23
return; // scope 0 at $DIR/references.rs:+8:13: +8:21
}
}
2 changes: 0 additions & 2 deletions src/test/mir-opt/building/custom/references.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@ pub fn mut_ref(x: &mut i32) -> &mut i32 {

{
t = addr_of_mut!(*x);
RetagRaw(t);
RET = &mut *t;
Retag(RET);
Return()
@@ -28,7 +27,6 @@ pub fn immut_ref(x: &i32) -> &i32 {

{
t = addr_of!(*x);
RetagRaw(t);
RET = & *t;
Retag(RET);
Return()
30 changes: 30 additions & 0 deletions src/test/ui/async-await/async-is-unwindsafe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// edition:2018

fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}

fn main() {
// A normal future created by an async block takes a `&mut Context<'_>` argument.
// That should not leak through to the whole async block.
is_unwindsafe(async {
async {}.await; // this needs an inner await point
});

is_unwindsafe(async {
//~^ ERROR the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
use std::ptr::null;
use std::task::{Context, RawWaker, RawWakerVTable, Waker};
let waker = unsafe {
Waker::from_raw(RawWaker::new(
null(),
&RawWakerVTable::new(|_| todo!(), |_| todo!(), |_| todo!(), |_| todo!()),
))
};
let mut cx = Context::from_waker(&waker);
let cx_ref = &mut cx;

async {}.await; // this needs an inner await point

// in this case, `&mut Context<'_>` is *truly* alive across an await point
drop(cx_ref);
});
}
38 changes: 38 additions & 0 deletions src/test/ui/async-await/async-is-unwindsafe.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
--> $DIR/async-is-unwindsafe.rs:12:19
|
LL | is_unwindsafe(async {
| ___________________^
LL | |
LL | | use std::ptr::null;
LL | | use std::task::{Context, RawWaker, RawWakerVTable, Waker};
... |
LL | | drop(cx_ref);
LL | | });
| | ^
| | |
| |_____`&mut Context<'_>` may not be safely transferred across an unwind boundary
| within this `[async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6]`
|
= help: within `[async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6]`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`
= note: `UnwindSafe` is implemented for `&std::task::Context<'_>`, but not for `&mut std::task::Context<'_>`
note: future does not implement `UnwindSafe` as this value is used across an await
--> $DIR/async-is-unwindsafe.rs:25:17
|
LL | let cx_ref = &mut cx;
| ------ has type `&mut Context<'_>` which does not implement `UnwindSafe`
LL |
LL | async {}.await; // this needs an inner await point
| ^^^^^^ await occurs here, with `cx_ref` maybe used later
...
LL | });
| - `cx_ref` is later dropped here
note: required by a bound in `is_unwindsafe`
--> $DIR/async-is-unwindsafe.rs:3:26
|
LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
8 changes: 4 additions & 4 deletions src/test/ui/iterators/invalid-iterator-chain.stderr
Original file line number Diff line number Diff line change
@@ -52,14 +52,14 @@ LL | .sum::<i32>(),
<i32 as Sum<&'a i32>>
<i32 as Sum>
note: the method call chain might not have had the expected associated types
--> $DIR/invalid-iterator-chain.rs:20:14
--> $DIR/invalid-iterator-chain.rs:25:14
|
LL | vec![0, 1]
| ---------- this expression has type `Vec<{integer}>`
LL | .iter()
| ------ `Iterator::Item` is `&{integer}` here
LL | .map(|x| x * 2)
| ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
| -------------- `Iterator::Item` changed to `{integer}` here
LL | .map(|x| x as f64)
| ----------------- `Iterator::Item` changed to `f64` here
LL | .map(|x| x as i64)
@@ -84,14 +84,14 @@ LL | .sum::<i32>(),
<i32 as Sum<&'a i32>>
<i32 as Sum>
note: the method call chain might not have had the expected associated types
--> $DIR/invalid-iterator-chain.rs:32:14
--> $DIR/invalid-iterator-chain.rs:33:14
|
LL | vec![0, 1]
| ---------- this expression has type `Vec<{integer}>`
LL | .iter()
| ------ `Iterator::Item` is `&{integer}` here
LL | .map(|x| x * 2)
| ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
| -------------- `Iterator::Item` changed to `{integer}` here
LL | .map(|x| x as f64)
| ^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `f64` here
LL | .filter(|x| *x > 0.0)
9 changes: 9 additions & 0 deletions src/test/ui/lint/must_not_suspend/tuple-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(generators)]

fn main() {
let _generator = || {
yield ((), ((), ()));
yield ((), ());
//~^ ERROR mismatched types
};
}
12 changes: 12 additions & 0 deletions src/test/ui/lint/must_not_suspend/tuple-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0308]: mismatched types
--> $DIR/tuple-mismatch.rs:6:20
|
LL | yield ((), ());
| ^^ expected tuple, found `()`
|
= note: expected tuple `((), ())`
found unit type `()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.