Skip to content

Commit d461555

Browse files
committed
Auto merge of #61460 - Centril:rollup-8txhjx4, r=Centril
Rollup of 6 pull requests Successful merges: - #61380 (Fix some issues with `unwrap_usize` instead of `assert_usize`) - #61423 (codegen: change `$6d$` to `$u6d$`) - #61438 (Point at individual type args on arg count mismatch) - #61441 (Tweak wording when encountering `fn` call in pattern) - #61451 (Fix missing semicolon in doc) - #61458 (Fix typo in AsRef doc) Failed merges: r? @ghost
2 parents 4c7bb8b + aaf264b commit d461555

33 files changed

+313
-92
lines changed

src/libcore/convert.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ pub const fn identity<T>(x: T) -> T { x }
129129
/// # Examples
130130
///
131131
/// By using trait bounds we can accept arguments of different types as long as they can be
132-
/// converted a the specified type `T`.
132+
/// converted to the specified type `T`.
133133
///
134134
/// For example: By creating a generic function that takes an `AsRef<str>` we express that we
135135
/// want to accept all references that can be converted to `&str` as an argument.

src/librustc/hir/map/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -628,10 +628,6 @@ impl<'hir> Map<'hir> {
628628
})
629629
}
630630

631-
pub fn get_generics_span(&self, id: DefId) -> Option<Span> {
632-
self.get_generics(id).map(|generics| generics.span).filter(|sp| *sp != DUMMY_SP)
633-
}
634-
635631
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
636632
pub fn find(&self, id: NodeId) -> Option<Node<'hir>> {
637633
let hir_id = self.node_to_hir_id(id);

src/librustc/hir/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::util::nodemap::{NodeMap, FxHashSet};
1616
use crate::mir::mono::Linkage;
1717

1818
use errors::FatalError;
19-
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString};
19+
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan};
2020
use syntax::source_map::Spanned;
2121
use rustc_target::spec::abi::Abi;
2222
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
@@ -625,6 +625,14 @@ impl Generics {
625625
}
626626
None
627627
}
628+
629+
pub fn spans(&self) -> MultiSpan {
630+
if self.params.is_empty() {
631+
self.span.into()
632+
} else {
633+
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
634+
}
635+
}
628636
}
629637

630638
/// Synthetic type parameters are converted to another form during lowering; this allows

src/librustc/traits/error_reporting.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -914,8 +914,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
914914
}
915915

916916
// already reported in the query
917-
ConstEvalFailure(_) => {
918-
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
917+
ConstEvalFailure(err) => {
918+
self.tcx.sess.delay_span_bug(
919+
span,
920+
&format!("constant in type had an ignored error: {:?}", err),
921+
);
919922
return;
920923
}
921924

src/librustc/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
549549
}
550550
}
551551

552+
let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
552553
let element = self.layout_of(element)?;
553-
let count = count.unwrap_usize(tcx);
554554
let size = element.size.checked_mul(count, dl)
555555
.ok_or(LayoutError::SizeOverflow(ty))?;
556556

