Skip to content

Rollup of 7 pull requests #72638

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

Closed
wants to merge 15 commits into from
Closed
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,12 +867,10 @@ impl<T: ?Sized> Arc<T> {
unsafe fn drop_slow(&mut self) {
// Destroy the data at this time, even though we may not free the box
// allocation itself (there may still be weak pointers lying around).
ptr::drop_in_place(&mut self.ptr.as_mut().data);
ptr::drop_in_place(Self::get_mut_unchecked(self));

if self.inner().weak.fetch_sub(1, Release) == 1 {
acquire!(self.inner().weak);
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
}
// Drop the weak ref collectively held by all strong references
drop(Weak { ptr: self.ptr });
}

#[inline]
Expand Down Expand Up @@ -1204,7 +1202,7 @@ impl<T: Clone> Arc<T> {

// As with `get_mut()`, the unsafety is ok because our reference was
// either unique to begin with, or became one upon cloning the contents.
unsafe { &mut this.ptr.as_mut().data }
unsafe { Self::get_mut_unchecked(this) }
}
}

Expand Down Expand Up @@ -1280,7 +1278,9 @@ impl<T: ?Sized> Arc<T> {
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
&mut this.ptr.as_mut().data
// We are careful to *not* create a reference covering the "count" fields, as
// this would alias with concurrent access to the reference counts (e.g. by `Weak`).
&mut (*this.ptr.as_ptr()).data
}

/// Determine whether this is the unique reference (including weak refs) to
Expand Down Expand Up @@ -1571,6 +1571,13 @@ impl<T> Weak<T> {
}
}

/// Helper type to allow accessing the reference counts without
/// making any assertions about the data field.
struct WeakInner<'a> {
weak: &'a atomic::AtomicUsize,
strong: &'a atomic::AtomicUsize,
}

