diff options
| author | bors <bors@rust-lang.org> | 2020-02-28 17:53:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-02-28 17:53:10 +0000 |
| commit | 0eb878d2aa6e3a1cb315f3f328681b26bb4bffdb (patch) | |
| tree | d04ae2e07f7382e6437a0d069e301592864cb2e7 | |
| parent | eaa02f599f651246d5d1b99e7a4c6fa8d04bc9dc (diff) | |
| parent | 13e4c6c51f7e239a429456dc62ba694219e591f9 (diff) | |
| download | rust-0eb878d2aa6e3a1cb315f3f328681b26bb4bffdb.tar.gz rust-0eb878d2aa6e3a1cb315f3f328681b26bb4bffdb.zip | |
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
98 files changed, 853 insertions, 390 deletions
diff --git a/RELEASES.md b/RELEASES.md index 427aa71b4b5..7e18f1befdd 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -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) =========================== @@ -8,6 +105,7 @@ Version 1.41.1 (2020-02-27) [69225]: https://github.com/rust-lang/rust/issues/69225 [69145]: https://github.com/rust-lang/rust/pull/69145 + Version 1.41.0 (2020-01-30) =========================== diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 3ac4bd82a3a..81b0e9817d2 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -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]> where [T; N]: LengthAtMost32, diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 9dc5447397f..6ee128f4fa1 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -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]> where [T; N]: LengthAtMost32, diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index fd285242d5b..9bd708c0f59 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -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]> where [T; N]: LengthAtMost32, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index adda0cde24f..f7301280acd 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -153,17 +153,13 @@ pub struct Map<'hir> { 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, 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> { 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) } + /// 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 /// immediate parent is an item or a closure. 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> { - let mut iter = ParentHirIterator::new(id, &self).peekable(); + let mut iter = self.parent_iter(id).peekable(); let mut ignore_tail = false; if let Some(entry) = self.find_entry(id) { 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 a module, trait, or impl. 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 { Node::Crate | Node::Item(_) @@ -753,7 +755,7 @@ impl<'hir> Map<'hir> { /// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no /// module parent is in this map. 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 { 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` /// expression needing to be unit. 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 { Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::ImplItem(_) => { break; @@ -788,7 +790,7 @@ impl<'hir> Map<'hir> { /// Returns the nearest enclosing scope. A scope is roughly an item or block. 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 { Node::Item(i) => match i.kind { ItemKind::Fn(..) diff --git a/src/librustc_builtin_macros/asm.rs b/src/librustc_builtin_macros/asm.rs index 4723544316f..9f98cf253c9 100644 --- a/src/librustc_builtin_macros/asm.rs +++ b/src/librustc_builtin_macros/asm.rs @@ -182,7 +182,7 @@ fn parse_inline_asm<'a>( }; let is_rw = output.is_some(); - let is_indirect = constraint_str.contains("*"); + let is_indirect = constraint_str.contains('*'); outputs.push(ast::InlineAsmOutput { constraint: output.unwrap_or(constraint), expr, @@ -199,7 +199,7 @@ fn parse_inline_asm<'a>( let constraint = parse_asm_str(&mut p)?; - if constraint.as_str().starts_with("=") { + if constraint.as_str().starts_with('=') { struct_span_err!( cx.parse_sess.span_diagnostic, p.prev_span, @@ -207,7 +207,7 @@ fn parse_inline_asm<'a>( "input operand constraint contains '='" ) .emit(); - } else if constraint.as_str().starts_with("+") { + } else if constraint.as_str().starts_with('+') { struct_span_err!( cx.parse_sess.span_diagnostic, p.prev_span, @@ -234,7 +234,7 @@ fn parse_inline_asm<'a>( if OPTIONS.iter().any(|&opt| s == opt) { 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!( cx.parse_sess.span_diagnostic, p.prev_span, diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs index a9298abe2d7..ad47e09aa67 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/src/librustc_builtin_macros/format.rs @@ -158,7 +158,7 @@ fn parse_args<'a>( } // accept trailing commas if p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq) { 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(); name } 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) { - Ok(s) => (s.starts_with("\"") || s.starts_with("r#"), Some(s)), + Ok(s) => (s.starts_with('"') || s.starts_with("r#"), Some(s)), _ => (false, None), }; diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index d7297ed4176..6b136aeb8d9 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -917,7 +917,7 @@ impl ThinLTOImports { if line.is_empty() { let importing_module = current_module.take().expect("Importing module not set"); 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 assert_ne!(current_module, None); current_imports.push(line.trim().to_string()); diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index 4dab4545b42..92cbc42388d 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -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 Some(s) = path.file_stem().and_then(|s| s.to_str()) { - if s.starts_with("-") { + if s.starts_with('-') { let msg = format!( "crate names cannot start with a `-`, but \ `{}` has a leading hyphen", diff --git a/src/librustc_driver/args.rs b/src/librustc_driver/args.rs index 5e2c43596db..5686819c61b 100644 --- a/src/librustc_driver/args.rs +++ b/src/librustc_driver/args.rs @@ -4,7 +4,7 @@ use std::fs; use std::io; pub fn arg_expand(arg: String) -> Result<Vec<String>, Error> { - if arg.starts_with("@") { + if arg.starts_with('@') { let path = &arg[1..]; let file = match fs::read_to_string(path) { Ok(file) => file, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f68ea7e0770..b00b1656bf7 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -521,7 +521,7 @@ fn stdout_isatty() -> bool { fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { 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) { Some(ref description) => { let mut is_in_code_block = false; @@ -601,7 +601,7 @@ impl RustcDefaultCalls { }); compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs) } else { - sess.fatal(&format!("rlink must be a file")) + sess.fatal("rlink must be a file") } } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 8ed7bbf6e12..dff243a51b3 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -503,13 +503,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) { - let attr = - attr::find_by_name(item.attrs(), sym::derive).expect("`derive` attribute should exist"); - let span = attr.span; + let attr = attr::find_by_name(item.attrs(), sym::derive); + let span = attr.map_or(item.span(), |attr| attr.span); let mut err = self .cx .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 suggestion = format!("#[derive({})]", trait_list.join(", ")); err.span_suggestion( @@ -1669,10 +1668,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } } else { - let mut err = self.cx.struct_span_err( - it.span(), - &format!("expected path to external documentation"), - ); + let mut err = self + .cx + .struct_span_err(it.span(), "expected path to external documentation"); // Check if the user erroneously used `doc(include(...))` syntax. let literal = it.meta_item_list().and_then(|list| { diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 6599e92222c..2a53d600c5b 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -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)> { match token.kind { 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, } } @@ -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 sym::ident => { if let Some((name, is_raw)) = get_macro_name(&p.token) { - let span = p.token.span; p.bump(); - token::NtIdent(Ident::new(name, span), is_raw) + token::NtIdent(Ident::new(name, p.normalized_prev_token.span), is_raw) } else { let token_str = pprust::token_to_string(&p.token); let msg = &format!("expected ident, found {}", &token_str); diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index afaba6bf315..ce4e262068c 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -205,7 +205,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> { TokenTree::Literal(self::Literal { lit: token::Lit { kind: token::Integer, symbol, suffix }, span, - }) if symbol.as_str().starts_with("-") => { + }) if symbol.as_str().starts_with('-') => { let minus = BinOp(BinOpToken::Minus); let symbol = Symbol::intern(&symbol.as_str()[1..]); 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 { lit: token::Lit { kind: token::Float, symbol, suffix }, span, - }) if symbol.as_str().starts_with("-") => { + }) if symbol.as_str().starts_with('-') => { let minus = BinOp(BinOpToken::Minus); let symbol = Symbol::intern(&symbol.as_str()[1..]); let float = TokenKind::lit(token::Float, symbol, suffix); diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 2e99998c627..6cbd8400783 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1504,7 +1504,7 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool { let end_point = sm.end_point(*span); 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 { false } diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 70abb38278a..4dd08b517e1 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -81,10 +81,7 @@ impl AssertModuleSource<'tcx> { if !self.tcx.sess.opts.debugging_opts.query_dep_graph { self.tcx.sess.span_fatal( 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. - 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..])) } else { (&user_path[..], None) diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 1fa57f1ecf2..f6e2956e5b2 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -537,10 +537,7 @@ impl FindAllAttrs<'tcx> { if !checked_attrs.contains(&attr.id) { self.tcx.sess.span_err( attr.span, - &format!( - "found unchecked \ - `#[rustc_dirty]` / `#[rustc_clean]` attribute" - ), + "found unchecked `#[rustc_dirty]` / `#[rustc_clean]` attribute", ); } } diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index ba20006d73c..8548ad392d2 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -152,7 +152,7 @@ pub fn lock_file_path(session_dir: &Path) -> PathBuf { let directory_name = session_dir.file_name().unwrap().to_string_lossy(); 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 { bug!( "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 // '-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 { bug!( "Encountered incremental compilation session directory with \ @@ -594,7 +594,7 @@ fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime 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 { return Err(()); } diff --git a/src/librustc_infer/traits/coherence.rs b/src/librustc_infer/traits/coherence.rs index d94231653ab..0dec5ae6da5 100644 --- a/src/librustc_infer/traits/coherence.rs +++ b/src/librustc_infer/traits/coherence.rs @@ -39,10 +39,10 @@ pub struct OverlapResult<'tcx> { } 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; \ - 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` diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/src/librustc_infer/traits/error_reporting/mod.rs index 9bfa2196950..ca5f6b8b7b2 100644 --- a/src/librustc_infer/traits/error_reporting/mod.rs +++ b/src/librustc_infer/traits/error_reporting/mod.rs @@ -935,9 +935,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Already reported in the query. ConstEvalFailure(ErrorHandled::Reported) => { - self.tcx - .sess - .delay_span_bug(span, &format!("constant in type had an ignored error")); + self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error"); return; } diff --git a/src/librustc_infer/traits/wf.rs b/src/librustc_infer/traits/wf.rs index 993eb41b9b1..980a3f04781 100644 --- a/src/librustc_infer/traits/wf.rs +++ b/src/librustc_infer/traits/wf.rs @@ -232,10 +232,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // found type `()` if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) { let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); - if let Some(impl_item) = items - .iter() - .filter(|item| item.ident == trait_assoc_item.ident) - .next() + if let Some(impl_item) = + items.iter().find(|item| item.ident == trait_assoc_item.ident) { cause.span = impl_item.span; 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 .iter() - .filter(|i| i.def_id == *item_def_id) - .next() + .find(|i| i.def_id == *item_def_id) .and_then(|trait_assoc_item| { items .iter() - .filter(|i| i.ident == trait_assoc_item.ident) - .next() + .find(|i| i.ident == trait_assoc_item.ident) .map(|impl_item| (impl_item, trait_assoc_item)) }) { diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 781b33bd94c..b816673a567 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -244,7 +244,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> { .as_ref() .unwrap_or(&sess.target.target.options.codegen_backend); 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), }; diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 405ce0307cd..9b4f03b3fb6 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -178,7 +178,7 @@ fn main() { for lib in output(&mut cmd).split_whitespace() { let name = if lib.starts_with("-l") { &lib[2..] - } else if lib.starts_with("-") { + } else if lib.starts_with('-') { &lib[1..] } else if Path::new(lib).exists() { // On MSVC llvm-config will print the full name to libraries, but diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4c4383aa603..647224bc8d6 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -680,10 +680,7 @@ impl<'a> CrateLoader<'a> { // Sanity check the loaded crate to ensure it is indeed a profiler runtime if !data.is_profiler_runtime() { - self.sess.err(&format!( - "the crate `profiler_builtins` is not \ - a profiler runtime" - )); + self.sess.err("the crate `profiler_builtins` is not a profiler runtime"); } } } diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index 8d991927d54..8cd75d4a2fd 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -612,7 +612,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { "'_".to_string() }; - let suggestion = if snippet.ends_with(";") { + let suggestion = if snippet.ends_with(';') { // `type X = impl Trait;` format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name) } else { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index c4d6023e06b..aa49ab1b722 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -365,7 +365,7 @@ fn do_mir_borrowck<'a, 'tcx>( // Skip over locals that begin with an underscore or have no name match mbcx.local_names[local] { Some(name) => { - if name.as_str().starts_with("_") { + if name.as_str().starts_with('_') { continue; } } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index eccdac2fb99..a0d93d6d19a 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -689,11 +689,7 @@ pub trait BottomValue { /// 3. Override `join` to do the opposite from what it's doing now. #[inline] fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool { - if Self::BOTTOM_VALUE == false { - inout_set.union(in_set) - } else { - inout_set.intersect(in_set) - } + if !Self::BOTTOM_VALUE { inout_set.union(in_set) } else { inout_set.intersect(in_set) } } } diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index 3263905eadb..9ba44a4d18e 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -65,10 +65,8 @@ impl NonConstOp for Downcast { pub struct FnCallIndirect; impl NonConstOp for FnCallIndirect { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - let mut err = item - .tcx - .sess - .struct_span_err(span, &format!("function pointers are not allowed in const fn")); + let mut err = + item.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn"); err.emit(); } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index c9038ccf37b..c534c2f3bb8 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -122,7 +122,7 @@ impl<'tcx> MirSource<'tcx> { /// type `T`. pub fn default_name<T: ?Sized>() -> Cow<'static, str> { 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 diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 018aef3c13c..00f5fb97052 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -13,7 +13,7 @@ use syntax::ast::{ }; use syntax::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use syntax::ptr::P; -use syntax::token::{self, token_can_begin_expr, TokenKind}; +use syntax::token::{self, TokenKind}; use syntax::util::parser::AssocOp; use log::{debug, trace}; @@ -192,12 +192,12 @@ impl<'a> Parser<'a> { TokenKind::CloseDelim(token::DelimToken::Brace), TokenKind::CloseDelim(token::DelimToken::Paren), ]; - if let token::Ident(name, false) = self.token.kind { - if Ident::new(name, self.token.span).is_raw_guess() + if let token::Ident(name, false) = self.normalized_token.kind { + if Ident::new(name, self.normalized_token.span).is_raw_guess() && self.look_ahead(1, |t| valid_follow.contains(&t.kind)) { err.span_suggestion( - self.token.span, + self.normalized_token.span, "you can escape reserved keywords to use them as identifiers", format!("r#{}", name), Applicability::MaybeIncorrect, @@ -900,8 +900,7 @@ impl<'a> Parser<'a> { } 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. } else if self.look_ahead(1, |t| { - t == &token::CloseDelim(token::Brace) - || token_can_begin_expr(t) && t.kind != token::Colon + t == &token::CloseDelim(token::Brace) || t.can_begin_expr() && t.kind != token::Colon }) && [token::Comma, token::Colon].contains(&self.token.kind) { // 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| { 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. ) }) { diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index b8f67e73bc3..71ca8fba0b4 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -97,15 +97,14 @@ impl<'a> Parser<'a> { fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> { match self.parse_expr() { Ok(expr) => Ok(expr), - Err(mut err) => match self.token.kind { + Err(mut err) => match self.normalized_token.kind { token::Ident(name, false) if name == kw::Underscore && self.look_ahead(1, |t| t == &token::Comma) => { // Special-case handling of `foo(_, _, _)` err.emit(); - let sp = self.token.span; 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), }, @@ -166,7 +165,7 @@ impl<'a> Parser<'a> { while let Some(op) = self.check_assoc_op() { // Adjust the span for interpolated LHS to point to the `$lhs` token // 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, _ => lhs.span, }; @@ -333,7 +332,7 @@ impl<'a> Parser<'a> { /// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively. fn check_assoc_op(&self) -> Option<Spanned<AssocOp>> { 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, (None, token::Ident(sym::and, false)) => { self.error_bad_logical_op("and", "&&", "conjunction"); @@ -345,7 +344,7 @@ impl<'a> Parser<'a> { } _ => 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 lo = self.token.span; // 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::Tilde => self.recover_tilde_expr(lo), // `~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>)> { expr.map(|e| { ( - match self.unnormalized_prev_token.kind { + match self.prev_token.kind { TokenKind::Interpolated(..) => self.prev_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>> { - match self.token.kind { + match self.normalized_token.kind { token::Ident(..) => self.parse_dot_suffix(base, lo), token::Literal(token::Lit { kind: token::Integer, 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.pclose(); 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( lo.to(self.prev_span), @@ -773,8 +772,8 @@ impl<'a> Parser<'a> { field: Symbol, suffix: Option<Symbol>, ) -> P<Expr> { - let span = self.token.span; self.bump(); + let span = self.prev_token.span; let field = ExprKind::Field(base, Ident::new(field, span)); self.expect_no_suffix(span, "a tuple index", suffix); 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. 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); } @@ -912,7 +911,7 @@ impl<'a> Parser<'a> { // | ^ expected expression self.bump(); 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. if self.check_keyword(kw::Async) { if self.is_async_block() { @@ -1342,7 +1341,7 @@ impl<'a> Parser<'a> { if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable }; 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() { // Feature-gate `async ||` closures. 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> { self.token.lifetime().map(|ident| { - let span = self.token.span; 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 { self.token.is_keyword(kw::Try) && 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. !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 }`. 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) { - let span = self.token.span; return Some(ast::Field { - ident: Ident::new(name, span), - span, - expr: self.mk_expr_err(span), + ident: Ident::new(name, self.normalized_token.span), + span: self.token.span, + expr: self.mk_expr_err(self.token.span), is_shorthand: false, attrs: AttrVec::new(), id: DUMMY_NODE_ID, diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 0984263bb28..ef01df2ea05 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -121,15 +121,12 @@ impl<'a> Parser<'a> { .span_label(attrs[0].span, "attributes must go before parameters") .emit(); } else { - self.struct_span_err( - attrs[0].span, - &format!("attribute without generic parameters"), - ) - .span_label( - attrs[0].span, - "attributes are only permitted when preceding parameters", - ) - .emit(); + self.struct_span_err(attrs[0].span, "attribute without generic parameters") + .span_label( + attrs[0].span, + "attributes are only permitted when preceding parameters", + ) + .emit(); } } break; diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index d7d6fcd05b7..ef4246609da 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -741,11 +741,10 @@ impl<'a> Parser<'a> { } 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) => { - let span = self.token.span; self.bump(); - Ok(Ident::new(name, span)) + Ok(Ident::new(name, self.normalized_prev_token.span)) } _ => self.parse_ident(), } @@ -1537,7 +1536,7 @@ impl<'a> Parser<'a> { let is_name_required = match self.token.kind { token::DotDotDot => false, - _ => req_name(&self.token), + _ => req_name(&self.normalized_token), }; let (pat, ty) = if is_name_required || self.is_named_param() { 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>> { // Extract an identifier *after* having confirmed that the token is one. let expect_self_ident = |this: &mut Self| { - match this.token.kind { + match this.normalized_token.kind { // Preserve hygienic context. token::Ident(name, _) => { - let span = this.token.span; this.bump(); - Ident::new(name, span) + Ident::new(name, this.normalized_prev_token.span) } _ => unreachable!(), } @@ -1645,7 +1643,7 @@ impl<'a> Parser<'a> { // 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. 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) => { let eself = if is_isolated_self(self, 1) { // `&self` diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 7b8642b0151..58a03ee2a74 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -86,23 +86,22 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { #[derive(Clone)] pub struct Parser<'a> { pub sess: &'a ParseSess, + /// The current non-normalized token. + pub token: Token, /// The current normalized token. /// "Normalized" means that some interpolated tokens /// (`$i: ident` and `$l: lifetime` meta-variables) are replaced /// with non-interpolated identifier and lifetime tokens they refer to. - /// Use span from this token if you need an isolated span. - pub token: Token, - /// The current non-normalized token if it's different from `token`. - /// Use span from this token if you need to concatenate it with some neighbouring spans. - unnormalized_token: Token, + /// Use this if you need to check for `token::Ident` or `token::Lifetime` specifically, + /// this also includes edition checks for edition-specific keyword identifiers. + pub normalized_token: Token, + /// The previous non-normalized token. + pub prev_token: Token, /// The previous normalized token. - /// Use span from this token if you need an isolated span. - prev_token: Token, - /// The previous non-normalized token if it's different from `prev_token`. - /// Use span from this token if you need to concatenate it with some neighbouring spans. - unnormalized_prev_token: Token, - /// Equivalent to `unnormalized_prev_token.span`. - /// FIXME: Remove in favor of `(unnormalized_)prev_token.span`. + /// Use this if you need to check for `token::Ident` or `token::Lifetime` specifically, + /// this also includes edition checks for edition-specific keyword identifiers. + pub normalized_prev_token: Token, + /// FIXME: Remove in favor of the equivalent `prev_token.span`. pub prev_span: Span, restrictions: Restrictions, /// Used to determine the path to externally loaded source files. @@ -375,9 +374,9 @@ impl<'a> Parser<'a> { let mut parser = Parser { sess, token: Token::dummy(), - unnormalized_token: Token::dummy(), + normalized_token: Token::dummy(), prev_token: Token::dummy(), - unnormalized_prev_token: Token::dummy(), + normalized_prev_token: Token::dummy(), prev_span: DUMMY_SP, restrictions: Restrictions::empty(), recurse_into_file_modules, @@ -482,7 +481,7 @@ impl<'a> Parser<'a> { } fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { - match self.token.kind { + match self.normalized_token.kind { token::Ident(name, _) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); @@ -492,9 +491,8 @@ impl<'a> Parser<'a> { return Err(err); } } - let span = self.token.span; self.bump(); - Ok(Ident::new(name, span)) + Ok(Ident::new(name, self.normalized_prev_token.span)) } _ => Err(match self.prev_token.kind { TokenKind::DocComment(..) => { @@ -824,16 +822,16 @@ impl<'a> Parser<'a> { // tokens are replaced with usual identifier and lifetime tokens, // so the former are never encountered during normal parsing. crate fn set_token(&mut self, token: Token) { - self.unnormalized_token = token; - self.token = match &self.unnormalized_token.kind { + self.token = token; + self.normalized_token = match &self.token.kind { token::Interpolated(nt) => match **nt { token::NtIdent(ident, is_raw) => { Token::new(token::Ident(ident.name, is_raw), 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. 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); // Update fields derived from the previous token. - self.prev_span = self.unnormalized_prev_token.span; + self.prev_span = self.prev_token.span; // Diagnostics. self.expected_tokens.clear(); @@ -859,7 +857,7 @@ impl<'a> Parser<'a> { /// Advance the parser by one token. 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); } @@ -890,7 +888,7 @@ impl<'a> Parser<'a> { /// Parses asyncness: `async` or nothing. fn parse_asyncness(&mut self) -> 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 } } else { Async::No diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 18e57c6a5d4..f3a61ad4419 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -134,7 +134,7 @@ impl<'a> Parser<'a> { path }); - let lo = self.unnormalized_token.span; + let lo = self.token.span; let mut segments = Vec::new(); let mod_sep_ctxt = self.token.span.ctxt(); 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> { - match self.token.kind { + match self.normalized_token.kind { token::Ident(name, _) if name.is_path_segment_keyword() => { - let span = self.token.span; self.bump(); - Ok(Ident::new(name, span)) + Ok(Ident::new(name, self.normalized_prev_token.span)) } _ => self.parse_ident(), } diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 257292ae072..9073e131f70 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -89,7 +89,7 @@ impl<'a> Parser<'a> { 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 item = self.parse_item_common(attrs.clone(), false, true, |_| true)?; + let item = self.parse_item_common(attrs, false, true, |_| true)?; self.directory.ownership = old; Ok(item) } diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 29615ac1470..7b2fdebcfb9 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -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_span::source_map::Span; 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::{ GenericBound, GenericBounds, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, }; @@ -323,7 +323,7 @@ impl<'a> Parser<'a> { /// Is a `dyn B0 + ... + Bn` type allowed here? fn is_explicit_dyn_type(&mut self) -> bool { self.check_keyword(kw::Dyn) - && (self.token.span.rust_2018() + && (self.normalized_token.span.rust_2018() || self.look_ahead(1, |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. pub fn expect_lifetime(&mut self) -> Lifetime { if let Some(ident) = self.token.lifetime() { - let span = self.token.span; self.bump(); - Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID } + Lifetime { ident, id: ast::DUMMY_NODE_ID } } else { self.span_bug(self.token.span, "not a lifetime") } diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index e0eef1db0f0..e2749c7bd7c 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -553,7 +553,7 @@ impl DeadVisitor<'tcx> { node_type: &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| { lint.build(&format!("{} is never {}: `{}`", node_type, participle, name)).emit() }); diff --git a/src/librustc_passes/weak_lang_items.rs b/src/librustc_passes/weak_lang_items.rs index 010712c28ba..1511742446b 100644 --- a/src/librustc_passes/weak_lang_items.rs +++ b/src/librustc_passes/weak_lang_items.rs @@ -64,9 +64,9 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) { for (name, &item) in WEAK_ITEMS_REFS.iter() { if missing.contains(&item) && !whitelisted(tcx, item) && items.require(item).is_err() { 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 { - tcx.sess.err(&format!("`#[alloc_error_handler]` function required, but not found")); + tcx.sess.err("`#[alloc_error_handler]` function required, but not found"); } else { tcx.sess.err(&format!("language item required, but not found: `{}`", name)); } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a81caea4e41..2a9e335e924 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1103,7 +1103,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Macro uses will remove items from this set, and the remaining // items will be reported as `unused_macros`. 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); } } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index bf9eeb0b6c5..b0206bb1a7a 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -143,7 +143,7 @@ impl<'a> Resolver<'a> { if has_generic_params == HasGenericParams::Yes { // Try to retrieve the span of the function signature and generate a new // 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) { // Suggest the modification to the user err.span_suggestion( @@ -158,7 +158,7 @@ impl<'a> Resolver<'a> { format!("try adding a local generic parameter in this method instead"), ); } else { - err.help(&format!("try using a local generic parameter instead")); + err.help("try using a local generic parameter instead"); } } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index c924fef4dc9..48a2f829d19 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -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) { let rib_kind = match fn_kind { - FnKind::Fn(FnCtxt::Foreign, ..) => return visit::walk_fn(self, fn_kind, sp), - FnKind::Fn(FnCtxt::Free, ..) => FnItemRibKind, + // Bail if there's no body. + 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, }; let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp)); diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 957574cced7..e2aa853e78c 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -968,18 +968,14 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { for missing in &self.missing_named_lifetime_spots { match missing { MissingLifetimeSpot::Generics(generics) => { - let (span, sugg) = if let Some(param) = generics - .params - .iter() - .filter(|p| match p.kind { + let (span, sugg) = if let Some(param) = + generics.params.iter().find(|p| match p.kind { hir::GenericParamKind::Type { synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), .. } => false, _ => true, - }) - .next() - { + }) { (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) } else { (generics.span, format!("<{}>", lifetime_ref)) @@ -1053,25 +1049,24 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { Applicability::MaybeIncorrect, ); }; - let suggest_new = - |err: &mut DiagnosticBuilder<'_>, sugg: &str| { - err.span_label(span, "expected named lifetime parameter"); + let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| { + err.span_label(span, "expected named lifetime parameter"); - for missing in self.missing_named_lifetime_spots.iter().rev() { - let mut introduce_suggestion = vec![]; - let msg; - let should_break; - introduce_suggestion.push(match missing { + for missing in self.missing_named_lifetime_spots.iter().rev() { + let mut introduce_suggestion = vec![]; + let msg; + let should_break; + introduce_suggestion.push(match missing { MissingLifetimeSpot::Generics(generics) => { msg = "consider introducing a named lifetime parameter".to_string(); 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 { synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), .. } => false, _ => true, - }).next() { + }) { (param.span.shrink_to_lo(), "'a, ".to_string()) } else { (generics.span, "<'a>".to_string()) @@ -1090,30 +1085,29 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { (*span, span_type.suggestion("'a")) } }); - for param in params { - if let Ok(snippet) = - self.tcx.sess.source_map().span_to_snippet(param.span) - { - if snippet.starts_with("&") && !snippet.starts_with("&'") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[1..]))); - } else if snippet.starts_with("&'_ ") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[4..]))); - } + for param in params { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) + { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[1..]))); + } else if snippet.starts_with("&'_ ") { + introduce_suggestion + .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 ( lifetime_names.len(), diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ebd3f8b832b..540877d22c2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2663,7 +2663,7 @@ impl<'a> Resolver<'a> { "{} as {}{}", &snippet[..pos], suggested_name, - if snippet.ends_with(";") { ";" } else { "" } + if snippet.ends_with(';') { ";" } else { "" } )) } } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index a6f9a5fe3e0..8392d2b50d2 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1500,10 +1500,8 @@ fn parse_libs( { early_error( error_format, - &format!( - "the library kind 'static-nobundle' is only \ - accepted on the nightly compiler" - ), + "the library kind 'static-nobundle' is only \ + accepted on the nightly compiler", ); } let mut name_parts = name.splitn(2, ':'); diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 3f44339bf4c..edd0ba46f75 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -101,7 +101,7 @@ impl TargetDataLayout { match &*spec_parts { ["e"] => dl.endian = Endian::Little, ["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")? } ["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?, @@ -111,7 +111,7 @@ impl TargetDataLayout { dl.pointer_size = size(s, 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>() { Ok(bits) => bits, Err(_) => { @@ -135,7 +135,7 @@ impl TargetDataLayout { 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 a = align(a, s)?; if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8daefb618d3..61986dd7b17 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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 \ - specified on object types" - )); + specified on object types", + ); err.emit(); } @@ -1876,7 +1876,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { let types: Vec<_> = 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 // suggest, but at least we can clue them to the correct syntax // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index c289176c303..761e2fa8eac 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -43,7 +43,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'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) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); @@ -404,7 +412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let hir::ExprKind::Lit(_) = expr.kind { if let Ok(src) = sm.span_to_snippet(sp) { - if src.starts_with("\"") { + if src.starts_with('"') { return Some(( sp, "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` let src = src.trim_end_matches(&checked_ty.to_string()); - src.split(".").next().unwrap() + src.split('.').next().unwrap() } else { src.trim_end_matches(&checked_ty.to_string()) }, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3c71e8bf6b8..ce2af9b96e5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4996,7 +4996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sugg = if receiver.ends_with(".clone()") && 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) } else { if expr.precedence().order() < ExprPrecedence::MethodCall.order() { @@ -5447,9 +5447,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(false); 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 adt_def = ty.ty_adt_def(); - + let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id)); match ty.kind { ty::Adt(adt_def, substs) if adt_def.has_ctor() => { let variant = adt_def.non_enum_variant(); @@ -5464,7 +5462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, "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() { AdtKind::Enum => { err.help("did you mean to use one of the enum's variants?"); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index cb6e028ab86..2c5dcdde5e8 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -597,12 +597,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(lstring) => { err.span_suggestion( lhs_expr.span, - if lstring.starts_with("&") { + if lstring.starts_with('&') { remove_borrow_msg } else { msg }, - if lstring.starts_with("&") { + if lstring.starts_with('&') { // let a = String::new(); // let _ = &a + "bar"; format!("{}", &lstring[1..]) @@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign, ) { (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 + b; format!("{}", &l[1..]) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 2c7cbed6a2d..1df7c64f2c6 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -9,9 +9,9 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{HirId, Pat, PatKind}; use rustc_infer::infer; 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::Span; +use rustc_span::source_map::{Span, Spanned}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -66,6 +66,11 @@ struct TopInfo<'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( &self, cause_span: Span, @@ -73,9 +78,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { actual: Ty<'tcx>, ti: TopInfo<'tcx>, ) -> Option<DiagnosticBuilder<'tcx>> { - let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr }; - let cause = self.cause(cause_span, code); - self.demand_eqtype_with_origin(&cause, expected, actual) + self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) } 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) } 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) => { 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 // They can denote both statically and dynamically-sized byte arrays. let mut pat_ty = ty; - if let hir::ExprKind::Lit(ref lt) = lt.kind { - if let ast::LitKind::ByteStr(_) = lt.node { - let expected_ty = self.structurally_resolved_type(span, expected); - if let ty::Ref(_, r_ty, _) = expected_ty.kind { - if let ty::Slice(_) = r_ty.kind { - let tcx = self.tcx; - pat_ty = - tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8)); - } - } + if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind { + let expected = self.structurally_resolved_type(span, expected); + if let ty::Ref(_, ty::TyS { kind: ty::Slice(_), .. }, _) = expected.kind { + 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 // // 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( ti.span .filter(|&s| { @@ -543,8 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. if var_id != pat.hir_id { - let vt = self.local_ty(pat.span, var_id).decl_ty; - self.demand_eqtype_pat(pat.span, vt, local_ty, ti); + self.check_binding_alt_eq_ty(pat.span, var_id, local_ty, ti); } if let Some(p) = sub { @@ -554,6 +552,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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( &self, err: &mut DiagnosticBuilder<'_>, @@ -659,6 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]), qpath: &hir::QPath<'_>, expected: Ty<'tcx>, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; @@ -684,7 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Type-check the path. 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 } @@ -901,7 +918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let element_tys = tcx.mk_substs(element_tys_iter); 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(); // Walk subpatterns with an expected type of `err` in this case to silence // 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); 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 // `fn foo(foo: &u32)` diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index d4c89b7e037..49fa45836e1 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -283,10 +283,10 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { "no base type found for inherent implementation" ) .span_label(ty.span, "impl requires a base type") - .note(&format!( + .note( "either implement a trait on it or create a newtype \ - to wrap it instead" - )) + to wrap it instead", + ) .emit(); return; } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f257fc5442c..427bcab632d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1301,10 +1301,10 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { param.hir_id, param.span, |lint| { - lint.build(&format!( + lint.build( "defaults for type parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions." - )) + `struct`, `enum`, `type`, or `trait` definitions.", + ) .emit(); }, ); @@ -2224,7 +2224,7 @@ fn from_target_feature( item.span(), format!("`{}` is not valid for this target", feature), ); - if feature.starts_with("+") { + if feature.starts_with('+') { let valid = whitelist.contains_key(&feature[1..]); if valid { 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; } else if attr.check_name(sym::export_name) { 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, // so it may not contain any null characters. struct_span_err!( diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 56f7b07cfc8..ff6431640d3 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -707,7 +707,7 @@ impl LangString { x if x.starts_with("edition") => { 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() { data.error_codes.push(x.to_owned()); seen_rust_tags = !seen_other_tags || seen_rust_tags; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index bda220d8806..59677b28245 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -86,7 +86,7 @@ pub type NameDoc = (String, Option<String>); crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { 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) } }) } diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 3acfb82fe78..e9ebccb7ec0 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -534,7 +534,7 @@ fn extern_location( if let Some(url) = extern_url { let mut url = url.to_string(); - if !url.ends_with("/") { + if !url.ends_with('/') { url.push('/'); } return Remote(url); @@ -548,7 +548,7 @@ fn extern_location( .filter_map(|a| a.value_str()) .map(|url| { let mut url = url.to_string(); - if !url.ends_with("/") { + if !url.ends_with('/') { url.push('/') } Remote(url) diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index a37efc22c93..a41fdd2ff17 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -19,7 +19,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) { let mut count = 0; 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 metadata.push(line[1..].trim_start()); count += line.len() + 1; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5dd7bd82755..4d51b63b740 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -398,7 +398,7 @@ pub fn make_test( use rustc_span::source_map::FilePathMapping; 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 // send all the errors that libsyntax emits directly into a `Sink` instead of stderr. diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 67b382c7a84..a50dd9575de 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -2396,9 +2396,9 @@ impl<B: BufRead> Iterator for Lines<B> { match self.buf.read_line(&mut buf) { Ok(0) => None, Ok(_n) => { - if buf.ends_with("\n") { + if buf.ends_with('\n') { buf.pop(); - if buf.ends_with("\r") { + if buf.ends_with('\r') { buf.pop(); } } diff --git a/src/libsyntax/token.rs b/src/libsyntax/token.rs index 52bf50604fb..a8a2c9b2fb3 100644 --- a/src/libsyntax/token.rs +++ b/src/libsyntax/token.rs @@ -147,36 +147,30 @@ impl Lit { 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); - token_can_begin_expr(&ident_token) -} -pub fn token_can_begin_expr(ident_token: &Token) -> bool { !ident_token.is_reserved_ident() || ident_token.is_path_segment_keyword() - || match ident_token.kind { - TokenKind::Ident(ident, _) => [ - kw::Async, - kw::Do, - kw::Box, - kw::Break, - kw::Continue, - kw::False, - kw::For, - kw::If, - kw::Let, - kw::Loop, - kw::Match, - kw::Move, - kw::Return, - kw::True, - kw::Unsafe, - kw::While, - kw::Yield, - kw::Static, - ] - .contains(&ident), - _ => false, - } + || [ + kw::Async, + kw::Do, + kw::Box, + kw::Break, + kw::Continue, + kw::False, + kw::For, + kw::If, + kw::Let, + kw::Loop, + kw::Match, + kw::Move, + kw::Return, + kw::True, + kw::Unsafe, + kw::While, + kw::Yield, + kw::Static, + ] + .contains(&name) } fn ident_can_begin_type(name: ast::Name, span: Span, is_raw: bool) -> bool { @@ -369,8 +363,8 @@ impl Token { Lifetime(..) | // labeled loop Pound => true, // expression attributes Interpolated(ref nt) => match **nt { + NtIdent(ident, is_raw) => ident_can_begin_expr(ident.name, ident.span, is_raw), NtLiteral(..) | - NtIdent(..) | NtExpr(..) | NtBlock(..) | NtPath(..) | @@ -397,7 +391,8 @@ impl Token { Lt | BinOp(Shl) | // associated path ModSep => true, // global path 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, @@ -442,6 +437,7 @@ impl Token { Literal(..) | BinOp(Minus) => true, Ident(name, false) if name.is_bool_lit() => true, 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(_)), _ => false, }, diff --git a/src/libsyntax/util/literal.rs b/src/libsyntax/util/literal.rs index 0c611adc06b..ecf17efc4e0 100644 --- a/src/libsyntax/util/literal.rs +++ b/src/libsyntax/util/literal.rs @@ -197,10 +197,17 @@ impl Lit { } token::Literal(lit) => lit, token::Interpolated(ref nt) => { - if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { - if let ast::ExprKind::Lit(lit) = &expr.kind { - return Ok(lit.clone()); + match &**nt { + token::NtIdent(ident, false) if ident.name.is_bool_lit() => { + 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); } diff --git a/src/test/ui/borrowck/move-error-snippets.stderr b/src/test/ui/borrowck/move-error-snippets.stderr index e0acd459571..58a90b2fca2 100644 --- a/src/test/ui/borrowck/move-error-snippets.stderr +++ b/src/test/ui/borrowck/move-error-snippets.stderr @@ -1,14 +1,16 @@ 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] - | |__________________^ move occurs because `D` has type `A`, which does not implement the `Copy` trait -... -LL | aaa!(D); - | __________________^ -... -LL | sss!(); - | ------- in this macro invocation +LL | let a = $c; + | ^^ + | | + | move occurs because `D` has type `A`, which does not implement the `Copy` trait + | help: consider borrowing here: `&$c` + | + ::: $DIR/move-error-snippets.rs:21:1 + | +LL | sss!(); + | ------- in this macro invocation | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr index f99bf2ffdc9..1382cf643a1 100644 --- a/src/test/ui/destructure-trait-ref.stderr +++ b/src/test/ui/destructure-trait-ref.stderr @@ -20,7 +20,7 @@ error[E0308]: mismatched types --> $DIR/destructure-trait-ref.rs:32:10 | LL | let &&x = &1isize as &dyn T; - | ^^ + | ^^ ----------------- this expression has type `&dyn T` | | | expected trait object `dyn T`, found reference | help: you can probably remove the explicit borrow: `x` @@ -32,7 +32,7 @@ error[E0308]: mismatched types --> $DIR/destructure-trait-ref.rs:36:11 | LL | let &&&x = &(&1isize as &dyn T); - | ^^ + | ^^ -------------------- this expression has type `&&dyn T` | | | expected trait object `dyn T`, found reference | help: you can probably remove the explicit borrow: `x` diff --git a/src/test/ui/directory_ownership/macro-expanded-mod.rs b/src/test/ui/directory_ownership/macro-expanded-mod.rs index 9752a64162e..376c1a9cd66 100644 --- a/src/test/ui/directory_ownership/macro-expanded-mod.rs +++ b/src/test/ui/directory_ownership/macro-expanded-mod.rs @@ -1,7 +1,7 @@ // Test that macro-expanded non-inline modules behave correctly 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 { @@ -10,5 +10,4 @@ mod macro_expanded_mod_helper { fn main() { mod_decl!(foo); - //~^ ERROR Cannot declare a non-inline module inside a block } diff --git a/src/test/ui/directory_ownership/macro-expanded-mod.stderr b/src/test/ui/directory_ownership/macro-expanded-mod.stderr index 620a00f89bb..c7780c869d6 100644 --- a/src/test/ui/directory_ownership/macro-expanded-mod.stderr +++ b/src/test/ui/directory_ownership/macro-expanded-mod.stderr @@ -1,8 +1,13 @@ 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); - | ^^^ + | --------------- 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 diff --git a/src/test/ui/elide-errors-on-mismatched-tuple.stderr b/src/test/ui/elide-errors-on-mismatched-tuple.stderr index 122c71bebc4..e0537ff6faa 100644 --- a/src/test/ui/elide-errors-on-mismatched-tuple.stderr +++ b/src/test/ui/elide-errors-on-mismatched-tuple.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $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 - | ^^^^^^^^^ 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)` found tuple `(_, _, _)` diff --git a/src/test/ui/hygiene/fields-definition.stderr b/src/test/ui/hygiene/fields-definition.stderr index 8070ffdfdeb..fd8846bb13c 100644 --- a/src/test/ui/hygiene/fields-definition.stderr +++ b/src/test/ui/hygiene/fields-definition.stderr @@ -1,10 +1,10 @@ error[E0124]: field `a` is already declared - --> $DIR/fields-definition.rs:14:17 + --> $DIR/fields-definition.rs:14:13 | LL | a: u8, | ----- `a` first declared here LL | $a: u8, - | ^^ field already declared + | ^^^^^^ field already declared ... LL | legacy!(a); | ----------- in this macro invocation diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/issues/issue-12552.stderr index 60c4cceac51..45fede44106 100644 --- a/src/test/ui/issues/issue-12552.stderr +++ b/src/test/ui/issues/issue-12552.stderr @@ -12,6 +12,9 @@ LL | Some(k) => match k { error[E0308]: mismatched types --> $DIR/issue-12552.rs:9:5 | +LL | match t { + | - this expression has type `std::result::Result<_, {integer}>` +... LL | None => () | ^^^^ expected enum `std::result::Result`, found enum `std::option::Option` | diff --git a/src/test/ui/issues/issue-37026.stderr b/src/test/ui/issues/issue-37026.stderr index 361369e68bc..f0285730c5a 100644 --- a/src/test/ui/issues/issue-37026.stderr +++ b/src/test/ui/issues/issue-37026.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-37026.rs:6:9 | 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 --> $DIR/issue-37026.rs:7:9 diff --git a/src/test/ui/issues/issue-39848.rs b/src/test/ui/issues/issue-39848.rs index 5d1db7be857..1964d739989 100644 --- a/src/test/ui/issues/issue-39848.rs +++ b/src/test/ui/issues/issue-39848.rs @@ -1,10 +1,9 @@ macro_rules! get_opt { ($tgt:expr, $field:ident) => { - if $tgt.has_$field() {} + if $tgt.has_$field() {} //~ ERROR expected `{`, found `foo` } } fn main() { get_opt!(bar, foo); - //~^ ERROR expected `{`, found `foo` } diff --git a/src/test/ui/issues/issue-39848.stderr b/src/test/ui/issues/issue-39848.stderr index 11b145d6e0d..0250c6b1fdd 100644 --- a/src/test/ui/issues/issue-39848.stderr +++ b/src/test/ui/issues/issue-39848.stderr @@ -1,13 +1,17 @@ error: expected `{`, found `foo` - --> $DIR/issue-39848.rs:8:19 + --> $DIR/issue-39848.rs:3:21 | 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 ... 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 diff --git a/src/test/ui/issues/issue-5100.stderr b/src/test/ui/issues/issue-5100.stderr index c47e8689436..c81d6dcaf02 100644 --- a/src/test/ui/issues/issue-5100.stderr +++ b/src/test/ui/issues/issue-5100.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-5100.rs:8:9 | +LL | match (true, false) { + | ------------- this expression has type `(bool, bool)` LL | A::B => (), | ^^^^ expected tuple, found enum `A` | @@ -10,6 +12,8 @@ LL | A::B => (), error[E0308]: mismatched types --> $DIR/issue-5100.rs:17:9 | +LL | match (true, false) { + | ------------- this expression has type `(bool, bool)` LL | (true, false, false) => () | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements | @@ -19,6 +23,8 @@ LL | (true, false, false) => () error[E0308]: mismatched types --> $DIR/issue-5100.rs:25:9 | +LL | match (true, false) { + | ------------- this expression has type `(bool, bool)` LL | (true, false, false) => () | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements | @@ -39,6 +45,8 @@ LL | box (true, false) => () error[E0308]: mismatched types --> $DIR/issue-5100.rs:40:9 | +LL | match (true, false) { + | ------------- this expression has type `(bool, bool)` LL | &(true, false) => () | ^^^^^^^^^^^^^^ expected tuple, found reference | diff --git a/src/test/ui/issues/issue-69306.rs b/src/test/ui/issues/issue-69306.rs new file mode 100644 index 00000000000..85d60952ac8 --- /dev/null +++ b/src/test/ui/issues/issue-69306.rs @@ -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 + } +} diff --git a/src/test/ui/issues/issue-69306.stderr b/src/test/ui/issues/issue-69306.stderr new file mode 100644 index 00000000000..a2a42739ca8 --- /dev/null +++ b/src/test/ui/issues/issue-69306.stderr @@ -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`. diff --git a/src/test/ui/issues/issue-7867.stderr b/src/test/ui/issues/issue-7867.stderr index 58e82facf80..4a29464aebd 100644 --- a/src/test/ui/issues/issue-7867.stderr +++ b/src/test/ui/issues/issue-7867.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-7867.rs:7:9 | +LL | match (true, false) { + | ------------- this expression has type `(bool, bool)` LL | A::B => (), | ^^^^ expected tuple, found enum `A` | diff --git a/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs b/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs new file mode 100644 index 00000000000..24692f7cf52 --- /dev/null +++ b/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs @@ -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 +} diff --git a/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr b/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr new file mode 100644 index 00000000000..e8f96178d10 --- /dev/null +++ b/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr @@ -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 + diff --git a/src/test/ui/match/match-ill-type2.stderr b/src/test/ui/match/match-ill-type2.stderr index 1cf61ebad43..5078f03d601 100644 --- a/src/test/ui/match/match-ill-type2.stderr +++ b/src/test/ui/match/match-ill-type2.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/match-ill-type2.rs:4:9 | +LL | match 1i32 { + | ---- this expression has type `i32` +LL | 1i32 => 1, LL | 2u32 => 1, | ^^^^ expected `i32`, found `u32` diff --git a/src/test/ui/match/match-tag-nullary.stderr b/src/test/ui/match/match-tag-nullary.stderr index 4b6260b2199..3703a59edb8 100644 --- a/src/test/ui/match/match-tag-nullary.stderr +++ b/src/test/ui/match/match-tag-nullary.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/match-tag-nullary.rs:4:40 | 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 diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr index 2306fb35273..f5c8b02ae27 100644 --- a/src/test/ui/mismatched_types/E0409.stderr +++ b/src/test/ui/mismatched_types/E0409.stderr @@ -12,7 +12,11 @@ error[E0308]: mismatched types LL | match x { | - this expression has type `({integer}, {integer})` 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 diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr index 802a2fef6bd..c2bce305877 100644 --- a/src/test/ui/mismatched_types/issue-38371.stderr +++ b/src/test/ui/mismatched_types/issue-38371.stderr @@ -3,7 +3,8 @@ error[E0308]: mismatched types | LL | fn foo(&foo: Foo) { | ^^^^------ - | | + | | | + | | expected due to this | expected struct `Foo`, found reference | help: did you mean `foo`: `&Foo` | @@ -14,7 +15,7 @@ error[E0308]: mismatched types --> $DIR/issue-38371.rs:18:9 | LL | fn agh(&&bar: &u32) { - | ^^^^ + | ^^^^ ---- expected due to this | | | expected `u32`, found reference | help: you can probably remove the explicit borrow: `bar` @@ -26,7 +27,9 @@ error[E0308]: mismatched types --> $DIR/issue-38371.rs:21:8 | LL | fn bgh(&&bar: u32) { - | ^^^^^ expected `u32`, found reference + | ^^^^^ --- expected due to this + | | + | expected `u32`, found reference | = note: expected type `u32` found reference `&_` diff --git a/src/test/ui/mut/mut-pattern-mismatched.stderr b/src/test/ui/mut/mut-pattern-mismatched.stderr index ccc8ac1278c..cad1cef5155 100644 --- a/src/test/ui/mut/mut-pattern-mismatched.stderr +++ b/src/test/ui/mut/mut-pattern-mismatched.stderr @@ -3,6 +3,9 @@ error[E0308]: mismatched types | LL | let &_ | ^^ types differ in mutability +... +LL | = foo; + | --- this expression has type `&mut {integer}` | = note: expected mutable reference `&mut {integer}` found reference `&_` @@ -12,6 +15,9 @@ error[E0308]: mismatched types | LL | let &mut _ | ^^^^^^ types differ in mutability +... +LL | = bar; + | --- this expression has type `&{integer}` | = note: expected reference `&{integer}` found mutable reference `&mut _` diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr index 9924b0d7f72..97933ca1229 100644 --- a/src/test/ui/or-patterns/already-bound-name.stderr +++ b/src/test/ui/or-patterns/already-bound-name.stderr @@ -86,12 +86,14 @@ error[E0308]: mismatched types --> $DIR/already-bound-name.rs:32:31 | LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); - | ^ ------- this expression has type `E<E<{integer}>>` - | | - | expected integer, found enum `E` + | - ^ ------- this expression has type `E<E<{integer}>>` + | | | + | | expected integer, found enum `E` + | first introduced with type `{integer}` here | = note: expected type `{integer}` found type `E<{integer}>` + = note: a binding must have the same type in all alternatives error: aborting due to 15 previous errors diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr index c329f905960..8c01e00bae3 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.stderr +++ b/src/test/ui/or-patterns/inconsistent-modes.stderr @@ -52,23 +52,27 @@ error[E0308]: mismatched types --> $DIR/inconsistent-modes.rs:11:25 | LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); - | ^^^^^^^^^ -------------------- expected due to this - | | - | types differ in mutability + | ----- ^^^^^^^^^ -------------------- expected due to this + | | | + | | types differ in mutability + | first introduced with type `&&u8` here | = note: expected type `&&u8` found type `&mut &mut u8` + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/inconsistent-modes.rs:14:31 | LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); - | ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>` - | | - | types differ in mutability + | ----- ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>` + | | | + | | types differ in mutability + | first introduced with type `&{integer}` here | = note: expected type `&{integer}` found type `&mut _` + = note: a binding must have the same type in all alternatives error: aborting due to 9 previous errors diff --git a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr index 5094f04b920..d5e029d668d 100644 --- a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr +++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr @@ -4,7 +4,11 @@ error[E0308]: mismatched types LL | match Blah::A(1, 1, 2) { | ---------------- this expression has type `main::Blah` 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 --> $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)) { | ---------------------- this expression has type `std::option::Option<main::Blah>` 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 --> $DIR/or-patterns-binding-type-mismatch.rs:21:19 @@ -20,7 +28,11 @@ error[E0308]: mismatched types LL | match (0u8, 1u16) { | ----------- this expression has type `(u8, u16)` 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 --> $DIR/or-patterns-binding-type-mismatch.rs:21:22 @@ -28,7 +40,11 @@ error[E0308]: mismatched types LL | match (0u8, 1u16) { | ----------- this expression has type `(u8, u16)` 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 --> $DIR/or-patterns-binding-type-mismatch.rs:26:41 @@ -36,7 +52,11 @@ error[E0308]: mismatched types LL | match Some((0u8, Some((1u16, 2u32)))) { | ------------------------------- 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)))) => {} - | ^ 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 --> $DIR/or-patterns-binding-type-mismatch.rs:26:50 @@ -44,7 +64,11 @@ error[E0308]: mismatched types LL | match Some((0u8, Some((1u16, 2u32)))) { | ------------------------------- 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)))) => {} - | ^ 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 --> $DIR/or-patterns-binding-type-mismatch.rs:26:59 @@ -52,7 +76,11 @@ error[E0308]: mismatched types LL | match Some((0u8, Some((1u16, 2u32)))) { | ------------------------------- 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)))) => {} - | ^ 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 --> $DIR/or-patterns-binding-type-mismatch.rs:26:62 @@ -60,123 +88,169 @@ error[E0308]: mismatched types LL | match Some((0u8, Some((1u16, 2u32)))) { | ------------------------------- 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)))) => {} - | ^ 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 --> $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) { - | ^ ---------------- this expression has type `main::Blah` - | | - | expected `usize`, found `isize` + | - ^ ---------------- this expression has type `main::Blah` + | | | + | | 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 --> $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)) { - | ^ ---------------------- this expression has type `std::option::Option<main::Blah>` - | | - | expected `usize`, found `isize` + | - ^ ---------------------- this expression has type `std::option::Option<main::Blah>` + | | | + | | 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 --> $DIR/or-patterns-binding-type-mismatch.rs:42:22 | LL | if let (x, y) | (y, x) = (0u8, 1u16) { - | ^ ----------- this expression has type `(u8, u16)` - | | - | expected `u16`, found `u8` + | - ^ ----------- this expression has type `(u8, u16)` + | | | + | | 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 --> $DIR/or-patterns-binding-type-mismatch.rs:42:25 | LL | if let (x, y) | (y, x) = (0u8, 1u16) { - | ^ ----------- this expression has type `(u8, u16)` - | | - | expected `u8`, found `u16` + | - ^ ----------- this expression has type `(u8, 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 --> $DIR/or-patterns-binding-type-mismatch.rs:47:44 | 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)))) | ------------------------------- 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 --> $DIR/or-patterns-binding-type-mismatch.rs:47:53 | 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)))) | ------------------------------- 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 --> $DIR/or-patterns-binding-type-mismatch.rs:47:62 | 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)))) | ------------------------------- 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 --> $DIR/or-patterns-binding-type-mismatch.rs:47:65 | 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)))) | ------------------------------- 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 --> $DIR/or-patterns-binding-type-mismatch.rs:55:39 | LL | let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2); - | ^ ---------------- this expression has type `main::Blah` - | | - | expected `usize`, found `isize` + | - ^ ---------------- this expression has type `main::Blah` + | | | + | | 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 --> $DIR/or-patterns-binding-type-mismatch.rs:58:19 | LL | let (x, y) | (y, x) = (0u8, 1u16); - | ^ ----------- this expression has type `(u8, u16)` - | | - | expected `u16`, found `u8` + | - ^ ----------- this expression has type `(u8, u16)` + | | | + | | 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 --> $DIR/or-patterns-binding-type-mismatch.rs:58:22 | LL | let (x, y) | (y, x) = (0u8, 1u16); - | ^ ----------- this expression has type `(u8, u16)` - | | - | expected `u8`, found `u16` + | - ^ ----------- this expression has type `(u8, 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 --> $DIR/or-patterns-binding-type-mismatch.rs:62:42 | LL | fn f1((Blah::A(_, x, y) | Blah::B(x, y)): Blah) {} - | ^ ---- expected due to this - | | - | expected `usize`, found `isize` + | - ^ ---- expected due to this + | | | + | | 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 --> $DIR/or-patterns-binding-type-mismatch.rs:65:22 | LL | fn f2(((x, y) | (y, x)): (u8, u16)) {} - | ^ --------- expected due to this - | | - | expected `u16`, found `u8` + | - ^ --------- expected due to this + | | | + | | 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 --> $DIR/or-patterns-binding-type-mismatch.rs:65:25 | LL | fn f2(((x, y) | (y, x)): (u8, u16)) {} - | ^ --------- expected due to this - | | - | expected `u8`, found `u16` + | - ^ --------- expected due to this + | | | + | | 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 diff --git a/src/test/ui/pattern/pat-tuple-bad-type.stderr b/src/test/ui/pattern/pat-tuple-bad-type.stderr index 95cca38f7de..598b6a3794e 100644 --- a/src/test/ui/pattern/pat-tuple-bad-type.stderr +++ b/src/test/ui/pattern/pat-tuple-bad-type.stderr @@ -12,6 +12,8 @@ LL | (..) => {} error[E0308]: mismatched types --> $DIR/pat-tuple-bad-type.rs:10:9 | +LL | match 0u8 { + | --- this expression has type `u8` LL | (..) => {} | ^^^^ expected `u8`, found `()` diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index 25d02b8627c..45b6fd1b4d4 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/pat-tuple-overfield.rs:5:9 | +LL | match (1, 2, 3) { + | --------- this expression has type `({integer}, {integer}, {integer})` LL | (1, 2, 3, 4) => {} | ^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements | @@ -10,6 +12,9 @@ LL | (1, 2, 3, 4) => {} error[E0308]: mismatched types --> $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) => {} | ^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements | diff --git a/src/test/ui/pattern/pattern-ident-path-generics.stderr b/src/test/ui/pattern/pattern-ident-path-generics.stderr index 338eb6ff0c8..24b5cdf98d5 100644 --- a/src/test/ui/pattern/pattern-ident-path-generics.stderr +++ b/src/test/ui/pattern/pattern-ident-path-generics.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/pattern-ident-path-generics.rs:3:9 | +LL | match Some("foo") { + | ----------- this expression has type `std::option::Option<&str>` LL | None::<isize> => {} | ^^^^^^^^^^^^^ expected `&str`, found `isize` | diff --git a/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs new file mode 100644 index 00000000000..4397baea4a9 --- /dev/null +++ b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs @@ -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 +} diff --git a/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr new file mode 100644 index 00000000000..109409d2731 --- /dev/null +++ b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr @@ -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`. diff --git a/src/test/ui/resolve/name-clash-nullary.stderr b/src/test/ui/resolve/name-clash-nullary.stderr index aeeb0c45191..2de0b6a4969 100644 --- a/src/test/ui/resolve/name-clash-nullary.stderr +++ b/src/test/ui/resolve/name-clash-nullary.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/name-clash-nullary.rs:2:7 | 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` found enum `std::option::Option<_>` diff --git a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr index 61d1001ce91..749ed131b20 100644 --- a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr @@ -26,7 +26,11 @@ error[E0308]: mismatched types LL | match x { | - this expression has type `Opts` 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 --> $DIR/resolve-inconsistent-binding-mode.rs:16:32 @@ -34,7 +38,11 @@ error[E0308]: mismatched types LL | match x { | - this expression has type `Opts` 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 --> $DIR/resolve-inconsistent-binding-mode.rs:25:36 @@ -42,10 +50,13 @@ error[E0308]: mismatched types LL | match x { | - this expression has type `Opts` 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` 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 diff --git a/src/test/ui/resolve/resolve-inconsistent-names.stderr b/src/test/ui/resolve/resolve-inconsistent-names.stderr index 5c87f7c684f..1d3079c90ba 100644 --- a/src/test/ui/resolve/resolve-inconsistent-names.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-names.stderr @@ -89,7 +89,11 @@ error[E0308]: mismatched types LL | match x { | - this expression has type `(E, E)` 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 diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.stderr b/src/test/ui/rfc-2005-default-binding-mode/const.stderr index f25fc300d7f..27efd450b94 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/const.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/const.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/const.rs:14:9 | +LL | match &f { + | -- this expression has type `&Foo` LL | FOO => {}, | ^^^ expected `&Foo`, found struct `Foo` diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr index b0d60c7a4c8..6d18a39606c 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/lit.rs:7:13 | +LL | match &s { + | -- this expression has type `&&str` LL | "abc" => true, | ^^^^^ expected `&str`, found `str` | @@ -10,6 +12,8 @@ LL | "abc" => true, error[E0308]: mismatched types --> $DIR/lit.rs:16:9 | +LL | match &s { + | -- this expression has type `&&[u8]` LL | b"abc" => true, | ^^^^^^ expected `&[u8]`, found array `[u8; 3]` | diff --git a/src/test/ui/slightly-nice-generic-literal-messages.stderr b/src/test/ui/slightly-nice-generic-literal-messages.stderr index 61eabed9504..14f01f0ebdf 100644 --- a/src/test/ui/slightly-nice-generic-literal-messages.stderr +++ b/src/test/ui/slightly-nice-generic-literal-messages.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/slightly-nice-generic-literal-messages.rs:7:9 | +LL | match Foo(1.1, marker::PhantomData) { + | ----------------------------- this expression has type `Foo<{float}, _>` LL | 1 => {} | ^ expected struct `Foo`, found integer | diff --git a/src/test/ui/suggestions/match-ergonomics.stderr b/src/test/ui/suggestions/match-ergonomics.stderr index abdb754acc5..559a2d29551 100644 --- a/src/test/ui/suggestions/match-ergonomics.stderr +++ b/src/test/ui/suggestions/match-ergonomics.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/match-ergonomics.rs:4:10 | +LL | match &x[..] { + | ------ this expression has type `&[i32]` LL | [&v] => {}, | ^^ | | @@ -25,6 +27,8 @@ LL | [v] => {}, error[E0308]: mismatched types --> $DIR/match-ergonomics.rs:29:9 | +LL | match y { + | - this expression has type `i32` LL | &v => {}, | ^^ | | @@ -38,7 +42,7 @@ error[E0308]: mismatched types --> $DIR/match-ergonomics.rs:40:13 | LL | if let [&v] = &x[..] {} - | ^^ + | ^^ ------ this expression has type `&[i32]` | | | expected `i32`, found reference | help: you can probably remove the explicit borrow: `v` diff --git a/src/test/ui/suppressed-error.stderr b/src/test/ui/suppressed-error.stderr index 846cd2adcd8..c2874ae9a14 100644 --- a/src/test/ui/suppressed-error.stderr +++ b/src/test/ui/suppressed-error.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/suppressed-error.rs:2:9 | LL | let (x, y) = (); - | ^^^^^^ expected `()`, found tuple + | ^^^^^^ -- this expression has type `()` + | | + | expected `()`, found tuple | = note: expected unit type `()` found tuple `(_, _)` |
