Skip to content

Commit

Permalink
Auto merge of #61460 - Centril:rollup-8txhjx4, r=Centril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jun 2, 2019
2 parents 4c7bb8b + aaf264b commit d461555
Show file tree
Hide file tree
Showing 33 changed files with 313 additions and 92 deletions.
2 changes: 1 addition & 1 deletion src/libcore/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub const fn identity<T>(x: T) -> T { x }
/// # Examples
///
/// By using trait bounds we can accept arguments of different types as long as they can be
/// converted a the specified type `T`.
/// converted to the specified type `T`.
///
/// For example: By creating a generic function that takes an `AsRef<str>` we express that we
/// want to accept all references that can be converted to `&str` as an argument.
Expand Down
4 changes: 0 additions & 4 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,10 +628,6 @@ impl<'hir> Map<'hir> {
})
}

pub fn get_generics_span(&self, id: DefId) -> Option<Span> {
self.get_generics(id).map(|generics| generics.span).filter(|sp| *sp != DUMMY_SP)
}

/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(&self, id: NodeId) -> Option<Node<'hir>> {
let hir_id = self.node_to_hir_id(id);
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::util::nodemap::{NodeMap, FxHashSet};
use crate::mir::mono::Linkage;

use errors::FatalError;
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString};
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan};
use syntax::source_map::Spanned;
use rustc_target::spec::abi::Abi;
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
Expand Down Expand Up @@ -625,6 +625,14 @@ impl Generics {
}
None
}

pub fn spans(&self) -> MultiSpan {
if self.params.is_empty() {
self.span.into()
} else {
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
}
}
}

/// Synthetic type parameters are converted to another form during lowering; this allows
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,8 +914,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

// already reported in the query
ConstEvalFailure(_) => {
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
ConstEvalFailure(err) => {
self.tcx.sess.delay_span_bug(
span,
&format!("constant in type had an ignored error: {:?}", err),
);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
}
}

let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
let element = self.layout_of(element)?;
let count = count.unwrap_usize(tcx);
let size = element.size.checked_mul(count, dl)
.ok_or(LayoutError::SizeOverflow(ty))?;

