Skip to content

Commit

Permalink
Auto merge of #67326 - Centril:rollup-sdv2jlj, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #65778 (Stabilize `std::{rc,sync}::Weak::{weak_count, strong_count}`)
 - #66570 (stabilize Result::map_or)
 - #67206 (Update cargo, books)
 - #67285 (Indicate origin of where type parameter for uninferred types )
 - #67317 (fix type_name_of_val doc comment)
 - #67324 (Fix repetition in matches/mod.rs)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Dec 15, 2019
2 parents a605441 + 6b0d4b4 commit 33d5875
Show file tree
Hide file tree
Showing 44 changed files with 144 additions and 104 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ dependencies = [

[[package]]
name = "cargo-platform"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"serde",
]
Expand Down
2 changes: 1 addition & 1 deletion src/doc/book
2 changes: 1 addition & 1 deletion src/doc/embedded-book
2 changes: 1 addition & 1 deletion src/doc/nomicon
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
16 changes: 6 additions & 10 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ impl<T: ?Sized> Weak<T> {
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong()
Expand All @@ -1847,20 +1847,16 @@ impl<T: ?Sized> Weak<T> {

/// Gets the number of `Weak` pointers pointing to this allocation.
///
/// If `self` was created using [`Weak::new`], this will return `None`. If
/// not, the returned value is at least 1, since `self` still points to the
/// allocation.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
pub fn weak_count(&self) -> Option<usize> {
/// If no strong pointers remain, this will return zero.
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn weak_count(&self) -> usize {
self.inner().map(|inner| {
if inner.strong() > 0 {
inner.weak() - 1 // subtract the implicit weak ptr
} else {
inner.weak()
0
}
})
}).unwrap_or(0)
}

/// Returns `None` when the pointer is dangling and there is no allocated `RcBox`
Expand Down
14 changes: 7 additions & 7 deletions src/liballoc/rc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,28 +114,28 @@ fn test_weak_count() {

#[test]
fn weak_counts() {
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);

let a = Rc::new(0);
let w = Rc::downgrade(&a);
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(1));
assert_eq!(Weak::weak_count(&w), 1);
let w2 = w.clone();
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(2));
assert_eq!(Weak::weak_count(&w), 2);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(2));
assert_eq!(Weak::weak_count(&w2), 2);
drop(w);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
let a2 = a.clone();
assert_eq!(Weak::strong_count(&w2), 2);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
drop(a2);
drop(a);
assert_eq!(Weak::strong_count(&w2), 0);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 0);
drop(w2);
}

