Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #61460

Merged
merged 20 commits into from
Jun 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
eb0afe1
Add more information in ConstEvalFailure error
varkor May 30, 2019
7e92607
Fix unwrapping usize issue in HasMutInterior
varkor May 30, 2019
8e595f5
Make generics always have a valid span
estebank Jun 1, 2019
e71f466
codegen: change `$6d$` to `$u6d$`
davidtwco Jun 1, 2019
2885947
Point at individual type arguments on arg count mismatch
estebank Jun 1, 2019
0754c84
Explain that `impl Trait` introduces an implicit type argument
estebank Jun 1, 2019
3d0eae1
Tweak wording when encountering `fn` call in pattern
estebank Jun 1, 2019
c2b663c
Fix unwrapping usize issue with transparent MaybeUnit array wrapper
varkor May 30, 2019
2155135
Use `assert_usize` instead of `unwrap_usize` in several places
varkor May 30, 2019
5a2410a
Add error for pattern-matching on arrays without a fixed size
varkor May 31, 2019
e82cd95
Add regression test for #61422
varkor Jun 1, 2019
31918d6
review comments: use param kind type to identify impl Trait
estebank Jun 1, 2019
b3fdde4
Fix missing semicolon in doc
0x1793d1 Jun 2, 2019
9583398
Fix typo in AsRef doc
fabric-and-ink Jun 2, 2019
c748c7b
Rollup merge of #61380 - varkor:expected-usize-got-param, r=eddyb
Centril Jun 2, 2019
5599985
Rollup merge of #61423 - davidtwco:correct-symbol-mangling, r=eddyb
Centril Jun 2, 2019
83b74f2
Rollup merge of #61438 - estebank:generics-span, r=varkor
Centril Jun 2, 2019
247e0a6
Rollup merge of #61441 - estebank:fn-call-in-match, r=varkor
Centril Jun 2, 2019
d70f288
Rollup merge of #61451 - 0x1793d1:master, r=Centril
Centril Jun 2, 2019
aaf264b
Rollup merge of #61458 - fabric-and-ink:doc-typo, r=jonas-schievink
Centril Jun 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -624,6 +624,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