mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #91093 - matthiaskrgr:rollup-kovzwx0, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #89741 (Mark `Arc::from_inner` / `Rc::from_inner` as unsafe) - #90927 (Fix float ICE) - #90994 (Fix ICE `#90993`: add missing call to cancel) - #91018 (Adopt let_else in more places in rustc_mir_build) - #91022 (Suggest `await` in more situations where infer types are involved) - #91088 (Revert "require full validity when determining the discriminant of a value") Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
5bc98076f3
@ -265,12 +265,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
sym::discriminant_value => {
|
sym::discriminant_value => {
|
||||||
let place = self.deref_operand(&args[0])?;
|
let place = self.deref_operand(&args[0])?;
|
||||||
if M::enforce_validity(self) {
|
|
||||||
// This is 'using' the value, so make sure the validity invariant is satisfied.
|
|
||||||
// (Also see https://github.com/rust-lang/rust/pull/89764.)
|
|
||||||
self.validate_operand(&place.into())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let discr_val = self.read_discriminant(&place.into())?.0;
|
let discr_val = self.read_discriminant(&place.into())?.0;
|
||||||
self.write_scalar(discr_val, dest)?;
|
self.write_scalar(discr_val, dest)?;
|
||||||
}
|
}
|
||||||
|
@ -304,12 +304,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
|
|
||||||
Discriminant(place) => {
|
Discriminant(place) => {
|
||||||
let op = self.eval_place_to_op(place, None)?;
|
let op = self.eval_place_to_op(place, None)?;
|
||||||
if M::enforce_validity(self) {
|
|
||||||
// This is 'using' the value, so make sure the validity invariant is satisfied.
|
|
||||||
// (Also see https://github.com/rust-lang/rust/pull/89764.)
|
|
||||||
self.validate_operand(&op)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let discr_val = self.read_discriminant(&op)?.0;
|
let discr_val = self.read_discriminant(&op)?.0;
|
||||||
self.write_scalar(discr_val, &dest)?;
|
self.write_scalar(discr_val, &dest)?;
|
||||||
}
|
}
|
||||||
|
@ -310,6 +310,34 @@ pub fn unexpected_hidden_region_diagnostic(
|
|||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Structurally compares two types, modulo any inference variables.
|
||||||
|
///
|
||||||
|
/// Returns `true` if two types are equal, or if one type is an inference variable compatible
|
||||||
|
/// with the other type. A TyVar inference type is compatible with any type, and an IntVar or
|
||||||
|
/// FloatVar inference type are compatible with themselves or their concrete types (Int and
|
||||||
|
/// Float types, respectively). When comparing two ADTs, these rules apply recursively.
|
||||||
|
pub fn same_type_modulo_infer(a: Ty<'tcx>, b: Ty<'ctx>) -> bool {
|
||||||
|
match (&a.kind(), &b.kind()) {
|
||||||
|
(&ty::Adt(did_a, substs_a), &ty::Adt(did_b, substs_b)) => {
|
||||||
|
if did_a != did_b {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
substs_a.types().zip(substs_b.types()).all(|(a, b)| same_type_modulo_infer(a, b))
|
||||||
|
}
|
||||||
|
(&ty::Int(_), &ty::Infer(ty::InferTy::IntVar(_)))
|
||||||
|
| (&ty::Infer(ty::InferTy::IntVar(_)), &ty::Int(_) | &ty::Infer(ty::InferTy::IntVar(_)))
|
||||||
|
| (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
|
||||||
|
| (
|
||||||
|
&ty::Infer(ty::InferTy::FloatVar(_)),
|
||||||
|
&ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)),
|
||||||
|
)
|
||||||
|
| (&ty::Infer(ty::InferTy::TyVar(_)), _)
|
||||||
|
| (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
|
||||||
|
_ => a == b,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
pub fn report_region_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>) {
|
pub fn report_region_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>) {
|
||||||
debug!("report_region_errors(): {} errors to start", errors.len());
|
debug!("report_region_errors(): {} errors to start", errors.len());
|
||||||
@ -1761,7 +1789,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
self.get_impl_future_output_ty(exp_found.expected),
|
self.get_impl_future_output_ty(exp_found.expected),
|
||||||
self.get_impl_future_output_ty(exp_found.found),
|
self.get_impl_future_output_ty(exp_found.found),
|
||||||
) {
|
) {
|
||||||
(Some(exp), Some(found)) if ty::TyS::same_type(exp, found) => match &cause.code {
|
(Some(exp), Some(found)) if same_type_modulo_infer(exp, found) => match &cause.code {
|
||||||
ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => {
|
ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => {
|
||||||
diag.multipart_suggestion(
|
diag.multipart_suggestion(
|
||||||
"consider `await`ing on both `Future`s",
|
"consider `await`ing on both `Future`s",
|
||||||
@ -1793,7 +1821,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
diag.help("consider `await`ing on both `Future`s");
|
diag.help("consider `await`ing on both `Future`s");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => {
|
(_, Some(ty)) if same_type_modulo_infer(exp_found.expected, ty) => {
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
exp_span.shrink_to_hi(),
|
exp_span.shrink_to_hi(),
|
||||||
"consider `await`ing on the `Future`",
|
"consider `await`ing on the `Future`",
|
||||||
@ -1801,7 +1829,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => match cause.code {
|
(Some(ty), _) if same_type_modulo_infer(ty, exp_found.found) => match cause.code {
|
||||||
ObligationCauseCode::Pattern { span: Some(span), .. }
|
ObligationCauseCode::Pattern { span: Some(span), .. }
|
||||||
| ObligationCauseCode::IfExpression(box IfExpressionCause { then: span, .. }) => {
|
| ObligationCauseCode::IfExpression(box IfExpressionCause { then: span, .. }) => {
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
|
@ -1606,13 +1606,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
// encounter a candidate where the test is not relevant; at
|
// encounter a candidate where the test is not relevant; at
|
||||||
// that point, we stop sorting.
|
// that point, we stop sorting.
|
||||||
while let Some(candidate) = candidates.first_mut() {
|
while let Some(candidate) = candidates.first_mut() {
|
||||||
if let Some(idx) = self.sort_candidate(&match_place.clone(), &test, candidate) {
|
let Some(idx) = self.sort_candidate(&match_place.clone(), &test, candidate) else {
|
||||||
let (candidate, rest) = candidates.split_first_mut().unwrap();
|
|
||||||
target_candidates[idx].push(candidate);
|
|
||||||
candidates = rest;
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
};
|
||||||
|
let (candidate, rest) = candidates.split_first_mut().unwrap();
|
||||||
|
target_candidates[idx].push(candidate);
|
||||||
|
candidates = rest;
|
||||||
}
|
}
|
||||||
// at least the first candidate ought to be tested
|
// at least the first candidate ought to be tested
|
||||||
assert!(total_candidate_count > candidates.len());
|
assert!(total_candidate_count > candidates.len());
|
||||||
|
@ -966,59 +966,58 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
DropKind::Value,
|
DropKind::Value,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(arg) = arg_opt {
|
let Some(arg) = arg_opt else {
|
||||||
let pat = match tcx.hir().get(arg.pat.hir_id) {
|
continue;
|
||||||
Node::Pat(pat) | Node::Binding(pat) => pat,
|
};
|
||||||
node => bug!("pattern became {:?}", node),
|
let pat = match tcx.hir().get(arg.pat.hir_id) {
|
||||||
};
|
Node::Pat(pat) | Node::Binding(pat) => pat,
|
||||||
let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat);
|
node => bug!("pattern became {:?}", node),
|
||||||
let original_source_scope = self.source_scope;
|
};
|
||||||
let span = pattern.span;
|
let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat);
|
||||||
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
|
let original_source_scope = self.source_scope;
|
||||||
match *pattern.kind {
|
let span = pattern.span;
|
||||||
// Don't introduce extra copies for simple bindings
|
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
|
||||||
PatKind::Binding {
|
match *pattern.kind {
|
||||||
mutability,
|
// Don't introduce extra copies for simple bindings
|
||||||
var,
|
PatKind::Binding {
|
||||||
mode: BindingMode::ByValue,
|
mutability,
|
||||||
subpattern: None,
|
var,
|
||||||
..
|
mode: BindingMode::ByValue,
|
||||||
} => {
|
subpattern: None,
|
||||||
self.local_decls[local].mutability = mutability;
|
..
|
||||||
self.local_decls[local].source_info.scope = self.source_scope;
|
} => {
|
||||||
self.local_decls[local].local_info = if let Some(kind) = self_binding {
|
self.local_decls[local].mutability = mutability;
|
||||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
self.local_decls[local].source_info.scope = self.source_scope;
|
||||||
BindingForm::ImplicitSelf(*kind),
|
self.local_decls[local].local_info = if let Some(kind) = self_binding {
|
||||||
))))
|
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
||||||
} else {
|
BindingForm::ImplicitSelf(*kind),
|
||||||
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
))))
|
||||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
} else {
|
||||||
VarBindingForm {
|
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
||||||
binding_mode,
|
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||||
opt_ty_info,
|
VarBindingForm {
|
||||||
opt_match_place: Some((Some(place), span)),
|
binding_mode,
|
||||||
pat_span: span,
|
opt_ty_info,
|
||||||
},
|
opt_match_place: Some((Some(place), span)),
|
||||||
)))))
|
pat_span: span,
|
||||||
};
|
},
|
||||||
self.var_indices.insert(var, LocalsForNode::One(local));
|
)))))
|
||||||
}
|
};
|
||||||
_ => {
|
self.var_indices.insert(var, LocalsForNode::One(local));
|
||||||
scope = self.declare_bindings(
|
}
|
||||||
scope,
|
_ => {
|
||||||
expr.span,
|
scope = self.declare_bindings(
|
||||||
&pattern,
|
scope,
|
||||||
matches::ArmHasGuard(false),
|
expr.span,
|
||||||
Some((Some(&place), span)),
|
&pattern,
|
||||||
);
|
matches::ArmHasGuard(false),
|
||||||
let place_builder = PlaceBuilder::from(local);
|
Some((Some(&place), span)),
|
||||||
unpack!(
|
);
|
||||||
block = self.place_into_pattern(block, pattern, place_builder, false)
|
let place_builder = PlaceBuilder::from(local);
|
||||||
);
|
unpack!(block = self.place_into_pattern(block, pattern, place_builder, false));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.source_scope = original_source_scope;
|
|
||||||
}
|
}
|
||||||
|
self.source_scope = original_source_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter the argument pattern bindings source scope, if it exists.
|
// Enter the argument pattern bindings source scope, if it exists.
|
||||||
|
@ -256,23 +256,22 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
PatKind::Binding { mode: BindingMode::ByRef(borrow_kind), ty, .. } => {
|
PatKind::Binding { mode: BindingMode::ByRef(borrow_kind), ty, .. } => {
|
||||||
if self.inside_adt {
|
if self.inside_adt {
|
||||||
if let ty::Ref(_, ty, _) = ty.kind() {
|
let ty::Ref(_, ty, _) = ty.kind() else {
|
||||||
match borrow_kind {
|
|
||||||
BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
|
|
||||||
if !ty.is_freeze(self.tcx.at(pat.span), self.param_env) {
|
|
||||||
self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BorrowKind::Mut { .. } => {
|
|
||||||
self.requires_unsafe(pat.span, MutationOfLayoutConstrainedField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
span_bug!(
|
span_bug!(
|
||||||
pat.span,
|
pat.span,
|
||||||
"BindingMode::ByRef in pattern, but found non-reference type {}",
|
"BindingMode::ByRef in pattern, but found non-reference type {}",
|
||||||
ty
|
ty
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
match borrow_kind {
|
||||||
|
BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
|
||||||
|
if !ty.is_freeze(self.tcx.at(pat.span), self.param_env) {
|
||||||
|
self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BorrowKind::Mut { .. } => {
|
||||||
|
self.requires_unsafe(pat.span, MutationOfLayoutConstrainedField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visit::walk_pat(self, pat);
|
visit::walk_pat(self, pat);
|
||||||
|
@ -1032,6 +1032,8 @@ impl<'a> Parser<'a> {
|
|||||||
[IdentLike(_), Punct('+' | '-')] |
|
[IdentLike(_), Punct('+' | '-')] |
|
||||||
// 1e+2 | 1e-2
|
// 1e+2 | 1e-2
|
||||||
[IdentLike(_), Punct('+' | '-'), IdentLike(_)] |
|
[IdentLike(_), Punct('+' | '-'), IdentLike(_)] |
|
||||||
|
// 1.2e+ | 1.2e-
|
||||||
|
[IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-')] |
|
||||||
// 1.2e+3 | 1.2e-3
|
// 1.2e+3 | 1.2e-3
|
||||||
[IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-'), IdentLike(_)] => {
|
[IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-'), IdentLike(_)] => {
|
||||||
// See the FIXME about `TokenCursor` above.
|
// See the FIXME about `TokenCursor` above.
|
||||||
|
@ -817,7 +817,7 @@ impl<'a> Parser<'a> {
|
|||||||
// Ensure the user doesn't receive unhelpful unexpected token errors
|
// Ensure the user doesn't receive unhelpful unexpected token errors
|
||||||
self.bump();
|
self.bump();
|
||||||
if self.is_pat_range_end_start(0) {
|
if self.is_pat_range_end_start(0) {
|
||||||
let _ = self.parse_pat_range_end();
|
let _ = self.parse_pat_range_end().map_err(|mut e| e.cancel());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.error_inclusive_range_with_extra_equals(span_with_eq);
|
self.error_inclusive_range_with_extra_equals(span_with_eq);
|
||||||
|
@ -341,12 +341,12 @@ impl<T: ?Sized> Rc<T> {
|
|||||||
unsafe { self.ptr.as_ref() }
|
unsafe { self.ptr.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_inner(ptr: NonNull<RcBox<T>>) -> Self {
|
unsafe fn from_inner(ptr: NonNull<RcBox<T>>) -> Self {
|
||||||
Self { ptr, phantom: PhantomData }
|
Self { ptr, phantom: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn from_ptr(ptr: *mut RcBox<T>) -> Self {
|
unsafe fn from_ptr(ptr: *mut RcBox<T>) -> Self {
|
||||||
Self::from_inner(unsafe { NonNull::new_unchecked(ptr) })
|
unsafe { Self::from_inner(NonNull::new_unchecked(ptr)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,9 +367,11 @@ impl<T> Rc<T> {
|
|||||||
// pointers, which ensures that the weak destructor never frees
|
// pointers, which ensures that the weak destructor never frees
|
||||||
// the allocation while the strong destructor is running, even
|
// the allocation while the strong destructor is running, even
|
||||||
// if the weak pointer is stored inside the strong one.
|
// if the weak pointer is stored inside the strong one.
|
||||||
Self::from_inner(
|
unsafe {
|
||||||
Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
|
Self::from_inner(
|
||||||
)
|
Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
|
/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
|
||||||
@ -420,16 +422,16 @@ impl<T> Rc<T> {
|
|||||||
// otherwise.
|
// otherwise.
|
||||||
let data = data_fn(&weak);
|
let data = data_fn(&weak);
|
||||||
|
|
||||||
unsafe {
|
let strong = unsafe {
|
||||||
let inner = init_ptr.as_ptr();
|
let inner = init_ptr.as_ptr();
|
||||||
ptr::write(ptr::addr_of_mut!((*inner).value), data);
|
ptr::write(ptr::addr_of_mut!((*inner).value), data);
|
||||||
|
|
||||||
let prev_value = (*inner).strong.get();
|
let prev_value = (*inner).strong.get();
|
||||||
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
|
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
|
||||||
(*inner).strong.set(1);
|
(*inner).strong.set(1);
|
||||||
}
|
|
||||||
|
|
||||||
let strong = Rc::from_inner(init_ptr);
|
Rc::from_inner(init_ptr)
|
||||||
|
};
|
||||||
|
|
||||||
// Strong references should collectively own a shared weak reference,
|
// Strong references should collectively own a shared weak reference,
|
||||||
// so don't run the destructor for our old weak reference.
|
// so don't run the destructor for our old weak reference.
|
||||||
@ -521,10 +523,12 @@ impl<T> Rc<T> {
|
|||||||
// pointers, which ensures that the weak destructor never frees
|
// pointers, which ensures that the weak destructor never frees
|
||||||
// the allocation while the strong destructor is running, even
|
// the allocation while the strong destructor is running, even
|
||||||
// if the weak pointer is stored inside the strong one.
|
// if the weak pointer is stored inside the strong one.
|
||||||
Ok(Self::from_inner(
|
unsafe {
|
||||||
Box::leak(Box::try_new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })?)
|
Ok(Self::from_inner(
|
||||||
.into(),
|
Box::leak(Box::try_new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })?)
|
||||||
))
|
.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Rc` with uninitialized contents, returning an error if the allocation fails
|
/// Constructs a new `Rc` with uninitialized contents, returning an error if the allocation fails
|
||||||
@ -746,7 +750,7 @@ impl<T> Rc<mem::MaybeUninit<T>> {
|
|||||||
#[unstable(feature = "new_uninit", issue = "63291")]
|
#[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn assume_init(self) -> Rc<T> {
|
pub unsafe fn assume_init(self) -> Rc<T> {
|
||||||
Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
|
unsafe { Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1214,9 +1218,11 @@ impl Rc<dyn Any> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
|
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
|
||||||
if (*self).is::<T>() {
|
if (*self).is::<T>() {
|
||||||
let ptr = self.ptr.cast::<RcBox<T>>();
|
unsafe {
|
||||||
forget(self);
|
let ptr = self.ptr.cast::<RcBox<T>>();
|
||||||
Ok(Rc::from_inner(ptr))
|
forget(self);
|
||||||
|
Ok(Rc::from_inner(ptr))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(self)
|
Err(self)
|
||||||
}
|
}
|
||||||
@ -1489,8 +1495,10 @@ impl<T: ?Sized> Clone for Rc<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Rc<T> {
|
fn clone(&self) -> Rc<T> {
|
||||||
self.inner().inc_strong();
|
unsafe {
|
||||||
Self::from_inner(self.ptr)
|
self.inner().inc_strong();
|
||||||
|
Self::from_inner(self.ptr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2245,11 +2253,14 @@ impl<T: ?Sized> Weak<T> {
|
|||||||
#[stable(feature = "rc_weak", since = "1.4.0")]
|
#[stable(feature = "rc_weak", since = "1.4.0")]
|
||||||
pub fn upgrade(&self) -> Option<Rc<T>> {
|
pub fn upgrade(&self) -> Option<Rc<T>> {
|
||||||
let inner = self.inner()?;
|
let inner = self.inner()?;
|
||||||
|
|
||||||
if inner.strong() == 0 {
|
if inner.strong() == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
inner.inc_strong();
|
unsafe {
|
||||||
Some(Rc::from_inner(self.ptr))
|
inner.inc_strong();
|
||||||
|
Some(Rc::from_inner(self.ptr))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
|
|||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
|
||||||
|
|
||||||
impl<T: ?Sized> Arc<T> {
|
impl<T: ?Sized> Arc<T> {
|
||||||
fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
|
unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
|
||||||
Self { ptr, phantom: PhantomData }
|
Self { ptr, phantom: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +348,7 @@ impl<T> Arc<T> {
|
|||||||
weak: atomic::AtomicUsize::new(1),
|
weak: atomic::AtomicUsize::new(1),
|
||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
Self::from_inner(Box::leak(x).into())
|
unsafe { Self::from_inner(Box::leak(x).into()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
|
/// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
|
||||||
@ -397,7 +397,7 @@ impl<T> Arc<T> {
|
|||||||
|
|
||||||
// Now we can properly initialize the inner value and turn our weak
|
// Now we can properly initialize the inner value and turn our weak
|
||||||
// reference into a strong reference.
|
// reference into a strong reference.
|
||||||
unsafe {
|
let strong = unsafe {
|
||||||
let inner = init_ptr.as_ptr();
|
let inner = init_ptr.as_ptr();
|
||||||
ptr::write(ptr::addr_of_mut!((*inner).data), data);
|
ptr::write(ptr::addr_of_mut!((*inner).data), data);
|
||||||
|
|
||||||
@ -415,9 +415,9 @@ impl<T> Arc<T> {
|
|||||||
// possible with safe code alone.
|
// possible with safe code alone.
|
||||||
let prev_value = (*inner).strong.fetch_add(1, Release);
|
let prev_value = (*inner).strong.fetch_add(1, Release);
|
||||||
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
|
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
|
||||||
}
|
|
||||||
|
|
||||||
let strong = Arc::from_inner(init_ptr);
|
Arc::from_inner(init_ptr)
|
||||||
|
};
|
||||||
|
|
||||||
// Strong references should collectively own a shared weak reference,
|
// Strong references should collectively own a shared weak reference,
|
||||||
// so don't run the destructor for our old weak reference.
|
// so don't run the destructor for our old weak reference.
|
||||||
@ -529,7 +529,7 @@ impl<T> Arc<T> {
|
|||||||
weak: atomic::AtomicUsize::new(1),
|
weak: atomic::AtomicUsize::new(1),
|
||||||
data,
|
data,
|
||||||
})?;
|
})?;
|
||||||
Ok(Self::from_inner(Box::leak(x).into()))
|
unsafe { Ok(Self::from_inner(Box::leak(x).into())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Arc` with uninitialized contents, returning an error
|
/// Constructs a new `Arc` with uninitialized contents, returning an error
|
||||||
@ -743,7 +743,7 @@ impl<T> Arc<mem::MaybeUninit<T>> {
|
|||||||
#[must_use = "`self` will be dropped if the result is not used"]
|
#[must_use = "`self` will be dropped if the result is not used"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn assume_init(self) -> Arc<T> {
|
pub unsafe fn assume_init(self) -> Arc<T> {
|
||||||
Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
|
unsafe { Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1341,7 +1341,7 @@ impl<T: ?Sized> Clone for Arc<T> {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::from_inner(self.ptr)
|
unsafe { Self::from_inner(self.ptr) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1668,9 +1668,11 @@ impl Arc<dyn Any + Send + Sync> {
|
|||||||
T: Any + Send + Sync + 'static,
|
T: Any + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
if (*self).is::<T>() {
|
if (*self).is::<T>() {
|
||||||
let ptr = self.ptr.cast::<ArcInner<T>>();
|
unsafe {
|
||||||
mem::forget(self);
|
let ptr = self.ptr.cast::<ArcInner<T>>();
|
||||||
Ok(Arc::from_inner(ptr))
|
mem::forget(self);
|
||||||
|
Ok(Arc::from_inner(ptr))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(self)
|
Err(self)
|
||||||
}
|
}
|
||||||
@ -1899,7 +1901,7 @@ impl<T: ?Sized> Weak<T> {
|
|||||||
// value can be initialized after `Weak` references have already been created. In that case, we
|
// value can be initialized after `Weak` references have already been created. In that case, we
|
||||||
// expect to observe the fully initialized value.
|
// expect to observe the fully initialized value.
|
||||||
match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) {
|
match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) {
|
||||||
Ok(_) => return Some(Arc::from_inner(self.ptr)), // null checked above
|
Ok(_) => return Some(unsafe { Arc::from_inner(self.ptr) }), // null checked above
|
||||||
Err(old) => n = old,
|
Err(old) => n = old,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,4 +54,21 @@ async fn suggest_await_on_match_expr() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn dummy_result() -> Result<(), ()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
async fn suggest_await_in_generic_pattern() {
|
||||||
|
match dummy_result() {
|
||||||
|
//~^ HELP consider `await`ing on the `Future`
|
||||||
|
//~| HELP consider `await`ing on the `Future`
|
||||||
|
//~| SUGGESTION .await
|
||||||
|
Ok(_) => {}
|
||||||
|
//~^ ERROR mismatched types [E0308]
|
||||||
|
Err(_) => {}
|
||||||
|
//~^ ERROR mismatched types [E0308]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -106,6 +106,42 @@ help: consider `await`ing on the `Future`
|
|||||||
LL | let _x = match dummy().await {
|
LL | let _x = match dummy().await {
|
||||||
| ++++++
|
| ++++++
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/suggest-missing-await.rs:67:9
|
||||||
|
|
|
||||||
|
LL | Ok(_) => {}
|
||||||
|
| ^^^^^ expected opaque type, found enum `Result`
|
||||||
|
|
|
||||||
|
note: while checking the return type of the `async fn`
|
||||||
|
--> $DIR/suggest-missing-await.rs:57:28
|
||||||
|
|
|
||||||
|
LL | async fn dummy_result() -> Result<(), ()> {
|
||||||
|
| ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type
|
||||||
|
= note: expected opaque type `impl Future<Output = Result<(), ()>>`
|
||||||
|
found enum `Result<_, _>`
|
||||||
|
help: consider `await`ing on the `Future`
|
||||||
|
|
|
||||||
|
LL | match dummy_result().await {
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/suggest-missing-await.rs:69:9
|
||||||
|
|
|
||||||
|
LL | Err(_) => {}
|
||||||
|
| ^^^^^^ expected opaque type, found enum `Result`
|
||||||
|
|
|
||||||
|
note: while checking the return type of the `async fn`
|
||||||
|
--> $DIR/suggest-missing-await.rs:57:28
|
||||||
|
|
|
||||||
|
LL | async fn dummy_result() -> Result<(), ()> {
|
||||||
|
| ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type
|
||||||
|
= note: expected opaque type `impl Future<Output = Result<(), ()>>`
|
||||||
|
found enum `Result<_, _>`
|
||||||
|
help: consider `await`ing on the `Future`
|
||||||
|
|
|
||||||
|
LL | match dummy_result().await {
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
6
src/test/ui/parser/issue-90728.rs
Normal file
6
src/test/ui/parser/issue-90728.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
fn main() {
|
||||||
|
a.5.2E+
|
||||||
|
//~^ ERROR: unexpected token: `5.2E+`
|
||||||
|
//~| ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+`
|
||||||
|
//~| ERROR: expected at least one digit in exponent
|
||||||
|
}
|
20
src/test/ui/parser/issue-90728.stderr
Normal file
20
src/test/ui/parser/issue-90728.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
error: expected at least one digit in exponent
|
||||||
|
--> $DIR/issue-90728.rs:2:7
|
||||||
|
|
|
||||||
|
LL | a.5.2E+
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: unexpected token: `5.2E+`
|
||||||
|
--> $DIR/issue-90728.rs:2:7
|
||||||
|
|
|
||||||
|
LL | a.5.2E+
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+`
|
||||||
|
--> $DIR/issue-90728.rs:2:7
|
||||||
|
|
|
||||||
|
LL | a.5.2E+
|
||||||
|
| ^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user