1
Fork 0

Auto merge of #69555 - Centril:rollup-e53lxz4, r=Centril

Rollup of 10 pull requests

Successful merges:

 - #68989 (Update RELEASES.md for 1.42.0)
 - #69340 (instantiate_value_path: on `SelfCtor`, avoid unconstrained tyvars)
 - #69384 (parser: `token` -> `normalized_token`, `nonnormalized_token` -> `token`)
 - #69452 (typeck: use `Pattern` obligation cause more for better diagnostics)
 - #69481 (use char instead of &str for single char patterns)
 - #69522 (error_derive_forbidden_on_non_adt: be more graceful)
 - #69538 (Stabilize `boxed_slice_try_from`)
 - #69539 (late resolve, visit_fn: bail early if there's no body.)
 - #69541 (Remove unneeded calls to format!())
 - #69547 (remove redundant clones, references to operands, explicit boolean comparisons and filter(x).next() calls.)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-02-28 17:53:10 +00:00
commit 0eb878d2aa
98 changed files with 853 additions and 390 deletions

View file

@ -1,3 +1,100 @@
Version 1.42.0 (2020-03-12)
==========================
Language
--------
- [You can now use the slice pattern syntax with subslices.][67712] e.g.
```rust
fn foo(words: &[&str]) {
match words {
["Hello", "World", "!", ..] => println!("Hello World!"),
["Foo", "Bar", ..] => println!("Baz"),
rest => println!("{:?}", rest),
}
}
```
- [You can now use `#[repr(transparent)]` on univariant `enum`s.][68122] Meaning
that you can create an enum that has the exact layout and ABI of the type
it contains.
- [There are some *syntax-only* changes:][67131]
- `default` is syntactically allowed before items in `trait` definitions.
- Items in `impl`s (i.e. `const`s, `type`s, and `fn`s) may syntactically
leave out their bodies in favor of `;`.
- Bounds on associated types in `impl`s are now syntactically allowed
(e.g. `type Foo: Ord;`).
- `...` (the C-variadic type) may occur syntactically directly as the type of
any function parameter.
These are still rejected *semantically*, so you will likely receive an error
but these changes can be seen and parsed by procedural macros and
conditional compilation.
Compiler
--------
- [Added tier 2\* support for `armv7a-none-eabi`.][68253]
- [Added tier 2 support for `riscv64gc-unknown-linux-gnu`.][68339]
- [`Option::{expect,unwrap}` and
`Result::{expect, expect_err, unwrap, unwrap_err}` now produce panic messages
pointing to the location where they were called, rather than
`core`'s internals. ][67887]
\* Refer to Rust's [platform support page][forge-platform-support] for more
information on Rust's tiered platform support.
Libraries
---------
- [`iter::Empty<T>` now implements `Send` and `Sync` for any `T`.][68348]
- [`Pin::{map_unchecked, map_unchecked_mut}` no longer require the return type
to implement `Sized`.][67935]
- [`io::Cursor` now derives `PartialEq` and `Eq`.][67233]
- [`Layout::new` is now `const`.][66254]
- [Added Standard Library support for `riscv64gc-unknown-linux-gnu`.][66899]
Stabilized APIs
---------------
- [`CondVar::wait_while`]
- [`CondVar::wait_timeout_while`]
- [`DebugMap::key`]
- [`DebugMap::value`]
- [`ManuallyDrop::take`]
- [`matches!`]
- [`ptr::slice_from_raw_parts_mut`]
- [`ptr::slice_from_raw_parts`]
Cargo
-----
- [You no longer need to include `extern crate proc_macro;` to be able to
`use proc_macro;` in the `2018` edition.][cargo/7700]
Compatibility Notes
-------------------
- [`Error::description` has been deprecated, and its use will now produce a
warning.][66919] It's recommended to use `Display`/`to_string` instead.
[68253]: https://github.com/rust-lang/rust/pull/68253/
[68348]: https://github.com/rust-lang/rust/pull/68348/
[67935]: https://github.com/rust-lang/rust/pull/67935/
[68339]: https://github.com/rust-lang/rust/pull/68339/
[68122]: https://github.com/rust-lang/rust/pull/68122/
[67712]: https://github.com/rust-lang/rust/pull/67712/
[67887]: https://github.com/rust-lang/rust/pull/67887/
[67131]: https://github.com/rust-lang/rust/pull/67131/
[67233]: https://github.com/rust-lang/rust/pull/67233/
[66899]: https://github.com/rust-lang/rust/pull/66899/
[66919]: https://github.com/rust-lang/rust/pull/66919/
[66254]: https://github.com/rust-lang/rust/pull/66254/
[cargo/7700]: https://github.com/rust-lang/cargo/pull/7700
[`DebugMap::key`]: https://doc.rust-lang.org/stable/std/fmt/struct.DebugMap.html#method.key
[`DebugMap::value`]: https://doc.rust-lang.org/stable/std/fmt/struct.DebugMap.html#method.value
[`ManuallyDrop::take`]: https://doc.rust-lang.org/stable/std/mem/struct.ManuallyDrop.html#method.take
[`matches!`]: https://doc.rust-lang.org/stable/std/macro.matches.html
[`ptr::slice_from_raw_parts_mut`]: https://doc.rust-lang.org/stable/std/ptr/fn.slice_from_raw_parts_mut.html
[`ptr::slice_from_raw_parts`]: https://doc.rust-lang.org/stable/std/ptr/fn.slice_from_raw_parts.html
[`CondVar::wait_while`]: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.wait_while
[`CondVar::wait_timeout_while`]: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.wait_timeout_while
Version 1.41.1 (2020-02-27) Version 1.41.1 (2020-02-27)
=========================== ===========================
@ -8,6 +105,7 @@ Version 1.41.1 (2020-02-27)
[69225]: https://github.com/rust-lang/rust/issues/69225 [69225]: https://github.com/rust-lang/rust/issues/69225
[69145]: https://github.com/rust-lang/rust/pull/69145 [69145]: https://github.com/rust-lang/rust/pull/69145
Version 1.41.0 (2020-01-30) Version 1.41.0 (2020-01-30)
=========================== ===========================

View file

@ -825,7 +825,7 @@ impl From<Box<str>> for Box<[u8]> {
} }
} }
#[unstable(feature = "boxed_slice_try_from", issue = "none")] #[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]>
where where
[T; N]: LengthAtMost32, [T; N]: LengthAtMost32,

View file

@ -1453,7 +1453,7 @@ impl<T> From<Vec<T>> for Rc<[T]> {
} }
} }
#[unstable(feature = "boxed_slice_try_from", issue = "none")] #[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]> impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]>
where where
[T; N]: LengthAtMost32, [T; N]: LengthAtMost32,

View file

@ -2002,7 +2002,7 @@ impl<T> From<Vec<T>> for Arc<[T]> {
} }
} }
#[unstable(feature = "boxed_slice_try_from", issue = "none")] #[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]> impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]>
where where
[T; N]: LengthAtMost32, [T; N]: LengthAtMost32,

View file

