Skip to content

Rollup of 6 pull requests #91093

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 14 commits into from
Nov 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
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