Skip to content

Commit 33d5875

Browse files
committed
Auto merge of #67326 - Centril:rollup-sdv2jlj, r=Centril
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
2 parents a605441 + 6b0d4b4 commit 33d5875

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+144
-104
lines changed

Diff for: Cargo.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ dependencies = [
338338

339339
[[package]]
340340
name = "cargo-platform"
341-
version = "0.1.0"
341+
version = "0.1.1"
342342
dependencies = [
343343
"serde",
344344
]

Diff for: src/doc/nomicon

Diff for: src/liballoc/rc.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ impl<T: ?Sized> Weak<T> {
18361836
/// If `self` was created using [`Weak::new`], this will return 0.
18371837
///
18381838
/// [`Weak::new`]: #method.new
1839-
#[unstable(feature = "weak_counts", issue = "57977")]
1839+
#[stable(feature = "weak_counts", since = "1.41.0")]
18401840
pub fn strong_count(&self) -> usize {
18411841
if let Some(inner) = self.inner() {
18421842
inner.strong()
@@ -1847,20 +1847,16 @@ impl<T: ?Sized> Weak<T> {
18471847

18481848
/// Gets the number of `Weak` pointers pointing to this allocation.
18491849
///
1850-
/// If `self` was created using [`Weak::new`], this will return `None`. If
1851-
/// not, the returned value is at least 1, since `self` still points to the
1852-
/// allocation.
1853-
///
1854-
/// [`Weak::new`]: #method.new
1855-
#[unstable(feature = "weak_counts", issue = "57977")]
1856-
pub fn weak_count(&self) -> Option<usize> {
1850+
/// If no strong pointers remain, this will return zero.
1851+
#[stable(feature = "weak_counts", since = "1.41.0")]
1852+
pub fn weak_count(&self) -> usize {
18571853
self.inner().map(|inner| {
18581854
if inner.strong() > 0 {
18591855
inner.weak() - 1 // subtract the implicit weak ptr
18601856
} else {
1861-
inner.weak()
1857+
0
18621858
}
1863-
})
1859+
}).unwrap_or(0)
18641860
}
18651861

18661862
/// Returns `None` when the pointer is dangling and there is no allocated `RcBox`

Diff for: src/liballoc/rc/tests.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,28 @@ fn test_weak_count() {
114114

115115
#[test]
116116
fn weak_counts() {
117-
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
117+
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
118118
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
119119

120120
let a = Rc::new(0);
121121
let w = Rc::downgrade(&a);
122122
assert_eq!(Weak::strong_count(&w), 1);
123-
assert_eq!(Weak::weak_count(&w), Some(1));
123+
assert_eq!(Weak::weak_count(&w), 1);
124124
let w2 = w.clone();
125125
assert_eq!(Weak::strong_count(&w), 1);
126-
assert_eq!(Weak::weak_count(&w), Some(2));
126+
assert_eq!(Weak::weak_count(&w), 2);
127127
assert_eq!(Weak::strong_count(&w2), 1);
128-
assert_eq!(Weak::weak_count(&w2), Some(2));
128+
assert_eq!(Weak::weak_count(&w2), 2);
129129
drop(w);
130130
assert_eq!(Weak::strong_count(&w2), 1);
131-
assert_eq!(Weak::weak_count(&w2), Some(1));
131+
assert_eq!(Weak::weak_count(&w2), 1);
132132
let a2 = a.clone();
133133
assert_eq!(Weak::strong_count(&w2), 2);
134-
assert_eq!(Weak::weak_count(&w2), Some(1));
134+
assert_eq!(Weak::weak_count(&w2), 1);
135135
drop(a2);
136136
drop(a);
137137
assert_eq!(Weak::strong_count(&w2), 0);
138-
assert_eq!(Weak::weak_count(&w2), Some(1));
138+
assert_eq!(Weak::weak_count(&w2), 0);
139139
drop(w2);
140140
}
141141

Diff for: src/liballoc/sync.rs

+15-25
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::sync::atomic;
1212
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
1313
use core::borrow;
1414
use core::fmt;
15-
use core::cmp::{self, Ordering};
15+
use core::cmp::Ordering;
1616
use core::iter;
1717
use core::intrinsics::abort;
1818
use core::mem::{self, align_of, align_of_val, size_of_val};
@@ -1529,7 +1529,7 @@ impl<T: ?Sized> Weak<T> {
15291529
/// If `self` was created using [`Weak::new`], this will return 0.
15301530
///
15311531
/// [`Weak::new`]: #method.new
1532-
#[unstable(feature = "weak_counts", issue = "57977")]
1532+
#[stable(feature = "weak_counts", since = "1.41.0")]
15331533
pub fn strong_count(&self) -> usize {
15341534
if let Some(inner) = self.inner() {
15351535
inner.strong.load(SeqCst)
@@ -1541,9 +1541,8 @@ impl<T: ?Sized> Weak<T> {
15411541
/// Gets an approximation of the number of `Weak` pointers pointing to this
15421542
/// allocation.
15431543
///
1544-
/// If `self` was created using [`Weak::new`], this will return 0. If not,
1545-
/// the returned value is at least 1, since `self` still points to the
1546-
/// allocation.
1544+
/// If `self` was created using [`Weak::new`], or if there are no remaining
1545+
/// strong pointers, this will return 0.
15471546
///
15481547
/// # Accuracy
15491548
///
@@ -1552,31 +1551,22 @@ impl<T: ?Sized> Weak<T> {
15521551
/// `Weak`s pointing to the same allocation.
15531552
///
15541553
/// [`Weak::new`]: #method.new
1555-
#[unstable(feature = "weak_counts", issue = "57977")]
1556-
pub fn weak_count(&self) -> Option<usize> {
1557-
// Due to the implicit weak pointer added when any strong pointers are
1558-
// around, we cannot implement `weak_count` correctly since it
1559-
// necessarily requires accessing the strong count and weak count in an
1560-
// unsynchronized fashion. So this version is a bit racy.
1554+
#[stable(feature = "weak_counts", since = "1.41.0")]
1555+
pub fn weak_count(&self) -> usize {
15611556
self.inner().map(|inner| {
1562-
let strong = inner.strong.load(SeqCst);
15631557
let weak = inner.weak.load(SeqCst);
1558+
let strong = inner.strong.load(SeqCst);
15641559
if strong == 0 {
1565-
// If the last `Arc` has *just* been dropped, it might not yet
1566-
// have removed the implicit weak count, so the value we get
1567-
// here might be 1 too high.
1568-
weak
1560+
0
15691561
} else {
1570-
// As long as there's still at least 1 `Arc` around, subtract
1571-
// the implicit weak pointer.
1572-
// Note that the last `Arc` might get dropped between the 2
1573-
// loads we do above, removing the implicit weak pointer. This
1574-
// means that the value might be 1 too low here. In order to not
1575-
// return 0 here (which would happen if we're the only weak
1576-
// pointer), we guard against that specifically.
1577-
cmp::max(1, weak - 1)
1562+
// Since we observed that there was at least one strong pointer
1563+
// after reading the weak count, we know that the implicit weak
1564+
// reference (present whenever any strong references are alive)
1565+
// was still around when we observed the weak count, and can
1566+
// therefore safely subtract it.
1567+
weak - 1
15781568
}
1579-
})
1569+
}).unwrap_or(0)
15801570
}
15811571

15821572
/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,

Diff for: src/liballoc/sync/tests.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,28 @@ fn test_arc_get_mut() {
6262

6363
#[test]
6464
fn weak_counts() {
65-
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
65+
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
6666
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
6767

6868
let a = Arc::new(0);
6969
let w = Arc::downgrade(&a);
7070
assert_eq!(Weak::strong_count(&w), 1);
71-
assert_eq!(Weak::weak_count(&w), Some(1));
71+
assert_eq!(Weak::weak_count(&w), 1);
7272
let w2 = w.clone();
7373
assert_eq!(Weak::strong_count(&w), 1);
74-
assert_eq!(Weak::weak_count(&w), Some(2));
74+
assert_eq!(Weak::weak_count(&w), 2);
7575
assert_eq!(Weak::strong_count(&w2), 1);
76-
assert_eq!(Weak::weak_count(&w2), Some(2));
76+
assert_eq!(Weak::weak_count(&w2), 2);
7777
drop(w);
7878
assert_eq!(Weak::strong_count(&w2), 1);
79-
assert_eq!(Weak::weak_count(&w2), Some(1));
79+
assert_eq!(Weak::weak_count(&w2), 1);
8080
let a2 = a.clone();
8181
assert_eq!(Weak::strong_count(&w2), 2);
82-
assert_eq!(Weak::weak_count(&w2), Some(1));
82+
assert_eq!(Weak::weak_count(&w2), 1);
8383
drop(a2);
8484
drop(a);
8585
assert_eq!(Weak::strong_count(&w2), 0);
86-
assert_eq!(Weak::weak_count(&w2), Some(1));
86+
assert_eq!(Weak::weak_count(&w2), 0);
8787
drop(w2);
8888
}
8989

Diff for: src/libcore/any.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
476476
///
477477
/// This is intended for diagnostic use. The exact contents and format of the
478478
/// string are not specified, other than being a best-effort description of the
479-
/// type. For example, `type_name_of::<Option<String>>(None)` could return the
479+
/// type. For example, `type_name_of::<Option<String>>(None)` could return
480480
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
481481
/// `"foobar"`. In addition, the output may change between versions of the
482482
/// compiler.

Diff for: src/libcore/result.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -520,15 +520,14 @@ impl<T, E> Result<T, E> {
520520
/// # Examples
521521
///
522522
/// ```
523-
/// #![feature(result_map_or)]
524523
/// let x: Result<_, &str> = Ok("foo");
525524
/// assert_eq!(x.map_or(42, |v| v.len()), 3);
526525
///
527526
/// let x: Result<&str, _> = Err("bar");
528527
/// assert_eq!(x.map_or(42, |v| v.len()), 42);
529528
/// ```
530529
#[inline]
531-
#[unstable(feature = "result_map_or", issue = "66293")]
530+
#[stable(feature = "result_map_or", since = "1.41.0")]
532531
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
533532
match self {
534533
Ok(t) => f(t),

Diff for: src/librustc/infer/error_reporting/need_type_info.rs

+65-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::hir::{self, Body, FunctionRetTy, Expr, ExprKind, HirId, Local, Pat};
33
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
44
use crate::infer::InferCtxt;
55
use crate::infer::type_variable::TypeVariableOriginKind;
6-
use crate::ty::{self, Ty, Infer, TyVar};
6+
use crate::ty::{self, Ty, Infer, TyVar, DefIdTree};
77
use crate::ty::print::Print;
88
use syntax::source_map::DesugaringKind;
99
use syntax::symbol::kw;
@@ -117,6 +117,8 @@ fn closure_return_type_suggestion(
117117
descr: &str,
118118
name: &str,
119119
ret: &str,
120+
parent_name: Option<String>,
121+
parent_descr: Option<&str>,
120122
) {
121123
let (arrow, post) = match output {
122124
FunctionRetTy::DefaultReturn(_) => ("-> ", " "),
@@ -138,7 +140,12 @@ fn closure_return_type_suggestion(
138140
suggestion,
139141
Applicability::HasPlaceholders,
140142
);
141-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
143+
err.span_label(span, InferCtxt::missing_type_msg(
144+
&name,
145+
&descr,
146+
parent_name,
147+
parent_descr
148+
));
142149
}
143150

144151
/// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -177,16 +184,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
177184
&self,
178185
ty: Ty<'tcx>,
179186
highlight: Option<ty::print::RegionHighlightMode>,
180-
) -> (String, Option<Span>, Cow<'static, str>) {
187+
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
181188
if let ty::Infer(ty::TyVar(ty_vid)) = ty.kind {
182189
let ty_vars = self.type_variables.borrow();
183190
let var_origin = ty_vars.var_origin(ty_vid);
184-
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
191+
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
192+
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
193+
let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id {
194+
let parent_name = self.tcx.def_key(parent_def_id).disambiguated_data.data
195+
.get_opt_name().map(|parent_symbol| parent_symbol.to_string());
196+
197+
let type_parent_desc = self.tcx.def_kind(parent_def_id)
198+
.map(|parent_def_kind| parent_def_kind.descr(parent_def_id));
199+
200+
(parent_name, type_parent_desc)
201+
} else {
202+
(None, None)
203+
};
204+
185205
if name != kw::SelfUpper {
186206
return (
187207
name.to_string(),
188208
Some(var_origin.span),
189209
"type parameter".into(),
210+
parent_name,
211+
parent_desc,
190212
);
191213
}
192214
}
@@ -198,7 +220,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
198220
printer.region_highlight_mode = highlight;
199221
}
200222
let _ = ty.print(printer);
201-
(s, None, ty.prefix_string())
223+
(s, None, ty.prefix_string(), None, None)
202224
}
203225

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

214237
let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
215238
let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -218,7 +241,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
218241
let ty_vars = self.type_variables.borrow();
219242
let getter = move |ty_vid| {
220243
let var_origin = ty_vars.var_origin(ty_vid);
221-
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
244+
if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind {
222245
return Some(name.to_string());
223246
}
224247
None
@@ -317,6 +340,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
317340
&descr,
318341
&name,
319342
&ret,
343+
parent_name,
344+
parent_descr,
320345
);
321346
// We don't want to give the other suggestions when the problem is the
322347
// closure return type.
@@ -433,8 +458,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
433458
if !err.span.span_labels().iter().any(|span_label| {
434459
span_label.label.is_some() && span_label.span == span
435460
}) && local_visitor.found_arg_pattern.is_none()
436-
{ // Avoid multiple labels pointing at `span`.
437-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
461+
{
462+
// Avoid multiple labels pointing at `span`.
463+
err.span_label(
464+
span,
465+
InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)
466+
);
438467
}
439468

440469
err
@@ -496,19 +525,42 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
496525
ty: Ty<'tcx>,
497526
) -> DiagnosticBuilder<'tcx> {
498527
let ty = self.resolve_vars_if_possible(&ty);
499-
let (name, _, descr) = self.extract_type_name(&ty, None);
528+
let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
529+
500530
let mut err = struct_span_err!(
501531
self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
502532
);
503-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
533+
err.span_label(span, InferCtxt::missing_type_msg(
534+
&name,
535+
&descr,
536+
parent_name,
537+
parent_descr
538+
));
504539
err
505540
}
506541

507-
fn missing_type_msg(type_name: &str, descr: &str) -> Cow<'static, str>{
542+
fn missing_type_msg(
543+
type_name: &str,
544+
descr: &str,
545+
parent_name: Option<String>,
546+
parent_descr: Option<&str>,
547+
) -> Cow<'static, str> {
508548
if type_name == "_" {
509549
"cannot infer type".into()
510550
} else {
511-
format!("cannot infer type for {} `{}`", descr, type_name).into()
551+
let parent_desc = if let Some(parent_name) = parent_name {
552+
let parent_type_descr = if let Some(parent_descr) = parent_descr {
553+
format!(" the {}", parent_descr)
554+
} else {
555+
"".into()
556+
};
557+
558+
format!(" declared on{} `{}`", parent_type_descr, parent_name)
559+
} else {
560+
"".to_string()
561+
};
562+
563+
format!("cannot infer type for {} `{}`{}", descr, type_name, parent_desc).into()
512564
}
513565
}
514566
}

0 commit comments

Comments
 (0)