@ -153,17 +153,13 @@ pub struct Map<'hir> {
hir_to_node_id: FxHashMap<HirId, NodeId>, hir_to_node_id: FxHashMap<HirId, NodeId>,
} }
struct ParentHirIterator<'map, 'hir> { /// An iterator that walks up the ancestor tree of a given `HirId`.
/// Constructed using `tcx.hir().parent_iter(hir_id)`.
pub struct ParentHirIterator<'map, 'hir> {
current_id: HirId, current_id: HirId,
map: &'map Map<'hir>, map: &'map Map<'hir>,
} }
impl<'map, 'hir> ParentHirIterator<'map, 'hir> {
fn new(current_id: HirId, map: &'map Map<'hir>) -> Self {
Self { current_id, map }
}
}
impl<'hir> Iterator for ParentHirIterator<'_, 'hir> { impl<'hir> Iterator for ParentHirIterator<'_, 'hir> {
type Item = (HirId, Node<'hir>); type Item = (HirId, Node<'hir>);
@ -618,6 +614,12 @@ impl<'hir> Map<'hir> {
self.find_entry(hir_id).and_then(|x| x.parent_node()).unwrap_or(hir_id) self.find_entry(hir_id).and_then(|x| x.parent_node()).unwrap_or(hir_id)
} }
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
pub fn parent_iter(&self, current_id: HirId) -> ParentHirIterator<'_, 'hir> {
ParentHirIterator { current_id, map: self }
}
/// Checks if the node is an argument. An argument is a local variable whose /// Checks if the node is an argument. An argument is a local variable whose
/// immediate parent is an item or a closure. /// immediate parent is an item or a closure.
pub fn is_argument(&self, id: HirId) -> bool { pub fn is_argument(&self, id: HirId) -> bool {
@ -684,7 +686,7 @@ impl<'hir> Map<'hir> {
/// } /// }
/// ``` /// ```
pub fn get_return_block(&self, id: HirId) -> Option<HirId> { pub fn get_return_block(&self, id: HirId) -> Option<HirId> {
let mut iter = ParentHirIterator::new(id, &self).peekable(); let mut iter = self.parent_iter(id).peekable();
let mut ignore_tail = false; let mut ignore_tail = false;
if let Some(entry) = self.find_entry(id) { if let Some(entry) = self.find_entry(id) {
if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = entry.node { if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = entry.node {
@ -731,7 +733,7 @@ impl<'hir> Map<'hir> {
/// in the HIR which is recorded by the map and is an item, either an item /// in the HIR which is recorded by the map and is an item, either an item
/// in a module, trait, or impl. /// in a module, trait, or impl.
pub fn get_parent_item(&self, hir_id: HirId) -> HirId { pub fn get_parent_item(&self, hir_id: HirId) -> HirId {
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) { for (hir_id, node) in self.parent_iter(hir_id) {
match node { match node {
Node::Crate Node::Crate
| Node::Item(_) | Node::Item(_)
@ -753,7 +755,7 @@ impl<'hir> Map<'hir> {
/// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no /// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no
/// module parent is in this map. /// module parent is in this map.
pub fn get_module_parent_node(&self, hir_id: HirId) -> HirId { pub fn get_module_parent_node(&self, hir_id: HirId) -> HirId {
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) { for (hir_id, node) in self.parent_iter(hir_id) {
if let Node::Item(&Item { kind: ItemKind::Mod(_), .. }) = node { if let Node::Item(&Item { kind: ItemKind::Mod(_), .. }) = node {
return hir_id; return hir_id;
} }
@ -767,7 +769,7 @@ impl<'hir> Map<'hir> {
/// Used by error reporting when there's a type error in a match arm caused by the `match` /// Used by error reporting when there's a type error in a match arm caused by the `match`
/// expression needing to be unit. /// expression needing to be unit.
pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&'hir Expr<'hir>> { pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&'hir Expr<'hir>> {
for (_, node) in ParentHirIterator::new(hir_id, &self) { for (_, node) in self.parent_iter(hir_id) {
match node { match node {
Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::ImplItem(_) => { Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::ImplItem(_) => {
break; break;
@ -788,7 +790,7 @@ impl<'hir> Map<'hir> {
/// Returns the nearest enclosing scope. A scope is roughly an item or block. /// Returns the nearest enclosing scope. A scope is roughly an item or block.
pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> { pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> {
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) { for (hir_id, node) in self.parent_iter(hir_id) {
if match node { if match node {
Node::Item(i) => match i.kind { Node::Item(i) => match i.kind {
ItemKind::Fn(..) ItemKind::Fn(..)

View file

@ -182,7 +182,7 @@ fn parse_inline_asm<'a>(
}; };
let is_rw = output.is_some(); let is_rw = output.is_some();
let is_indirect = constraint_str.contains("*"); let is_indirect = constraint_str.contains('*');
outputs.push(ast::InlineAsmOutput { outputs.push(ast::InlineAsmOutput {
constraint: output.unwrap_or(constraint), constraint: output.unwrap_or(constraint),
expr, expr,
@ -199,7 +199,7 @@ fn parse_inline_asm<'a>(
let constraint = parse_asm_str(&mut p)?; let constraint = parse_asm_str(&mut p)?;
if constraint.as_str().starts_with("=") { if constraint.as_str().starts_with('=') {
struct_span_err!( struct_span_err!(
cx.parse_sess.span_diagnostic, cx.parse_sess.span_diagnostic,
p.prev_span, p.prev_span,
@ -207,7 +207,7 @@ fn parse_inline_asm<'a>(
"input operand constraint contains '='" "input operand constraint contains '='"
) )
.emit(); .emit();
} else if constraint.as_str().starts_with("+") { } else if constraint.as_str().starts_with('+') {
struct_span_err!( struct_span_err!(
cx.parse_sess.span_diagnostic, cx.parse_sess.span_diagnostic,
p.prev_span, p.prev_span,
@ -234,7 +234,7 @@ fn parse_inline_asm<'a>(
if OPTIONS.iter().any(|&opt| s == opt) { if OPTIONS.iter().any(|&opt| s == opt) {
cx.span_warn(p.prev_span, "expected a clobber, found an option"); cx.span_warn(p.prev_span, "expected a clobber, found an option");
} else if s.as_str().starts_with("{") || s.as_str().ends_with("}") { } else if s.as_str().starts_with('{') || s.as_str().ends_with('}') {
struct_span_err!( struct_span_err!(
cx.parse_sess.span_diagnostic, cx.parse_sess.span_diagnostic,
p.prev_span, p.prev_span,

View file

@ -158,7 +158,7 @@ fn parse_args<'a>(
} // accept trailing commas } // accept trailing commas
if p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq) { if p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq) {
named = true; named = true;
let name = if let token::Ident(name, _) = p.token.kind { let name = if let token::Ident(name, _) = p.normalized_token.kind {
p.bump(); p.bump();
name name
} else { } else {
@ -894,7 +894,7 @@ pub fn expand_preparsed_format_args(
}; };
let (is_literal, fmt_snippet) = match ecx.source_map().span_to_snippet(fmt_sp) { let (is_literal, fmt_snippet) = match ecx.source_map().span_to_snippet(fmt_sp) {
Ok(s) => (s.starts_with("\"") || s.starts_with("r#"), Some(s)), Ok(s) => (s.starts_with('"') || s.starts_with("r#"), Some(s)),
_ => (false, None), _ => (false, None),
}; };

View file

@ -917,7 +917,7 @@ impl ThinLTOImports {
if line.is_empty() { if line.is_empty() {
let importing_module = current_module.take().expect("Importing module not set"); let importing_module = current_module.take().expect("Importing module not set");
imports.insert(importing_module, mem::replace(&mut current_imports, vec![])); imports.insert(importing_module, mem::replace(&mut current_imports, vec![]));
} else if line.starts_with(" ") { } else if line.starts_with(' ') {
// Space marks an imported module // Space marks an imported module
assert_ne!(current_module, None); assert_ne!(current_module, None);
current_imports.push(line.trim().to_string()); current_imports.push(line.trim().to_string());

View file

@ -78,7 +78,7 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input:
} }
if let Input::File(ref path) = *input { if let Input::File(ref path) = *input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with("-") { if s.starts_with('-') {
let msg = format!( let msg = format!(
"crate names cannot start with a `-`, but \ "crate names cannot start with a `-`, but \
`{}` has a leading hyphen", `{}` has a leading hyphen",

View file

@ -4,7 +4,7 @@ use std::fs;
use std::io; use std::io;
pub fn arg_expand(arg: String) -> Result<Vec<String>, Error> { pub fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
if arg.starts_with("@") { if arg.starts_with('@') {
let path = &arg[1..]; let path = &arg[1..];
let file = match fs::read_to_string(path) { let file = match fs::read_to_string(path) {
Ok(file) => file, Ok(file) => file,

View file

@ -521,7 +521,7 @@ fn stdout_isatty() -> bool {
fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
let normalised = let normalised =
if code.starts_with("E") { code.to_string() } else { format!("E{0:0>4}", code) }; if code.starts_with('E') { code.to_string() } else { format!("E{0:0>4}", code) };
match registry.find_description(&normalised) { match registry.find_description(&normalised) {
Some(ref description) => { Some(ref description) => {
let mut is_in_code_block = false; let mut is_in_code_block = false;
@ -601,7 +601,7 @@ impl RustcDefaultCalls {
}); });
compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs) compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs)
} else { } else {
sess.fatal(&format!("rlink must be a file")) sess.fatal("rlink must be a file")
} }
} }

View file

@ -503,13 +503,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
} }
fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) { fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) {
let attr = let attr = attr::find_by_name(item.attrs(), sym::derive);
attr::find_by_name(item.attrs(), sym::derive).expect("`derive` attribute should exist"); let span = attr.map_or(item.span(), |attr| attr.span);
let span = attr.span;
let mut err = self let mut err = self
.cx .cx
.struct_span_err(span, "`derive` may only be applied to structs, enums and unions"); .struct_span_err(span, "`derive` may only be applied to structs, enums and unions");
if let ast::AttrStyle::Inner = attr.style { if let Some(ast::Attribute { style: ast::AttrStyle::Inner, .. }) = attr {
let trait_list = derives.iter().map(|t| pprust::path_to_string(t)).collect::<Vec<_>>(); let trait_list = derives.iter().map(|t| pprust::path_to_string(t)).collect::<Vec<_>>();
let suggestion = format!("#[derive({})]", trait_list.join(", ")); let suggestion = format!("#[derive({})]", trait_list.join(", "));
err.span_suggestion( err.span_suggestion(
@ -1669,10 +1668,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
} }
} }
} else { } else {
let mut err = self.cx.struct_span_err( let mut err = self
it.span(), .cx
&format!("expected path to external documentation"), .struct_span_err(it.span(), "expected path to external documentation");
);
// Check if the user erroneously used `doc(include(...))` syntax. // Check if the user erroneously used `doc(include(...))` syntax.
let literal = it.meta_item_list().and_then(|list| { let literal = it.meta_item_list().and_then(|list| {

View file

@ -753,6 +753,12 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
fn get_macro_name(token: &Token) -> Option<(Name, bool)> { fn get_macro_name(token: &Token) -> Option<(Name, bool)> {
match token.kind { match token.kind {
token::Ident(name, is_raw) if name != kw::Underscore => Some((name, is_raw)), token::Ident(name, is_raw) if name != kw::Underscore => Some((name, is_raw)),
token::Interpolated(ref nt) => match **nt {
token::NtIdent(ident, is_raw) if ident.name != kw::Underscore => {
Some((ident.name, is_raw))
}
_ => None,
},
_ => None, _ => None,
} }
} }
@ -883,9 +889,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
// this could be handled like a token, since it is one // this could be handled like a token, since it is one
sym::ident => { sym::ident => {
if let Some((name, is_raw)) = get_macro_name(&p.token) { if let Some((name, is_raw)) = get_macro_name(&p.token) {
let span = p.token.span;
p.bump(); p.bump();
token::NtIdent(Ident::new(name, span), is_raw) token::NtIdent(Ident::new(name, p.normalized_prev_token.span), is_raw)
} else { } else {
let token_str = pprust::token_to_string(&p.token); let token_str = pprust::token_to_string(&p.token);
let msg = &format!("expected ident, found {}", &token_str); let msg = &format!("expected ident, found {}", &token_str);

View file

@ -205,7 +205,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
TokenTree::Literal(self::Literal { TokenTree::Literal(self::Literal {
lit: token::Lit { kind: token::Integer, symbol, suffix }, lit: token::Lit { kind: token::Integer, symbol, suffix },
span, span,
}) if symbol.as_str().starts_with("-") => { }) if symbol.as_str().starts_with('-') => {
let minus = BinOp(BinOpToken::Minus); let minus = BinOp(BinOpToken::Minus);
let symbol = Symbol::intern(&symbol.as_str()[1..]); let symbol = Symbol::intern(&symbol.as_str()[1..]);
let integer = TokenKind::lit(token::Integer, symbol, suffix); let integer = TokenKind::lit(token::Integer, symbol, suffix);
@ -216,7 +216,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
TokenTree::Literal(self::Literal { TokenTree::Literal(self::Literal {
lit: token::Lit { kind: token::Float, symbol, suffix }, lit: token::Lit { kind: token::Float, symbol, suffix },
span, span,
}) if symbol.as_str().starts_with("-") => { }) if symbol.as_str().starts_with('-') => {
let minus = BinOp(BinOpToken::Minus); let minus = BinOp(BinOpToken::Minus);
let symbol = Symbol::intern(&symbol.as_str()[1..]); let symbol = Symbol::intern(&symbol.as_str()[1..]);
let float = TokenKind::lit(token::Float, symbol, suffix); let float = TokenKind::lit(token::Float, symbol, suffix);

View file

@ -1504,7 +1504,7 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
let end_point = sm.end_point(*span); let end_point = sm.end_point(*span);
if let Ok(end_string) = sm.span_to_snippet(end_point) { if let Ok(end_string) = sm.span_to_snippet(end_point) {
!(end_string.ends_with("}") || end_string.ends_with(")")) !(end_string.ends_with('}') || end_string.ends_with(')'))
} else { } else {
false false
} }

View file

@ -81,10 +81,7 @@ impl AssertModuleSource<'tcx> {
if !self.tcx.sess.opts.debugging_opts.query_dep_graph { if !self.tcx.sess.opts.debugging_opts.query_dep_graph {
self.tcx.sess.span_fatal( self.tcx.sess.span_fatal(
attr.span, attr.span,
&format!( "found CGU-reuse attribute but `-Zquery-dep-graph` was not specified",
"found CGU-reuse attribute but `-Zquery-dep-graph` \
was not specified"
),
); );
} }
@ -107,7 +104,7 @@ impl AssertModuleSource<'tcx> {
} }
// Split of the "special suffix" if there is one. // Split of the "special suffix" if there is one.
let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind(".") { let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind('.') {
(&user_path[..index], Some(&user_path[index + 1..])) (&user_path[..index], Some(&user_path[index + 1..]))
} else { } else {
(&user_path[..], None) (&user_path[..], None)

View file

@ -537,10 +537,7 @@ impl FindAllAttrs<'tcx> {
if !checked_attrs.contains(&attr.id) { if !checked_attrs.contains(&attr.id) {
self.tcx.sess.span_err( self.tcx.sess.span_err(
attr.span, attr.span,
&format!( "found unchecked `#[rustc_dirty]` / `#[rustc_clean]` attribute",
"found unchecked \
`#[rustc_dirty]` / `#[rustc_clean]` attribute"
),
); );
} }
} }

View file

@ -152,7 +152,7 @@ pub fn lock_file_path(session_dir: &Path) -> PathBuf {
let directory_name = session_dir.file_name().unwrap().to_string_lossy(); let directory_name = session_dir.file_name().unwrap().to_string_lossy();
assert_no_characters_lost(&directory_name); assert_no_characters_lost(&directory_name);
let dash_indices: Vec<_> = directory_name.match_indices("-").map(|(idx, _)| idx).collect(); let dash_indices: Vec<_> = directory_name.match_indices('-').map(|(idx, _)| idx).collect();
if dash_indices.len() != 3 { if dash_indices.len() != 3 {
bug!( bug!(
"Encountered incremental compilation session directory with \ "Encountered incremental compilation session directory with \
@ -342,7 +342,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
// Keep the 's-{timestamp}-{random-number}' prefix, but replace the // Keep the 's-{timestamp}-{random-number}' prefix, but replace the
// '-working' part with the SVH of the crate // '-working' part with the SVH of the crate
let dash_indices: Vec<_> = old_sub_dir_name.match_indices("-").map(|(idx, _)| idx).collect(); let dash_indices: Vec<_> = old_sub_dir_name.match_indices('-').map(|(idx, _)| idx).collect();
if dash_indices.len() != 3 { if dash_indices.len() != 3 {
bug!( bug!(
"Encountered incremental compilation session directory with \ "Encountered incremental compilation session directory with \
@ -594,7 +594,7 @@ fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime
return Err(()); return Err(());
} }
let dash_indices: Vec<_> = directory_name.match_indices("-").map(|(idx, _)| idx).collect(); let dash_indices: Vec<_> = directory_name.match_indices('-').map(|(idx, _)| idx).collect();
if dash_indices.len() != 3 { if dash_indices.len() != 3 {
return Err(()); return Err(());
} }

View file

@ -39,10 +39,10 @@ pub struct OverlapResult<'tcx> {
} }
pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) { pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) {
err.note(&format!( err.note(
"this behavior recently changed as a result of a bug fix; \ "this behavior recently changed as a result of a bug fix; \
see rust-lang/rust#56105 for details" see rust-lang/rust#56105 for details",
)); );
} }
/// If there are types that satisfy both impls, invokes `on_overlap` /// If there are types that satisfy both impls, invokes `on_overlap`

View file

@ -935,9 +935,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// Already reported in the query. // Already reported in the query.
ConstEvalFailure(ErrorHandled::Reported) => { ConstEvalFailure(ErrorHandled::Reported) => {
self.tcx self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
.sess
.delay_span_bug(span, &format!("constant in type had an ignored error"));
return; return;
} }

View file

@ -232,10 +232,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// found type `()` // found type `()`
if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) { if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) {
let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); let trait_assoc_item = tcx.associated_item(proj.projection_def_id());
if let Some(impl_item) = items if let Some(impl_item) =
.iter() items.iter().find(|item| item.ident == trait_assoc_item.ident)
.filter(|item| item.ident == trait_assoc_item.ident)
.next()
{ {
cause.span = impl_item.span; cause.span = impl_item.span;
cause.code = traits::AssocTypeBound(Box::new(AssocTypeBoundData { cause.code = traits::AssocTypeBound(Box::new(AssocTypeBoundData {
@ -285,13 +283,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
{ {
if let Some((impl_item, trait_assoc_item)) = trait_assoc_items if let Some((impl_item, trait_assoc_item)) = trait_assoc_items
.iter() .iter()
.filter(|i| i.def_id == *item_def_id) .find(|i| i.def_id == *item_def_id)
.next()
.and_then(|trait_assoc_item| { .and_then(|trait_assoc_item| {
items items
.iter() .iter()
.filter(|i| i.ident == trait_assoc_item.ident) .find(|i| i.ident == trait_assoc_item.ident)
.next()
.map(|impl_item| (impl_item, trait_assoc_item)) .map(|impl_item| (impl_item, trait_assoc_item))
}) })
{ {

View file

@ -244,7 +244,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
.as_ref() .as_ref()
.unwrap_or(&sess.target.target.options.codegen_backend); .unwrap_or(&sess.target.target.options.codegen_backend);
let backend = match &codegen_name[..] { let backend = match &codegen_name[..] {
filename if filename.contains(".") => load_backend_from_dylib(filename.as_ref()), filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
codegen_name => get_builtin_codegen_backend(codegen_name), codegen_name => get_builtin_codegen_backend(codegen_name),
}; };

View file

@ -178,7 +178,7 @@ fn main() {
for lib in output(&mut cmd).split_whitespace() { for lib in output(&mut cmd).split_whitespace() {
let name = if lib.starts_with("-l") { let name = if lib.starts_with("-l") {
&lib[2..] &lib[2..]
} else if lib.starts_with("-") { } else if lib.starts_with('-') {
&lib[1..] &lib[1..]
} else if Path::new(lib).exists() { } else if Path::new(lib).exists() {
// On MSVC llvm-config will print the full name to libraries, but // On MSVC llvm-config will print the full name to libraries, but

View file

@ -680,10 +680,7 @@ impl<'a> CrateLoader<'a> {
// Sanity check the loaded crate to ensure it is indeed a profiler runtime // Sanity check the loaded crate to ensure it is indeed a profiler runtime
if !data.is_profiler_runtime() { if !data.is_profiler_runtime() {
self.sess.err(&format!( self.sess.err("the crate `profiler_builtins` is not a profiler runtime");
"the crate `profiler_builtins` is not \
a profiler runtime"
));
} }
} }
} }

View file

@ -612,7 +612,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} else { } else {
"'_".to_string() "'_".to_string()
}; };
let suggestion = if snippet.ends_with(";") { let suggestion = if snippet.ends_with(';') {
// `type X = impl Trait;` // `type X = impl Trait;`
format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name) format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name)
} else { } else {

View file

@ -365,7 +365,7 @@ fn do_mir_borrowck<'a, 'tcx>(
// Skip over locals that begin with an underscore or have no name // Skip over locals that begin with an underscore or have no name
match mbcx.local_names[local] { match mbcx.local_names[local] {
Some(name) => { Some(name) => {
if name.as_str().starts_with("_") { if name.as_str().starts_with('_') {
continue; continue;
} }
} }

View file

@ -689,11 +689,7 @@ pub trait BottomValue {
/// 3. Override `join` to do the opposite from what it's doing now. /// 3. Override `join` to do the opposite from what it's doing now.
#[inline] #[inline]
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool { fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
if Self::BOTTOM_VALUE == false { if !Self::BOTTOM_VALUE { inout_set.union(in_set) } else { inout_set.intersect(in_set) }
inout_set.union(in_set)
} else {
inout_set.intersect(in_set)
}
} }
} }

View file

@ -65,10 +65,8 @@ impl NonConstOp for Downcast {
pub struct FnCallIndirect; pub struct FnCallIndirect;
impl NonConstOp for FnCallIndirect { impl NonConstOp for FnCallIndirect {
fn emit_error(&self, item: &Item<'_, '_>, span: Span) { fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
let mut err = item let mut err =
.tcx item.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn");
.sess
.struct_span_err(span, &format!("function pointers are not allowed in const fn"));
err.emit(); err.emit();
} }
} }

View file

@ -122,7 +122,7 @@ impl<'tcx> MirSource<'tcx> {
/// type `T`. /// type `T`.
pub fn default_name<T: ?Sized>() -> Cow<'static, str> { pub fn default_name<T: ?Sized>() -> Cow<'static, str> {
let name = ::std::any::type_name::<T>(); let name = ::std::any::type_name::<T>();
if let Some(tail) = name.rfind(":") { Cow::from(&name[tail + 1..]) } else { Cow::from(name) } if let Some(tail) = name.rfind(':') { Cow::from(&name[tail + 1..]) } else { Cow::from(name) }
} }
/// A streamlined trait that you can implement to create a pass; the /// A streamlined trait that you can implement to create a pass; the

View file

@ -13,7 +13,7 @@ use syntax::ast::{
}; };
use syntax::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use syntax::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::token::{self, token_can_begin_expr, TokenKind}; use syntax::token::{self, TokenKind};
use syntax::util::parser::AssocOp; use syntax::util::parser::AssocOp;
use log::{debug, trace}; use log::{debug, trace};
@ -192,12 +192,12 @@ impl<'a> Parser<'a> {
TokenKind::CloseDelim(token::DelimToken::Brace), TokenKind::CloseDelim(token::DelimToken::Brace),
TokenKind::CloseDelim(token::DelimToken::Paren), TokenKind::CloseDelim(token::DelimToken::Paren),
]; ];
if let token::Ident(name, false) = self.token.kind { if let token::Ident(name, false) = self.normalized_token.kind {
if Ident::new(name, self.token.span).is_raw_guess() if Ident::new(name, self.normalized_token.span).is_raw_guess()
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind)) && self.look_ahead(1, |t| valid_follow.contains(&t.kind))
{ {
err.span_suggestion( err.span_suggestion(
self.token.span, self.normalized_token.span,
"you can escape reserved keywords to use them as identifiers", "you can escape reserved keywords to use them as identifiers",
format!("r#{}", name), format!("r#{}", name),
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
@ -900,8 +900,7 @@ impl<'a> Parser<'a> {
} else if !sm.is_multiline(self.prev_span.until(self.token.span)) { } else if !sm.is_multiline(self.prev_span.until(self.token.span)) {
// The current token is in the same line as the prior token, not recoverable. // The current token is in the same line as the prior token, not recoverable.
} else if self.look_ahead(1, |t| { } else if self.look_ahead(1, |t| {
t == &token::CloseDelim(token::Brace) t == &token::CloseDelim(token::Brace) || t.can_begin_expr() && t.kind != token::Colon
|| token_can_begin_expr(t) && t.kind != token::Colon
}) && [token::Comma, token::Colon].contains(&self.token.kind) }) && [token::Comma, token::Colon].contains(&self.token.kind)
{ {
// Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is // Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is
@ -919,7 +918,7 @@ impl<'a> Parser<'a> {
} else if self.look_ahead(0, |t| { } else if self.look_ahead(0, |t| {
t == &token::CloseDelim(token::Brace) t == &token::CloseDelim(token::Brace)
|| ( || (
token_can_begin_expr(t) && t != &token::Semi && t != &token::Pound t.can_begin_expr() && t != &token::Semi && t != &token::Pound
// Avoid triggering with too many trailing `#` in raw string. // Avoid triggering with too many trailing `#` in raw string.
) )
}) { }) {

View file

@ -97,15 +97,14 @@ impl<'a> Parser<'a> {
fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> { fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> {
match self.parse_expr() { match self.parse_expr() {
Ok(expr) => Ok(expr), Ok(expr) => Ok(expr),
Err(mut err) => match self.token.kind { Err(mut err) => match self.normalized_token.kind {
token::Ident(name, false) token::Ident(name, false)
if name == kw::Underscore && self.look_ahead(1, |t| t == &token::Comma) => if name == kw::Underscore && self.look_ahead(1, |t| t == &token::Comma) =>
{ {
// Special-case handling of `foo(_, _, _)` // Special-case handling of `foo(_, _, _)`
err.emit(); err.emit();
let sp = self.token.span;
self.bump(); self.bump();
Ok(self.mk_expr(sp, ExprKind::Err, AttrVec::new())) Ok(self.mk_expr(self.prev_token.span, ExprKind::Err, AttrVec::new()))
} }
_ => Err(err), _ => Err(err),
}, },
@ -166,7 +165,7 @@ impl<'a> Parser<'a> {
while let Some(op) = self.check_assoc_op() { while let Some(op) = self.check_assoc_op() {
// Adjust the span for interpolated LHS to point to the `$lhs` token // Adjust the span for interpolated LHS to point to the `$lhs` token
// and not to what it refers to. // and not to what it refers to.
let lhs_span = match self.unnormalized_prev_token.kind { let lhs_span = match self.prev_token.kind {
TokenKind::Interpolated(..) => self.prev_span, TokenKind::Interpolated(..) => self.prev_span,
_ => lhs.span, _ => lhs.span,
}; };
@ -333,7 +332,7 @@ impl<'a> Parser<'a> {
/// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively. /// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively.
fn check_assoc_op(&self) -> Option<Spanned<AssocOp>> { fn check_assoc_op(&self) -> Option<Spanned<AssocOp>> {
Some(Spanned { Some(Spanned {
node: match (AssocOp::from_token(&self.token), &self.token.kind) { node: match (AssocOp::from_token(&self.token), &self.normalized_token.kind) {
(Some(op), _) => op, (Some(op), _) => op,
(None, token::Ident(sym::and, false)) => { (None, token::Ident(sym::and, false)) => {
self.error_bad_logical_op("and", "&&", "conjunction"); self.error_bad_logical_op("and", "&&", "conjunction");
@ -345,7 +344,7 @@ impl<'a> Parser<'a> {
} }
_ => return None, _ => return None,
}, },
span: self.token.span, span: self.normalized_token.span,
}) })
} }
@ -437,7 +436,7 @@ impl<'a> Parser<'a> {
let attrs = self.parse_or_use_outer_attributes(attrs)?; let attrs = self.parse_or_use_outer_attributes(attrs)?;
let lo = self.token.span; let lo = self.token.span;
// Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr() // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
let (hi, ex) = match self.token.kind { let (hi, ex) = match self.normalized_token.kind {
token::Not => self.parse_unary_expr(lo, UnOp::Not), // `!expr` token::Not => self.parse_unary_expr(lo, UnOp::Not), // `!expr`
token::Tilde => self.recover_tilde_expr(lo), // `~expr` token::Tilde => self.recover_tilde_expr(lo), // `~expr`
token::BinOp(token::Minus) => self.parse_unary_expr(lo, UnOp::Neg), // `-expr` token::BinOp(token::Minus) => self.parse_unary_expr(lo, UnOp::Neg), // `-expr`
@ -523,7 +522,7 @@ impl<'a> Parser<'a> {
) -> PResult<'a, (Span, P<Expr>)> { ) -> PResult<'a, (Span, P<Expr>)> {
expr.map(|e| { expr.map(|e| {
( (
match self.unnormalized_prev_token.kind { match self.prev_token.kind {
TokenKind::Interpolated(..) => self.prev_span, TokenKind::Interpolated(..) => self.prev_span,
_ => e.span, _ => e.span,
}, },
@ -704,7 +703,7 @@ impl<'a> Parser<'a> {
} }
fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
match self.token.kind { match self.normalized_token.kind {
token::Ident(..) => self.parse_dot_suffix(base, lo), token::Ident(..) => self.parse_dot_suffix(base, lo),
token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => { token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
Ok(self.parse_tuple_field_access_expr(lo, base, symbol, suffix)) Ok(self.parse_tuple_field_access_expr(lo, base, symbol, suffix))
@ -754,7 +753,7 @@ impl<'a> Parser<'a> {
s.print_usize(float.trunc() as usize); s.print_usize(float.trunc() as usize);
s.pclose(); s.pclose();
s.s.word("."); s.s.word(".");
s.s.word(fstr.splitn(2, ".").last().unwrap().to_string()) s.s.word(fstr.splitn(2, '.').last().unwrap().to_string())
}); });
err.span_suggestion( err.span_suggestion(
lo.to(self.prev_span), lo.to(self.prev_span),
@ -773,8 +772,8 @@ impl<'a> Parser<'a> {
field: Symbol, field: Symbol,
suffix: Option<Symbol>, suffix: Option<Symbol>,
) -> P<Expr> { ) -> P<Expr> {
let span = self.token.span;
self.bump(); self.bump();
let span = self.prev_token.span;
let field = ExprKind::Field(base, Ident::new(field, span)); let field = ExprKind::Field(base, Ident::new(field, span));
self.expect_no_suffix(span, "a tuple index", suffix); self.expect_no_suffix(span, "a tuple index", suffix);
self.mk_expr(lo.to(span), field, AttrVec::new()) self.mk_expr(lo.to(span), field, AttrVec::new())
@ -798,7 +797,7 @@ impl<'a> Parser<'a> {
/// Assuming we have just parsed `.`, continue parsing into an expression. /// Assuming we have just parsed `.`, continue parsing into an expression.
fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> { fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
if self.token.span.rust_2018() && self.eat_keyword(kw::Await) { if self.normalized_token.span.rust_2018() && self.eat_keyword(kw::Await) {
return self.mk_await_expr(self_arg, lo); return self.mk_await_expr(self_arg, lo);
} }
@ -912,7 +911,7 @@ impl<'a> Parser<'a> {
// | ^ expected expression // | ^ expected expression
self.bump(); self.bump();
Ok(self.mk_expr_err(self.token.span)) Ok(self.mk_expr_err(self.token.span))
} else if self.token.span.rust_2018() { } else if self.normalized_token.span.rust_2018() {
// `Span::rust_2018()` is somewhat expensive; don't get it repeatedly. // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
if self.check_keyword(kw::Async) { if self.check_keyword(kw::Async) {
if self.is_async_block() { if self.is_async_block() {
@ -1342,7 +1341,7 @@ impl<'a> Parser<'a> {
if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable }; if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
let asyncness = let asyncness =
if self.token.span.rust_2018() { self.parse_asyncness() } else { Async::No }; if self.normalized_token.span.rust_2018() { self.parse_asyncness() } else { Async::No };
if asyncness.is_async() { if asyncness.is_async() {
// Feature-gate `async ||` closures. // Feature-gate `async ||` closures.
self.sess.gated_spans.gate(sym::async_closure, self.prev_span); self.sess.gated_spans.gate(sym::async_closure, self.prev_span);
@ -1556,9 +1555,8 @@ impl<'a> Parser<'a> {
fn eat_label(&mut self) -> Option<Label> { fn eat_label(&mut self) -> Option<Label> {
self.token.lifetime().map(|ident| { self.token.lifetime().map(|ident| {
let span = self.token.span;
self.bump(); self.bump();
Label { ident: Ident::new(ident.name, span) } Label { ident }
}) })
} }
@ -1700,7 +1698,7 @@ impl<'a> Parser<'a> {
fn is_try_block(&self) -> bool { fn is_try_block(&self) -> bool {
self.token.is_keyword(kw::Try) && self.token.is_keyword(kw::Try) &&
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
self.token.span.rust_2018() && self.normalized_token.span.rust_2018() &&
// Prevent `while try {} {}`, `if try {} {} else {}`, etc. // Prevent `while try {} {}`, `if try {} {} else {}`, etc.
!self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
} }
@ -1850,13 +1848,12 @@ impl<'a> Parser<'a> {
/// Use in case of error after field-looking code: `S { foo: () with a }`. /// Use in case of error after field-looking code: `S { foo: () with a }`.
fn find_struct_error_after_field_looking_code(&self) -> Option<Field> { fn find_struct_error_after_field_looking_code(&self) -> Option<Field> {
if let token::Ident(name, _) = self.token.kind { if let token::Ident(name, _) = self.normalized_token.kind {
if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) { if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
let span = self.token.span;
return Some(ast::Field { return Some(ast::Field {
ident: Ident::new(name, span), ident: Ident::new(name, self.normalized_token.span),
span, span: self.token.span,
expr: self.mk_expr_err(span), expr: self.mk_expr_err(self.token.span),
is_shorthand: false, is_shorthand: false,
attrs: AttrVec::new(), attrs: AttrVec::new(),
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,

View file

@ -121,15 +121,12 @@ impl<'a> Parser<'a> {
.span_label(attrs[0].span, "attributes must go before parameters") .span_label(attrs[0].span, "attributes must go before parameters")
.emit(); .emit();
} else { } else {
self.struct_span_err( self.struct_span_err(attrs[0].span, "attribute without generic parameters")
attrs[0].span, .span_label(
&format!("attribute without generic parameters"), attrs[0].span,
) "attributes are only permitted when preceding parameters",
.span_label( )
attrs[0].span, .emit();
"attributes are only permitted when preceding parameters",
)
.emit();
} }
} }
break; break;

View file

@ -741,11 +741,10 @@ impl<'a> Parser<'a> {
} }
fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> { fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
match self.token.kind { match self.normalized_token.kind {
token::Ident(name @ kw::Underscore, false) => { token::Ident(name @ kw::Underscore, false) => {
let span = self.token.span;
self.bump(); self.bump();
Ok(Ident::new(name, span)) Ok(Ident::new(name, self.normalized_prev_token.span))
} }
_ => self.parse_ident(), _ => self.parse_ident(),
} }
@ -1537,7 +1536,7 @@ impl<'a> Parser<'a> {
let is_name_required = match self.token.kind { let is_name_required = match self.token.kind {
token::DotDotDot => false, token::DotDotDot => false,
_ => req_name(&self.token), _ => req_name(&self.normalized_token),
}; };
let (pat, ty) = if is_name_required || self.is_named_param() { let (pat, ty) = if is_name_required || self.is_named_param() {
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required); debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
@ -1603,12 +1602,11 @@ impl<'a> Parser<'a> {
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> { fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
// Extract an identifier *after* having confirmed that the token is one. // Extract an identifier *after* having confirmed that the token is one.
let expect_self_ident = |this: &mut Self| { let expect_self_ident = |this: &mut Self| {
match this.token.kind { match this.normalized_token.kind {
// Preserve hygienic context. // Preserve hygienic context.
token::Ident(name, _) => { token::Ident(name, _) => {
let span = this.token.span;
this.bump(); this.bump();
Ident::new(name, span) Ident::new(name, this.normalized_prev_token.span)
} }
_ => unreachable!(), _ => unreachable!(),
} }
@ -1645,7 +1643,7 @@ impl<'a> Parser<'a> {
// Only a limited set of initial token sequences is considered `self` parameters; anything // Only a limited set of initial token sequences is considered `self` parameters; anything
// else is parsed as a normal function parameter list, so some lookahead is required. // else is parsed as a normal function parameter list, so some lookahead is required.
let eself_lo = self.token.span; let eself_lo = self.token.span;
let (eself, eself_ident, eself_hi) = match self.token.kind { let (eself, eself_ident, eself_hi) = match self.normalized_token.kind {
token::BinOp(token::And) => { token::BinOp(token::And) => {
let eself = if is_isolated_self(self, 1) { let eself = if is_isolated_self(self, 1) {
// `&self` // `&self`

View file

@ -86,23 +86,22 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
#[derive(Clone)] #[derive(Clone)]
pub struct Parser<'a> { pub struct Parser<'a> {
pub sess: &'a ParseSess, pub sess: &'a ParseSess,
/// The current non-normalized token.
pub token: Token,
/// The current normalized token. /// The current normalized token.
/// "Normalized" means that some interpolated tokens /// "Normalized" means that some interpolated tokens
/// (`$i: ident` and `$l: lifetime` meta-variables) are replaced /// (`$i: ident` and `$l: lifetime` meta-variables) are replaced
/// with non-interpolated identifier and lifetime tokens they refer to. /// with non-interpolated identifier and lifetime tokens they refer to.
/// Use span from this token if you need an isolated span. /// Use this if you need to check for `token::Ident` or `token::Lifetime` specifically,
pub token: Token, /// this also includes edition checks for edition-specific keyword identifiers.
/// The current non-normalized token if it's different from `token`. pub normalized_token: Token,
/// Use span from this token if you need to concatenate it with some neighbouring spans. /// The previous non-normalized token.
unnormalized_token: Token, pub prev_token: Token,
/// The previous normalized token. /// The previous normalized token.
/// Use span from this token if you need an isolated span. /// Use this if you need to check for `token::Ident` or `token::Lifetime` specifically,
prev_token: Token, /// this also includes edition checks for edition-specific keyword identifiers.
/// The previous non-normalized token if it's different from `prev_token`. pub normalized_prev_token: Token,
/// Use span from this token if you need to concatenate it with some neighbouring spans. /// FIXME: Remove in favor of the equivalent `prev_token.span`.
unnormalized_prev_token: Token,
/// Equivalent to `unnormalized_prev_token.span`.
/// FIXME: Remove in favor of `(unnormalized_)prev_token.span`.
pub prev_span: Span, pub prev_span: Span,
restrictions: Restrictions, restrictions: Restrictions,
/// Used to determine the path to externally loaded source files. /// Used to determine the path to externally loaded source files.
@ -375,9 +374,9 @@ impl<'a> Parser<'a> {
let mut parser = Parser { let mut parser = Parser {
sess, sess,
token: Token::dummy(), token: Token::dummy(),
unnormalized_token: Token::dummy(), normalized_token: Token::dummy(),
prev_token: Token::dummy(), prev_token: Token::dummy(),
unnormalized_prev_token: Token::dummy(), normalized_prev_token: Token::dummy(),
prev_span: DUMMY_SP, prev_span: DUMMY_SP,
restrictions: Restrictions::empty(), restrictions: Restrictions::empty(),
recurse_into_file_modules, recurse_into_file_modules,
@ -482,7 +481,7 @@ impl<'a> Parser<'a> {
} }
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
match self.token.kind { match self.normalized_token.kind {
token::Ident(name, _) => { token::Ident(name, _) => {
if self.token.is_reserved_ident() { if self.token.is_reserved_ident() {
let mut err = self.expected_ident_found(); let mut err = self.expected_ident_found();
@ -492,9 +491,8 @@ impl<'a> Parser<'a> {
return Err(err); return Err(err);
} }
} }
let span = self.token.span;
self.bump(); self.bump();
Ok(Ident::new(name, span)) Ok(Ident::new(name, self.normalized_prev_token.span))
} }
_ => Err(match self.prev_token.kind { _ => Err(match self.prev_token.kind {
TokenKind::DocComment(..) => { TokenKind::DocComment(..) => {
@ -824,16 +822,16 @@ impl<'a> Parser<'a> {
// tokens are replaced with usual identifier and lifetime tokens, // tokens are replaced with usual identifier and lifetime tokens,
// so the former are never encountered during normal parsing. // so the former are never encountered during normal parsing.
crate fn set_token(&mut self, token: Token) { crate fn set_token(&mut self, token: Token) {
self.unnormalized_token = token; self.token = token;
self.token = match &self.unnormalized_token.kind { self.normalized_token = match &self.token.kind {
token::Interpolated(nt) => match **nt { token::Interpolated(nt) => match **nt {
token::NtIdent(ident, is_raw) => { token::NtIdent(ident, is_raw) => {
Token::new(token::Ident(ident.name, is_raw), ident.span) Token::new(token::Ident(ident.name, is_raw), ident.span)
} }
token::NtLifetime(ident) => Token::new(token::Lifetime(ident.name), ident.span), token::NtLifetime(ident) => Token::new(token::Lifetime(ident.name), ident.span),
_ => self.unnormalized_token.clone(), _ => self.token.clone(),
}, },
_ => self.unnormalized_token.clone(), _ => self.token.clone(),
} }
} }
@ -847,11 +845,11 @@ impl<'a> Parser<'a> {
// Update the current and previous tokens. // Update the current and previous tokens.
self.prev_token = self.token.take(); self.prev_token = self.token.take();
self.unnormalized_prev_token = self.unnormalized_token.take(); self.normalized_prev_token = self.normalized_token.take();
self.set_token(next_token); self.set_token(next_token);
// Update fields derived from the previous token. // Update fields derived from the previous token.
self.prev_span = self.unnormalized_prev_token.span; self.prev_span = self.prev_token.span;
// Diagnostics. // Diagnostics.
self.expected_tokens.clear(); self.expected_tokens.clear();
@ -859,7 +857,7 @@ impl<'a> Parser<'a> {
/// Advance the parser by one token. /// Advance the parser by one token.
pub fn bump(&mut self) { pub fn bump(&mut self) {
let next_token = self.next_tok(self.unnormalized_token.span); let next_token = self.next_tok(self.token.span);
self.bump_with(next_token); self.bump_with(next_token);
} }
@ -890,7 +888,7 @@ impl<'a> Parser<'a> {
/// Parses asyncness: `async` or nothing. /// Parses asyncness: `async` or nothing.
fn parse_asyncness(&mut self) -> Async { fn parse_asyncness(&mut self) -> Async {
if self.eat_keyword(kw::Async) { if self.eat_keyword(kw::Async) {
let span = self.prev_span; let span = self.normalized_prev_token.span;
Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID } Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
} else { } else {
Async::No Async::No

View file

@ -134,7 +134,7 @@ impl<'a> Parser<'a> {
path path
}); });
let lo = self.unnormalized_token.span; let lo = self.token.span;
let mut segments = Vec::new(); let mut segments = Vec::new();
let mod_sep_ctxt = self.token.span.ctxt(); let mod_sep_ctxt = self.token.span.ctxt();
if self.eat(&token::ModSep) { if self.eat(&token::ModSep) {
@ -238,11 +238,10 @@ impl<'a> Parser<'a> {
} }
pub(super) fn parse_path_segment_ident(&mut self) -> PResult<'a, Ident> { pub(super) fn parse_path_segment_ident(&mut self) -> PResult<'a, Ident> {
match self.token.kind { match self.normalized_token.kind {
token::Ident(name, _) if name.is_path_segment_keyword() => { token::Ident(name, _) if name.is_path_segment_keyword() => {
let span = self.token.span;
self.bump(); self.bump();
Ok(Ident::new(name, span)) Ok(Ident::new(name, self.normalized_prev_token.span))
} }
_ => self.parse_ident(), _ => self.parse_ident(),
} }

View file

@ -89,7 +89,7 @@ impl<'a> Parser<'a> {
fn parse_stmt_item(&mut self, attrs: Vec<Attribute>) -> PResult<'a, Option<ast::Item>> { fn parse_stmt_item(&mut self, attrs: Vec<Attribute>) -> PResult<'a, Option<ast::Item>> {
let old = mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock); let old = mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
let item = self.parse_item_common(attrs.clone(), false, true, |_| true)?; let item = self.parse_item_common(attrs, false, true, |_| true)?;
self.directory.ownership = old; self.directory.ownership = old;
Ok(item) Ok(item)
} }

View file

@ -5,7 +5,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult}; use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::{kw, sym};
use syntax::ast::{self, BareFnTy, FnRetTy, GenericParam, Ident, Lifetime, MutTy, Ty, TyKind}; use syntax::ast::{self, BareFnTy, FnRetTy, GenericParam, Lifetime, MutTy, Ty, TyKind};
use syntax::ast::{ use syntax::ast::{
GenericBound, GenericBounds, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax,
}; };
@ -323,7 +323,7 @@ impl<'a> Parser<'a> {
/// Is a `dyn B0 + ... + Bn` type allowed here? /// Is a `dyn B0 + ... + Bn` type allowed here?
fn is_explicit_dyn_type(&mut self) -> bool { fn is_explicit_dyn_type(&mut self) -> bool {
self.check_keyword(kw::Dyn) self.check_keyword(kw::Dyn)
&& (self.token.span.rust_2018() && (self.normalized_token.span.rust_2018()
|| self.look_ahead(1, |t| { || self.look_ahead(1, |t| {
t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t) t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t)
})) }))
@ -604,9 +604,8 @@ impl<'a> Parser<'a> {
/// Parses a single lifetime `'a` or panics. /// Parses a single lifetime `'a` or panics.
pub fn expect_lifetime(&mut self) -> Lifetime { pub fn expect_lifetime(&mut self) -> Lifetime {
if let Some(ident) = self.token.lifetime() { if let Some(ident) = self.token.lifetime() {
let span = self.token.span;
self.bump(); self.bump();
Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID } Lifetime { ident, id: ast::DUMMY_NODE_ID }
} else { } else {
self.span_bug(self.token.span, "not a lifetime") self.span_bug(self.token.span, "not a lifetime")
} }

View file

@ -553,7 +553,7 @@ impl DeadVisitor<'tcx> {
node_type: &str, node_type: &str,
participle: &str, participle: &str,
) { ) {
if !name.as_str().starts_with("_") { if !name.as_str().starts_with('_') {
self.tcx.struct_span_lint_hir(lint::builtin::DEAD_CODE, id, span, |lint| { self.tcx.struct_span_lint_hir(lint::builtin::DEAD_CODE, id, span, |lint| {
lint.build(&format!("{} is never {}: `{}`", node_type, participle, name)).emit() lint.build(&format!("{} is never {}: `{}`", node_type, participle, name)).emit()
}); });

View file

@ -64,9 +64,9 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
for (name, &item) in WEAK_ITEMS_REFS.iter() { for (name, &item) in WEAK_ITEMS_REFS.iter() {
if missing.contains(&item) && !whitelisted(tcx, item) && items.require(item).is_err() { if missing.contains(&item) && !whitelisted(tcx, item) && items.require(item).is_err() {
if item == lang_items::PanicImplLangItem { if item == lang_items::PanicImplLangItem {
tcx.sess.err(&format!("`#[panic_handler]` function required, but not found")); tcx.sess.err("`#[panic_handler]` function required, but not found");
} else if item == lang_items::OomLangItem { } else if item == lang_items::OomLangItem {
tcx.sess.err(&format!("`#[alloc_error_handler]` function required, but not found")); tcx.sess.err("`#[alloc_error_handler]` function required, but not found");
} else { } else {
tcx.sess.err(&format!("language item required, but not found: `{}`", name)); tcx.sess.err(&format!("language item required, but not found: `{}`", name));
} }

View file

@ -1103,7 +1103,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// Macro uses will remove items from this set, and the remaining // Macro uses will remove items from this set, and the remaining
// items will be reported as `unused_macros`. // items will be reported as `unused_macros`.
fn insert_unused_macro(&mut self, ident: Ident, node_id: NodeId, span: Span) { fn insert_unused_macro(&mut self, ident: Ident, node_id: NodeId, span: Span) {
if !ident.as_str().starts_with("_") { if !ident.as_str().starts_with('_') {
self.r.unused_macros.insert(node_id, span); self.r.unused_macros.insert(node_id, span);
} }
} }

View file

@ -143,7 +143,7 @@ impl<'a> Resolver<'a> {
if has_generic_params == HasGenericParams::Yes { if has_generic_params == HasGenericParams::Yes {
// Try to retrieve the span of the function signature and generate a new // Try to retrieve the span of the function signature and generate a new
// message with a local type or const parameter. // message with a local type or const parameter.
let sugg_msg = &format!("try using a local generic parameter instead"); let sugg_msg = "try using a local generic parameter instead";
if let Some((sugg_span, snippet)) = sm.generate_local_type_param_snippet(span) { if let Some((sugg_span, snippet)) = sm.generate_local_type_param_snippet(span) {
// Suggest the modification to the user // Suggest the modification to the user
err.span_suggestion( err.span_suggestion(
@ -158,7 +158,7 @@ impl<'a> Resolver<'a> {
format!("try adding a local generic parameter in this method instead"), format!("try adding a local generic parameter in this method instead"),
); );
} else { } else {
err.help(&format!("try using a local generic parameter instead")); err.help("try using a local generic parameter instead");
} }
} }

View file

@ -456,8 +456,9 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
} }
fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) { fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) {
let rib_kind = match fn_kind { let rib_kind = match fn_kind {
FnKind::Fn(FnCtxt::Foreign, ..) => return visit::walk_fn(self, fn_kind, sp), // Bail if there's no body.
FnKind::Fn(FnCtxt::Free, ..) => FnItemRibKind, FnKind::Fn(.., None) => return visit::walk_fn(self, fn_kind, sp),
FnKind::Fn(FnCtxt::Free, ..) | FnKind::Fn(FnCtxt::Foreign, ..) => FnItemRibKind,
FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind, FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind,
}; };
let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp)); let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));

View file

@ -968,18 +968,14 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
for missing in &self.missing_named_lifetime_spots { for missing in &self.missing_named_lifetime_spots {
match missing { match missing {
MissingLifetimeSpot::Generics(generics) => { MissingLifetimeSpot::Generics(generics) => {
let (span, sugg) = if let Some(param) = generics let (span, sugg) = if let Some(param) =
.params generics.params.iter().find(|p| match p.kind {
.iter()
.filter(|p| match p.kind {
hir::GenericParamKind::Type { hir::GenericParamKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
.. ..
} => false, } => false,
_ => true, _ => true,
}) }) {
.next()
{
(param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref))
} else { } else {
(generics.span, format!("<{}>", lifetime_ref)) (generics.span, format!("<{}>", lifetime_ref))
@ -1053,25 +1049,24 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
}; };
let suggest_new = let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| {
|err: &mut DiagnosticBuilder<'_>, sugg: &str| { err.span_label(span, "expected named lifetime parameter");
err.span_label(span, "expected named lifetime parameter");
for missing in self.missing_named_lifetime_spots.iter().rev() { for missing in self.missing_named_lifetime_spots.iter().rev() {
let mut introduce_suggestion = vec![]; let mut introduce_suggestion = vec![];
let msg; let msg;
let should_break; let should_break;
introduce_suggestion.push(match missing { introduce_suggestion.push(match missing {
MissingLifetimeSpot::Generics(generics) => { MissingLifetimeSpot::Generics(generics) => {
msg = "consider introducing a named lifetime parameter".to_string(); msg = "consider introducing a named lifetime parameter".to_string();
should_break = true; should_break = true;
if let Some(param) = generics.params.iter().filter(|p| match p.kind { if let Some(param) = generics.params.iter().find(|p| match p.kind {
hir::GenericParamKind::Type { hir::GenericParamKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
.. ..
} => false, } => false,
_ => true, _ => true,
}).next() { }) {
(param.span.shrink_to_lo(), "'a, ".to_string()) (param.span.shrink_to_lo(), "'a, ".to_string())
} else { } else {
(generics.span, "<'a>".to_string()) (generics.span, "<'a>".to_string())
@ -1090,30 +1085,29 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
(*span, span_type.suggestion("'a")) (*span, span_type.suggestion("'a"))
} }
}); });
for param in params { for param in params {
if let Ok(snippet) = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span)
self.tcx.sess.source_map().span_to_snippet(param.span) {
{ if snippet.starts_with("&") && !snippet.starts_with("&'") {
if snippet.starts_with("&") && !snippet.starts_with("&'") { introduce_suggestion
introduce_suggestion .push((param.span, format!("&'a {}", &snippet[1..])));
.push((param.span, format!("&'a {}", &snippet[1..]))); } else if snippet.starts_with("&'_ ") {
} else if snippet.starts_with("&'_ ") { introduce_suggestion
introduce_suggestion .push((param.span, format!("&'a {}", &snippet[4..])));
.push((param.span, format!("&'a {}", &snippet[4..])));
}
} }
} }
introduce_suggestion.push((span, sugg.to_string()));
err.multipart_suggestion(
&msg,
introduce_suggestion,
Applicability::MaybeIncorrect,
);
if should_break {
break;
}
} }
}; introduce_suggestion.push((span, sugg.to_string()));
err.multipart_suggestion(
&msg,
introduce_suggestion,
Applicability::MaybeIncorrect,
);
if should_break {
break;
}
}
};
match ( match (
lifetime_names.len(), lifetime_names.len(),

View file

@ -2663,7 +2663,7 @@ impl<'a> Resolver<'a> {
"{} as {}{}", "{} as {}{}",
&snippet[..pos], &snippet[..pos],
suggested_name, suggested_name,
if snippet.ends_with(";") { ";" } else { "" } if snippet.ends_with(';') { ";" } else { "" }
)) ))
} }
} }

View file

@ -1500,10 +1500,8 @@ fn parse_libs(
{ {
early_error( early_error(
error_format, error_format,
&format!( "the library kind 'static-nobundle' is only \
"the library kind 'static-nobundle' is only \ accepted on the nightly compiler",
accepted on the nightly compiler"
),
); );
} }
let mut name_parts = name.splitn(2, ':'); let mut name_parts = name.splitn(2, ':');

View file

@ -101,7 +101,7 @@ impl TargetDataLayout {
match &*spec_parts { match &*spec_parts {
["e"] => dl.endian = Endian::Little, ["e"] => dl.endian = Endian::Little,
["E"] => dl.endian = Endian::Big, ["E"] => dl.endian = Endian::Big,
[p] if p.starts_with("P") => { [p] if p.starts_with('P') => {
dl.instruction_address_space = parse_address_space(&p[1..], "P")? dl.instruction_address_space = parse_address_space(&p[1..], "P")?
} }
["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?, ["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
@ -111,7 +111,7 @@ impl TargetDataLayout {
dl.pointer_size = size(s, p)?; dl.pointer_size = size(s, p)?;
dl.pointer_align = align(a, p)?; dl.pointer_align = align(a, p)?;
} }
[s, ref a @ ..] if s.starts_with("i") => { [s, ref a @ ..] if s.starts_with('i') => {
let bits = match s[1..].parse::<u64>() { let bits = match s[1..].parse::<u64>() {
Ok(bits) => bits, Ok(bits) => bits,
Err(_) => { Err(_) => {
@ -135,7 +135,7 @@ impl TargetDataLayout {
dl.i128_align = a; dl.i128_align = a;
} }
} }
[s, ref a @ ..] if s.starts_with("v") => { [s, ref a @ ..] if s.starts_with('v') => {
let v_size = size(&s[1..], "v")?; let v_size = size(&s[1..], "v")?;
let a = align(a, s)?; let a = align(a, s)?;
if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {

View file

@ -982,10 +982,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
), ),
); );
} }
err.note(&format!( err.note(
"because of the default `Self` reference, type parameters must be \ "because of the default `Self` reference, type parameters must be \
specified on object types" specified on object types",
)); );
err.emit(); err.emit();
} }
@ -1876,7 +1876,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
{ {
let types: Vec<_> = let types: Vec<_> =
assoc_items.iter().map(|item| format!("{} = Type", item.ident)).collect(); assoc_items.iter().map(|item| format!("{} = Type", item.ident)).collect();
let code = if snippet.ends_with(">") { let code = if snippet.ends_with('>') {
// The user wrote `Trait<'a>` or similar and we don't have a type we can // The user wrote `Trait<'a>` or similar and we don't have a type we can
// suggest, but at least we can clue them to the correct syntax // suggest, but at least we can clue them to the correct syntax
// `Trait<'a, Item = Type>` while accounting for the `<'a>` in the // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the

View file

@ -43,7 +43,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let cause = &self.misc(sp); self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
}
pub fn demand_suptype_with_origin(
&self,
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
match self.at(cause, self.param_env).sup(expected, actual) { match self.at(cause, self.param_env).sup(expected, actual) {
Ok(InferOk { obligations, value: () }) => { Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations); self.register_predicates(obligations);
@ -404,7 +412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{ {
if let hir::ExprKind::Lit(_) = expr.kind { if let hir::ExprKind::Lit(_) = expr.kind {
if let Ok(src) = sm.span_to_snippet(sp) { if let Ok(src) = sm.span_to_snippet(sp) {
if src.starts_with("\"") { if src.starts_with('"') {
return Some(( return Some((
sp, sp,
"consider adding a leading `b`", "consider adding a leading `b`",
@ -701,7 +709,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{ {
// Remove fractional part from literal, for example `42.0f32` into `42` // Remove fractional part from literal, for example `42.0f32` into `42`
let src = src.trim_end_matches(&checked_ty.to_string()); let src = src.trim_end_matches(&checked_ty.to_string());
src.split(".").next().unwrap() src.split('.').next().unwrap()
} else { } else {
src.trim_end_matches(&checked_ty.to_string()) src.trim_end_matches(&checked_ty.to_string())
}, },

View file

@ -4996,7 +4996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let sugg = if receiver.ends_with(".clone()") let sugg = if receiver.ends_with(".clone()")
&& method_call_list.contains(&method_call.as_str()) && method_call_list.contains(&method_call.as_str())
{ {
let max_len = receiver.rfind(".").unwrap(); let max_len = receiver.rfind('.').unwrap();
format!("{}{}", &receiver[..max_len], method_call) format!("{}{}", &receiver[..max_len], method_call)
} else { } else {
if expr.precedence().order() < ExprPrecedence::MethodCall.order() { if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
@ -5447,9 +5447,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or(false); .unwrap_or(false);
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res { let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
let ty = self.impl_self_ty(span, impl_def_id).ty; let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
let adt_def = ty.ty_adt_def();
match ty.kind { match ty.kind {
ty::Adt(adt_def, substs) if adt_def.has_ctor() => { ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
@ -5464,7 +5462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span, span,
"the `Self` constructor can only be used with tuple or unit structs", "the `Self` constructor can only be used with tuple or unit structs",
); );
if let Some(adt_def) = adt_def { if let Some(adt_def) = ty.ty_adt_def() {
match adt_def.adt_kind() { match adt_def.adt_kind() {
AdtKind::Enum => { AdtKind::Enum => {
err.help("did you mean to use one of the enum's variants?"); err.help("did you mean to use one of the enum's variants?");

View file

@ -597,12 +597,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ok(lstring) => { Ok(lstring) => {
err.span_suggestion( err.span_suggestion(
lhs_expr.span, lhs_expr.span,
if lstring.starts_with("&") { if lstring.starts_with('&') {
remove_borrow_msg remove_borrow_msg
} else { } else {
msg msg
}, },
if lstring.starts_with("&") { if lstring.starts_with('&') {
// let a = String::new(); // let a = String::new();
// let _ = &a + "bar"; // let _ = &a + "bar";
format!("{}", &lstring[1..]) format!("{}", &lstring[1..])
@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
is_assign, is_assign,
) { ) {
(Ok(l), Ok(r), false) => { (Ok(l), Ok(r), false) => {
let to_string = if l.starts_with("&") { let to_string = if l.starts_with('&') {
// let a = String::new(); let b = String::new(); // let a = String::new(); let b = String::new();
// let _ = &a + b; // let _ = &a + b;
format!("{}", &l[1..]) format!("{}", &l[1..])

View file

@ -9,9 +9,9 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{HirId, Pat, PatKind}; use rustc_hir::{HirId, Pat, PatKind};
use rustc_infer::infer; use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::Pattern; use rustc_infer::traits::{ObligationCause, Pattern};
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::Span; use rustc_span::source_map::{Span, Spanned};
use syntax::ast; use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name; use syntax::util::lev_distance::find_best_match_for_name;
@ -66,6 +66,11 @@ struct TopInfo<'tcx> {
} }
impl<'tcx> FnCtxt<'_, 'tcx> { impl<'tcx> FnCtxt<'_, 'tcx> {
fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr };
self.cause(cause_span, code)
}
fn demand_eqtype_pat_diag( fn demand_eqtype_pat_diag(
&self, &self,
cause_span: Span, cause_span: Span,
@ -73,9 +78,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
actual: Ty<'tcx>, actual: Ty<'tcx>,
ti: TopInfo<'tcx>, ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr }; self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
let cause = self.cause(cause_span, code);
self.demand_eqtype_with_origin(&cause, expected, actual)
} }
fn demand_eqtype_pat( fn demand_eqtype_pat(
@ -152,7 +155,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti) self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
} }
PatKind::Path(ref qpath) => { PatKind::Path(ref qpath) => {
self.check_pat_path(pat, path_res.unwrap(), qpath, expected) self.check_pat_path(pat, path_res.unwrap(), qpath, expected, ti)
} }
PatKind::Struct(ref qpath, fields, etc) => { PatKind::Struct(ref qpath, fields, etc) => {
self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti) self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti)
@ -361,16 +364,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Byte string patterns behave the same way as array patterns // Byte string patterns behave the same way as array patterns
// They can denote both statically and dynamically-sized byte arrays. // They can denote both statically and dynamically-sized byte arrays.
let mut pat_ty = ty; let mut pat_ty = ty;
if let hir::ExprKind::Lit(ref lt) = lt.kind { if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind {
if let ast::LitKind::ByteStr(_) = lt.node { let expected = self.structurally_resolved_type(span, expected);
let expected_ty = self.structurally_resolved_type(span, expected); if let ty::Ref(_, ty::TyS { kind: ty::Slice(_), .. }, _) = expected.kind {
if let ty::Ref(_, r_ty, _) = expected_ty.kind { let tcx = self.tcx;
if let ty::Slice(_) = r_ty.kind { pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
let tcx = self.tcx;
pat_ty =
tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
}
}
} }
} }
@ -384,7 +382,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// &'static str <: expected // &'static str <: expected
// //
// then that's equivalent to there existing a LUB. // then that's equivalent to there existing a LUB.
if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) { let cause = self.pattern_cause(ti, span);
if let Some(mut err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) {
err.emit_unless( err.emit_unless(
ti.span ti.span
.filter(|&s| { .filter(|&s| {
@ -543,8 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If there are multiple arms, make sure they all agree on // If there are multiple arms, make sure they all agree on
// what the type of the binding `x` ought to be. // what the type of the binding `x` ought to be.
if var_id != pat.hir_id { if var_id != pat.hir_id {
let vt = self.local_ty(pat.span, var_id).decl_ty; self.check_binding_alt_eq_ty(pat.span, var_id, local_ty, ti);
self.demand_eqtype_pat(pat.span, vt, local_ty, ti);
} }
if let Some(p) = sub { if let Some(p) = sub {
@ -554,6 +552,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
local_ty local_ty
} }
fn check_binding_alt_eq_ty(&self, span: Span, var_id: HirId, ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
let var_ty = self.local_ty(span, var_id).decl_ty;
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
let hir = self.tcx.hir();
let var_ty = self.resolve_vars_with_obligations(var_ty);
let msg = format!("first introduced with type `{}` here", var_ty);
err.span_label(hir.span(var_id), msg);
let in_arm = hir.parent_iter(var_id).any(|(_, n)| matches!(n, hir::Node::Arm(..)));
let pre = if in_arm { "in the same arm, " } else { "" };
err.note(&format!("{}a binding must have the same type in all alternatives", pre));
err.emit();
}
}
fn borrow_pat_suggestion( fn borrow_pat_suggestion(
&self, &self,
err: &mut DiagnosticBuilder<'_>, err: &mut DiagnosticBuilder<'_>,
@ -659,6 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]), path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]),
qpath: &hir::QPath<'_>, qpath: &hir::QPath<'_>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
@ -684,7 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type-check the path. // Type-check the path.
let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0; let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
self.demand_suptype(pat.span, expected, pat_ty); if let Some(mut err) =
self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
{
err.emit();
}
pat_ty pat_ty
} }
@ -901,7 +918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
let element_tys = tcx.mk_substs(element_tys_iter); let element_tys = tcx.mk_substs(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys)); let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
if let Some(mut err) = self.demand_eqtype_diag(span, expected, pat_ty) { if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) {
err.emit(); err.emit();
// Walk subpatterns with an expected type of `err` in this case to silence // Walk subpatterns with an expected type of `err` in this case to silence
// further errors being emitted when using the bindings. #50333 // further errors being emitted when using the bindings. #50333
@ -1205,7 +1222,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
let rptr_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); let rptr_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty); debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty);
let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty); let err = self.demand_eqtype_pat_diag(pat.span, expected, rptr_ty, ti);
// Look for a case like `fn foo(&foo: u32)` and suggest // Look for a case like `fn foo(&foo: u32)` and suggest
// `fn foo(foo: &u32)` // `fn foo(foo: &u32)`

View file

@ -283,10 +283,10 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
"no base type found for inherent implementation" "no base type found for inherent implementation"
) )
.span_label(ty.span, "impl requires a base type") .span_label(ty.span, "impl requires a base type")
.note(&format!( .note(
"either implement a trait on it or create a newtype \ "either implement a trait on it or create a newtype \
to wrap it instead" to wrap it instead",
)) )
.emit(); .emit();
return; return;
} }

View file

@ -1301,10 +1301,10 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
param.hir_id, param.hir_id,
param.span, param.span,
|lint| { |lint| {
lint.build(&format!( lint.build(
"defaults for type parameters are only allowed in \ "defaults for type parameters are only allowed in \
`struct`, `enum`, `type`, or `trait` definitions." `struct`, `enum`, `type`, or `trait` definitions.",
)) )
.emit(); .emit();
}, },
); );
@ -2224,7 +2224,7 @@ fn from_target_feature(
item.span(), item.span(),
format!("`{}` is not valid for this target", feature), format!("`{}` is not valid for this target", feature),
); );
if feature.starts_with("+") { if feature.starts_with('+') {
let valid = whitelist.contains_key(&feature[1..]); let valid = whitelist.contains_key(&feature[1..]);
if valid { if valid {
err.help("consider removing the leading `+` in the feature name"); err.help("consider removing the leading `+` in the feature name");
@ -2355,7 +2355,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
} else if attr.check_name(sym::export_name) { } else if attr.check_name(sym::export_name) {
if let Some(s) = attr.value_str() { if let Some(s) = attr.value_str() {
if s.as_str().contains("\0") { if s.as_str().contains('\0') {
// `#[export_name = ...]` will be converted to a null-terminated string, // `#[export_name = ...]` will be converted to a null-terminated string,
// so it may not contain any null characters. // so it may not contain any null characters.
struct_span_err!( struct_span_err!(

View file

@ -707,7 +707,7 @@ impl LangString {
x if x.starts_with("edition") => { x if x.starts_with("edition") => {
data.edition = x[7..].parse::<Edition>().ok(); data.edition = x[7..].parse::<Edition>().ok();
} }
x if allow_error_code_check && x.starts_with("E") && x.len() == 5 => { x if allow_error_code_check && x.starts_with('E') && x.len() == 5 => {
if x[1..].parse::<u32>().is_ok() { if x[1..].parse::<u32>().is_ok() {
data.error_codes.push(x.to_owned()); data.error_codes.push(x.to_owned());
seen_rust_tags = !seen_other_tags || seen_rust_tags; seen_rust_tags = !seen_other_tags || seen_rust_tags;

View file

@ -86,7 +86,7 @@ pub type NameDoc = (String, Option<String>);
crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
crate::html::format::display_fn(move |f| { crate::html::format::display_fn(move |f| {
if !v.ends_with("/") && !v.is_empty() { write!(f, "{}/", v) } else { write!(f, "{}", v) } if !v.ends_with('/') && !v.is_empty() { write!(f, "{}/", v) } else { write!(f, "{}", v) }
}) })
} }

View file

@ -534,7 +534,7 @@ fn extern_location(
if let Some(url) = extern_url { if let Some(url) = extern_url {
let mut url = url.to_string(); let mut url = url.to_string();
if !url.ends_with("/") { if !url.ends_with('/') {
url.push('/'); url.push('/');
} }
return Remote(url); return Remote(url);
@ -548,7 +548,7 @@ fn extern_location(
.filter_map(|a| a.value_str()) .filter_map(|a| a.value_str())
.map(|url| { .map(|url| {
let mut url = url.to_string(); let mut url = url.to_string();
if !url.ends_with("/") { if !url.ends_with('/') {
url.push('/') url.push('/')
} }
Remote(url) Remote(url)

View file

@ -19,7 +19,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
let mut count = 0; let mut count = 0;
for line in s.lines() { for line in s.lines() {
if line.starts_with("# ") || line.starts_with("%") { if line.starts_with("# ") || line.starts_with('%') {
// trim the whitespace after the symbol // trim the whitespace after the symbol
metadata.push(line[1..].trim_start()); metadata.push(line[1..].trim_start());
count += line.len() + 1; count += line.len() + 1;

View file

@ -398,7 +398,7 @@ pub fn make_test(
use rustc_span::source_map::FilePathMapping; use rustc_span::source_map::FilePathMapping;
let filename = FileName::anon_source_code(s); let filename = FileName::anon_source_code(s);
let source = crates + &everything_else; let source = crates + everything_else;
// Any errors in parsing should also appear when the doctest is compiled for real, so just // Any errors in parsing should also appear when the doctest is compiled for real, so just
// send all the errors that libsyntax emits directly into a `Sink` instead of stderr. // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.

View file

@ -2396,9 +2396,9 @@ impl<B: BufRead> Iterator for Lines<B> {
match self.buf.read_line(&mut buf) { match self.buf.read_line(&mut buf) {
Ok(0) => None, Ok(0) => None,
Ok(_n) => { Ok(_n) => {
if buf.ends_with("\n") { if buf.ends_with('\n') {
buf.pop(); buf.pop();
if buf.ends_with("\r") { if buf.ends_with('\r') {
buf.pop(); buf.pop();
} }
} }

View file

@ -147,36 +147,30 @@ impl Lit {
pub fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool { pub fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool {
let ident_token = Token::new(Ident(name, is_raw), span); let ident_token = Token::new(Ident(name, is_raw), span);
token_can_begin_expr(&ident_token)
}
pub fn token_can_begin_expr(ident_token: &Token) -> bool {
!ident_token.is_reserved_ident() !ident_token.is_reserved_ident()
|| ident_token.is_path_segment_keyword() || ident_token.is_path_segment_keyword()
|| match ident_token.kind { || [
TokenKind::Ident(ident, _) => [ kw::Async,
kw::Async, kw::Do,
kw::Do, kw::Box,
kw::Box, kw::Break,
kw::Break, kw::Continue,
kw::Continue, kw::False,
kw::False, kw::For,
kw::For, kw::If,
kw::If, kw::Let,
kw::Let, kw::Loop,
kw::Loop, kw::Match,
kw::Match, kw::Move,
kw::Move, kw::Return,
kw::Return, kw::True,
kw::True, kw::Unsafe,
kw::Unsafe, kw::While,
kw::While, kw::Yield,
kw::Yield, kw::Static,
kw::Static, ]
] .contains(&name)
.contains(&ident),
_ => false,
}
} }
fn ident_can_begin_type(name: ast::Name, span: Span, is_raw: bool) -> bool { fn ident_can_begin_type(name: ast::Name, span: Span, is_raw: bool) -> bool {
@ -369,8 +363,8 @@ impl Token {
Lifetime(..) | // labeled loop Lifetime(..) | // labeled loop
Pound => true, // expression attributes Pound => true, // expression attributes
Interpolated(ref nt) => match **nt { Interpolated(ref nt) => match **nt {
NtIdent(ident, is_raw) => ident_can_begin_expr(ident.name, ident.span, is_raw),
NtLiteral(..) | NtLiteral(..) |
NtIdent(..) |
NtExpr(..) | NtExpr(..) |
NtBlock(..) | NtBlock(..) |
NtPath(..) | NtPath(..) |
@ -397,7 +391,8 @@ impl Token {
Lt | BinOp(Shl) | // associated path Lt | BinOp(Shl) | // associated path
ModSep => true, // global path ModSep => true, // global path
Interpolated(ref nt) => match **nt { Interpolated(ref nt) => match **nt {
NtIdent(..) | NtTy(..) | NtPath(..) | NtLifetime(..) => true, NtIdent(ident, is_raw) => ident_can_begin_type(ident.name, ident.span, is_raw),
NtTy(..) | NtPath(..) | NtLifetime(..) => true,
_ => false, _ => false,
}, },
_ => false, _ => false,
@ -442,6 +437,7 @@ impl Token {
Literal(..) | BinOp(Minus) => true, Literal(..) | BinOp(Minus) => true,
Ident(name, false) if name.is_bool_lit() => true, Ident(name, false) if name.is_bool_lit() => true,
Interpolated(ref nt) => match &**nt { Interpolated(ref nt) => match &**nt {
NtIdent(ident, false) if ident.name.is_bool_lit() => true,
NtExpr(e) | NtLiteral(e) => matches!(e.kind, ast::ExprKind::Lit(_)), NtExpr(e) | NtLiteral(e) => matches!(e.kind, ast::ExprKind::Lit(_)),
_ => false, _ => false,
}, },

View file

@ -197,10 +197,17 @@ impl Lit {
} }
token::Literal(lit) => lit, token::Literal(lit) => lit,
token::Interpolated(ref nt) => { token::Interpolated(ref nt) => {
if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { match &**nt {
if let ast::ExprKind::Lit(lit) = &expr.kind { token::NtIdent(ident, false) if ident.name.is_bool_lit() => {
return Ok(lit.clone()); let lit = token::Lit::new(token::Bool, ident.name, None);
return Lit::from_lit_token(lit, ident.span);
} }
token::NtExpr(expr) | token::NtLiteral(expr) => {
if let ast::ExprKind::Lit(lit) = &expr.kind {
return Ok(lit.clone());
}
}
_ => {}
} }
return Err(LitError::NotLiteral); return Err(LitError::NotLiteral);
} }

View file

@ -1,14 +1,16 @@
error[E0507]: cannot move out of static item `D` error[E0507]: cannot move out of static item `D`
--> $DIR/move-error-snippets.rs:16:18 --> $DIR/move-error-snippets-ext.rs:5:17
| |
LL | | #[macro_use] LL | let a = $c;
| |__________________^ move occurs because `D` has type `A`, which does not implement the `Copy` trait | ^^
... | |
LL | aaa!(D); | move occurs because `D` has type `A`, which does not implement the `Copy` trait
| __________________^ | help: consider borrowing here: `&$c`
... |
LL | sss!(); ::: $DIR/move-error-snippets.rs:21:1
| ------- in this macro invocation |
LL | sss!();
| ------- in this macro invocation
| |
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -20,7 +20,7 @@ error[E0308]: mismatched types
--> $DIR/destructure-trait-ref.rs:32:10 --> $DIR/destructure-trait-ref.rs:32:10
| |
LL | let &&x = &1isize as &dyn T; LL | let &&x = &1isize as &dyn T;
| ^^ | ^^ ----------------- this expression has type `&dyn T`
| | | |
| expected trait object `dyn T`, found reference | expected trait object `dyn T`, found reference
| help: you can probably remove the explicit borrow: `x` | help: you can probably remove the explicit borrow: `x`
@ -32,7 +32,7 @@ error[E0308]: mismatched types
--> $DIR/destructure-trait-ref.rs:36:11 --> $DIR/destructure-trait-ref.rs:36:11
| |
LL | let &&&x = &(&1isize as &dyn T); LL | let &&&x = &(&1isize as &dyn T);
| ^^ | ^^ -------------------- this expression has type `&&dyn T`
| | | |
| expected trait object `dyn T`, found reference | expected trait object `dyn T`, found reference
| help: you can probably remove the explicit borrow: `x` | help: you can probably remove the explicit borrow: `x`

View file

@ -1,7 +1,7 @@
// Test that macro-expanded non-inline modules behave correctly // Test that macro-expanded non-inline modules behave correctly
macro_rules! mod_decl { macro_rules! mod_decl {
($i:ident) => { mod $i; } ($i:ident) => { mod $i; } //~ ERROR Cannot declare a non-inline module inside a block
} }
mod macro_expanded_mod_helper { mod macro_expanded_mod_helper {
@ -10,5 +10,4 @@ mod macro_expanded_mod_helper {
fn main() { fn main() {
mod_decl!(foo); mod_decl!(foo);
//~^ ERROR Cannot declare a non-inline module inside a block
} }

View file

@ -1,8 +1,13 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute error: Cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/macro-expanded-mod.rs:12:15 --> $DIR/macro-expanded-mod.rs:4:25
| |
LL | ($i:ident) => { mod $i; }
| ^^
...
LL | mod_decl!(foo); LL | mod_decl!(foo);
| ^^^ | --------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/elide-errors-on-mismatched-tuple.rs:14:9 --> $DIR/elide-errors-on-mismatched-tuple.rs:14:9
| |
LL | let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three LL | let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three
| ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements | ^^^^^^^^^ -------------------- this expression has type `(A, A)`
| |
| expected a tuple with 2 elements, found one with 3 elements
| |
= note: expected tuple `(A, A)` = note: expected tuple `(A, A)`
found tuple `(_, _, _)` found tuple `(_, _, _)`

View file

@ -1,10 +1,10 @@
error[E0124]: field `a` is already declared error[E0124]: field `a` is already declared
--> $DIR/fields-definition.rs:14:17 --> $DIR/fields-definition.rs:14:13
| |
LL | a: u8, LL | a: u8,
| ----- `a` first declared here | ----- `a` first declared here
LL | $a: u8, LL | $a: u8,
| ^^ field already declared | ^^^^^^ field already declared
... ...
LL | legacy!(a); LL | legacy!(a);
| ----------- in this macro invocation | ----------- in this macro invocation

View file

@ -12,6 +12,9 @@ LL | Some(k) => match k {
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-12552.rs:9:5 --> $DIR/issue-12552.rs:9:5
| |
LL | match t {
| - this expression has type `std::result::Result<_, {integer}>`
...
LL | None => () LL | None => ()
| ^^^^ expected enum `std::result::Result`, found enum `std::option::Option` | ^^^^ expected enum `std::result::Result`, found enum `std::option::Option`
| |

View file

@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/issue-37026.rs:6:9 --> $DIR/issue-37026.rs:6:9
| |
LL | let empty_struct::XEmpty2 = (); LL | let empty_struct::XEmpty2 = ();
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `empty_struct::XEmpty2` | ^^^^^^^^^^^^^^^^^^^^^ -- this expression has type `()`
| |
| expected `()`, found struct `empty_struct::XEmpty2`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-37026.rs:7:9 --> $DIR/issue-37026.rs:7:9

View file

@ -1,10 +1,9 @@
macro_rules! get_opt { macro_rules! get_opt {
($tgt:expr, $field:ident) => { ($tgt:expr, $field:ident) => {
if $tgt.has_$field() {} if $tgt.has_$field() {} //~ ERROR expected `{`, found `foo`
} }
} }
fn main() { fn main() {
get_opt!(bar, foo); get_opt!(bar, foo);
//~^ ERROR expected `{`, found `foo`
} }

View file

@ -1,13 +1,17 @@
error: expected `{`, found `foo` error: expected `{`, found `foo`
--> $DIR/issue-39848.rs:8:19 --> $DIR/issue-39848.rs:3:21
| |
LL | if $tgt.has_$field() {} LL | if $tgt.has_$field() {}
| -- -- help: try placing this code inside a block: `{ () }` | -- ^^^^^^--
| | | | |
| | expected `{`
| | help: try placing this code inside a block: `{ $field() }`
| this `if` expression has a condition, but no block | this `if` expression has a condition, but no block
... ...
LL | get_opt!(bar, foo); LL | get_opt!(bar, foo);
| ^^^ expected `{` | ------------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-5100.rs:8:9 --> $DIR/issue-5100.rs:8:9
| |
LL | match (true, false) {
| ------------- this expression has type `(bool, bool)`
LL | A::B => (), LL | A::B => (),
| ^^^^ expected tuple, found enum `A` | ^^^^ expected tuple, found enum `A`
| |
@ -10,6 +12,8 @@ LL | A::B => (),
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-5100.rs:17:9 --> $DIR/issue-5100.rs:17:9
| |
LL | match (true, false) {
| ------------- this expression has type `(bool, bool)`
LL | (true, false, false) => () LL | (true, false, false) => ()
| ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
| |
@ -19,6 +23,8 @@ LL | (true, false, false) => ()
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-5100.rs:25:9 --> $DIR/issue-5100.rs:25:9
| |
LL | match (true, false) {
| ------------- this expression has type `(bool, bool)`
LL | (true, false, false) => () LL | (true, false, false) => ()
| ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
| |
@ -39,6 +45,8 @@ LL | box (true, false) => ()
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-5100.rs:40:9 --> $DIR/issue-5100.rs:40:9
| |
LL | match (true, false) {
| ------------- this expression has type `(bool, bool)`
LL | &(true, false) => () LL | &(true, false) => ()
| ^^^^^^^^^^^^^^ expected tuple, found reference | ^^^^^^^^^^^^^^ expected tuple, found reference
| |

View file

@ -0,0 +1,45 @@
fn main() {}
struct S0<T>(T);
impl<T> S0<T> {
const C: S0<u8> = Self(0);
//~^ ERROR mismatched types
//~| ERROR mismatched types
fn foo() {
Self(0);
//~^ ERROR mismatched types
}
}
// Testing normalization.
trait Fun {
type Out;
}
impl<T> Fun for S0<T> {
type Out = Self;
}
trait Foo<T> {
fn foo();
}
impl<T> Foo<T> for <S0<T> as Fun>::Out {
fn foo() {
Self(0); //~ ERROR mismatched types
}
}
struct S1<T, U>(T, U);
impl<T> S1<T, u8> {
const C: S1<u8, u8> = Self(0, 1);
//~^ ERROR mismatched types
//~| ERROR mismatched types
}
struct S2<T>(T);
impl<T> S2<T> {
fn map<U>(x: U) -> S2<U> {
Self(x)
//~^ ERROR mismatched types
//~| ERROR mismatched types
}
}

View file

@ -0,0 +1,115 @@
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:5:28
|
LL | impl<T> S0<T> {
| - this type parameter
LL | const C: S0<u8> = Self(0);
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:5:23
|
LL | impl<T> S0<T> {
| - this type parameter
LL | const C: S0<u8> = Self(0);
| ^^^^^^^ expected `u8`, found type parameter `T`
|
= note: expected struct `S0<u8>`
found struct `S0<T>`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:10:14
|
LL | impl<T> S0<T> {
| - this type parameter
...
LL | Self(0);
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:27:14
|
LL | impl<T> Foo<T> for <S0<T> as Fun>::Out {
| - this type parameter
LL | fn foo() {
LL | Self(0);
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:33:32
|
LL | impl<T> S1<T, u8> {
| - this type parameter
LL | const C: S1<u8, u8> = Self(0, 1);
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:33:27
|
LL | impl<T> S1<T, u8> {
| - this type parameter
LL | const C: S1<u8, u8> = Self(0, 1);
| ^^^^^^^^^^ expected `u8`, found type parameter `T`
|
= note: expected struct `S1<u8, _>`
found struct `S1<T, _>`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:41:14
|
LL | impl<T> S2<T> {
| - expected type parameter
LL | fn map<U>(x: U) -> S2<U> {
| - found type parameter
LL | Self(x)
| ^ expected type parameter `T`, found type parameter `U`
|
= note: expected type parameter `T`
found type parameter `U`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:41:9
|
LL | impl<T> S2<T> {
| - found type parameter
LL | fn map<U>(x: U) -> S2<U> {
| - ----- expected `S2<U>` because of return type
| |
| expected type parameter
LL | Self(x)
| ^^^^^^^ expected type parameter `U`, found type parameter `T`
|
= note: expected struct `S2<U>`
found struct `S2<T>`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-7867.rs:7:9 --> $DIR/issue-7867.rs:7:9
| |
LL | match (true, false) {
| ------------- this expression has type `(bool, bool)`
LL | A::B => (), LL | A::B => (),
| ^^^^ expected tuple, found enum `A` | ^^^^ expected tuple, found enum `A`
| |

View file

@ -0,0 +1,10 @@
fn main() {}
struct CLI {
#[derive(parse())]
//~^ ERROR traits in `#[derive(...)]` don't accept arguments
//~| ERROR cannot find derive macro `parse` in this scope
//~| ERROR cannot find derive macro `parse` in this scope
path: (),
//~^ ERROR `derive` may only be applied to structs, enums and unions
}

View file

@ -0,0 +1,26 @@
error: traits in `#[derive(...)]` don't accept arguments
--> $DIR/issue-69341-malformed-derive-inert.rs:4:19
|
LL | #[derive(parse())]
| ^^ help: remove the arguments
error: `derive` may only be applied to structs, enums and unions
--> $DIR/issue-69341-malformed-derive-inert.rs:8:5
|
LL | path: (),
| ^^^^^^^^
error: cannot find derive macro `parse` in this scope
--> $DIR/issue-69341-malformed-derive-inert.rs:4:14
|
LL | #[derive(parse())]
| ^^^^^
error: cannot find derive macro `parse` in this scope
--> $DIR/issue-69341-malformed-derive-inert.rs:4:14
|
LL | #[derive(parse())]
| ^^^^^
error: aborting due to 4 previous errors

View file

@ -1,6 +1,9 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/match-ill-type2.rs:4:9 --> $DIR/match-ill-type2.rs:4:9
| |
LL | match 1i32 {
| ---- this expression has type `i32`
LL | 1i32 => 1,
LL | 2u32 => 1, LL | 2u32 => 1,
| ^^^^ expected `i32`, found `u32` | ^^^^ expected `i32`, found `u32`

View file

@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/match-tag-nullary.rs:4:40 --> $DIR/match-tag-nullary.rs:4:40
| |
LL | fn main() { let x: A = A::A; match x { B::B => { } } } LL | fn main() { let x: A = A::A; match x { B::B => { } } }
| ^^^^ expected enum `A`, found enum `B` | - ^^^^ expected enum `A`, found enum `B`
| |
| this expression has type `A`
error: aborting due to previous error error: aborting due to previous error

View file

@ -12,7 +12,11 @@ error[E0308]: mismatched types
LL | match x { LL | match x {
| - this expression has type `({integer}, {integer})` | - this expression has type `({integer}, {integer})`
LL | (0, ref y) | (y, 0) => {} LL | (0, ref y) | (y, 0) => {}
| ^ expected `&{integer}`, found integer | ----- ^ expected `&{integer}`, found integer
| |
| first introduced with type `&{integer}` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -3,7 +3,8 @@ error[E0308]: mismatched types
| |
LL | fn foo(&foo: Foo) { LL | fn foo(&foo: Foo) {
| ^^^^------ | ^^^^------
| | | | |
| | expected due to this
| expected struct `Foo`, found reference | expected struct `Foo`, found reference
| help: did you mean `foo`: `&Foo` | help: did you mean `foo`: `&Foo`
| |
@ -14,7 +15,7 @@ error[E0308]: mismatched types
--> $DIR/issue-38371.rs:18:9 --> $DIR/issue-38371.rs:18:9
| |
LL | fn agh(&&bar: &u32) { LL | fn agh(&&bar: &u32) {
| ^^^^ | ^^^^ ---- expected due to this
| | | |
| expected `u32`, found reference | expected `u32`, found reference
| help: you can probably remove the explicit borrow: `bar` | help: you can probably remove the explicit borrow: `bar`
@ -26,7 +27,9 @@ error[E0308]: mismatched types
--> $DIR/issue-38371.rs:21:8 --> $DIR/issue-38371.rs:21:8
| |
LL | fn bgh(&&bar: u32) { LL | fn bgh(&&bar: u32) {
| ^^^^^ expected `u32`, found reference | ^^^^^ --- expected due to this
| |
| expected `u32`, found reference
| |
= note: expected type `u32` = note: expected type `u32`
found reference `&_` found reference `&_`

View file

@ -3,6 +3,9 @@ error[E0308]: mismatched types
| |
LL | let &_ LL | let &_
| ^^ types differ in mutability | ^^ types differ in mutability
...
LL | = foo;
| --- this expression has type `&mut {integer}`
| |
= note: expected mutable reference `&mut {integer}` = note: expected mutable reference `&mut {integer}`
found reference `&_` found reference `&_`
@ -12,6 +15,9 @@ error[E0308]: mismatched types
| |
LL | let &mut _ LL | let &mut _
| ^^^^^^ types differ in mutability | ^^^^^^ types differ in mutability
...
LL | = bar;
| --- this expression has type `&{integer}`
| |
= note: expected reference `&{integer}` = note: expected reference `&{integer}`
found mutable reference `&mut _` found mutable reference `&mut _`

View file

@ -86,12 +86,14 @@ error[E0308]: mismatched types
--> $DIR/already-bound-name.rs:32:31 --> $DIR/already-bound-name.rs:32:31
| |
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
| ^ ------- this expression has type `E<E<{integer}>>` | - ^ ------- this expression has type `E<E<{integer}>>`
| | | | |
| expected integer, found enum `E` | | expected integer, found enum `E`
| first introduced with type `{integer}` here
| |
= note: expected type `{integer}` = note: expected type `{integer}`
found type `E<{integer}>` found type `E<{integer}>`
= note: a binding must have the same type in all alternatives
error: aborting due to 15 previous errors error: aborting due to 15 previous errors

View file

@ -52,23 +52,27 @@ error[E0308]: mismatched types
--> $DIR/inconsistent-modes.rs:11:25 --> $DIR/inconsistent-modes.rs:11:25
| |
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
| ^^^^^^^^^ -------------------- expected due to this | ----- ^^^^^^^^^ -------------------- expected due to this
| | | | |
| types differ in mutability | | types differ in mutability
| first introduced with type `&&u8` here
| |
= note: expected type `&&u8` = note: expected type `&&u8`
found type `&mut &mut u8` found type `&mut &mut u8`
= note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/inconsistent-modes.rs:14:31 --> $DIR/inconsistent-modes.rs:14:31
| |
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
| ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>` | ----- ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>`
| | | | |
| types differ in mutability | | types differ in mutability
| first introduced with type `&{integer}` here
| |
= note: expected type `&{integer}` = note: expected type `&{integer}`
found type `&mut _` found type `&mut _`
= note: a binding must have the same type in all alternatives
error: aborting due to 9 previous errors error: aborting due to 9 previous errors

View file

@ -4,7 +4,11 @@ error[E0308]: mismatched types
LL | match Blah::A(1, 1, 2) { LL | match Blah::A(1, 1, 2) {
| ---------------- this expression has type `main::Blah` | ---------------- this expression has type `main::Blah`
LL | Blah::A(_, x, y) | Blah::B(x, y) => {} LL | Blah::A(_, x, y) | Blah::B(x, y) => {}
| ^ expected `usize`, found `isize` | - ^ expected `usize`, found `isize`
| |
| first introduced with type `usize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:17:44 --> $DIR/or-patterns-binding-type-mismatch.rs:17:44
@ -12,7 +16,11 @@ error[E0308]: mismatched types
LL | match Some(Blah::A(1, 1, 2)) { LL | match Some(Blah::A(1, 1, 2)) {
| ---------------------- this expression has type `std::option::Option<main::Blah>` | ---------------------- this expression has type `std::option::Option<main::Blah>`
LL | Some(Blah::A(_, x, y) | Blah::B(x, y)) => {} LL | Some(Blah::A(_, x, y) | Blah::B(x, y)) => {}
| ^ expected `usize`, found `isize` | - ^ expected `usize`, found `isize`
| |
| first introduced with type `usize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:21:19 --> $DIR/or-patterns-binding-type-mismatch.rs:21:19
@ -20,7 +28,11 @@ error[E0308]: mismatched types
LL | match (0u8, 1u16) { LL | match (0u8, 1u16) {
| ----------- this expression has type `(u8, u16)` | ----------- this expression has type `(u8, u16)`
LL | (x, y) | (y, x) => {} LL | (x, y) | (y, x) => {}
| ^ expected `u16`, found `u8` | - ^ expected `u16`, found `u8`
| |
| first introduced with type `u16` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:21:22 --> $DIR/or-patterns-binding-type-mismatch.rs:21:22
@ -28,7 +40,11 @@ error[E0308]: mismatched types
LL | match (0u8, 1u16) { LL | match (0u8, 1u16) {
| ----------- this expression has type `(u8, u16)` | ----------- this expression has type `(u8, u16)`
LL | (x, y) | (y, x) => {} LL | (x, y) | (y, x) => {}
| ^ expected `u8`, found `u16` | - ^ expected `u8`, found `u16`
| |
| first introduced with type `u8` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:26:41 --> $DIR/or-patterns-binding-type-mismatch.rs:26:41
@ -36,7 +52,11 @@ error[E0308]: mismatched types
LL | match Some((0u8, Some((1u16, 2u32)))) { LL | match Some((0u8, Some((1u16, 2u32)))) {
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {} LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
| ^ expected `u16`, found `u8` | - ^ expected `u16`, found `u8`
| |
| first introduced with type `u16` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:26:50 --> $DIR/or-patterns-binding-type-mismatch.rs:26:50
@ -44,7 +64,11 @@ error[E0308]: mismatched types
LL | match Some((0u8, Some((1u16, 2u32)))) { LL | match Some((0u8, Some((1u16, 2u32)))) {
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {} LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
| ^ expected `u8`, found `u16` | - ^ expected `u8`, found `u16`
| |
| first introduced with type `u8` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:26:59 --> $DIR/or-patterns-binding-type-mismatch.rs:26:59
@ -52,7 +76,11 @@ error[E0308]: mismatched types
LL | match Some((0u8, Some((1u16, 2u32)))) { LL | match Some((0u8, Some((1u16, 2u32)))) {
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {} LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
| ^ expected `u32`, found `u16` | - ^ expected `u32`, found `u16`
| |
| first introduced with type `u32` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:26:62 --> $DIR/or-patterns-binding-type-mismatch.rs:26:62
@ -60,123 +88,169 @@ error[E0308]: mismatched types
LL | match Some((0u8, Some((1u16, 2u32)))) { LL | match Some((0u8, Some((1u16, 2u32)))) {
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {} LL | Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
| ^ expected `u8`, found `u32` | - first introduced with type `u8` here ^ expected `u8`, found `u32`
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:34:42 --> $DIR/or-patterns-binding-type-mismatch.rs:34:42
| |
LL | if let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2) { LL | if let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2) {
| ^ ---------------- this expression has type `main::Blah` | - ^ ---------------- this expression has type `main::Blah`
| | | | |
| expected `usize`, found `isize` | | expected `usize`, found `isize`
| first introduced with type `usize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:38:47 --> $DIR/or-patterns-binding-type-mismatch.rs:38:47
| |
LL | if let Some(Blah::A(_, x, y) | Blah::B(x, y)) = Some(Blah::A(1, 1, 2)) { LL | if let Some(Blah::A(_, x, y) | Blah::B(x, y)) = Some(Blah::A(1, 1, 2)) {
| ^ ---------------------- this expression has type `std::option::Option<main::Blah>` | - ^ ---------------------- this expression has type `std::option::Option<main::Blah>`
| | | | |
| expected `usize`, found `isize` | | expected `usize`, found `isize`
| first introduced with type `usize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:42:22 --> $DIR/or-patterns-binding-type-mismatch.rs:42:22
| |
LL | if let (x, y) | (y, x) = (0u8, 1u16) { LL | if let (x, y) | (y, x) = (0u8, 1u16) {
| ^ ----------- this expression has type `(u8, u16)` | - ^ ----------- this expression has type `(u8, u16)`
| | | | |
| expected `u16`, found `u8` | | expected `u16`, found `u8`
| first introduced with type `u16` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:42:25 --> $DIR/or-patterns-binding-type-mismatch.rs:42:25
| |
LL | if let (x, y) | (y, x) = (0u8, 1u16) { LL | if let (x, y) | (y, x) = (0u8, 1u16) {
| ^ ----------- this expression has type `(u8, u16)` | - ^ ----------- this expression has type `(u8, u16)`
| | | | |
| expected `u8`, found `u16` | | expected `u8`, found `u16`
| first introduced with type `u8` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:47:44 --> $DIR/or-patterns-binding-type-mismatch.rs:47:44
| |
LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
| ^ expected `u16`, found `u8` | - ^ expected `u16`, found `u8`
| |
| first introduced with type `u16` here
... ...
LL | = Some((0u8, Some((1u16, 2u32)))) LL | = Some((0u8, Some((1u16, 2u32))))
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:47:53 --> $DIR/or-patterns-binding-type-mismatch.rs:47:53
| |
LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
| ^ expected `u8`, found `u16` | - ^ expected `u8`, found `u16`
| |
| first introduced with type `u8` here
... ...
LL | = Some((0u8, Some((1u16, 2u32)))) LL | = Some((0u8, Some((1u16, 2u32))))
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:47:62 --> $DIR/or-patterns-binding-type-mismatch.rs:47:62
| |
LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
| ^ expected `u32`, found `u16` | - ^ expected `u32`, found `u16`
| |
| first introduced with type `u32` here
... ...
LL | = Some((0u8, Some((1u16, 2u32)))) LL | = Some((0u8, Some((1u16, 2u32))))
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:47:65 --> $DIR/or-patterns-binding-type-mismatch.rs:47:65
| |
LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
| ^ expected `u8`, found `u32` | - first introduced with type `u8` here ^ expected `u8`, found `u32`
... ...
LL | = Some((0u8, Some((1u16, 2u32)))) LL | = Some((0u8, Some((1u16, 2u32))))
| ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:55:39 --> $DIR/or-patterns-binding-type-mismatch.rs:55:39
| |
LL | let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2); LL | let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
| ^ ---------------- this expression has type `main::Blah` | - ^ ---------------- this expression has type `main::Blah`
| | | | |
| expected `usize`, found `isize` | | expected `usize`, found `isize`
| first introduced with type `usize` here
|
= note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:58:19 --> $DIR/or-patterns-binding-type-mismatch.rs:58:19
| |
LL | let (x, y) | (y, x) = (0u8, 1u16); LL | let (x, y) | (y, x) = (0u8, 1u16);
| ^ ----------- this expression has type `(u8, u16)` | - ^ ----------- this expression has type `(u8, u16)`
| | | | |
| expected `u16`, found `u8` | | expected `u16`, found `u8`
| first introduced with type `u16` here
|
= note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:58:22 --> $DIR/or-patterns-binding-type-mismatch.rs:58:22
| |
LL | let (x, y) | (y, x) = (0u8, 1u16); LL | let (x, y) | (y, x) = (0u8, 1u16);
| ^ ----------- this expression has type `(u8, u16)` | - ^ ----------- this expression has type `(u8, u16)`
| | | | |
| expected `u8`, found `u16` | | expected `u8`, found `u16`
| first introduced with type `u8` here
|
= note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:62:42 --> $DIR/or-patterns-binding-type-mismatch.rs:62:42
| |
LL | fn f1((Blah::A(_, x, y) | Blah::B(x, y)): Blah) {} LL | fn f1((Blah::A(_, x, y) | Blah::B(x, y)): Blah) {}
| ^ ---- expected due to this | - ^ ---- expected due to this
| | | | |
| expected `usize`, found `isize` | | expected `usize`, found `isize`
| first introduced with type `usize` here
|
= note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:65:22 --> $DIR/or-patterns-binding-type-mismatch.rs:65:22
| |
LL | fn f2(((x, y) | (y, x)): (u8, u16)) {} LL | fn f2(((x, y) | (y, x)): (u8, u16)) {}
| ^ --------- expected due to this | - ^ --------- expected due to this
| | | | |
| expected `u16`, found `u8` | | expected `u16`, found `u8`
| first introduced with type `u16` here
|
= note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:65:25 --> $DIR/or-patterns-binding-type-mismatch.rs:65:25
| |
LL | fn f2(((x, y) | (y, x)): (u8, u16)) {} LL | fn f2(((x, y) | (y, x)): (u8, u16)) {}
| ^ --------- expected due to this | - ^ --------- expected due to this
| | | | |
| expected `u8`, found `u16` | | expected `u8`, found `u16`
| first introduced with type `u8` here
|
= note: a binding must have the same type in all alternatives
error: aborting due to 22 previous errors error: aborting due to 22 previous errors

View file

@ -12,6 +12,8 @@ LL | (..) => {}
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/pat-tuple-bad-type.rs:10:9 --> $DIR/pat-tuple-bad-type.rs:10:9
| |
LL | match 0u8 {
| --- this expression has type `u8`
LL | (..) => {} LL | (..) => {}
| ^^^^ expected `u8`, found `()` | ^^^^ expected `u8`, found `()`

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/pat-tuple-overfield.rs:5:9 --> $DIR/pat-tuple-overfield.rs:5:9
| |
LL | match (1, 2, 3) {
| --------- this expression has type `({integer}, {integer}, {integer})`
LL | (1, 2, 3, 4) => {} LL | (1, 2, 3, 4) => {}
| ^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements | ^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements
| |
@ -10,6 +12,9 @@ LL | (1, 2, 3, 4) => {}
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/pat-tuple-overfield.rs:6:9 --> $DIR/pat-tuple-overfield.rs:6:9
| |
LL | match (1, 2, 3) {
| --------- this expression has type `({integer}, {integer}, {integer})`
LL | (1, 2, 3, 4) => {}
LL | (1, 2, .., 3, 4) => {} LL | (1, 2, .., 3, 4) => {}
| ^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements | ^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements
| |

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/pattern-ident-path-generics.rs:3:9 --> $DIR/pattern-ident-path-generics.rs:3:9
| |
LL | match Some("foo") {
| ----------- this expression has type `std::option::Option<&str>`
LL | None::<isize> => {} LL | None::<isize> => {}
| ^^^^^^^^^^^^^ expected `&str`, found `isize` | ^^^^^^^^^^^^^ expected `&str`, found `isize`
| |

View file

@ -0,0 +1,6 @@
fn main() {}
trait Foo {
fn fn_with_type_named_same_as_local_in_param(b: b);
//~^ ERROR cannot find type `b` in this scope
}

View file

@ -0,0 +1,9 @@
error[E0412]: cannot find type `b` in this scope
--> $DIR/issue-69401-trait-fn-no-body-ty-local.rs:4:53
|
LL | fn fn_with_type_named_same_as_local_in_param(b: b);
| ^ not found in this scope
error: aborting due to previous error
For more information about this error, try `rustc --explain E0412`.

View file

@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/name-clash-nullary.rs:2:7 --> $DIR/name-clash-nullary.rs:2:7
| |
LL | let None: isize = 42; LL | let None: isize = 42;
| ^^^^ expected `isize`, found enum `std::option::Option` | ^^^^ ----- expected due to this
| |
| expected `isize`, found enum `std::option::Option`
| |
= note: expected type `isize` = note: expected type `isize`
found enum `std::option::Option<_>` found enum `std::option::Option<_>`

View file

@ -26,7 +26,11 @@ error[E0308]: mismatched types
LL | match x { LL | match x {
| - this expression has type `Opts` | - this expression has type `Opts`
LL | Opts::A(ref i) | Opts::B(i) => {} LL | Opts::A(ref i) | Opts::B(i) => {}
| ^ expected `&isize`, found `isize` | ----- ^ expected `&isize`, found `isize`
| |
| first introduced with type `&isize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:16:32 --> $DIR/resolve-inconsistent-binding-mode.rs:16:32
@ -34,7 +38,11 @@ error[E0308]: mismatched types
LL | match x { LL | match x {
| - this expression has type `Opts` | - this expression has type `Opts`
LL | Opts::A(ref i) | Opts::B(i) => {} LL | Opts::A(ref i) | Opts::B(i) => {}
| ^ expected `&isize`, found `isize` | ----- ^ expected `&isize`, found `isize`
| |
| first introduced with type `&isize` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:25:36 --> $DIR/resolve-inconsistent-binding-mode.rs:25:36
@ -42,10 +50,13 @@ error[E0308]: mismatched types
LL | match x { LL | match x {
| - this expression has type `Opts` | - this expression has type `Opts`
LL | Opts::A(ref mut i) | Opts::B(ref i) => {} LL | Opts::A(ref mut i) | Opts::B(ref i) => {}
| ^^^^^ types differ in mutability | --------- ^^^^^ types differ in mutability
| |
| first introduced with type `&mut isize` here
| |
= note: expected type `&mut isize` = note: expected type `&mut isize`
found type `&isize` found type `&isize`
= note: in the same arm, a binding must have the same type in all alternatives
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -89,7 +89,11 @@ error[E0308]: mismatched types
LL | match x { LL | match x {
| - this expression has type `(E, E)` | - this expression has type `(E, E)`
LL | (A, B) | (ref B, c) | (c, A) => () LL | (A, B) | (ref B, c) | (c, A) => ()
| ^^^^^ expected enum `E`, found `&E` | - ^^^^^ expected enum `E`, found `&E`
| |
| first introduced with type `E` here
|
= note: in the same arm, a binding must have the same type in all alternatives
error: aborting due to 9 previous errors error: aborting due to 9 previous errors

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/const.rs:14:9 --> $DIR/const.rs:14:9
| |
LL | match &f {
| -- this expression has type `&Foo`
LL | FOO => {}, LL | FOO => {},
| ^^^ expected `&Foo`, found struct `Foo` | ^^^ expected `&Foo`, found struct `Foo`

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/lit.rs:7:13 --> $DIR/lit.rs:7:13
| |
LL | match &s {
| -- this expression has type `&&str`
LL | "abc" => true, LL | "abc" => true,
| ^^^^^ expected `&str`, found `str` | ^^^^^ expected `&str`, found `str`
| |
@ -10,6 +12,8 @@ LL | "abc" => true,
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/lit.rs:16:9 --> $DIR/lit.rs:16:9
| |
LL | match &s {
| -- this expression has type `&&[u8]`
LL | b"abc" => true, LL | b"abc" => true,
| ^^^^^^ expected `&[u8]`, found array `[u8; 3]` | ^^^^^^ expected `&[u8]`, found array `[u8; 3]`
| |

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/slightly-nice-generic-literal-messages.rs:7:9 --> $DIR/slightly-nice-generic-literal-messages.rs:7:9
| |
LL | match Foo(1.1, marker::PhantomData) {
| ----------------------------- this expression has type `Foo<{float}, _>`
LL | 1 => {} LL | 1 => {}
| ^ expected struct `Foo`, found integer | ^ expected struct `Foo`, found integer
| |

View file

@ -1,6 +1,8 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/match-ergonomics.rs:4:10 --> $DIR/match-ergonomics.rs:4:10
| |
LL | match &x[..] {
| ------ this expression has type `&[i32]`
LL | [&v] => {}, LL | [&v] => {},
| ^^ | ^^
| | | |
@ -25,6 +27,8 @@ LL | [v] => {},
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/match-ergonomics.rs:29:9 --> $DIR/match-ergonomics.rs:29:9
| |
LL | match y {
| - this expression has type `i32`
LL | &v => {}, LL | &v => {},
| ^^ | ^^
| | | |
@ -38,7 +42,7 @@ error[E0308]: mismatched types
--> $DIR/match-ergonomics.rs:40:13 --> $DIR/match-ergonomics.rs:40:13
| |
LL | if let [&v] = &x[..] {} LL | if let [&v] = &x[..] {}
| ^^ | ^^ ------ this expression has type `&[i32]`
| | | |
| expected `i32`, found reference | expected `i32`, found reference
| help: you can probably remove the explicit borrow: `v` | help: you can probably remove the explicit borrow: `v`

View file

@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/suppressed-error.rs:2:9 --> $DIR/suppressed-error.rs:2:9
| |
LL | let (x, y) = (); LL | let (x, y) = ();
| ^^^^^^ expected `()`, found tuple | ^^^^^^ -- this expression has type `()`
| |
| expected `()`, found tuple
| |
= note: expected unit type `()` = note: expected unit type `()`
found tuple `(_, _)` found tuple `(_, _)`