Skip to content

Commit 582b696

Browse files
committed
Auto merge of rust-lang#94072 - matthiaskrgr:rollup-7uu2286, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#89869 (Add documentation to more `From::from` implementations.) - rust-lang#93479 (Use `optflag` for `--report-time`) - rust-lang#93693 (Suggest deriving required supertraits) - rust-lang#93981 (Fix suggestion to slice if scurtinee is a reference to `Result` or `Option`) - rust-lang#93996 (Do not suggest "is a function" for free variables) - rust-lang#94030 (Correctly mark the span of captured arguments in `format_args!()`) - rust-lang#94031 ([diagnostics] Add mentions to `Copy` types being valid for `union` fields) - rust-lang#94064 (Update dist-x86_64-musl to Ubuntu 20.04) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 930fc4f + aa83189 commit 582b696

File tree

62 files changed

+545
-189
lines changed

Some content is hidden

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

62 files changed

+545
-189
lines changed

compiler/rustc_builtin_macros/src/asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
700700
Some(idx)
701701
}
702702
}
703-
parse::ArgumentNamed(name) => match args.named_args.get(&name) {
703+
parse::ArgumentNamed(name, span) => match args.named_args.get(&name) {
704704
Some(&idx) => Some(idx),
705705
None => {
706706
let msg = format!("there is no argument named `{}`", name);
707-
ecx.struct_span_err(span, &msg).emit();
707+
ecx.struct_span_err(template_span.from_inner(span), &msg).emit();
708708
None
709709
}
710710
},

compiler/rustc_builtin_macros/src/format.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
1111
use rustc_expand::base::{self, *};
1212
use rustc_parse_format as parse;
1313
use rustc_span::symbol::{sym, Ident, Symbol};
14-
use rustc_span::{MultiSpan, Span};
14+
use rustc_span::{InnerSpan, MultiSpan, Span};
1515
use smallvec::SmallVec;
1616

1717
use std::borrow::Cow;
@@ -26,7 +26,7 @@ enum ArgumentType {
2626
enum Position {
2727
Exact(usize),
2828
Capture(usize),
29-
Named(Symbol),
29+
Named(Symbol, InnerSpan),
3030
}
3131

3232
struct Context<'a, 'b> {
@@ -247,13 +247,13 @@ impl<'a, 'b> Context<'a, 'b> {
247247
match *p {
248248
parse::String(_) => {}
249249
parse::NextArgument(ref mut arg) => {
250-
if let parse::ArgumentNamed(s) = arg.position {
250+
if let parse::ArgumentNamed(s, _) = arg.position {
251251
arg.position = parse::ArgumentIs(lookup(s));
252252
}
253-
if let parse::CountIsName(s) = arg.format.width {
253+
if let parse::CountIsName(s, _) = arg.format.width {
254254
arg.format.width = parse::CountIsParam(lookup(s));
255255
}
256-
if let parse::CountIsName(s) = arg.format.precision {
256+
if let parse::CountIsName(s, _) = arg.format.precision {
257257
arg.format.precision = parse::CountIsParam(lookup(s));
258258
}
259259
}
@@ -276,7 +276,7 @@ impl<'a, 'b> Context<'a, 'b> {
276276
// it's written second, so it should come after width/precision.
277277
let pos = match arg.position {
278278
parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => Exact(i),
279-
parse::ArgumentNamed(s) => Named(s),
279+
parse::ArgumentNamed(s, span) => Named(s, span),
280280
};
281281

282282
let ty = Placeholder(match arg.format.ty {
@@ -346,8 +346,8 @@ impl<'a, 'b> Context<'a, 'b> {
346346
parse::CountIsParam(i) => {
347347
self.verify_arg_type(Exact(i), Count);
348348
}
349-
parse::CountIsName(s) => {
350-
self.verify_arg_type(Named(s), Count);
349+
parse::CountIsName(s, span) => {
350+
self.verify_arg_type(Named(s, span), Count);
351351
}
352352
}
353353
}
@@ -533,7 +533,7 @@ impl<'a, 'b> Context<'a, 'b> {
533533
}
534534
}
535535

536-
Named(name) => {
536+
Named(name, span) => {
537537
match self.names.get(&name) {
538538
Some(&idx) => {
539539
// Treat as positional arg.
@@ -548,7 +548,7 @@ impl<'a, 'b> Context<'a, 'b> {
548548
self.arg_types.push(Vec::new());
549549
self.arg_unique_types.push(Vec::new());
550550
let span = if self.is_literal {
551-
*self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
551+
self.fmtsp.from_inner(span)
552552
} else {
553553
self.fmtsp
554554
};
@@ -559,7 +559,7 @@ impl<'a, 'b> Context<'a, 'b> {
559559
} else {
560560
let msg = format!("there is no argument named `{}`", name);
561561
let sp = if self.is_literal {
562-
*self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
562+
self.fmtsp.from_inner(span)
563563
} else {
564564
self.fmtsp
565565
};
@@ -629,7 +629,7 @@ impl<'a, 'b> Context<'a, 'b> {
629629
}
630630
parse::CountImplied => count(sym::Implied, None),
631631
// should never be the case, names are already resolved
632-
parse::CountIsName(_) => panic!("should never happen"),
632+
parse::CountIsName(..) => panic!("should never happen"),
633633
}
634634
}
635635

@@ -676,7 +676,7 @@ impl<'a, 'b> Context<'a, 'b> {
676676

677677
// should never be the case, because names are already
678678
// resolved.
679-
parse::ArgumentNamed(_) => panic!("should never happen"),
679+
parse::ArgumentNamed(..) => panic!("should never happen"),
680680
}
681681
};
682682

compiler/rustc_parse_format/src/lib.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub enum Position {
9595
/// The argument is located at a specific index given in the format
9696
ArgumentIs(usize),
9797
/// The argument has a name.
98-
ArgumentNamed(Symbol),
98+
ArgumentNamed(Symbol, InnerSpan),
9999
}
100100

101101
impl Position {
@@ -147,7 +147,7 @@ pub enum Count {
147147
/// The count is specified explicitly.
148148
CountIs(usize),
149149
/// The count is specified by the argument with the given name.
150-
CountIsName(Symbol),
150+
CountIsName(Symbol, InnerSpan),
151151
/// The count is specified by the argument at the given index.
152152
CountIsParam(usize),
153153
/// The count is implied and cannot be explicitly specified.
@@ -494,8 +494,11 @@ impl<'a> Parser<'a> {
494494
Some(ArgumentIs(i))
495495
} else {
496496
match self.cur.peek() {
497-
Some(&(_, c)) if rustc_lexer::is_id_start(c) => {
498-
Some(ArgumentNamed(Symbol::intern(self.word())))
497+
Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
498+
let word = self.word();
499+
let end = start + word.len();
500+
let span = self.to_span_index(start).to(self.to_span_index(end));
501+
Some(ArgumentNamed(Symbol::intern(word), span))
499502
}
500503

501504
// This is an `ArgumentNext`.
@@ -662,8 +665,9 @@ impl<'a> Parser<'a> {
662665
if word.is_empty() {
663666
self.cur = tmp;
664667
(CountImplied, None)
665-
} else if self.consume('$') {
666-
(CountIsName(Symbol::intern(word)), None)
668+
} else if let Some(end) = self.consume_pos('$') {
669+
let span = self.to_span_index(start + 1).to(self.to_span_index(end));
670+
(CountIsName(Symbol::intern(word), span), None)
667671
} else {
668672
self.cur = tmp;
669673
(CountImplied, None)

compiler/rustc_parse_format/src/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ fn format_counts() {
221221
fill: None,
222222
align: AlignUnknown,
223223
flags: 0,
224-
precision: CountIsName(Symbol::intern("b")),
225-
width: CountIsName(Symbol::intern("a")),
224+
precision: CountIsName(Symbol::intern("b"), InnerSpan::new(6, 7)),
225+
width: CountIsName(Symbol::intern("a"), InnerSpan::new(4, 4)),
226226
precision_span: None,
227227
width_span: None,
228228
ty: "?",

compiler/rustc_trait_selection/src/traits/on_unimplemented.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -309,23 +309,23 @@ impl<'tcx> OnUnimplementedFormatString {
309309
Piece::String(_) => (), // Normal string, no need to check it
310310
Piece::NextArgument(a) => match a.position {
311311
// `{Self}` is allowed
312-
Position::ArgumentNamed(s) if s == kw::SelfUpper => (),
312+
Position::ArgumentNamed(s, _) if s == kw::SelfUpper => (),
313313
// `{ThisTraitsName}` is allowed
314-
Position::ArgumentNamed(s) if s == name => (),
314+
Position::ArgumentNamed(s, _) if s == name => (),
315315
// `{from_method}` is allowed
316-
Position::ArgumentNamed(s) if s == sym::from_method => (),
316+
Position::ArgumentNamed(s, _) if s == sym::from_method => (),
317317
// `{from_desugaring}` is allowed
318-
Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
318+
Position::ArgumentNamed(s, _) if s == sym::from_desugaring => (),
319319
// `{ItemContext}` is allowed
320-
Position::ArgumentNamed(s) if s == sym::ItemContext => (),
320+
Position::ArgumentNamed(s, _) if s == sym::ItemContext => (),
321321
// `{integral}` and `{integer}` and `{float}` are allowed
322-
Position::ArgumentNamed(s)
322+
Position::ArgumentNamed(s, _)
323323
if s == sym::integral || s == sym::integer_ || s == sym::float =>
324324
{
325325
()
326326
}
327327
// So is `{A}` if A is a type parameter
328-
Position::ArgumentNamed(s) => {
328+
Position::ArgumentNamed(s, _) => {
329329
match generics.params.iter().find(|param| param.name == s) {
330330
Some(_) => (),
331331
None => {
@@ -392,7 +392,7 @@ impl<'tcx> OnUnimplementedFormatString {
392392
.map(|p| match p {
393393
Piece::String(s) => s,
394394
Piece::NextArgument(a) => match a.position {
395-
Position::ArgumentNamed(s) => match generic_map.get(&s) {
395+
Position::ArgumentNamed(s, _) => match generic_map.get(&s) {
396396
Some(val) => val,
397397
None if s == name => &trait_str,
398398
None => {

compiler/rustc_typeck/src/check/check.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,15 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
382382
tcx.sess,
383383
field_span,
384384
E0740,
385-
"unions may not contain fields that need dropping"
385+
"unions cannot contain fields that may need dropping"
386+
)
387+
.note(
388+
"a type is guaranteed not to need dropping \
389+
when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type",
386390
)
387391
.multipart_suggestion_verbose(
388-
"wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped",
392+
"when the type does not implement `Copy`, \
393+
wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped",
389394
vec![
390395
(ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
391396
(ty_span.shrink_to_hi(), ">".into()),

compiler/rustc_typeck/src/check/method/suggest.rs

+41-13
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use rustc_hir::def_id::{DefId, LocalDefId};
99
use rustc_hir::lang_items::LangItem;
1010
use rustc_hir::{ExprKind, Node, QPath};
1111
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
12+
use rustc_middle::traits::util::supertraits;
1213
use rustc_middle::ty::fast_reject::{simplify_type, SimplifyParams};
1314
use rustc_middle::ty::print::with_crate_prefix;
15+
use rustc_middle::ty::ToPolyTraitRef;
1416
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
1517
use rustc_span::lev_distance;
1618
use rustc_span::symbol::{kw, sym, Ident};
@@ -40,7 +42,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4042
Err(..) => return false,
4143
};
4244

45+
// This conditional prevents us from asking to call errors and unresolved types.
46+
// It might seem that we can use `predicate_must_hold_modulo_regions`,
47+
// but since a Dummy binder is used to fill in the FnOnce trait's arguments,
48+
// type resolution always gives a "maybe" here.
49+
if self.autoderef(span, ty).any(|(ty, _)| {
50+
info!("check deref {:?} error", ty);
51+
matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
52+
}) {
53+
return false;
54+
}
55+
4356
self.autoderef(span, ty).any(|(ty, _)| {
57+
info!("check deref {:?} impl FnOnce", ty);
4458
self.probe(|_| {
4559
let fn_once_substs = tcx.mk_substs_trait(
4660
ty,
@@ -1196,26 +1210,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11961210
Some(adt) if adt.did.is_local() => adt,
11971211
_ => continue,
11981212
};
1199-
let can_derive = match self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1200-
Some(sym::Default) => !adt.is_enum(),
1201-
Some(
1213+
if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
1214+
let can_derive = match diagnostic_name {
1215+
sym::Default => !adt.is_enum(),
12021216
sym::Eq
12031217
| sym::PartialEq
12041218
| sym::Ord
12051219
| sym::PartialOrd
12061220
| sym::Clone
12071221
| sym::Copy
12081222
| sym::Hash
1209-
| sym::Debug,
1210-
) => true,
1211-
_ => false,
1212-
};
1213-
if can_derive {
1214-
derives.push((
1215-
format!("{}", trait_pred.self_ty()),
1216-
self.tcx.def_span(adt.did),
1217-
format!("{}", trait_pred.trait_ref.print_only_trait_name()),
1218-
));
1223+
| sym::Debug => true,
1224+
_ => false,
1225+
};
1226+
if can_derive {
1227+
let self_name = trait_pred.self_ty().to_string();
1228+
let self_span = self.tcx.def_span(adt.did);
1229+
if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
1230+
for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
1231+
{
1232+
if let Some(parent_diagnostic_name) =
1233+
self.tcx.get_diagnostic_name(super_trait.def_id())
1234+
{
1235+
derives.push((
1236+
self_name.clone(),
1237+
self_span.clone(),
1238+
parent_diagnostic_name.to_string(),
1239+
));
1240+
}
1241+
}
1242+
}
1243+
derives.push((self_name, self_span, diagnostic_name.to_string()));
1244+
} else {
1245+
traits.push(self.tcx.def_span(trait_pred.def_id()));
1246+
}
12191247
} else {
12201248
traits.push(self.tcx.def_span(trait_pred.def_id()));
12211249
}

compiler/rustc_typeck/src/check/pat.rs

+32-24
Original file line numberDiff line numberDiff line change
@@ -2029,34 +2029,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20292029
err.help("the semantics of slice patterns changed recently; see issue #62254");
20302030
}
20312031
} else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span)
2032-
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..)))
2032+
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
20332033
{
20342034
if let (Some(span), true) = (ti.span, ti.origin_expr) {
20352035
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
2036-
let applicability = match self.resolve_vars_if_possible(ti.expected).kind() {
2037-
ty::Adt(adt_def, _)
2038-
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
2039-
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
2040-
{
2041-
// Slicing won't work here, but `.as_deref()` might (issue #91328).
2042-
err.span_suggestion(
2043-
span,
2044-
"consider using `as_deref` here",
2045-
format!("{}.as_deref()", snippet),
2046-
Applicability::MaybeIncorrect,
2047-
);
2048-
None
2049-
}
2050-
// FIXME: instead of checking for Vec only, we could check whether the
2051-
// type implements `Deref<Target=X>`; see
2052-
// https://github.com/rust-lang/rust/pull/91343#discussion_r761466979
2053-
ty::Adt(adt_def, _)
2054-
if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did) =>
2055-
{
2056-
Some(Applicability::MachineApplicable)
2036+
let applicability = Autoderef::new(
2037+
&self.infcx,
2038+
self.param_env,
2039+
self.body_id,
2040+
span,
2041+
self.resolve_vars_if_possible(ti.expected),
2042+
span,
2043+
)
2044+
.find_map(|(ty, _)| {
2045+
match ty.kind() {
2046+
ty::Adt(adt_def, _)
2047+
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
2048+
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
2049+
{
2050+
// Slicing won't work here, but `.as_deref()` might (issue #91328).
2051+
err.span_suggestion(
2052+
span,
2053+
"consider using `as_deref` here",
2054+
format!("{}.as_deref()", snippet),
2055+
Applicability::MaybeIncorrect,
2056+
);
2057+
Some(None)
2058+
}
2059+
2060+
ty::Slice(..) | ty::Array(..) => {
2061+
Some(Some(Applicability::MachineApplicable))
2062+
}
2063+
2064+
_ => None,
20572065
}
2058-
_ => Some(Applicability::MaybeIncorrect),
2059-
};
2066+
})
2067+
.unwrap_or(Some(Applicability::MaybeIncorrect));
20602068

20612069
if let Some(applicability) = applicability {
20622070
err.span_suggestion(

library/alloc/src/collections/btree/map.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,8 @@ where
20522052

20532053
#[stable(feature = "std_collections_from_array", since = "1.56.0")]
20542054
impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {
2055+
/// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`.
2056+
///
20552057
/// ```
20562058
/// use std::collections::BTreeMap;
20572059
///

library/alloc/src/collections/btree/set.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,8 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
10971097

10981098
#[stable(feature = "std_collections_from_array", since = "1.56.0")]
10991099
impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
1100+
/// Converts a `[T; N]` into a `BTreeSet<T>`.
1101+
///
11001102
/// ```
11011103
/// use std::collections::BTreeSet;
11021104
///

0 commit comments

Comments
 (0)