Skip to content

Commit

Permalink
Auto merge of rust-lang#91093 - matthiaskrgr:rollup-kovzwx0, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#89741 (Mark `Arc::from_inner` / `Rc::from_inner` as unsafe)
 - rust-lang#90927 (Fix float ICE)
 - rust-lang#90994 (Fix ICE `rust-lang#90993`: add missing call to cancel)
 - rust-lang#91018 (Adopt let_else in more places in rustc_mir_build)
 - rust-lang#91022 (Suggest `await` in more situations where infer types are involved)
 - rust-lang#91088 (Revert "require full validity when determining the discriminant of a value")

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Nov 20, 2021
2 parents 2885c47 + 83c83d4 commit 5bc9807
Show file tree
Hide file tree
Showing 352 changed files with 263 additions and 119 deletions.
6 changes: 0 additions & 6 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
sym::discriminant_value => {
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;
self.write_scalar(discr_val, dest)?;
}
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

Discriminant(place) => {
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;
self.write_scalar(discr_val, &dest)?;
}
Expand Down
34 changes: 31 additions & 3 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,34 @@ pub fn unexpected_hidden_region_diagnostic(
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> {
pub fn report_region_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>) {
debug!("report_region_errors(): {} errors to start", errors.len());
Expand Down Expand Up @@ -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.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, .. }) => {
diag.multipart_suggestion(
"consider `await`ing on both `Future`s",
Expand Down Expand Up @@ -1793,15 +1821,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
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(
exp_span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await".to_string(),
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::IfExpression(box IfExpressionCause { then: span, .. }) => {
diag.span_suggestion_verbose(
Expand Down
11 changes: 5 additions & 6 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1606,13 +1606,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// encounter a candidate where the test is not relevant; at
// that point, we stop sorting.
while let Some(candidate) = candidates.first_mut() {
if let Some(idx) = self.sort_candidate(&match_place.clone(), &test, candidate) {
let (candidate, rest) = candidates.split_first_mut().unwrap();
target_candidates[idx].push(candidate);
candidates = rest;
} else {
let Some(idx) = self.sort_candidate(&match_place.clone(), &test, candidate) else {
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
assert!(total_candidate_count > candidates.len());
Expand Down
101 changes: 50 additions & 51 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,59 +966,58 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
DropKind::Value,
);

if let Some(arg) = arg_opt {
let pat = match tcx.hir().get(arg.pat.hir_id) {
Node::Pat(pat) | Node::Binding(pat) => pat,
node => bug!("pattern became {:?}", node),
};
let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat);
let original_source_scope = self.source_scope;
let span = pattern.span;
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
match *pattern.kind {
// Don't introduce extra copies for simple bindings
PatKind::Binding {
mutability,
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 {
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
BindingForm::ImplicitSelf(*kind),
))))
} else {
let binding_mode = ty::BindingMode::BindByValue(mutability);
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
VarBindingForm {
binding_mode,
opt_ty_info,
opt_match_place: Some((Some(place), span)),
pat_span: span,
},
)))))
};
self.var_indices.insert(var, LocalsForNode::One(local));
}
_ => {
scope = self.declare_bindings(
scope,
expr.span,
&pattern,
matches::ArmHasGuard(false),
Some((Some(&place), span)),
);
let place_builder = PlaceBuilder::from(local);
unpack!(
block = self.place_into_pattern(block, pattern, place_builder, false)
);
}
let Some(arg) = arg_opt else {
continue;
};
let pat = match tcx.hir().get(arg.pat.hir_id) {
Node::Pat(pat) | Node::Binding(pat) => pat,
node => bug!("pattern became {:?}", node),
};
let pattern = pat_from_hir(tcx, self.param_env, self.typeck_results, pat);
let original_source_scope = self.source_scope;
let span = pattern.span;
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
match *pattern.kind {
// Don't introduce extra copies for simple bindings
PatKind::Binding {
mutability,
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 {
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
BindingForm::ImplicitSelf(*kind),
))))
} else {
let binding_mode = ty::BindingMode::BindByValue(mutability);
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
VarBindingForm {
binding_mode,
opt_ty_info,
opt_match_place: Some((Some(place), span)),
pat_span: span,
},
)))))
};
self.var_indices.insert(var, LocalsForNode::One(local));
}
_ => {
scope = self.declare_bindings(
scope,
expr.span,
&pattern,
matches::ArmHasGuard(false),
Some((Some(&place), span)),
);
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.
Expand Down
23 changes: 11 additions & 12 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,23 +256,22 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
}
PatKind::Binding { mode: BindingMode::ByRef(borrow_kind), ty, .. } => {
if self.inside_adt {
if let ty::Ref(_, ty, _) = ty.kind() {
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 {
let ty::Ref(_, ty, _) = ty.kind() else {
span_bug!(
pat.span,
"BindingMode::ByRef in pattern, but found non-reference type {}",
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);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,8 @@ impl<'a> Parser<'a> {
[IdentLike(_), Punct('+' | '-')] |
// 1e+2 | 1e-2
[IdentLike(_), Punct('+' | '-'), IdentLike(_)] |
// 1.2e+ | 1.2e-
[IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-')] |
// 1.2e+3 | 1.2e-3
[IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-'), IdentLike(_)] => {
// See the FIXME about `TokenCursor` above.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ impl<'a> Parser<'a> {
// Ensure the user doesn't receive unhelpful unexpected token errors
self.bump();
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);
Expand Down
51 changes: 31 additions & 20 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,12 +341,12 @@ impl<T: ?Sized> Rc<T> {
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 }
}

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)) }
}
}

Expand All @@ -367,9 +367,11 @@ impl<T> Rc<T> {
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
Self::from_inner(
Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
)
unsafe {
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
Expand Down Expand Up @@ -420,16 +422,16 @@ impl<T> Rc<T> {
// otherwise.
let data = data_fn(&weak);

unsafe {
let strong = unsafe {
let inner = init_ptr.as_ptr();
ptr::write(ptr::addr_of_mut!((*inner).value), data);

let prev_value = (*inner).strong.get();
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
(*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,
// so don't run the destructor for our old weak reference.
Expand Down Expand Up @@ -521,10 +523,12 @@ impl<T> Rc<T> {
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
Ok(Self::from_inner(
Box::leak(Box::try_new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })?)
.into(),
))
unsafe {
Ok(Self::from_inner(
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
Expand Down Expand Up @@ -746,7 +750,7 @@ impl<T> Rc<mem::MaybeUninit<T>> {
#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
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()) }
}
}

Expand Down Expand Up @@ -1214,9 +1218,11 @@ impl Rc<dyn Any> {
/// ```
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
if (*self).is::<T>() {
let ptr = self.ptr.cast::<RcBox<T>>();
forget(self);
Ok(Rc::from_inner(ptr))
unsafe {
let ptr = self.ptr.cast::<RcBox<T>>();
forget(self);
Ok(Rc::from_inner(ptr))
}
} else {
Err(self)
}
Expand Down Expand Up @@ -1489,8 +1495,10 @@ impl<T: ?Sized> Clone for Rc<T> {
/// ```
#[inline]
fn clone(&self) -> Rc<T> {
self.inner().inc_strong();
Self::from_inner(self.ptr)
unsafe {
self.inner().inc_strong();
Self::from_inner(self.ptr)
}
}
}

Expand Down Expand Up @@ -2245,11 +2253,14 @@ impl<T: ?Sized> Weak<T> {
#[stable(feature = "rc_weak", since = "1.4.0")]
pub fn upgrade(&self) -> Option<Rc<T>> {
let inner = self.inner()?;

if inner.strong() == 0 {
None
} else {
inner.inc_strong();
Some(Rc::from_inner(self.ptr))
unsafe {
inner.inc_strong();
Some(Rc::from_inner(self.ptr))
}
}
}

Expand Down
Loading

0 comments on commit 5bc9807

Please sign in to comment.