Expand Down
40 changes: 15 additions & 25 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::sync::atomic;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use core::borrow;
use core::fmt;
use core::cmp::{self, Ordering};
use core::cmp::Ordering;
use core::iter;
use core::intrinsics::abort;
use core::mem::{self, align_of, align_of_val, size_of_val};
Expand Down Expand Up @@ -1529,7 +1529,7 @@ impl<T: ?Sized> Weak<T> {
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong.load(SeqCst)
Expand All @@ -1541,9 +1541,8 @@ impl<T: ?Sized> Weak<T> {
/// Gets an approximation of the number of `Weak` pointers pointing to this
/// allocation.
///
/// If `self` was created using [`Weak::new`], this will return 0. If not,
/// the returned value is at least 1, since `self` still points to the
/// allocation.
/// If `self` was created using [`Weak::new`], or if there are no remaining
/// strong pointers, this will return 0.
///
/// # Accuracy
///
Expand All @@ -1552,31 +1551,22 @@ impl<T: ?Sized> Weak<T> {
/// `Weak`s pointing to the same allocation.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
pub fn weak_count(&self) -> Option<usize> {
// Due to the implicit weak pointer added when any strong pointers are
// around, we cannot implement `weak_count` correctly since it
// necessarily requires accessing the strong count and weak count in an
// unsynchronized fashion. So this version is a bit racy.
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn weak_count(&self) -> usize {
self.inner().map(|inner| {
let strong = inner.strong.load(SeqCst);
let weak = inner.weak.load(SeqCst);
let strong = inner.strong.load(SeqCst);
if strong == 0 {
// If the last `Arc` has *just* been dropped, it might not yet
// have removed the implicit weak count, so the value we get
// here might be 1 too high.
weak
0
} else {
// As long as there's still at least 1 `Arc` around, subtract
// the implicit weak pointer.
// Note that the last `Arc` might get dropped between the 2
// loads we do above, removing the implicit weak pointer. This
// means that the value might be 1 too low here. In order to not
// return 0 here (which would happen if we're the only weak
// pointer), we guard against that specifically.
cmp::max(1, weak - 1)
// Since we observed that there was at least one strong pointer
// after reading the weak count, we know that the implicit weak
// reference (present whenever any strong references are alive)
// was still around when we observed the weak count, and can
// therefore safely subtract it.
weak - 1
}
})
}).unwrap_or(0)
}

/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
Expand Down
14 changes: 7 additions & 7 deletions src/liballoc/sync/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,28 @@ fn test_arc_get_mut() {

#[test]
fn weak_counts() {
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);

let a = Arc::new(0);
let w = Arc::downgrade(&a);
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(1));
assert_eq!(Weak::weak_count(&w), 1);
let w2 = w.clone();
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(2));
assert_eq!(Weak::weak_count(&w), 2);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(2));
assert_eq!(Weak::weak_count(&w2), 2);
drop(w);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
let a2 = a.clone();
assert_eq!(Weak::strong_count(&w2), 2);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
drop(a2);
drop(a);
assert_eq!(Weak::strong_count(&w2), 0);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 0);
drop(w2);
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
///
/// This is intended for diagnostic use. The exact contents and format of the
/// string are not specified, other than being a best-effort description of the
/// type. For example, `type_name_of::<Option<String>>(None)` could return the
/// type. For example, `type_name_of::<Option<String>>(None)` could return
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
/// `"foobar"`. In addition, the output may change between versions of the
/// compiler.
Expand Down
3 changes: 1 addition & 2 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,15 +520,14 @@ impl<T, E> Result<T, E> {
/// # Examples
///
/// ```
/// #![feature(result_map_or)]
/// let x: Result<_, &str> = Ok("foo");
/// assert_eq!(x.map_or(42, |v| v.len()), 3);
///
/// let x: Result<&str, _> = Err("bar");
/// assert_eq!(x.map_or(42, |v| v.len()), 42);
/// ```
#[inline]
#[unstable(feature = "result_map_or", issue = "66293")]
#[stable(feature = "result_map_or", since = "1.41.0")]
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
match self {
Ok(t) => f(t),
Expand Down
78 changes: 65 additions & 13 deletions src/librustc/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::hir::{self, Body, FunctionRetTy, Expr, ExprKind, HirId, Local, Pat};
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use crate::infer::InferCtxt;
use crate::infer::type_variable::TypeVariableOriginKind;
use crate::ty::{self, Ty, Infer, TyVar};
use crate::ty::{self, Ty, Infer, TyVar, DefIdTree};
use crate::ty::print::Print;
use syntax::source_map::DesugaringKind;
use syntax::symbol::kw;
Expand Down Expand Up @@ -117,6 +117,8 @@ fn closure_return_type_suggestion(
descr: &str,
name: &str,
ret: &str,
parent_name: Option<String>,
parent_descr: Option<&str>,
) {
let (arrow, post) = match output {
FunctionRetTy::DefaultReturn(_) => ("-> ", " "),
Expand All @@ -138,7 +140,12 @@ fn closure_return_type_suggestion(
suggestion,
Applicability::HasPlaceholders,
);
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
err.span_label(span, InferCtxt::missing_type_msg(
&name,
&descr,
parent_name,
parent_descr
));
}

/// Given a closure signature, return a `String` containing a list of all its argument types.
Expand Down Expand Up @@ -177,16 +184,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&self,
ty: Ty<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
) -> (String, Option<Span>, Cow<'static, str>) {
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
if let ty::Infer(ty::TyVar(ty_vid)) = ty.kind {
let ty_vars = self.type_variables.borrow();
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id {
let parent_name = self.tcx.def_key(parent_def_id).disambiguated_data.data
.get_opt_name().map(|parent_symbol| parent_symbol.to_string());

let type_parent_desc = self.tcx.def_kind(parent_def_id)
.map(|parent_def_kind| parent_def_kind.descr(parent_def_id));

(parent_name, type_parent_desc)
} else {
(None, None)
};

if name != kw::SelfUpper {
return (
name.to_string(),
Some(var_origin.span),
"type parameter".into(),
parent_name,
parent_desc,
);
}
}
Expand All @@ -198,7 +220,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
printer.region_highlight_mode = highlight;
}
let _ = ty.print(printer);
(s, None, ty.prefix_string())
(s, None, ty.prefix_string(), None, None)
}

pub fn need_type_info_err(
Expand All @@ -209,7 +231,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty);
let (name, name_sp, descr) = self.extract_type_name(&ty, None);
let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);


let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
let ty_to_string = |ty: Ty<'tcx>| -> String {
Expand All @@ -218,7 +241,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let ty_vars = self.type_variables.borrow();
let getter = move |ty_vid| {
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind {
return Some(name.to_string());
}
None
Expand Down Expand Up @@ -317,6 +340,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&descr,
&name,
&ret,
parent_name,
parent_descr,
);
// We don't want to give the other suggestions when the problem is the
// closure return type.
Expand Down Expand Up @@ -433,8 +458,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if !err.span.span_labels().iter().any(|span_label| {
span_label.label.is_some() && span_label.span == span
}) && local_visitor.found_arg_pattern.is_none()
{ // Avoid multiple labels pointing at `span`.
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
{
// Avoid multiple labels pointing at `span`.
err.span_label(
span,
InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)
);
}

err
Expand Down Expand Up @@ -496,19 +525,42 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty);
let (name, _, descr) = self.extract_type_name(&ty, None);
let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);

let mut err = struct_span_err!(
self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
);
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
err.span_label(span, InferCtxt::missing_type_msg(
&name,
&descr,
parent_name,
parent_descr
));
err
}

fn missing_type_msg(type_name: &str, descr: &str) -> Cow<'static, str>{
fn missing_type_msg(
type_name: &str,
descr: &str,
parent_name: Option<String>,
parent_descr: Option<&str>,
) -> Cow<'static, str> {
if type_name == "_" {
"cannot infer type".into()
} else {
format!("cannot infer type for {} `{}`", descr, type_name).into()
let parent_desc = if let Some(parent_name) = parent_name {
let parent_type_descr = if let Some(parent_descr) = parent_descr {
format!(" the {}", parent_descr)
} else {
"".into()
};

format!(" declared on{} `{}`", parent_type_descr, parent_name)
} else {
"".to_string()
};

format!("cannot infer type for {} `{}`{}", descr, type_name, parent_desc).into()
}
}
}
Loading

0 comments on commit 33d5875

Please sign in to comment.