src/librustc_codegen_llvm/debuginfo/metadata.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,7 @@ fn fixed_vec_metadata(
342342
let (size, align) = cx.size_and_align_of(array_or_slice_type);
343343

344344
let upper_bound = match array_or_slice_type.sty {
345-
ty::Array(_, len) => {
346-
len.unwrap_usize(cx.tcx) as c_longlong
347-
}
345+
ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
348346
_ => -1
349347
};
350348

src/librustc_codegen_utils/symbol_names/legacy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ impl fmt::Write for SymbolPrinter<'_, '_> {
440440
'-' | ':' => self.path.temp_buf.push('.'),
441441

442442
// Avoid crashing LLVM in certain (LTO-related) situations, see #60925.
443-
'm' if self.path.temp_buf.ends_with(".llv") => self.path.temp_buf.push_str("$6d$"),
443+
'm' if self.path.temp_buf.ends_with(".llv") => self.path.temp_buf.push_str("$u6d$"),
444444

445445
// These are legal symbols
446446
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c),

src/librustc_mir/borrow_check/places_conflict.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
332332
},
333333
(StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
334334
if promoted_1 == promoted_2 {
335-
if let ty::Array(_, size) = s1.ty.sty {
336-
if size.unwrap_usize(tcx) == 0 {
335+
if let ty::Array(_, len) = s1.ty.sty {
336+
if let Some(0) = len.assert_usize(tcx) {
337337
// Ignore conflicts with promoted [T; 0].
338338
debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
339339
return Overlap::Disjoint;

src/librustc_mir/transform/qualify_consts.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,9 @@ impl Qualif for HasMutInterior {
316316
} else if let ty::Array(_, len) = ty.sty {
317317
// FIXME(eddyb) the `cx.mode == Mode::Fn` condition
318318
// seems unnecessary, given that this is merely a ZST.
319-
if !(len.unwrap_usize(cx.tcx) == 0 && cx.mode == Mode::Fn) {
320-
return true;
319+
match len.assert_usize(cx.tcx) {
320+
Some(0) if cx.mode == Mode::Fn => {},
321+
_ => return true,
321322
}
322323
} else {
323324
return true;

src/librustc_typeck/check/_match.rs

+39-20
Original file line numberDiff line numberDiff line change
@@ -400,27 +400,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
400400
let expected_ty = self.structurally_resolved_type(pat.span, expected);
401401
let (inner_ty, slice_ty) = match expected_ty.sty {
402402
ty::Array(inner_ty, size) => {
403-
let size = size.unwrap_usize(tcx);
404-
let min_len = before.len() as u64 + after.len() as u64;
405-
if slice.is_none() {
406-
if min_len != size {
407-
struct_span_err!(
408-
tcx.sess, pat.span, E0527,
409-
"pattern requires {} elements but array has {}",
410-
min_len, size)
411-
.span_label(pat.span, format!("expected {} elements", size))
403+
if let Some(size) = size.assert_usize(tcx) {
404+
let min_len = before.len() as u64 + after.len() as u64;
405+
if slice.is_none() {
406+
if min_len != size {
407+
struct_span_err!(
408+
tcx.sess, pat.span, E0527,
409+
"pattern requires {} elements but array has {}",
410+
min_len, size)
411+
.span_label(pat.span, format!("expected {} elements", size))
412+
.emit();
413+
}
414+
(inner_ty, tcx.types.err)
415+
} else if let Some(rest) = size.checked_sub(min_len) {
416+
(inner_ty, tcx.mk_array(inner_ty, rest))
417+
} else {
418+
struct_span_err!(tcx.sess, pat.span, E0528,
419+
"pattern requires at least {} elements but array has {}",
420+
min_len, size)
421+
.span_label(pat.span,
422+
format!("pattern cannot match array of {} elements", size))
412423
.emit();
424+
(inner_ty, tcx.types.err)
413425
}
414-
(inner_ty, tcx.types.err)
415-
} else if let Some(rest) = size.checked_sub(min_len) {
416-
(inner_ty, tcx.mk_array(inner_ty, rest))
417426
} else {
418-
struct_span_err!(tcx.sess, pat.span, E0528,
419-
"pattern requires at least {} elements but array has {}",
420-
min_len, size)
421-
.span_label(pat.span,
422-
format!("pattern cannot match array of {} elements", size))
423-
.emit();
427+
struct_span_err!(
428+
tcx.sess,
429+
pat.span,
430+
E0730,
431+
"cannot pattern-match on an array without a fixed length",
432+
).emit();
424433
(inner_ty, tcx.types.err)
425434
}
426435
}
@@ -1080,8 +1089,18 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
10801089
let msg = format!("expected tuple struct/variant, found {} `{}`",
10811090
res.descr(),
10821091
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1083-
struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
1084-
.span_label(pat.span, "not a tuple variant or struct").emit();
1092+
let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
1093+
match (res, &pat.node) {
1094+
(Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
1095+
err.span_label(pat.span, "`fn` calls are not allowed in patterns");
1096+
err.help("for more information, visit \
1097+
https://doc.rust-lang.org/book/ch18-00-patterns.html");
1098+
}
1099+
_ => {
1100+
err.span_label(pat.span, "not a tuple variant or struct");
1101+
}
1102+
}
1103+
err.emit();
10851104
on_error();
10861105
};
10871106

src/librustc_typeck/check/compare_method.rs

+62-21
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
385385
// the moment, give a kind of vague error message.
386386
if trait_params != impl_params {
387387
let def_span = tcx.sess.source_map().def_span(span);
388-
let span = tcx.hir().get_generics_span(impl_m.def_id).unwrap_or(def_span);
388+
let span = tcx.hir().get_generics(impl_m.def_id).map(|g| g.span).unwrap_or(def_span);
389389
let mut err = struct_span_err!(
390390
tcx.sess,
391391
span,
@@ -396,7 +396,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
396396
err.span_label(span, "lifetimes do not match method in trait");
397397
if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) {
398398
let def_sp = tcx.sess.source_map().def_span(sp);
399-
let sp = tcx.hir().get_generics_span(trait_m.def_id).unwrap_or(def_sp);
399+
let sp = tcx.hir().get_generics(trait_m.def_id).map(|g| g.span).unwrap_or(def_sp);
400400
err.span_label(sp, "lifetimes in impl do not match this method in trait");
401401
}
402402
err.emit();
@@ -583,7 +583,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
583583
fn compare_number_of_generics<'a, 'tcx>(
584584
tcx: TyCtxt<'a, 'tcx, 'tcx>,
585585
impl_: &ty::AssocItem,
586-
impl_span: Span,
586+
_impl_span: Span,
587587
trait_: &ty::AssocItem,
588588
trait_span: Option<Span>,
589589
) -> Result<(), ErrorReported> {
@@ -600,17 +600,44 @@ fn compare_number_of_generics<'a, 'tcx>(
600600
if impl_count != trait_count {
601601
err_occurred = true;
602602

603-
let impl_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
604-
let impl_item = tcx.hir().expect_impl_item(impl_hir_id);
605-
let span = if impl_item.generics.params.is_empty()
606-
|| impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
607-
impl_span
603+
let (
604+
trait_spans,
605+
impl_trait_spans,
606+
) = if let Some(trait_hir_id) = tcx.hir().as_local_hir_id(trait_.def_id) {
607+
let trait_item = tcx.hir().expect_trait_item(trait_hir_id);
608+
if trait_item.generics.params.is_empty() {
609+
(Some(vec![trait_item.generics.span]), vec![])
610+
} else {
611+
let arg_spans: Vec<Span> = trait_item.generics.params.iter()
612+
.map(|p| p.span)
613+
.collect();
614+
let impl_trait_spans: Vec<Span> = trait_item.generics.params.iter()
615+
.filter_map(|p| match p.kind {
616+
GenericParamKind::Type {
617+
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
618+
} => Some(p.span),
619+
_ => None,
620+
}).collect();
621+
(Some(arg_spans), impl_trait_spans)
622+
}
608623
} else {
609-
impl_item.generics.span
624+
(trait_span.map(|s| vec![s]), vec![])
610625
};
611626

627+
let impl_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
628+
let impl_item = tcx.hir().expect_impl_item(impl_hir_id);
629+
let impl_item_impl_trait_spans: Vec<Span> = impl_item.generics.params.iter()
630+
.filter_map(|p| match p.kind {
631+
GenericParamKind::Type {
632+
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
633+
} => Some(p.span),
634+
_ => None,
635+
}).collect();
636+
let spans = impl_item.generics.spans();
637+
let span = spans.primary_span();
638+
612639
let mut err = tcx.sess.struct_span_err_with_code(
613-
span,
640+
spans,
614641
&format!(
615642
"method `{}` has {} {kind} parameter{} but its trait \
616643
declaration has {} {kind} parameter{}",
@@ -626,22 +653,36 @@ fn compare_number_of_generics<'a, 'tcx>(
626653

627654
let mut suffix = None;
628655

629-
if let Some(span) = trait_span {
630-
err.span_label(
631-
span,
632-
format!("expected {} {} parameter{}", trait_count, kind,
633-
if trait_count != 1 { "s" } else { "" })
634-
);
656+
if let Some(spans) = trait_spans {
657+
let mut spans = spans.iter();
658+
if let Some(span) = spans.next() {
659+
err.span_label(*span, format!(
660+
"expected {} {} parameter{}",
661+
trait_count,
662+
kind,
663+
if trait_count != 1 { "s" } else { "" },
664+
));
665+
}
666+
for span in spans {
667+
err.span_label(*span, "");
668+
}
635669
} else {
636670
suffix = Some(format!(", expected {}", trait_count));
637671
}
638672

639-
err.span_label(
640-
span,
641-
format!("found {} {} parameter{}{}", impl_count, kind,
673+
if let Some(span) = span {
674+
err.span_label(span, format!(
675+
"found {} {} parameter{}{}",
676+
impl_count,
677+
kind,
642678
if impl_count != 1 { "s" } else { "" },
643-
suffix.unwrap_or_else(|| String::new())),
644-
);
679+
suffix.unwrap_or_else(|| String::new()),
680+
));
681+
}
682+
683+
for span in impl_trait_spans.iter().chain(impl_item_impl_trait_spans.iter()) {
684+
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
685+
}
645686

646687
err.emit();
647688
}

src/librustc_typeck/error_codes.rs

+32
Original file line numberDiff line numberDiff line change
@@ -4648,6 +4648,38 @@ fn make_recursive_type() -> impl Sized {
46484648
```
46494649
"##,
46504650

4651+
E0730: r##"
4652+
An array without a fixed length was pattern-matched.
4653+
4654+
Example of erroneous code:
4655+
4656+
```compile_fail,E0730
4657+
#![feature(const_generics)]
4658+
4659+
fn is_123<const N: usize>(x: [u32; N]) -> bool {
4660+
match x {
4661+
[1, 2, 3] => true, // error: cannot pattern-match on an
4662+
// array without a fixed length
4663+
_ => false
4664+
}
4665+
}
4666+
```
4667+
4668+
Ensure that the pattern is consistent with the size of the matched
4669+
array. Additional elements can be matched with `..`:
4670+
4671+
```
4672+
#![feature(slice_patterns)]
4673+
4674+
let r = &[1, 2, 3, 4];
4675+
match r {
4676+
&[a, b, ..] => { // ok!
4677+
println!("a={}, b={}", a, b);
4678+
}
4679+
}
4680+
```
4681+
"##,
4682+
46514683
}
46524684

46534685
register_diagnostics! {

src/libstd/macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ mod builtin {
405405
///
406406
/// ```compile_fail
407407
/// #[cfg(not(any(feature = "foo", feature = "bar")))]
408-
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
408+
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
409409
/// ```
410410
///
411411
/// [`panic!`]: ../std/macro.panic.html

src/libsyntax/parse/parser.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -5050,21 +5050,22 @@ impl<'a> Parser<'a> {
50505050
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
50515051
fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
50525052
let span_lo = self.span;
5053-
if self.eat_lt() {
5053+
let (params, span) = if self.eat_lt() {
50545054
let params = self.parse_generic_params()?;
50555055
self.expect_gt()?;
5056-
Ok(ast::Generics {
5057-
params,
5058-
where_clause: WhereClause {
5059-
id: ast::DUMMY_NODE_ID,
5060-
predicates: Vec::new(),
5061-
span: DUMMY_SP,
5062-
},
5063-
span: span_lo.to(self.prev_span),
5064-
})
5056+
(params, span_lo.to(self.prev_span))
50655057
} else {
5066-
Ok(ast::Generics::default())
5067-
}
5058+
(vec![], self.prev_span.between(self.span))
5059+
};
5060+
Ok(ast::Generics {
5061+
params,
5062+
where_clause: WhereClause {
5063+
id: ast::DUMMY_NODE_ID,
5064+
predicates: Vec::new(),
5065+
span: DUMMY_SP,
5066+
},
5067+
span,
5068+
})
50685069
}
50695070

50705071
/// Parses generic args (within a path segment) with recovery for extra leading angle brackets.

0 commit comments

Comments
 (0)