Expand Down
4 changes: 1 addition & 3 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,7 @@ fn fixed_vec_metadata(
let (size, align) = cx.size_and_align_of(array_or_slice_type);

let upper_bound = match array_or_slice_type.sty {
ty::Array(_, len) => {
len.unwrap_usize(cx.tcx) as c_longlong
}
ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
_ => -1
};

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_utils/symbol_names/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ impl fmt::Write for SymbolPrinter<'_, '_> {
'-' | ':' => self.path.temp_buf.push('.'),

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

// These are legal symbols
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/borrow_check/places_conflict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
},
(StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
if promoted_1 == promoted_2 {
if let ty::Array(_, size) = s1.ty.sty {
if size.unwrap_usize(tcx) == 0 {
if let ty::Array(_, len) = s1.ty.sty {
if let Some(0) = len.assert_usize(tcx) {
// Ignore conflicts with promoted [T; 0].
debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
return Overlap::Disjoint;
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ impl Qualif for HasMutInterior {
} else if let ty::Array(_, len) = ty.sty {
// FIXME(eddyb) the `cx.mode == Mode::Fn` condition
// seems unnecessary, given that this is merely a ZST.
if !(len.unwrap_usize(cx.tcx) == 0 && cx.mode == Mode::Fn) {
return true;
match len.assert_usize(cx.tcx) {
Some(0) if cx.mode == Mode::Fn => {},
_ => return true,
}
} else {
return true;
Expand Down
59 changes: 39 additions & 20 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,27 +400,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let expected_ty = self.structurally_resolved_type(pat.span, expected);
let (inner_ty, slice_ty) = match expected_ty.sty {
ty::Array(inner_ty, size) => {
let size = size.unwrap_usize(tcx);
let min_len = before.len() as u64 + after.len() as u64;
if slice.is_none() {
if min_len != size {
struct_span_err!(
tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size)
.span_label(pat.span, format!("expected {} elements", size))
if let Some(size) = size.assert_usize(tcx) {
let min_len = before.len() as u64 + after.len() as u64;
if slice.is_none() {
if min_len != size {
struct_span_err!(
tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size)
.span_label(pat.span, format!("expected {} elements", size))
.emit();
}
(inner_ty, tcx.types.err)
} else if let Some(rest) = size.checked_sub(min_len) {
(inner_ty, tcx.mk_array(inner_ty, rest))
} else {
struct_span_err!(tcx.sess, pat.span, E0528,
"pattern requires at least {} elements but array has {}",
min_len, size)
.span_label(pat.span,
format!("pattern cannot match array of {} elements", size))
.emit();
(inner_ty, tcx.types.err)
}
(inner_ty, tcx.types.err)
} else if let Some(rest) = size.checked_sub(min_len) {
(inner_ty, tcx.mk_array(inner_ty, rest))
} else {
struct_span_err!(tcx.sess, pat.span, E0528,
"pattern requires at least {} elements but array has {}",
min_len, size)
.span_label(pat.span,
format!("pattern cannot match array of {} elements", size))
.emit();
struct_span_err!(
tcx.sess,
pat.span,
E0730,
"cannot pattern-match on an array without a fixed length",
).emit();
(inner_ty, tcx.types.err)
}
}
Expand Down Expand Up @@ -1080,8 +1089,18 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
let msg = format!("expected tuple struct/variant, found {} `{}`",
res.descr(),
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
.span_label(pat.span, "not a tuple variant or struct").emit();
let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
match (res, &pat.node) {
(Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
err.span_label(pat.span, "`fn` calls are not allowed in patterns");
err.help("for more information, visit \
https://doc.rust-lang.org/book/ch18-00-patterns.html");
}
_ => {
err.span_label(pat.span, "not a tuple variant or struct");
}
}
err.emit();
on_error();
};

Expand Down
83 changes: 62 additions & 21 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// the moment, give a kind of vague error message.
if trait_params != impl_params {
let def_span = tcx.sess.source_map().def_span(span);
let span = tcx.hir().get_generics_span(impl_m.def_id).unwrap_or(def_span);
let span = tcx.hir().get_generics(impl_m.def_id).map(|g| g.span).unwrap_or(def_span);
let mut err = struct_span_err!(
tcx.sess,
span,
Expand All @@ -396,7 +396,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
err.span_label(span, "lifetimes do not match method in trait");
if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) {
let def_sp = tcx.sess.source_map().def_span(sp);
let sp = tcx.hir().get_generics_span(trait_m.def_id).unwrap_or(def_sp);
let sp = tcx.hir().get_generics(trait_m.def_id).map(|g| g.span).unwrap_or(def_sp);
err.span_label(sp, "lifetimes in impl do not match this method in trait");
}
err.emit();
Expand Down Expand Up @@ -583,7 +583,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn compare_number_of_generics<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_: &ty::AssocItem,
impl_span: Span,
_impl_span: Span,
trait_: &ty::AssocItem,
trait_span: Option<Span>,
) -> Result<(), ErrorReported> {
Expand All @@ -600,17 +600,44 @@ fn compare_number_of_generics<'a, 'tcx>(
if impl_count != trait_count {
err_occurred = true;

let impl_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
let impl_item = tcx.hir().expect_impl_item(impl_hir_id);
let span = if impl_item.generics.params.is_empty()
|| impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
impl_span
let (
trait_spans,
impl_trait_spans,
) = if let Some(trait_hir_id) = tcx.hir().as_local_hir_id(trait_.def_id) {
let trait_item = tcx.hir().expect_trait_item(trait_hir_id);
if trait_item.generics.params.is_empty() {
(Some(vec![trait_item.generics.span]), vec![])
} else {
let arg_spans: Vec<Span> = trait_item.generics.params.iter()
.map(|p| p.span)
.collect();
let impl_trait_spans: Vec<Span> = trait_item.generics.params.iter()
.filter_map(|p| match p.kind {
GenericParamKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
} => Some(p.span),
_ => None,
}).collect();
(Some(arg_spans), impl_trait_spans)
}
} else {
impl_item.generics.span
(trait_span.map(|s| vec![s]), vec![])
};

let impl_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
let impl_item = tcx.hir().expect_impl_item(impl_hir_id);
let impl_item_impl_trait_spans: Vec<Span> = impl_item.generics.params.iter()
.filter_map(|p| match p.kind {
GenericParamKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
} => Some(p.span),
_ => None,
}).collect();
let spans = impl_item.generics.spans();
let span = spans.primary_span();

let mut err = tcx.sess.struct_span_err_with_code(
span,
spans,
&format!(
"method `{}` has {} {kind} parameter{} but its trait \
declaration has {} {kind} parameter{}",
Expand All @@ -626,22 +653,36 @@ fn compare_number_of_generics<'a, 'tcx>(

let mut suffix = None;

if let Some(span) = trait_span {
err.span_label(
span,
format!("expected {} {} parameter{}", trait_count, kind,
if trait_count != 1 { "s" } else { "" })
);
if let Some(spans) = trait_spans {
let mut spans = spans.iter();
if let Some(span) = spans.next() {
err.span_label(*span, format!(
"expected {} {} parameter{}",
trait_count,
kind,
if trait_count != 1 { "s" } else { "" },
));
}
for span in spans {
err.span_label(*span, "");
}
} else {
suffix = Some(format!(", expected {}", trait_count));
}

err.span_label(
span,
format!("found {} {} parameter{}{}", impl_count, kind,
if let Some(span) = span {
err.span_label(span, format!(
"found {} {} parameter{}{}",
impl_count,
kind,
if impl_count != 1 { "s" } else { "" },
suffix.unwrap_or_else(|| String::new())),
);
suffix.unwrap_or_else(|| String::new()),
));
}

for span in impl_trait_spans.iter().chain(impl_item_impl_trait_spans.iter()) {
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
}

err.emit();
}
Expand Down
32 changes: 32 additions & 0 deletions src/librustc_typeck/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4648,6 +4648,38 @@ fn make_recursive_type() -> impl Sized {
```
"##,

E0730: r##"
An array without a fixed length was pattern-matched.
Example of erroneous code:
```compile_fail,E0730
#![feature(const_generics)]
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, 3] => true, // error: cannot pattern-match on an
// array without a fixed length
_ => false
}
}
```
Ensure that the pattern is consistent with the size of the matched
array. Additional elements can be matched with `..`:
```
#![feature(slice_patterns)]
let r = &[1, 2, 3, 4];
match r {
&[a, b, ..] => { // ok!
println!("a={}, b={}", a, b);
}
}
```
"##,

}

register_diagnostics! {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ mod builtin {
///
/// ```compile_fail
/// #[cfg(not(any(feature = "foo", feature = "bar")))]
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
/// ```
///
/// [`panic!`]: ../std/macro.panic.html
Expand Down
25 changes: 13 additions & 12 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5050,21 +5050,22 @@ impl<'a> Parser<'a> {
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
let span_lo = self.span;
if self.eat_lt() {
let (params, span) = if self.eat_lt() {
let params = self.parse_generic_params()?;
self.expect_gt()?;
Ok(ast::Generics {
params,
where_clause: WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: DUMMY_SP,
},
span: span_lo.to(self.prev_span),
})
(params, span_lo.to(self.prev_span))
} else {
Ok(ast::Generics::default())
}
(vec![], self.prev_span.between(self.span))
};
Ok(ast::Generics {
params,
where_clause: WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
span: DUMMY_SP,
},
span,
})
}

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

0 comments on commit d461555

Please sign in to comment.