impl<T: ?Sized> Weak<T> {
/// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying
/// dropping of the inner value if successful.
Expand Down Expand Up @@ -1678,8 +1685,18 @@ impl<T: ?Sized> Weak<T> {
/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
/// (i.e., when this `Weak` was created by `Weak::new`).
#[inline]
fn inner(&self) -> Option<&ArcInner<T>> {
if is_dangling(self.ptr) { None } else { Some(unsafe { self.ptr.as_ref() }) }
fn inner(&self) -> Option<WeakInner<'_>> {
if is_dangling(self.ptr) {
None
} else {
// We are careful to *not* create a reference covering the "data" field, as
// the field may be mutated concurrently (for example, if the last `Arc`
// is dropped, the data field will be dropped in-place).
Some(unsafe {
let ptr = self.ptr.as_ptr();
WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak }
})
}
}

/// Returns `true` if the two `Weak`s point to the same allocation (similar to
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,11 +849,11 @@ impl<T: ?Sized> RefCell<T> {
/// ```
/// use std::cell::RefCell;
///
/// let c = RefCell::new(5);
/// let c = RefCell::new("hello".to_owned());
///
/// *c.borrow_mut() = 7;
/// *c.borrow_mut() = "bonjour".to_owned();
///
/// assert_eq!(*c.borrow(), 7);
/// assert_eq!(&*c.borrow(), "bonjour");
/// ```
///
/// An example of panic:
Expand Down
26 changes: 26 additions & 0 deletions src/libcore/iter/traits/double_ended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,32 @@ pub trait DoubleEndedIterator: Iterator {
/// assert_eq!(None, iter.next());
/// assert_eq!(None, iter.next_back());
/// ```
///
/// # Remarks
///
/// The elements yielded by `DoubleEndedIterator`'s methods may differ from
/// the ones yielded by `Iterator`'s methods:
///
/// ```
/// let vec = vec![(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b')];
/// let uniq_by_fst_comp = || {
/// let mut seen = std::collections::HashSet::new();
/// vec.iter().copied().filter(move |x| seen.insert(x.0))
/// };
///
/// assert_eq!(uniq_by_fst_comp().last(), Some((2, 'a')));
/// assert_eq!(uniq_by_fst_comp().next_back(), Some((2, 'b')));
///
/// assert_eq!(
/// uniq_by_fst_comp().fold(vec![], |mut v, x| {v.push(x); v}),
/// vec![(1, 'a'), (2, 'a')]
/// );
/// assert_eq!(
/// uniq_by_fst_comp().rfold(vec![], |mut v, x| {v.push(x); v}),
/// vec![(2, 'b'), (1, 'c')]
/// );
/// ```
///
#[stable(feature = "rust1", since = "1.0.0")]
fn next_back(&mut self) -> Option<Self::Item>;

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_middle/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,8 @@ impl<'tcx> TraitRef<'tcx> {
pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;

impl<'tcx> PolyTraitRef<'tcx> {
pub fn self_ty(&self) -> Ty<'tcx> {
self.skip_binder().self_ty()
pub fn self_ty(&self) -> Binder<Ty<'tcx>> {
self.map_bound_ref(|tr| tr.self_ty())
}

pub fn def_id(&self) -> DefId {
Expand Down
13 changes: 13 additions & 0 deletions src/librustc_parse/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,19 @@ impl<'a> Parser<'a> {
return self.expect(&token::Semi).map(drop);
} else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) {
// The current token is in the same line as the prior token, not recoverable.
} else if [token::Comma, token::Colon].contains(&self.token.kind)
&& &self.prev_token.kind == &token::CloseDelim(token::Paren)
{
// Likely typo: The current token is on a new line and is expected to be
// `.`, `;`, `?`, or an operator after a close delimiter token.
//
// let a = std::process::Command::new("echo")
// .arg("1")
// ,arg("2")
// ^
// https://github.com/rust-lang/rust/issues/72253
self.expect(&token::Semi)?;
return Ok(());
} else if self.look_ahead(1, |t| {
t == &token::CloseDelim(token::Brace) || t.can_begin_expr() && t.kind != token::Colon
}) && [token::Comma, token::Colon].contains(&self.token.kind)
Expand Down
32 changes: 21 additions & 11 deletions src/librustc_trait_selection/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
(
Some(format!(
"`?` couldn't convert the error to `{}`",
trait_ref.self_ty(),
trait_ref.skip_binder().self_ty(),
)),
Some(
"the question mark operation (`?`) implicitly performs a \
Expand Down Expand Up @@ -339,7 +339,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if let Some(ret_span) = self.return_type_span(obligation) {
err.span_label(
ret_span,
&format!("expected `{}` because of this", trait_ref.self_ty()),
&format!(
"expected `{}` because of this",
trait_ref.skip_binder().self_ty()
),
);
}
}
Expand All @@ -352,7 +355,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
"{}the trait `{}` is not implemented for `{}`",
pre_message,
trait_ref.print_only_trait_path(),
trait_ref.self_ty(),
trait_ref.skip_binder().self_ty(),
)
};

Expand Down Expand Up @@ -642,7 +645,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
return;
}

let found_trait_ty = found_trait_ref.self_ty();
let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() {
Some(ty) => ty,
None => return,
};

let found_did = match found_trait_ty.kind {
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
Expand Down Expand Up @@ -1359,11 +1365,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
) {
let get_trait_impl = |trait_def_id| {
let mut trait_impl = None;
self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| {
if trait_impl.is_none() {
trait_impl = Some(impl_def_id);
}
});
self.tcx.for_each_relevant_impl(
trait_def_id,
trait_ref.skip_binder().self_ty(),
|impl_def_id| {
if trait_impl.is_none() {
trait_impl = Some(impl_def_id);
}
},
);
trait_impl
};
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
Expand Down Expand Up @@ -1434,7 +1444,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
let mut err = match predicate.kind() {
ty::PredicateKind::Trait(ref data, _) => {
let trait_ref = data.to_poly_trait_ref();
let self_ty = trait_ref.self_ty();
let self_ty = trait_ref.skip_binder().self_ty();
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);

if predicate.references_error() {
Expand Down Expand Up @@ -1552,7 +1562,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
}
ty::PredicateKind::Projection(ref data) => {
let trait_ref = data.to_poly_trait_ref(self.tcx);
let self_ty = trait_ref.self_ty();
let self_ty = trait_ref.skip_binder().self_ty();
let ty = data.skip_binder().ty;
if predicate.references_error() {
return;
Expand Down
19 changes: 13 additions & 6 deletions src/librustc_trait_selection/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
body_id: hir::HirId,
) {
let self_ty = trait_ref.self_ty();
let self_ty = trait_ref.skip_binder().self_ty();
let (param_ty, projection) = match &self_ty.kind {
ty::Param(_) => (true, None),
ty::Projection(projection) => (false, Some(projection)),
Expand Down Expand Up @@ -524,7 +524,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
points_at_arg: bool,
) {
let self_ty = trait_ref.self_ty();
let self_ty = match trait_ref.self_ty().no_bound_vars() {
None => return,
Some(ty) => ty,
};

let (def_id, output_ty, callable) = match self_ty.kind {
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
Expand Down Expand Up @@ -829,6 +833,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
span: Span,
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
) {
let is_empty_tuple =
|ty: ty::Binder<Ty<'_>>| ty.skip_binder().kind == ty::Tuple(ty::List::empty());

let hir = self.tcx.hir();
let parent_node = hir.get_parent_node(obligation.cause.body_id);
let node = hir.find(parent_node);
Expand All @@ -840,7 +847,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if let hir::ExprKind::Block(blk, _) = &body.value.kind {
if sig.decl.output.span().overlaps(span)
&& blk.expr.is_none()
&& "()" == &trait_ref.self_ty().to_string()
&& is_empty_tuple(trait_ref.self_ty())
{
// FIXME(estebank): When encountering a method with a trait
// bound not satisfied in the return type with a body that has
Expand Down Expand Up @@ -1271,7 +1278,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ObligationCauseCode::DerivedObligation(derived_obligation)
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
let ty = derived_obligation.parent_trait_ref.self_ty();
let ty = derived_obligation.parent_trait_ref.skip_binder().self_ty();
debug!(
"maybe_note_obligation_cause_for_async_await: \
parent_trait_ref={:?} self_ty.kind={:?}",
Expand Down Expand Up @@ -1911,7 +1918,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {

let impls_future = self.tcx.type_implements_trait((
future_trait,
self_ty,
self_ty.skip_binder(),
ty::List::empty(),
obligation.param_env,
));
Expand All @@ -1927,7 +1934,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let projection_ty = ty::ProjectionTy {
// `T`
substs: self.tcx.mk_substs_trait(
trait_ref.self_ty(),
trait_ref.self_ty().skip_binder(),
self.fresh_substs_for_item(span, item_def_id),
),
// `Future::Output`
Expand Down
11 changes: 0 additions & 11 deletions src/librustc_trait_selection/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,17 +1040,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
if stack.obligation.predicate.references_error() {
// If we encounter a `Error`, we generally prefer the
// most "optimistic" result in response -- that is, the
// one least likely to report downstream errors. But
// because this routine is shared by coherence and by
// trait selection, there isn't an obvious "right" choice
// here in that respect, so we opt to just return
// ambiguity and let the upstream clients sort it out.
return Ok(None);
}

if let Some(conflict) = self.is_knowable(stack) {
debug!("coherence stage: not knowable");
if self.intercrate_ambiguity_causes.is_some() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trait_selection/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
for (p, _) in predicates {
if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
if Some(poly_trait_ref.def_id()) == sized_trait {
types_without_default_bounds.remove(poly_trait_ref.self_ty());
types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder());
continue;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3810,7 +3810,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
expected_vid: ty::TyVid,
) -> bool {
let self_ty = self.shallow_resolve(trait_ref.self_ty());
let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
debug!(
"self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
trait_ref, self_ty, expected_vid
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
WherePredicate::BoundPredicate {
ty: poly_trait_ref.self_ty().clean(cx),
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
bounds: vec![poly_trait_ref.clean(cx)],
}
}
Expand Down Expand Up @@ -755,7 +755,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
let mut projection = None;
let param_idx = (|| {
if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
if let ty::Param(param) = trait_ref.self_ty().kind {
if let ty::Param(param) = trait_ref.skip_binder().self_ty().kind {
return Some(param.index);
}
} else if let Some(outlives) = p.to_opt_type_outlives() {
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/async-await/issue-72590-type-error-sized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Regression test for issue #72590
// Tests that we don't emit a spurious "size cannot be statically determined" error
// edition:2018

struct Foo {
foo: Nonexistent, //~ ERROR cannot find
other: str
}

struct Bar {
test: Missing //~ ERROR cannot find
}

impl Foo {
async fn frob(self) {} //~ ERROR the size
}

impl Bar {
async fn myfn(self) {}
}

fn main() {}
Loading