From e658144586e0fe4f77a7dadf7c80185fd0b71279 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Nov 2022 13:01:04 +1100 Subject: [PATCH 01/30] Rename `LitKind::to_token_lit` as `LitKind::synthesize_token_lit`. This makes it clearer that it's not a lossless conversion, which I find helpful. --- compiler/rustc_ast/src/attr/mod.rs | 4 ++-- compiler/rustc_ast/src/util/literal.rs | 4 ++-- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- compiler/rustc_expand/src/build.rs | 2 +- compiler/rustc_expand/src/proc_macro_server.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 057cc26b5799e..1ba4691467586 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -328,7 +328,7 @@ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> Meta } pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem { - let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span }; + let lit = MetaItemLit { token_lit: kind.synthesize_token_lit(), kind, span: lit_span }; let span = ident.span.to(lit_span); MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span } } @@ -408,7 +408,7 @@ pub fn mk_attr_name_value_str( val: Symbol, span: Span, ) -> Attribute { - let lit = LitKind::Str(val, StrStyle::Cooked).to_token_lit(); + let lit = LitKind::Str(val, StrStyle::Cooked).synthesize_token_lit(); let expr = P(Expr { id: DUMMY_NODE_ID, kind: ExprKind::Lit(lit), diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 1d6e7914f3a5c..5e6c94f1e6fc8 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -142,10 +142,10 @@ impl LitKind { }) } - /// Attempts to recover a token from semantic literal. + /// Synthesizes a token from a semantic literal. /// This function is used when the original token doesn't exist (e.g. the literal is created /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn to_token_lit(&self) -> token::Lit { + pub fn synthesize_token_lit(&self) -> token::Lit { let (kind, symbol, suffix) = match *self { LitKind::Str(symbol, ast::StrStyle::Cooked) => { // Don't re-intern unless the escaped string is different. diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 81483ac30d1de..828b9d5ad5f68 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -323,7 +323,7 @@ impl<'a> State<'a> { self.print_token_literal(*token_lit, expr.span); } ast::ExprKind::IncludedBytes(bytes) => { - let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit(); + let lit = ast::LitKind::ByteStr(bytes.clone()).synthesize_token_lit(); self.print_token_literal(lit, expr.span) } ast::ExprKind::Cast(expr, ty) => { diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index c978297295d40..b56e1a24834f0 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -333,7 +333,7 @@ impl<'a> ExtCtxt<'a> { } fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { - let token_lit = lit_kind.to_token_lit(); + let token_lit = lit_kind.synthesize_token_lit(); self.expr(span, ast::ExprKind::Lit(token_lit)) } diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 7616579611711..57f66758ef005 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -526,7 +526,7 @@ impl server::TokenStream for Rustc<'_, '_> { Ok(tokenstream::TokenStream::token_alone(token::Literal(*token_lit), expr.span)) } ast::ExprKind::IncludedBytes(bytes) => { - let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit(); + let lit = ast::LitKind::ByteStr(bytes.clone()).synthesize_token_lit(); Ok(tokenstream::TokenStream::token_alone(token::TokenKind::Literal(lit), expr.span)) } ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 95729822677bd..10b2265c522a0 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1256,7 +1256,7 @@ impl<'a> State<'a> { fn print_literal(&mut self, lit: &hir::Lit) { self.maybe_print_comment(lit.span.lo()); - self.word(lit.node.to_token_lit().to_string()) + self.word(lit.node.synthesize_token_lit().to_string()) } fn print_inline_asm(&mut self, asm: &hir::InlineAsm<'_>) { From a7f35c42d474f893c56b6e0f7df3f8bb965f2650 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Nov 2022 13:35:44 +1100 Subject: [PATCH 02/30] Add `StrStyle` to `ast::LitKind::ByteStr`. This is required to distinguish between cooked and raw byte string literals in an `ast::LitKind`, without referring to an adjacent `token::Lit`. It's a prerequisite for the next commit. --- compiler/rustc_ast/src/ast.rs | 7 ++++--- compiler/rustc_ast/src/util/literal.rs | 16 +++++++++++----- compiler/rustc_ast_lowering/src/expr.rs | 2 +- .../rustc_ast_pretty/src/pprust/state/expr.rs | 3 ++- .../rustc_builtin_macros/src/concat_bytes.rs | 6 +++--- compiler/rustc_expand/src/base.rs | 2 +- compiler/rustc_expand/src/build.rs | 2 +- compiler/rustc_expand/src/proc_macro_server.rs | 3 ++- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- .../src/build/expr/as_constant.rs | 4 ++-- compiler/rustc_mir_build/src/thir/constant.rs | 4 ++-- .../src/invalid_utf8_in_unchecked.rs | 2 +- .../clippy_lints/src/large_include_file.rs | 2 +- .../clippy_lints/src/matches/match_same_arms.rs | 2 +- .../clippy/clippy_lints/src/utils/author.rs | 2 +- .../clippy/clippy_utils/src/check_proc_macro.rs | 4 +++- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- 18 files changed, 39 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 6a2f1f0c5749c..b869b2f8af994 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1796,8 +1796,9 @@ pub enum LitKind { /// A string literal (`"foo"`). The symbol is unescaped, and so may differ /// from the original token's symbol. Str(Symbol, StrStyle), - /// A byte string (`b"foo"`). - ByteStr(Lrc<[u8]>), + /// A byte string (`b"foo"`). Not stored as a symbol because it might be + /// non-utf8, and symbols only allow utf8 strings. + ByteStr(Lrc<[u8]>, StrStyle), /// A byte char (`b'f'`). Byte(u8), /// A character literal (`'a'`). @@ -1822,7 +1823,7 @@ impl LitKind { /// Returns `true` if this literal is byte literal string. pub fn is_bytestr(&self) -> bool { - matches!(self, LitKind::ByteStr(_)) + matches!(self, LitKind::ByteStr(..)) } /// Returns `true` if this is a numeric literal. diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 5e6c94f1e6fc8..9f6fdf44ac0b5 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -1,11 +1,12 @@ //! Code related to parsing literals. -use crate::ast::{self, LitKind, MetaItemLit}; +use crate::ast::{self, LitKind, MetaItemLit, StrStyle}; use crate::token::{self, Token}; use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use std::ascii; +use std::str; #[derive(Debug)] pub enum LitError { @@ -115,9 +116,9 @@ impl LitKind { } }); error?; - LitKind::ByteStr(buf.into()) + LitKind::ByteStr(buf.into(), StrStyle::Cooked) } - token::ByteStrRaw(_) => { + token::ByteStrRaw(n) => { let s = symbol.as_str(); let bytes = if s.contains('\r') { let mut buf = Vec::with_capacity(s.len()); @@ -136,7 +137,7 @@ impl LitKind { symbol.to_string().into_bytes() }; - LitKind::ByteStr(bytes.into()) + LitKind::ByteStr(bytes.into(), StrStyle::Raw(n)) } token::Err => LitKind::Err, }) @@ -155,10 +156,15 @@ impl LitKind { (token::Str, symbol, None) } LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None), - LitKind::ByteStr(ref bytes) => { + LitKind::ByteStr(ref bytes, ast::StrStyle::Cooked) => { let string = bytes.escape_ascii().to_string(); (token::ByteStr, Symbol::intern(&string), None) } + LitKind::ByteStr(ref bytes, ast::StrStyle::Raw(n)) => { + // Unwrap because raw byte string literals can only contain ASCII. + let string = str::from_utf8(bytes).unwrap(); + (token::ByteStrRaw(n), Symbol::intern(&string), None) + } LitKind::Byte(byte) => { let string: String = ascii::escape_default(byte).map(Into::::into).collect(); (token::Byte, Symbol::intern(&string), None) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 82912a733d552..e18bbcf65e719 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -97,7 +97,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan( self.lower_span(e.span), - LitKind::ByteStr(bytes.clone()), + LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), )), ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 828b9d5ad5f68..7306b10d60ffb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -323,7 +323,8 @@ impl<'a> State<'a> { self.print_token_literal(*token_lit, expr.span); } ast::ExprKind::IncludedBytes(bytes) => { - let lit = ast::LitKind::ByteStr(bytes.clone()).synthesize_token_lit(); + let lit = ast::LitKind::ByteStr(bytes.clone(), ast::StrStyle::Cooked) + .synthesize_token_lit(); self.print_token_literal(lit, expr.span) } ast::ExprKind::Cast(expr, ty) => { diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 161e3499584e2..56b77fdf58050 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -69,7 +69,7 @@ fn invalid_type_err( Ok(ast::LitKind::Int(_, _)) => { cx.span_err(span, "numeric literal is not a `u8`"); } - Ok(ast::LitKind::ByteStr(_) | ast::LitKind::Byte(_)) => unreachable!(), + Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(), Err(err) => { report_lit_error(&cx.sess.parse_sess, err, token_lit, span); } @@ -97,7 +97,7 @@ fn handle_array_element( )) if val <= u8::MAX.into() => Some(val as u8), Ok(ast::LitKind::Byte(val)) => Some(val), - Ok(ast::LitKind::ByteStr(_)) => { + Ok(ast::LitKind::ByteStr(..)) => { if !*has_errors { cx.struct_span_err(expr.span, "cannot concatenate doubly nested array") .note("byte strings are treated as arrays of bytes") @@ -174,7 +174,7 @@ pub fn expand_concat_bytes( Ok(ast::LitKind::Byte(val)) => { accumulator.push(val); } - Ok(ast::LitKind::ByteStr(ref bytes)) => { + Ok(ast::LitKind::ByteStr(ref bytes, _)) => { accumulator.extend_from_slice(&bytes); } _ => { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 13e2d1ebbe786..d491e9e34a784 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1234,7 +1234,7 @@ pub fn expr_to_spanned_string<'a>( Err(match expr.kind { ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { Ok(ast::LitKind::Str(s, style)) => return Ok((s, style, expr.span)), - Ok(ast::LitKind::ByteStr(_)) => { + Ok(ast::LitKind::ByteStr(..)) => { let mut err = cx.struct_span_err(expr.span, err_msg); let span = expr.span.shrink_to_lo(); err.span_suggestion( diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b56e1a24834f0..d8245ff613a9d 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -361,7 +361,7 @@ impl<'a> ExtCtxt<'a> { } pub fn expr_byte_str(&self, sp: Span, bytes: Vec) -> P { - self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes))) + self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes), ast::StrStyle::Cooked)) } /// `[expr1, expr2, ...]` diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 57f66758ef005..255e5105ff4a9 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -526,7 +526,8 @@ impl server::TokenStream for Rustc<'_, '_> { Ok(tokenstream::TokenStream::token_alone(token::Literal(*token_lit), expr.span)) } ast::ExprKind::IncludedBytes(bytes) => { - let lit = ast::LitKind::ByteStr(bytes.clone()).synthesize_token_lit(); + let lit = ast::LitKind::ByteStr(bytes.clone(), ast::StrStyle::Cooked) + .synthesize_token_lit(); Ok(tokenstream::TokenStream::token_alone(token::TokenKind::Literal(lit), expr.span)) } ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 86384c7b93e71..0d6b0175406fe 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1169,7 +1169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match lit.node { ast::LitKind::Str(..) => tcx.mk_static_str(), - ast::LitKind::ByteStr(ref v) => { + ast::LitKind::ByteStr(ref v, _) => { tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64)) } ast::LitKind::Byte(_) => tcx.types.u8, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index decd317d9fc9b..6810353f9e778 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -386,7 +386,7 @@ 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(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind { + if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(..), .. }) = lt.kind { let expected = self.structurally_resolved_type(span, expected); if let ty::Ref(_, inner_ty, _) = expected.kind() && matches!(inner_ty.kind(), ty::Slice(_)) diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 717c62315745b..3b7ed818dc9b7 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -135,14 +135,14 @@ pub(crate) fn lit_to_mir_constant<'tcx>( let allocation = tcx.intern_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: s.len() } } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) + (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); let allocation = tcx.intern_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: data.len() } } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { + (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index a9ed945d4a15a..57ae6a3652df5 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -33,13 +33,13 @@ pub(crate) fn lit_to_const<'tcx>( let str_bytes = s.as_str().as_bytes(); ty::ValTree::from_raw_bytes(tcx, str_bytes) } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) + (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { let bytes = data as &[u8]; ty::ValTree::from_raw_bytes(tcx, bytes) } - (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { + (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { let bytes = data as &[u8]; ty::ValTree::from_raw_bytes(tcx, bytes) } diff --git a/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs b/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs index e0a607f9a95b6..6a4861747d267 100644 --- a/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs +++ b/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs @@ -33,7 +33,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidUtf8InUnchecked { if let Some([arg]) = match_function_call(cx, expr, &paths::STR_FROM_UTF8_UNCHECKED) { match &arg.kind { ExprKind::Lit(Spanned { node: lit, .. }) => { - if let LitKind::ByteStr(bytes) = &lit + if let LitKind::ByteStr(bytes, _) = &lit && std::str::from_utf8(bytes).is_err() { lint(cx, expr.span); diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index 84dd61a1e4b0d..424c0d9e79828 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -60,7 +60,7 @@ impl LateLintPass<'_> for LargeIncludeFile { then { let len = match &lit.node { // include_bytes - LitKind::ByteStr(bstr) => bstr.len(), + LitKind::ByteStr(bstr, _) => bstr.len(), // include_str LitKind::Str(sym, _) => sym.as_str().len(), _ => return, diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 168c1e4d2e60d..158e6caa4de54 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -282,7 +282,7 @@ impl<'a> NormalizedPat<'a> { // TODO: Handle negative integers. They're currently treated as a wild match. ExprKind::Lit(lit) => match lit.node { LitKind::Str(sym, _) => Self::LitStr(sym), - LitKind::ByteStr(ref bytes) => Self::LitBytes(bytes), + LitKind::ByteStr(ref bytes, _) => Self::LitBytes(bytes), LitKind::Byte(val) => Self::LitInt(val.into()), LitKind::Char(val) => Self::LitInt(val.into()), LitKind::Int(val, _) => Self::LitInt(val), diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 0c052d86eda40..bd7daf0773caf 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -299,7 +299,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }; kind!("Float(_, {float_ty})"); }, - LitKind::ByteStr(ref vec) => { + LitKind::ByteStr(ref vec, _) => { bind!(self, vec); kind!("ByteStr(ref {vec})"); chain!(self, "let [{:?}] = **{vec}", vec.value); diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index c6bf98b7b8bbd..43f0df145f0ec 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -69,7 +69,9 @@ fn lit_search_pat(lit: &LitKind) -> (Pat, Pat) { LitKind::Str(_, StrStyle::Cooked) => (Pat::Str("\""), Pat::Str("\"")), LitKind::Str(_, StrStyle::Raw(0)) => (Pat::Str("r"), Pat::Str("\"")), LitKind::Str(_, StrStyle::Raw(_)) => (Pat::Str("r#"), Pat::Str("#")), - LitKind::ByteStr(_) => (Pat::Str("b\""), Pat::Str("\"")), + LitKind::ByteStr(_, StrStyle::Cooked) => (Pat::Str("b\""), Pat::Str("\"")), + LitKind::ByteStr(_, StrStyle::Raw(0)) => (Pat::Str("br\""), Pat::Str("\"")), + LitKind::ByteStr(_, StrStyle::Raw(_)) => (Pat::Str("br#\""), Pat::Str("#")), LitKind::Byte(_) => (Pat::Str("b'"), Pat::Str("'")), LitKind::Char(_) => (Pat::Str("'"), Pat::Str("'")), LitKind::Int(_, LitIntType::Signed(IntTy::Isize)) => (Pat::Num, Pat::Str("isize")), diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 315aea9aa091b..7a637d32babec 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -210,7 +210,7 @@ pub fn lit_to_mir_constant(lit: &LitKind, ty: Option>) -> Constant { match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), - LitKind::ByteStr(ref s) => Constant::Binary(Lrc::clone(s)), + LitKind::ByteStr(ref s, _) => Constant::Binary(Lrc::clone(s)), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { From 2fd364acff5f962b0ce4f4dffb5ae085d5f2b67a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Nov 2022 13:36:00 +1100 Subject: [PATCH 03/30] Remove `token::Lit` from `ast::MetaItemLit`. `token::Lit` contains a `kind` field that indicates what kind of literal it is. `ast::MetaItemLit` currently wraps a `token::Lit` but also has its own `kind` field. This means that `ast::MetaItemLit` encodes the literal kind in two different ways. This commit changes `ast::MetaItemLit` so it no longer wraps `token::Lit`. It now contains the `symbol` and `suffix` fields from `token::Lit`, but not the `kind` field, eliminating the redundancy. --- compiler/rustc_ast/src/ast.rs | 8 +++--- compiler/rustc_ast/src/attr/mod.rs | 4 ++- compiler/rustc_ast/src/util/literal.rs | 27 +++++++++++++++++-- compiler/rustc_ast_lowering/src/lib.rs | 3 ++- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_builtin_macros/src/derive.rs | 10 ++++--- compiler/rustc_parse/src/parser/expr.rs | 11 ++++---- compiler/rustc_parse/src/parser/pat.rs | 2 +- src/tools/rustfmt/src/attr.rs | 12 +++++---- 9 files changed, 56 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b869b2f8af994..c1795be229098 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1733,8 +1733,10 @@ pub enum StrStyle { /// A literal in a meta item. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MetaItemLit { - /// The original literal token as written in source code. - pub token_lit: token::Lit, + /// The original literal as written in the source code. + pub symbol: Symbol, + /// The original suffix as written in the source code. + pub suffix: Option, /// The "semantic" representation of the literal lowered from the original tokens. /// Strings are unescaped, hexadecimal forms are eliminated, etc. pub kind: LitKind, @@ -3103,7 +3105,7 @@ mod size_asserts { static_assert_size!(ItemKind, 112); static_assert_size!(LitKind, 24); static_assert_size!(Local, 72); - static_assert_size!(MetaItemLit, 48); + static_assert_size!(MetaItemLit, 40); static_assert_size!(Param, 40); static_assert_size!(Pat, 88); static_assert_size!(Path, 24); diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 1ba4691467586..2ec126715e79e 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -328,7 +328,9 @@ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> Meta } pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem { - let lit = MetaItemLit { token_lit: kind.synthesize_token_lit(), kind, span: lit_span }; + let token_lit = kind.synthesize_token_lit(); + let lit = + MetaItemLit { symbol: token_lit.symbol, suffix: token_lit.suffix, kind, span: lit_span }; let span = ident.span.to(lit_span); MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span } } diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 9f6fdf44ac0b5..a0a925d4700bd 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -202,9 +202,32 @@ impl LitKind { } impl MetaItemLit { - /// Converts token literal into a meta item literal. + /// Converts a token literal into a meta item literal. pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result { - Ok(MetaItemLit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span }) + Ok(MetaItemLit { + symbol: token_lit.symbol, + suffix: token_lit.suffix, + kind: LitKind::from_token_lit(token_lit)?, + span, + }) + } + + /// Cheaply converts a meta item literal into a token literal. + pub fn as_token_lit(&self) -> token::Lit { + let kind = match self.kind { + LitKind::Bool(_) => token::Bool, + LitKind::Str(_, ast::StrStyle::Cooked) => token::Str, + LitKind::Str(_, ast::StrStyle::Raw(n)) => token::StrRaw(n), + LitKind::ByteStr(_, ast::StrStyle::Cooked) => token::ByteStr, + LitKind::ByteStr(_, ast::StrStyle::Raw(n)) => token::ByteStrRaw(n), + LitKind::Byte(_) => token::Byte, + LitKind::Char(_) => token::Char, + LitKind::Int(..) => token::Integer, + LitKind::Float(..) => token::Float, + LitKind::Err => token::Err, + }; + + token::Lit::new(kind, self.symbol, self.suffix) } /// Converts an arbitrary token into meta item literal. diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1d27970627854..8e4bfb7133606 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -954,7 +954,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lit } else { MetaItemLit { - token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None), + symbol: kw::Empty, + suffix: None, kind: LitKind::Err, span: DUMMY_SP, } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index ebe55a4b77183..d555cf4873099 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -376,7 +376,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) { - self.print_token_literal(lit.token_lit, lit.span) + self.print_token_literal(lit.as_token_lit(), lit.span) } fn print_token_literal(&mut self, token_lit: token::Lit, span: Span) { diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index fa5a45730ac7a..2a8dc02849ea7 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -1,7 +1,7 @@ use crate::cfg_eval::cfg_eval; use rustc_ast as ast; -use rustc_ast::{token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; +use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; use rustc_feature::AttributeTemplate; @@ -130,9 +130,11 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool { } fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) { - let help_msg = match lit.token_lit.kind { - token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => { - format!("try using `#[derive({})]`", lit.token_lit.symbol) + let help_msg = match lit.kind { + ast::LitKind::Str(_, ast::StrStyle::Cooked) + if rustc_lexer::is_ident(lit.symbol.as_str()) => + { + format!("try using `#[derive({})]`", lit.symbol) } _ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(), }; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e0443a697b504..1c773bea000b2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1551,7 +1551,7 @@ impl<'a> Parser<'a> { }) }); consume_colon = false; - Ok(self.mk_expr(lo, ExprKind::Lit(lit.token_lit))) + Ok(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit()))) } else if !ate_colon && (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt)) { @@ -1654,7 +1654,8 @@ impl<'a> Parser<'a> { } let name = lifetime.without_first_quote().name; ast::MetaItemLit { - token_lit: token::Lit::new(token::LitKind::Char, name, None), + symbol: name, + suffix: None, kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')), span: lifetime.span, } @@ -1773,8 +1774,8 @@ impl<'a> Parser<'a> { Some(lit) => match lit.kind { ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit { style, - symbol: lit.token_lit.symbol, - suffix: lit.token_lit.suffix, + symbol: lit.symbol, + suffix: lit.suffix, span: lit.span, symbol_unescaped, }), @@ -1817,7 +1818,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_token_lit(&mut self) -> PResult<'a, (token::Lit, Span)> { self.parse_opt_token_lit() .ok_or(()) - .or_else(|()| self.handle_missing_lit().map(|lit| (lit.token_lit, lit.span))) + .or_else(|()| self.handle_missing_lit().map(|lit| (lit.as_token_lit(), lit.span))) } pub(super) fn parse_meta_item_lit(&mut self) -> PResult<'a, MetaItemLit> { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index cbeec951e2dfe..b5147158f708e 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -420,7 +420,7 @@ impl<'a> Parser<'a> { err.span_label(self_.token.span, format!("expected {}", expected)); err }); - PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit.token_lit))) + PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit()))) } else { // Try to parse everything else as literal with optional minus match self.parse_literal_maybe_minus() { diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index 2ac703b957b86..c503eeeb9b3b9 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -260,7 +260,9 @@ impl Rewrite for ast::NestedMetaItem { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match self { ast::NestedMetaItem::MetaItem(ref meta_item) => meta_item.rewrite(context, shape), - ast::NestedMetaItem::Lit(ref l) => rewrite_literal(context, l.token_lit, l.span, shape), + ast::NestedMetaItem::Lit(ref l) => { + rewrite_literal(context, l.as_token_lit(), l.span, shape) + } } } } @@ -308,18 +310,18 @@ impl Rewrite for ast::MetaItem { }), )? } - ast::MetaItemKind::NameValue(ref literal) => { + ast::MetaItemKind::NameValue(ref lit) => { let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?; // 3 = ` = ` let lit_shape = shape.shrink_left(path.len() + 3)?; - // `rewrite_literal` returns `None` when `literal` exceeds max + // `rewrite_literal` returns `None` when `lit` exceeds max // width. Since a literal is basically unformattable unless it // is a string literal (and only if `format_strings` is set), // we might be better off ignoring the fact that the attribute // is longer than the max width and continue on formatting. // See #2479 for example. - let value = rewrite_literal(context, literal.token_lit, literal.span, lit_shape) - .unwrap_or_else(|| context.snippet(literal.span).to_owned()); + let value = rewrite_literal(context, lit.as_token_lit(), lit.span, lit_shape) + .unwrap_or_else(|| context.snippet(lit.span).to_owned()); format!("{} = {}", path, value) } }) From d5526ff40d3213f6138c1c1311d0c1a0f5c40133 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 29 Nov 2022 13:46:28 +1100 Subject: [PATCH 04/30] Reorder `StrLit` fields. To better match `MetaItemLit`. --- compiler/rustc_ast/src/ast.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index c1795be229098..fc70b68e27fd2 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1746,13 +1746,14 @@ pub struct MetaItemLit { /// Similar to `MetaItemLit`, but restricted to string literals. #[derive(Clone, Copy, Encodable, Decodable, Debug)] pub struct StrLit { - /// The original literal token as written in source code. - pub style: StrStyle, + /// The original literal as written in source code. pub symbol: Symbol, + /// The original suffix as written in source code. pub suffix: Option, - pub span: Span, - /// The unescaped "semantic" representation of the literal lowered from the original token. + /// The semantic (unescaped) representation of the literal. pub symbol_unescaped: Symbol, + pub style: StrStyle, + pub span: Span, } impl StrLit { From 4a4270a1bbda1ecfc0ff5cab93c4ec3069d4b654 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 20 Aug 2022 14:28:43 +0300 Subject: [PATCH 05/30] Migrate "function cannot return without recursing" diagnostic --- Cargo.lock | 1 + .../locales/en-US/mir_build.ftl | 5 +++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_mir_build/Cargo.toml | 1 + compiler/rustc_mir_build/src/errors.rs | 13 +++++++++++++ compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_mir_build/src/lints.rs | 19 +++++-------------- 7 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 compiler/rustc_error_messages/locales/en-US/mir_build.ftl create mode 100644 compiler/rustc_mir_build/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index d56ac132b6f69..bfeae98c93439 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4050,6 +4050,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_infer", + "rustc_macros", "rustc_middle", "rustc_serialize", "rustc_session", diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl new file mode 100644 index 0000000000000..b5bd2eb21a8ad --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -0,0 +1,5 @@ +mir_build_unconditional_recursion = function cannot return without recursing + .label = cannot return without recursing + .help = a `loop` may express intention better if this is on purpose + +mir_build_unconditional_recursion_call_site_label = recursive call site diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 418ba3c74d776..db62643bc24ac 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -58,6 +58,7 @@ fluent_messages! { metadata => "../locales/en-US/metadata.ftl", middle => "../locales/en-US/middle.ftl", mir_dataflow => "../locales/en-US/mir_dataflow.ftl", + mir_build => "../locales/en-US/mir_build.ftl", monomorphize => "../locales/en-US/monomorphize.ftl", parse => "../locales/en-US/parse.ftl", passes => "../locales/en-US/passes.ftl", diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 2baa3bfcb6401..4ad3343d3031b 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -17,6 +17,7 @@ rustc_index = { path = "../rustc_index" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } rustc_infer = { path = "../rustc_infer" } +rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs new file mode 100644 index 0000000000000..1d44db7eb3a7d --- /dev/null +++ b/compiler/rustc_mir_build/src/errors.rs @@ -0,0 +1,13 @@ +use rustc_macros::LintDiagnostic; +use rustc_span::Span; + +#[derive(LintDiagnostic)] +#[lint(mir_build::unconditional_recursion)] +#[help] +pub struct UnconditionalRecursion { + #[primary_span] + #[label] + pub span: Span, + #[label(mir_build::unconditional_recursion_call_site_label)] + pub call_sites: Vec, +} diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8797529459534..2b05e92fdcf20 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -19,6 +19,7 @@ extern crate rustc_middle; mod build; mod check_unsafety; +mod errors; mod lints; pub mod thir; diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index b21f30efce807..383598fb094b6 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -1,3 +1,4 @@ +use crate::errors::UnconditionalRecursion; use rustc_data_structures::graph::iterate::{ NodeStatus, TriColorDepthFirstSearch, TriColorVisitor, }; @@ -36,20 +37,10 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let sp = tcx.def_span(def_id); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.struct_span_lint_hir( - UNCONDITIONAL_RECURSION, - hir_id, - sp, - "function cannot return without recursing", - |lint| { - lint.span_label(sp, "cannot return without recursing"); - // offer some help to the programmer. - for call_span in vis.reachable_recursive_calls { - lint.span_label(call_span, "recursive call site"); - } - lint.help("a `loop` may express intention better if this is on purpose") - }, - ); + tcx.emit_spanned_lint(UNCONDITIONAL_RECURSION, hir_id, sp, UnconditionalRecursion { + span: sp, + call_sites: vis.reachable_recursive_calls, + }); } } From 6b000cb688f1f730b227c58abeff1329bce2f34a Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 20 Aug 2022 23:54:58 +0300 Subject: [PATCH 06/30] Migrate "unsafe_op_in_unsafe_fn" lints --- .../locales/en-US/mir_build.ftl | 56 +++++++++++ .../rustc_mir_build/src/check_unsafety.rs | 92 +++++++++++++++++-- compiler/rustc_mir_build/src/errors.rs | 92 ++++++++++++++++++- compiler/rustc_mir_build/src/lints.rs | 10 +- 4 files changed, 236 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index b5bd2eb21a8ad..2dfc4984786b9 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -3,3 +3,59 @@ mir_build_unconditional_recursion = function cannot return without recursing .help = a `loop` may express intention better if this is on purpose mir_build_unconditional_recursion_call_site_label = recursive call site + +mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe = + call to unsafe function `{$function}` is unsafe and requires unsafe block (error E0133) + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + +mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless = + call to unsafe function is unsafe and requires unsafe block (error E0133) + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + +mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe = + use of inline assembly is unsafe and requires unsafe block (error E0133) + .note = inline assembly is entirely unchecked and can cause undefined behavior + .label = use of inline assembly + +mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe = + initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe + block (error E0133) + .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior + .label = initializing type with `rustc_layout_scalar_valid_range` attr + +mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe = + use of mutable static is unsafe and requires unsafe block (error E0133) + .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + .label = use of mutable static + +mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe = + use of extern static is unsafe and requires unsafe block (error E0133) + .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + .label = use of extern static + +mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe = + dereference of raw pointer is unsafe and requires unsafe block (error E0133) + .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + .label = dereference of raw pointer + +mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe = + access to union field is unsafe and requires unsafe block (error E0133) + .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior + .label = access to union field + +mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe = + mutation of layout constrained field is unsafe and requires unsafe block (error E0133) + .note = mutating layout constrained fields cannot statically be checked for valid values + .label = mutation of layout constrained field + +mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe = + borrow of layout constrained field with interior mutability is unsafe and requires unsafe block (error E0133) + .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + .label = borrow of layout constrained field with interior mutability + +mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe = + call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) + .note = can only be called if the required target features are available + .label = call to function with `#[target_feature]` diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index fb1ea9ed300ad..a7993e7dfe4da 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -1,4 +1,5 @@ use crate::build::ExprCategory; +use crate::errors::*; use rustc_middle::thir::visit::{self, Visitor}; use rustc_errors::struct_span_err; @@ -83,15 +84,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { } SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {} SafetyContext::UnsafeFn => { - let (description, note) = kind.description_and_note(self.tcx); // unsafe_op_in_unsafe_fn is disallowed - self.tcx.struct_span_lint_hir( - UNSAFE_OP_IN_UNSAFE_FN, - self.hir_context, - span, - format!("{} is unsafe and requires unsafe block (error E0133)", description,), - |lint| lint.span_label(span, kind.simple_description()).note(note), - ) + kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span); } SafetyContext::Safe => { let (description, note) = kind.description_and_note(self.tcx); @@ -529,6 +523,88 @@ enum UnsafeOpKind { use UnsafeOpKind::*; impl UnsafeOpKind { + pub fn emit_unsafe_op_in_unsafe_fn_lint( + &self, + tcx: TyCtxt<'_>, + hir_id: hir::HirId, + span: Span, + ) { + match self { + CallToUnsafeFunction(did) if did.is_some() => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { + span, + function: &tcx.def_path_str(did.unwrap()), + }, + ), + CallToUnsafeFunction(..) => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { span }, + ), + UseOfInlineAssembly => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span }, + ), + InitializingTypeWith => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span }, + ), + UseOfMutableStatic => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span }, + ), + UseOfExternStatic => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span }, + ), + DerefOfRawPointer => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span }, + ), + AccessToUnionField => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span }, + ), + MutationOfLayoutConstrainedField => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span }, + ), + BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span }, + ), + CallToFunctionWith(did) => tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + hir_id, + span, + UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe { + span, + function: &tcx.def_path_str(*did), + }, + ), + } + } + pub fn simple_description(&self) -> &'static str { match self { CallToUnsafeFunction(..) => "call to unsafe function", diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 1d44db7eb3a7d..61131c0d733cd 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -2,12 +2,100 @@ use rustc_macros::LintDiagnostic; use rustc_span::Span; #[derive(LintDiagnostic)] -#[lint(mir_build::unconditional_recursion)] +#[diag(mir_build::unconditional_recursion)] #[help] pub struct UnconditionalRecursion { - #[primary_span] #[label] pub span: Span, #[label(mir_build::unconditional_recursion_call_site_label)] pub call_sites: Vec, } + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> { + #[label] + pub span: Span, + pub function: &'a str, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)] +#[note] +pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_union_field_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)] +pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)] +#[note] +pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> { + #[label] + pub span: Span, + pub function: &'a str, +} diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 383598fb094b6..8529c64cd5cca 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -37,10 +37,12 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let sp = tcx.def_span(def_id); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.emit_spanned_lint(UNCONDITIONAL_RECURSION, hir_id, sp, UnconditionalRecursion { - span: sp, - call_sites: vis.reachable_recursive_calls, - }); + tcx.emit_spanned_lint( + UNCONDITIONAL_RECURSION, + hir_id, + sp, + UnconditionalRecursion { span: sp, call_sites: vis.reachable_recursive_calls }, + ); } } From 1443d1b5122ff1b516a02f9dde10c85b9518465b Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Wed, 24 Aug 2022 11:01:53 +0300 Subject: [PATCH 07/30] Migrate "requires unsafe" diagnostics --- .../locales/en-US/mir_build.ftl | 110 +++++++++ .../rustc_mir_build/src/check_unsafety.rs | 200 ++++++++-------- compiler/rustc_mir_build/src/errors.rs | 216 +++++++++++++++++- 3 files changed, 431 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 2dfc4984786b9..fd42cc6cb0876 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -59,3 +59,113 @@ mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe = call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) .note = can only be called if the required target features are available .label = call to function with `#[target_feature]` + +mir_build_call_to_unsafe_fn_requires_unsafe = + call to unsafe function `{$function}` is unsafe and requires unsafe block + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + +mir_build_call_to_unsafe_fn_requires_unsafe_nameless = + call to unsafe function is unsafe and requires unsafe block + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + +mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + call to unsafe function `{$function}` is unsafe and requires unsafe function or block + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + +mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed = + call to unsafe function is unsafe and requires unsafe function or block + .note = consult the function's documentation for information on how to avoid undefined behavior + .label = call to unsafe function + +mir_build_inline_assembly_requires_unsafe = + use of inline assembly is unsafe and requires unsafe block + .note = inline assembly is entirely unchecked and can cause undefined behavior + .label = use of inline assembly + +mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + use of inline assembly is unsafe and requires unsafe function or block + .note = inline assembly is entirely unchecked and can cause undefined behavior + .label = use of inline assembly + +mir_build_initializing_type_with_requires_unsafe = + initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block + .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior + .label = initializing type with `rustc_layout_scalar_valid_range` attr + +mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block + .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior + .label = initializing type with `rustc_layout_scalar_valid_range` attr + +mir_build_mutable_static_requires_unsafe = + use of mutable static is unsafe and requires unsafe block + .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + .label = use of mutable static + +mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + use of mutable static is unsafe and requires unsafe function or block + .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + .label = use of mutable static + +mir_build_extern_static_requires_unsafe = + use of extern static is unsafe and requires unsafe block + .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + .label = use of extern static + +mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + use of extern static is unsafe and requires unsafe function or block + .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + .label = use of extern static + +mir_build_deref_raw_pointer_requires_unsafe = + dereference of raw pointer is unsafe and requires unsafe block + .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + .label = dereference of raw pointer + +mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + dereference of raw pointer is unsafe and requires unsafe function or block + .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + .label = dereference of raw pointer + +mir_build_union_field_requires_unsafe = + access to union field is unsafe and requires unsafe block + .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior + .label = access to union field + +mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + access to union field is unsafe and requires unsafe function or block + .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior + .label = access to union field + +mir_build_mutation_of_layout_constrained_field_requires_unsafe = + mutation of layout constrained field is unsafe and requires unsafe block + .note = mutating layout constrained fields cannot statically be checked for valid values + .label = mutation of layout constrained field + +mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + mutation of layout constrained field is unsafe and requires unsafe function or block + .note = mutating layout constrained fields cannot statically be checked for valid values + .label = mutation of layout constrained field + +mir_build_borrow_of_layout_constrained_field_requires_unsafe = + borrow of layout constrained field with interior mutability is unsafe and requires unsafe block + .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + .label = borrow of layout constrained field with interior mutability + +mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + .label = borrow of layout constrained field with interior mutability + +mir_build_call_to_fn_with_requires_unsafe = + call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block + .note = can only be called if the required target features are available + .label = call to function with `#[target_feature]` + +mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = + call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe function or block + .note = can only be called if the required target features are available + .label = call to function with `#[target_feature]` diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index a7993e7dfe4da..b68241bc96b8e 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -2,7 +2,6 @@ use crate::build::ExprCategory; use crate::errors::*; use rustc_middle::thir::visit::{self, Visitor}; -use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_middle::mir::BorrowKind; use rustc_middle::thir::*; @@ -13,7 +12,6 @@ use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::symbol::Symbol; use rustc_span::Span; -use std::borrow::Cow; use std::ops::Bound; struct UnsafetyVisitor<'a, 'tcx> { @@ -88,19 +86,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span); } SafetyContext::Safe => { - let (description, note) = kind.description_and_note(self.tcx); - let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" }; - struct_span_err!( - self.tcx.sess, - span, - E0133, - "{} is unsafe and requires unsafe{} block", - description, - fn_sugg, - ) - .span_label(span, kind.simple_description()) - .note(note) - .emit(); + kind.emit_requires_unsafe_err(self.tcx, span, unsafe_op_in_unsafe_fn_allowed); } } } @@ -549,55 +535,55 @@ impl UnsafeOpKind { UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span }, + UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { span }, ), InitializingTypeWith => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span }, + UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { span }, ), UseOfMutableStatic => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span }, + UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { span }, ), UseOfExternStatic => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span }, + UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { span }, ), DerefOfRawPointer => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span }, + UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { span }, ), AccessToUnionField => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span }, + UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { span }, ), MutationOfLayoutConstrainedField => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span }, + UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { span }, ), BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span }, + UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span }, ), CallToFunctionWith(did) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe { + UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { span, function: &tcx.def_path_str(*did), }, @@ -605,79 +591,105 @@ impl UnsafeOpKind { } } - pub fn simple_description(&self) -> &'static str { + pub fn emit_requires_unsafe_err( + &self, + tcx: TyCtxt<'_>, + span: Span, + unsafe_op_in_unsafe_fn_allowed: bool, + ) { match self { - CallToUnsafeFunction(..) => "call to unsafe function", - UseOfInlineAssembly => "use of inline assembly", - InitializingTypeWith => "initializing type with `rustc_layout_scalar_valid_range` attr", - UseOfMutableStatic => "use of mutable static", - UseOfExternStatic => "use of extern static", - DerefOfRawPointer => "dereference of raw pointer", - AccessToUnionField => "access to union field", - MutationOfLayoutConstrainedField => "mutation of layout constrained field", + CallToUnsafeFunction(did) if did.is_some() && unsafe_op_in_unsafe_fn_allowed => { + tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + function: &tcx.def_path_str(did.unwrap()), + }); + } + CallToUnsafeFunction(did) if did.is_some() => { + tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe { + span, + function: &tcx.def_path_str(did.unwrap()), + }); + } + CallToUnsafeFunction(..) if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess.emit_err( + CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span }, + ); + } + CallToUnsafeFunction(..) => { + tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span }); + } + UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess + .emit_err(UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + } + UseOfInlineAssembly => { + tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafe { span }); + } + InitializingTypeWith if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess + .emit_err(InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + } + InitializingTypeWith => { + tcx.sess.emit_err(InitializingTypeWithRequiresUnsafe { span }); + } + UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess + .emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + } + UseOfMutableStatic => { + tcx.sess.emit_err(UseOfMutableStaticRequiresUnsafe { span }); + } + UseOfExternStatic if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess + .emit_err(UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + } + UseOfExternStatic => { + tcx.sess.emit_err(UseOfExternStaticRequiresUnsafe { span }); + } + DerefOfRawPointer if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess + .emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + } + DerefOfRawPointer => { + tcx.sess.emit_err(DerefOfRawPointerRequiresUnsafe { span }); + } + AccessToUnionField if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess + .emit_err(AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + } + AccessToUnionField => { + tcx.sess.emit_err(AccessToUnionFieldRequiresUnsafe { span }); + } + MutationOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess.emit_err( + MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + }, + ); + } + MutationOfLayoutConstrainedField => { + tcx.sess.emit_err(MutationOfLayoutConstrainedFieldRequiresUnsafe { span }); + } + BorrowOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess.emit_err( + BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }, + ); + } BorrowOfLayoutConstrainedField => { - "borrow of layout constrained field with interior mutability" + tcx.sess.emit_err(BorrowOfLayoutConstrainedFieldRequiresUnsafe { span }); + } + CallToFunctionWith(did) if unsafe_op_in_unsafe_fn_allowed => { + tcx.sess.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + function: &tcx.def_path_str(*did), + }); + } + CallToFunctionWith(did) => { + tcx.sess.emit_err(CallToFunctionWithRequiresUnsafe { + span, + function: &tcx.def_path_str(*did), + }); } - CallToFunctionWith(..) => "call to function with `#[target_feature]`", - } - } - - pub fn description_and_note(&self, tcx: TyCtxt<'_>) -> (Cow<'static, str>, &'static str) { - match self { - CallToUnsafeFunction(did) => ( - if let Some(did) = did { - Cow::from(format!("call to unsafe function `{}`", tcx.def_path_str(*did))) - } else { - Cow::Borrowed(self.simple_description()) - }, - "consult the function's documentation for information on how to avoid undefined \ - behavior", - ), - UseOfInlineAssembly => ( - Cow::Borrowed(self.simple_description()), - "inline assembly is entirely unchecked and can cause undefined behavior", - ), - InitializingTypeWith => ( - Cow::Borrowed(self.simple_description()), - "initializing a layout restricted type's field with a value outside the valid \ - range is undefined behavior", - ), - UseOfMutableStatic => ( - Cow::Borrowed(self.simple_description()), - "mutable statics can be mutated by multiple threads: aliasing violations or data \ - races will cause undefined behavior", - ), - UseOfExternStatic => ( - Cow::Borrowed(self.simple_description()), - "extern statics are not controlled by the Rust type system: invalid data, \ - aliasing violations or data races will cause undefined behavior", - ), - DerefOfRawPointer => ( - Cow::Borrowed(self.simple_description()), - "raw pointers may be null, dangling or unaligned; they can violate aliasing rules \ - and cause data races: all of these are undefined behavior", - ), - AccessToUnionField => ( - Cow::Borrowed(self.simple_description()), - "the field may not be properly initialized: using uninitialized data will cause \ - undefined behavior", - ), - MutationOfLayoutConstrainedField => ( - Cow::Borrowed(self.simple_description()), - "mutating layout constrained fields cannot statically be checked for valid values", - ), - BorrowOfLayoutConstrainedField => ( - Cow::Borrowed(self.simple_description()), - "references to fields of layout constrained fields lose the constraints. Coupled \ - with interior mutability, the field can be changed to invalid values", - ), - CallToFunctionWith(did) => ( - Cow::from(format!( - "call to function `{}` with `#[target_feature]`", - tcx.def_path_str(*did) - )), - "can only be called if the required target features are available", - ), } } } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 61131c0d733cd..260a9f6375bb9 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_macros::LintDiagnostic; +use rustc_macros::{LintDiagnostic, SessionDiagnostic}; use rustc_span::Span; #[derive(LintDiagnostic)] @@ -99,3 +99,217 @@ pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> { pub span: Span, pub function: &'a str, } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::call_to_unsafe_fn_requires_unsafe, code = "E0133")] +#[note] +pub struct CallToUnsafeFunctionRequiresUnsafe<'a> { + #[primary_span] + #[label] + pub span: Span, + pub function: &'a str, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")] +#[note] +pub struct CallToUnsafeFunctionRequiresUnsafeNameless { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { + #[primary_span] + #[label] + pub span: Span, + pub function: &'a str, +} + +#[derive(SessionDiagnostic)] +#[diag( + mir_build::call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed, + code = "E0133" +)] +#[note] +pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::inline_assembly_requires_unsafe, code = "E0133")] +#[note] +pub struct UseOfInlineAssemblyRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::initializing_type_with_requires_unsafe, code = "E0133")] +#[note] +pub struct InitializingTypeWithRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag( + mir_build::initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + code = "E0133" +)] +#[note] +pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::mutable_static_requires_unsafe, code = "E0133")] +#[note] +pub struct UseOfMutableStaticRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::extern_static_requires_unsafe, code = "E0133")] +#[note] +pub struct UseOfExternStaticRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::deref_raw_pointer_requires_unsafe, code = "E0133")] +#[note] +pub struct DerefOfRawPointerRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::union_field_requires_unsafe, code = "E0133")] +#[note] +pub struct AccessToUnionFieldRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")] +#[note] +pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag( + mir_build::mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + code = "E0133" +)] +#[note] +pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")] +#[note] +pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag( + mir_build::borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + code = "E0133" +)] +#[note] +pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::call_to_fn_with_requires_unsafe, code = "E0133")] +#[note] +pub struct CallToFunctionWithRequiresUnsafe<'a> { + #[primary_span] + #[label] + pub span: Span, + pub function: &'a str, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[note] +pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { + #[primary_span] + #[label] + pub span: Span, + pub function: &'a str, +} From cc85b0195823d9efe11f22672ca56bc5fa581e34 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Wed, 24 Aug 2022 20:16:50 +0300 Subject: [PATCH 08/30] Migrate "unused unsafe" lint --- .../locales/en-US/mir_build.ftl | 6 +++++ .../rustc_mir_build/src/check_unsafety.rs | 24 ++++++++++-------- compiler/rustc_mir_build/src/errors.rs | 25 ++++++++++++++++++- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index fd42cc6cb0876..9dab6f8e88320 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -169,3 +169,9 @@ mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe function or block .note = can only be called if the required target features are available .label = call to function with `#[target_feature]` + +mir_build_unused_unsafe = unnecessary `unsafe` block + .label = unnecessary `unsafe` block + +mir_build_unused_unsafe_enclosing_block_label = because it's nested under this `unsafe` block +mir_build_unused_unsafe_enclosing_fn_label = because it's nested under this `unsafe` fn diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index b68241bc96b8e..3f0f05711edd3 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -45,7 +45,9 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { self.warn_unused_unsafe( hir_id, block_span, - Some((self.tcx.sess.source_map().guess_head_span(enclosing_span), "block")), + Some(UnusedUnsafeEnclosing::Block { + span: self.tcx.sess.source_map().guess_head_span(enclosing_span), + }), ); f(self); } else { @@ -59,7 +61,9 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { hir_id, span, if self.unsafe_op_in_unsafe_fn_allowed() { - self.body_unsafety.unsafe_fn_sig_span().map(|span| (span, "fn")) + self.body_unsafety + .unsafe_fn_sig_span() + .map(|span| UnusedUnsafeEnclosing::Function { span }) } else { None }, @@ -95,17 +99,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { &self, hir_id: hir::HirId, block_span: Span, - enclosing_unsafe: Option<(Span, &'static str)>, + enclosing_unsafe: Option, ) { let block_span = self.tcx.sess.source_map().guess_head_span(block_span); - let msg = "unnecessary `unsafe` block"; - self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, msg, |lint| { - lint.span_label(block_span, msg); - if let Some((span, kind)) = enclosing_unsafe { - lint.span_label(span, format!("because it's nested under this `unsafe` {}", kind)); - } - lint - }); + self.tcx.emit_spanned_lint( + UNUSED_UNSAFE, + hir_id, + block_span, + UnusedUnsafe { span: block_span, enclosing: enclosing_unsafe }, + ); } /// Whether the `unsafe_op_in_unsafe_fn` lint is `allow`ed at the current HIR node. diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 260a9f6375bb9..a3e8715122667 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_macros::{LintDiagnostic, SessionDiagnostic}; +use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::Span; #[derive(LintDiagnostic)] @@ -313,3 +313,26 @@ pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { pub span: Span, pub function: &'a str, } + +#[derive(LintDiagnostic)] +#[diag(mir_build::unused_unsafe)] +pub struct UnusedUnsafe { + #[label] + pub span: Span, + #[subdiagnostic] + pub enclosing: Option, +} + +#[derive(SessionSubdiagnostic)] +pub enum UnusedUnsafeEnclosing { + #[label(mir_build::unused_unsafe_enclosing_block_label)] + Block { + #[primary_span] + span: Span, + }, + #[label(mir_build::unused_unsafe_enclosing_fn_label)] + Function { + #[primary_span] + span: Span, + }, +} From 07d3ce580ceeda1efeccd8a075558bdab9f2fcd6 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Fri, 26 Aug 2022 16:38:21 +0300 Subject: [PATCH 09/30] Migrate "non-exhaustive patterns: type is non-empty" diagnostic --- .../locales/en-US/mir_build.ftl | 8 ++ compiler/rustc_mir_build/src/errors.rs | 93 +++++++++++++++++++ .../src/thir/pattern/check_match.rs | 18 ++-- .../rustc_mir_build/src/thir/pattern/mod.rs | 1 + 4 files changed, 113 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 9dab6f8e88320..5fb89dcccaeeb 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -175,3 +175,11 @@ mir_build_unused_unsafe = unnecessary `unsafe` block mir_build_unused_unsafe_enclosing_block_label = because it's nested under this `unsafe` block mir_build_unused_unsafe_enclosing_fn_label = because it's nested under this `unsafe` fn + +mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type `{$ty}` is non-empty + .def_note = `{$peeled_ty}` defined here + .type_note = the matched value is of type `{$ty}` + .non_exhaustive_type_note = the matched value is of type `{$ty}`, which is marked as non-exhaustive + .reference_note = references are always considered inhabited + .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index a3e8715122667..9e63141d7160c 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,4 +1,8 @@ +use crate::thir::pattern::MatchCheckCtxt; +use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; +use rustc_middle::ty::{self, Ty}; +use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::Span; #[derive(LintDiagnostic)] @@ -336,3 +340,92 @@ pub enum UnusedUnsafeEnclosing { span: Span, }, } + +pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> { + pub cx: &'m MatchCheckCtxt<'p, 'tcx>, + pub expr_span: Span, + pub span: Span, + pub ty: Ty<'tcx>, +} + +impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = sess.span_diagnostic.struct_span_err_with_code( + self.span, + rustc_errors::fluent::mir_build::non_exhaustive_patterns_type_not_empty, + error_code!(E0004), + ); + + let peeled_ty = self.ty.peel_refs(); + diag.set_arg("ty", self.ty); + diag.set_arg("peeled_ty", peeled_ty); + + if let ty::Adt(def, _) = peeled_ty.kind() { + let def_span = self + .cx + .tcx + .hir() + .get_if_local(def.did()) + .and_then(|node| node.ident()) + .map(|ident| ident.span) + .unwrap_or_else(|| self.cx.tcx.def_span(def.did())); + + // workaround to make test pass + let mut span: MultiSpan = def_span.into(); + span.push_span_label(def_span, ""); + + diag.span_note(span, rustc_errors::fluent::mir_build::def_note); + } + + let is_variant_list_non_exhaustive = match self.ty.kind() { + ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => { + true + } + _ => false, + }; + + if is_variant_list_non_exhaustive { + diag.note(rustc_errors::fluent::mir_build::non_exhaustive_type_note); + } else { + diag.note(rustc_errors::fluent::mir_build::type_note); + } + + if let ty::Ref(_, sub_ty, _) = self.ty.kind() { + if self.cx.tcx.is_ty_uninhabited_from(self.cx.module, *sub_ty, self.cx.param_env) { + diag.note(rustc_errors::fluent::mir_build::reference_note); + } + } + + let mut suggestion = None; + let sm = self.cx.tcx.sess.source_map(); + if self.span.eq_ctxt(self.expr_span) { + // Get the span for the empty match body `{}`. + let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.span) { + (format!("\n{}", snippet), " ") + } else { + (" ".to_string(), "") + }; + suggestion = Some(( + self.span.shrink_to_hi().with_hi(self.expr_span.hi()), + format!( + " {{{indentation}{more}_ => todo!(),{indentation}}}", + indentation = indentation, + more = more, + ), + )); + } + + if let Some((span, sugg)) = suggestion { + diag.span_suggestion_verbose( + span, + rustc_errors::fluent::mir_build::suggestion, + sugg, + Applicability::HasPlaceholders, + ); + } else { + diag.help(rustc_errors::fluent::mir_build::help); + } + + diag + } +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index e369dba55242c..c818a2a3a898c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -4,6 +4,8 @@ use super::usefulness::{ }; use super::{PatCtxt, PatternError}; +use crate::errors::NonExhaustivePatternsTypeNotEmpty; + use rustc_arena::TypedArena; use rustc_ast::Mutability; use rustc_errors::{ @@ -760,15 +762,17 @@ fn non_exhaustive_match<'p, 'tcx>( // informative. let mut err; let pattern; - let mut patterns_len = 0; + let patterns_len; if is_empty_match && !non_empty_enum { - err = create_e0004( - cx.tcx.sess, - sp, - format!("non-exhaustive patterns: type `{}` is non-empty", scrut_ty), - ); - pattern = "_".to_string(); + cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty { + cx, + expr_span, + span: sp, + ty: scrut_ty, + }); + return; } else { + // FIXME: migration of this diagnostic will require list support let joined_patterns = joined_uncovered_patterns(cx, &witnesses); err = create_e0004( cx.tcx.sess, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 4c2a80e523f35..1d7c48adc70b8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -6,6 +6,7 @@ mod deconstruct_pat; mod usefulness; pub(crate) use self::check_match::check_match; +pub(crate) use self::usefulness::MatchCheckCtxt; use crate::thir::util::UserAnnotatedTyHelpers; From 85c68180f66a0310509f788b22e9b90f44354475 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Fri, 26 Aug 2022 19:30:33 +0300 Subject: [PATCH 10/30] Migrate pattern inlining error diagnostics --- .../locales/en-US/mir_build.ftl | 8 ++++++ compiler/rustc_mir_build/src/errors.rs | 28 +++++++++++++++++++ .../src/thir/pattern/check_match.rs | 18 ++++-------- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 5fb89dcccaeeb..610e16ab7d8e7 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -183,3 +183,11 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type .reference_note = references are always considered inhabited .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern + +mir_build_static_in_pattern = statics cannot be referenced in patterns + +mir_build_assoc_const_in_pattern = associated consts cannot be referenced in patterns + +mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns + +mir_build_non_const_path = runtime values cannot be referenced in patterns diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 9e63141d7160c..ceaf057bb465b 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -429,3 +429,31 @@ impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> diag } } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::static_in_pattern, code = "E0158")] +pub struct StaticInPattern { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::assoc_const_in_pattern, code = "E0158")] +pub struct AssocConstInPattern { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::const_param_in_pattern, code = "E0158")] +pub struct ConstParamInPattern { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::non_const_path, code = "E0080")] +pub struct NonConstPath { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index c818a2a3a898c..42c8787102914 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -4,7 +4,7 @@ use super::usefulness::{ }; use super::{PatCtxt, PatternError}; -use crate::errors::NonExhaustivePatternsTypeNotEmpty; +use crate::errors::*; use rustc_arena::TypedArena; use rustc_ast::Mutability; @@ -109,28 +109,20 @@ impl PatCtxt<'_, '_> { for error in &self.errors { match *error { PatternError::StaticInPattern(span) => { - self.span_e0158(span, "statics cannot be referenced in patterns") + self.tcx.sess.emit_err(StaticInPattern { span }); } PatternError::AssocConstInPattern(span) => { - self.span_e0158(span, "associated consts cannot be referenced in patterns") + self.tcx.sess.emit_err(AssocConstInPattern { span }); } PatternError::ConstParamInPattern(span) => { - self.span_e0158(span, "const parameters cannot be referenced in patterns") + self.tcx.sess.emit_err(ConstParamInPattern { span }); } PatternError::NonConstPath(span) => { - rustc_middle::mir::interpret::struct_error( - self.tcx.at(span), - "runtime values cannot be referenced in patterns", - ) - .emit(); + self.tcx.sess.emit_err(NonConstPath { span }); } } } } - - fn span_e0158(&self, span: Span, text: &str) { - struct_span_err!(self.tcx.sess, span, E0158, "{}", text).emit(); - } } impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { From 7d0d2de2b1435afb0af6609237e82adf1cc79dc5 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 27 Aug 2022 22:06:06 +0300 Subject: [PATCH 11/30] Migrate unreachable pattern diagnostic --- .../locales/en-US/mir_build.ftl | 4 ++++ compiler/rustc_mir_build/src/errors.rs | 9 +++++++++ .../src/thir/pattern/check_match.rs | 14 ++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 610e16ab7d8e7..8ff5c9b3fdebb 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -191,3 +191,7 @@ mir_build_assoc_const_in_pattern = associated consts cannot be referenced in pat mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns mir_build_non_const_path = runtime values cannot be referenced in patterns + +mir_build_unreachable_pattern = unreachable pattern + .label = unreachable pattern + .catchall_label = matches any value diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index ceaf057bb465b..3049ebc5b037b 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -457,3 +457,12 @@ pub struct NonConstPath { #[primary_span] pub span: Span, } + +#[derive(LintDiagnostic)] +#[diag(mir_build::unreachable_pattern)] +pub struct UnreachablePattern { + #[label] + pub span: Option, + #[label(mir_build::catchall_label)] + pub catchall: Option, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 42c8787102914..b21cd0d1404d4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -605,14 +605,12 @@ fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool { } fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option) { - tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, "unreachable pattern", |lint| { - if let Some(catchall) = catchall { - // We had a catchall pattern, hint at that. - lint.span_label(span, "unreachable pattern"); - lint.span_label(catchall, "matches any value"); - } - lint - }); + tcx.emit_spanned_lint( + UNREACHABLE_PATTERNS, + id, + span, + UnreachablePattern { span: if catchall.is_some() { Some(span) } else { None }, catchall }, + ); } fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) { From 75694d532cbb6ab0cc042080070549feb5e32530 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 27 Aug 2022 22:17:10 +0300 Subject: [PATCH 12/30] Migrate "constant pattern depends on generic parameter" diagnostic --- compiler/rustc_error_messages/locales/en-US/mir_build.ftl | 3 +++ compiler/rustc_mir_build/src/errors.rs | 7 +++++++ compiler/rustc_mir_build/src/thir/pattern/mod.rs | 7 ++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 8ff5c9b3fdebb..4504d557da3f0 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -195,3 +195,6 @@ mir_build_non_const_path = runtime values cannot be referenced in patterns mir_build_unreachable_pattern = unreachable pattern .label = unreachable pattern .catchall_label = matches any value + +mir_build_const_pattern_depends_on_generic_parameter = + constant pattern depends on a generic parameter diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 3049ebc5b037b..e6ed824b8bb91 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -466,3 +466,10 @@ pub struct UnreachablePattern { #[label(mir_build::catchall_label)] pub catchall: Option, } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::const_pattern_depends_on_generic_parameter)] +pub struct ConstPatternDependsOnGenericParameter { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 1d7c48adc70b8..c29b0dd6770a3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -8,6 +8,7 @@ mod usefulness; pub(crate) use self::check_match::check_match; pub(crate) use self::usefulness::MatchCheckCtxt; +use crate::errors::ConstPatternDependsOnGenericParameter; use crate::thir::util::UserAnnotatedTyHelpers; use rustc_errors::struct_span_err; @@ -549,7 +550,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Err(ErrorHandled::TooGeneric) => { // While `Reported | Linted` cases will have diagnostics emitted already // it is not true for TooGeneric case, so we need to give user more information. - self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); + self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); pat_from_kind(PatKind::Wild) } Err(_) => { @@ -583,9 +584,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => bug!("Expected ConstKind::Param"), }, mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind, - mir::ConstantKind::Unevaluated(..) => { + mir::ConstKind::Unevaluated(_) => { // If we land here it means the const can't be evaluated because it's `TooGeneric`. - self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); + self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); return PatKind::Wild; } } From baa6c159037b5e6c7c655ad04847e6339b8993e4 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 27 Aug 2022 22:25:09 +0300 Subject: [PATCH 13/30] Migrate "could not evaluate const pattern" diagnostic --- compiler/rustc_error_messages/locales/en-US/mir_build.ftl | 2 ++ compiler/rustc_mir_build/src/errors.rs | 7 +++++++ compiler/rustc_mir_build/src/thir/pattern/mod.rs | 6 +++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 4504d557da3f0..87e7f348ee080 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -198,3 +198,5 @@ mir_build_unreachable_pattern = unreachable pattern mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter + +mir_build_could_not_eval_const_pattern = could not evaluate constant pattern diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index e6ed824b8bb91..0d7e62e616f3c 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -473,3 +473,10 @@ pub struct ConstPatternDependsOnGenericParameter { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::could_not_eval_const_pattern)] +pub struct CouldNotEvalConstPattern { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index c29b0dd6770a3..c79702134fd55 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -8,7 +8,7 @@ mod usefulness; pub(crate) use self::check_match::check_match; pub(crate) use self::usefulness::MatchCheckCtxt; -use crate::errors::ConstPatternDependsOnGenericParameter; +use crate::errors::*; use crate::thir::util::UserAnnotatedTyHelpers; use rustc_errors::struct_span_err; @@ -503,7 +503,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } Err(_) => { - self.tcx.sess.span_err(span, "could not evaluate constant pattern"); + self.tcx.sess.emit_err(CouldNotEvalConstPattern { span }); return pat_from_kind(PatKind::Wild); } }; @@ -554,7 +554,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pat_from_kind(PatKind::Wild) } Err(_) => { - self.tcx.sess.span_err(span, "could not evaluate constant pattern"); + self.tcx.sess.emit_err(CouldNotEvalConstPattern { span }); pat_from_kind(PatKind::Wild) } } From 5c64edf0d4125e106ad5dfb1d60c1f7050947767 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 27 Aug 2022 22:48:18 +0300 Subject: [PATCH 14/30] Migrate lower range bound diagnostics --- .../locales/en-US/mir_build.ftl | 7 +++++ compiler/rustc_mir_build/src/errors.rs | 17 +++++++++++ .../rustc_mir_build/src/thir/pattern/mod.rs | 29 ++++--------------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 87e7f348ee080..6bfab0774feae 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -200,3 +200,10 @@ mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter mir_build_could_not_eval_const_pattern = could not evaluate constant pattern + +mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper = + lower range bound must be less than or equal to upper + .label = lower bound larger than upper bound + .teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range. + +mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 0d7e62e616f3c..96728970c5be0 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -480,3 +480,20 @@ pub struct CouldNotEvalConstPattern { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")] +pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper { + #[primary_span] + #[label] + pub span: Span, + #[note(mir_build::teach_note)] + pub teach: Option<()>, +} + +#[derive(SessionDiagnostic)] +#[diag(mir_build::lower_range_bound_must_be_less_than_upper, code = "E0579")] +pub struct LowerRangeBoundMustBeLessThanUpper { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index c79702134fd55..991b0292f9003 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -11,7 +11,7 @@ pub(crate) use self::usefulness::MatchCheckCtxt; use crate::errors::*; use crate::thir::util::UserAnnotatedTyHelpers; -use rustc_errors::struct_span_err; +use rustc_errors::error_code; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; @@ -141,13 +141,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } // `x..y` where `x >= y`. The range is empty => error. (RangeEnd::Excluded, _) => { - struct_span_err!( - self.tcx.sess, - span, - E0579, - "lower range bound must be less than upper" - ) - .emit(); + self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanUpper { span }); PatKind::Wild } // `x..=y` where `x == y`. @@ -158,23 +152,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } // `x..=y` where `x > y` hence the range is empty => error. (RangeEnd::Included, _) => { - let mut err = struct_span_err!( - self.tcx.sess, + self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper { span, - E0030, - "lower range bound must be less than or equal to upper" - ); - err.span_label(span, "lower bound larger than upper bound"); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "When matching against a range, the compiler \ - verifies that the range is non-empty. Range \ - patterns include both end-points, so this is \ - equivalent to requiring the start of the range \ - to be less than or equal to the end of the range.", - ); - } - err.emit(); + teach: if self.tcx.sess.teach(&error_code!(E0030)) { Some(()) } else { None }, + }); PatKind::Wild } } From 42a8f37c914829baf64e85aada660202188d9daf Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sun, 28 Aug 2022 21:48:09 +0300 Subject: [PATCH 15/30] Migrate leading/trailing irrefutable let pattern diagnostics --- .../locales/en-US/mir_build.ftl | 26 ++++++++++++++ compiler/rustc_mir_build/src/errors.rs | 16 +++++++++ .../src/thir/pattern/check_match.rs | 35 ++++++------------- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 6bfab0774feae..280b82b4ea400 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -207,3 +207,29 @@ mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper = .teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range. mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper + +mir_build_leading_irrefutable_let_patterns = leading irrefutable {$count -> + [one] pattern + *[other] patterns + } in let chain + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match + .help = consider moving {$count -> + [one] it + *[other] them + } outside of the construct + +mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count -> + [one] pattern + *[other] patterns + } in let chain + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match + .help = consider moving {$count -> + [one] it + *[other] them + } into the body diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 96728970c5be0..3331e785b95f2 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -497,3 +497,19 @@ pub struct LowerRangeBoundMustBeLessThanUpper { #[primary_span] pub span: Span, } + +#[derive(LintDiagnostic)] +#[diag(mir_build::leading_irrefutable_let_patterns)] +#[note] +#[help] +pub struct LeadingIrrefutableLetPatterns { + pub count: usize, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::trailing_irrefutable_let_patterns)] +#[note] +#[help] +pub struct TrailingIrrefutableLetPatterns { + pub count: usize, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index b21cd0d1404d4..8e1a3f10f4acb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -339,29 +339,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { ); return true; } - let lint_affix = |affix: &[Option<(Span, bool)>], kind, suggestion| { - let span_start = affix[0].unwrap().0; - let span_end = affix.last().unwrap().unwrap().0; - let span = span_start.to(span_end); - let cnt = affix.len(); - let s = pluralize!(cnt); - cx.tcx.struct_span_lint_hir( - IRREFUTABLE_LET_PATTERNS, - top, - span, - format!("{kind} irrefutable pattern{s} in let chain"), - |lint| { - lint.note(format!( - "{these} pattern{s} will always match", - these = pluralize!("this", cnt), - )) - .help(format!( - "consider moving {} {suggestion}", - if cnt > 1 { "them" } else { "it" } - )) - }, - ); - }; if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 { // The chain has a non-zero prefix of irrefutable `let` statements. @@ -375,13 +352,21 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { if !matches!(let_source, LetSource::WhileLet | LetSource::IfLetGuard) { // Emit the lint let prefix = &chain_refutabilities[..until]; - lint_affix(prefix, "leading", "outside of the construct"); + let span_start = prefix[0].unwrap().0; + let span_end = prefix.last().unwrap().unwrap().0; + let span = span_start.to(span_end); + let count = prefix.len(); + cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, LeadingIrrefutableLetPatterns { count }); } } if let Some(from) = chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, false)))) && from != (chain_refutabilities.len() - 1) { // The chain has a non-empty suffix of irrefutable `let` statements let suffix = &chain_refutabilities[from + 1..]; - lint_affix(suffix, "trailing", "into the body"); + let span_start = suffix[0].unwrap().0; + let span_end = suffix.last().unwrap().unwrap().0; + let span = span_start.to(span_end); + let count = suffix.len(); + cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, TrailingIrrefutableLetPatterns { count }); } true } From 8c002829eca07090674088e7089e3b3a1e117ad9 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Mon, 29 Aug 2022 10:06:50 +0300 Subject: [PATCH 16/30] Migrate pattern bindings with variant name lint --- .../locales/en-US/mir_build.ftl | 4 +++ compiler/rustc_mir_build/src/errors.rs | 11 ++++++- .../src/thir/pattern/check_match.rs | 32 ++++++------------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 280b82b4ea400..539794086ee26 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -233,3 +233,7 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count -> [one] it *[other] them } into the body + +mir_build_bindings_with_variant_name = + pattern binding `{$ident}` is named the same as one of the variants of the type `{$ty_path}` + .suggestion = to match on the variant, qualify the path diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 3331e785b95f2..085511a9d7c0a 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -3,7 +3,7 @@ use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::{self, Ty}; use rustc_session::{parse::ParseSess, SessionDiagnostic}; -use rustc_span::Span; +use rustc_span::{symbol::Ident, Span}; #[derive(LintDiagnostic)] #[diag(mir_build::unconditional_recursion)] @@ -513,3 +513,12 @@ pub struct LeadingIrrefutableLetPatterns { pub struct TrailingIrrefutableLetPatterns { pub count: usize, } + +#[derive(LintDiagnostic)] +#[diag(mir_build::bindings_with_variant_name, code = "E0170")] +pub struct BindingsWithVariantName { + #[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")] + pub suggestion: Option, + pub ty_path: String, + pub ident: Ident, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 8e1a3f10f4acb..a62c1a232fac1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -9,8 +9,8 @@ use crate::errors::*; use rustc_arena::TypedArena; use rustc_ast::Mutability; use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, MultiSpan, + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, + MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::*; @@ -547,32 +547,20 @@ fn check_for_bindings_named_same_as_variants( }) { let variant_count = edef.variants().len(); - cx.tcx.struct_span_lint_hir( + let ty_path = cx.tcx.def_path_str(edef.did()); + cx.tcx.emit_spanned_lint( BINDINGS_WITH_VARIANT_NAME, p.hir_id, p.span, - DelayDm(|| format!( - "pattern binding `{}` is named the same as one \ - of the variants of the type `{}`", - ident, cx.tcx.def_path_str(edef.did()) - )), - |lint| { - let ty_path = cx.tcx.def_path_str(edef.did()); - lint.code(error_code!(E0170)); - + BindingsWithVariantName { // If this is an irrefutable pattern, and there's > 1 variant, // then we can't actually match on this. Applying the below // suggestion would produce code that breaks on `check_irrefutable`. - if rf == Refutable || variant_count == 1 { - lint.span_suggestion( - p.span, - "to match on the variant, qualify the path", - format!("{}::{}", ty_path, ident), - Applicability::MachineApplicable, - ); - } - - lint + suggestion: if rf == Refutable || variant_count == 1 { + Some(p.span) + } else { None }, + ty_path, + ident, }, ) } From 1a18ee87cab361a02041412d0e2a5aa288b77bd2 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Mon, 29 Aug 2022 11:21:25 +0300 Subject: [PATCH 17/30] Migrate irrefutable let pattern diagnostics --- .../locales/en-US/mir_build.ftl | 50 +++++++++++++ compiler/rustc_mir_build/src/errors.rs | 40 +++++++++++ .../src/thir/pattern/check_match.rs | 70 ++++--------------- 3 files changed, 103 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 539794086ee26..7555bd608498d 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -237,3 +237,53 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count -> mir_build_bindings_with_variant_name = pattern binding `{$ident}` is named the same as one of the variants of the type `{$ty_path}` .suggestion = to match on the variant, qualify the path + +mir_build_irrefutable_let_patterns_generic_let = irrefutable `let` {$count -> + [one] pattern + *[other] patterns + } + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match, so the `let` is useless + .help = consider removing `let` + +mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count -> + [one] pattern + *[other] patterns + } + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match, so the `if let` is useless + .help = consider replacing the `if let` with a `let` + +mir_build_irrefutable_let_patterns_if_let_guard = irrefutable `if let` guard {$count -> + [one] pattern + *[other] patterns + } + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match, so the guard is useless + .help = consider removing the guard and adding a `let` inside the match arm + +mir_build_irrefutable_let_patterns_let_else = irrefutable `let...else` {$count -> + [one] pattern + *[other] patterns + } + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match, so the `else` clause is useless + .help = consider removing the `else` clause + +mir_build_irrefutable_let_patterns_while_let = irrefutable `while let` {$count -> + [one] pattern + *[other] patterns + } + .note = {$count -> + [one] this pattern + *[other] these patterns + } will always match, so the loop will never exit + .help = consider instead using a `loop {"{"} ... {"}"}` with a `let` inside it diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 085511a9d7c0a..eecef26b94cb6 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -522,3 +522,43 @@ pub struct BindingsWithVariantName { pub ty_path: String, pub ident: Ident, } + +#[derive(LintDiagnostic)] +#[diag(mir_build::irrefutable_let_patterns_generic_let)] +#[note] +#[help] +pub struct IrrefutableLetPatternsGenericLet { + pub count: usize, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::irrefutable_let_patterns_if_let)] +#[note] +#[help] +pub struct IrrefutableLetPatternsIfLet { + pub count: usize, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::irrefutable_let_patterns_if_let_guard)] +#[note] +#[help] +pub struct IrrefutableLetPatternsIfLetGuard { + pub count: usize, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::irrefutable_let_patterns_let_else)] +#[note] +#[help] +pub struct IrrefutableLetPatternsLetElse { + pub count: usize, +} + +#[derive(LintDiagnostic)] +#[diag(mir_build::irrefutable_let_patterns_while_let)] +#[note] +#[help] +pub struct IrrefutableLetPatternsWhileLet { + pub count: usize, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a62c1a232fac1..a488253b992b2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -598,68 +598,24 @@ fn irrefutable_let_patterns( count: usize, span: Span, ) { + let span = match source { + LetSource::LetElse(span) => span, + _ => span, + }; + macro_rules! emit_diag { - ( - $lint:expr, - $source_name:expr, - $note_sufix:expr, - $help_sufix:expr - ) => {{ - let s = pluralize!(count); - let these = pluralize!("this", count); - tcx.struct_span_lint_hir( - IRREFUTABLE_LET_PATTERNS, - id, - span, - format!("irrefutable {} pattern{s}", $source_name), - |lint| { - lint.note(&format!( - "{these} pattern{s} will always match, so the {}", - $note_sufix - )) - .help(concat!("consider ", $help_sufix)) - }, - ) + ($lint:tt) => {{ + tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, id, span, $lint { count }); }}; } match source { - LetSource::GenericLet => { - emit_diag!(lint, "`let`", "`let` is useless", "removing `let`"); - } - LetSource::IfLet => { - emit_diag!( - lint, - "`if let`", - "`if let` is useless", - "replacing the `if let` with a `let`" - ); - } - LetSource::IfLetGuard => { - emit_diag!( - lint, - "`if let` guard", - "guard is useless", - "removing the guard and adding a `let` inside the match arm" - ); - } - LetSource::LetElse => { - emit_diag!( - lint, - "`let...else`", - "`else` clause is useless", - "removing the `else` clause" - ); - } - LetSource::WhileLet => { - emit_diag!( - lint, - "`while let`", - "loop will never exit", - "instead using a `loop { ... }` with a `let` inside it" - ); - } - }; + LetSource::GenericLet => emit_diag!(IrrefutableLetPatternsGenericLet), + LetSource::IfLet => emit_diag!(IrrefutableLetPatternsIfLet), + LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard), + LetSource::LetElse(..) => emit_diag!(IrrefutableLetPatternsLetElse), + LetSource::WhileLet => emit_diag!(IrrefutableLetPatternsWhileLet), + } } fn is_let_irrefutable<'p, 'tcx>( From e2d938042dec09a4fe3421a05ad352d6fdb8821d Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Tue, 30 Aug 2022 20:01:28 +0300 Subject: [PATCH 18/30] Migrate borrow of moved value diagnostic --- .../locales/en-US/mir_build.ftl | 6 +++++ compiler/rustc_mir_build/src/errors.rs | 16 +++++++++++++ .../src/thir/pattern/check_match.rs | 24 ++++++------------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 7555bd608498d..118ca985b87ff 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -287,3 +287,9 @@ mir_build_irrefutable_let_patterns_while_let = irrefutable `while let` {$count - *[other] these patterns } will always match, so the loop will never exit .help = consider instead using a `loop {"{"} ... {"}"}` with a `let` inside it + +mir_build_borrow_of_moved_value = borrow of moved value + .label = value moved into `{$name}` here + .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait + .value_borrowed_label = value borrowed here after move + .suggest_borrowing = borrow this binding in the pattern to avoid moving the value diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index eecef26b94cb6..639c07f419401 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -562,3 +562,19 @@ pub struct IrrefutableLetPatternsLetElse { pub struct IrrefutableLetPatternsWhileLet { pub count: usize, } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::borrow_of_moved_value)] +pub struct BorrowOfMovedValue<'tcx> { + #[primary_span] + pub span: Span, + #[label] + #[label(mir_build::occurs_because_label)] + pub binding_span: Span, + #[label(mir_build::value_borrowed_label)] + pub conflicts_ref: Vec, + pub name: Ident, + pub ty: Ty<'tcx>, + #[suggestion(code = "ref ", applicability = "machine-applicable")] + pub suggest_borrowing: Option, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a488253b992b2..3b6b188bc6cfb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -962,24 +962,14 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa } }); if !conflicts_ref.is_empty() { - let occurs_because = format!( - "move occurs because `{}` has type `{}` which does not implement the `Copy` trait", + sess.emit_err(BorrowOfMovedValue { + span: pat.span, + binding_span, + conflicts_ref, name, - typeck_results.node_type(pat.hir_id), - ); - let mut err = sess.struct_span_err(pat.span, "borrow of moved value"); - err.span_label(binding_span, format!("value moved into `{}` here", name)) - .span_label(binding_span, occurs_because) - .span_labels(conflicts_ref, "value borrowed here after move"); - if pat.span.contains(binding_span) { - err.span_suggestion_verbose( - binding_span.shrink_to_lo(), - "borrow this binding in the pattern to avoid moving the value", - "ref ".to_string(), - Applicability::MachineApplicable, - ); - } - err.emit(); + ty: typeck_results.node_type(pat.hir_id), + suggest_borrowing: pat.span.contains(binding_span).then(|| binding_span.shrink_to_lo()), + }); } return; } From 03128ba60b31f99a65ebd141d6ab3b382ff8a28c Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Tue, 30 Aug 2022 20:38:10 +0300 Subject: [PATCH 19/30] Migrate multiple mut borrows diagnostic --- .../locales/en-US/mir_build.ftl | 6 ++++ compiler/rustc_mir_build/src/errors.rs | 34 +++++++++++++++++++ .../src/thir/pattern/check_match.rs | 14 ++++---- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 118ca985b87ff..94e061a2af6a8 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -293,3 +293,9 @@ mir_build_borrow_of_moved_value = borrow of moved value .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait .value_borrowed_label = value borrowed here after move .suggest_borrowing = borrow this binding in the pattern to avoid moving the value + +mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time + .label = first mutable borrow, by `{$name}`, occurs here + .mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here + .immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here + .moved = also moved into `{$name_moved}` here diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 639c07f419401..dd715fcfc6c58 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -578,3 +578,37 @@ pub struct BorrowOfMovedValue<'tcx> { #[suggestion(code = "ref ", applicability = "machine-applicable")] pub suggest_borrowing: Option, } + +#[derive(SessionDiagnostic)] +#[diag(mir_build::multiple_mut_borrows)] +pub struct MultipleMutBorrows { + #[primary_span] + pub span: Span, + #[label] + pub binding_span: Span, + #[subdiagnostic] + pub occurences: Vec, + pub name: Ident, +} + +#[derive(SessionSubdiagnostic)] +pub enum MultipleMutBorrowOccurence { + #[label(mir_build::mutable_borrow)] + Mutable { + #[primary_span] + span: Span, + name_mut: Ident, + }, + #[label(mir_build::immutable_borrow)] + Immutable { + #[primary_span] + span: Span, + name_immut: Ident, + }, + #[label(mir_build::moved)] + Moved { + #[primary_span] + span: Span, + name_moved: Ident, + }, +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 3b6b188bc6cfb..374942ee798b8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -999,19 +999,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa // Report errors if any. if !conflicts_mut_mut.is_empty() { // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. - let mut err = sess - .struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time"); - err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name)); + let mut occurences = vec![]; + for (span, name) in conflicts_mut_mut { - err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name)); + occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut: name }); } for (span, name) in conflicts_mut_ref { - err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name)); + occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut: name }); } for (span, name) in conflicts_move { - err.span_label(span, format!("also moved into `{}` here", name)); + occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved: name }); } - err.emit(); + + sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name }); } else if !conflicts_mut_ref.is_empty() { // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. let (primary, also) = match mut_outer { From 1d324dd126cd575e4887ac86e9c97e76908df123 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Sat, 26 Nov 2022 21:22:49 +0100 Subject: [PATCH 20/30] Resolve various merge conflicts --- .../locales/en-US/mir_build.ftl | 2 +- compiler/rustc_error_messages/src/lib.rs | 2 +- compiler/rustc_mir_build/src/errors.rs | 228 +++++++++--------- .../src/thir/pattern/check_match.rs | 25 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- 5 files changed, 129 insertions(+), 130 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 94e061a2af6a8..60d3d3e69abbe 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -292,7 +292,7 @@ mir_build_borrow_of_moved_value = borrow of moved value .label = value moved into `{$name}` here .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait .value_borrowed_label = value borrowed here after move - .suggest_borrowing = borrow this binding in the pattern to avoid moving the value + .suggestion = borrow this binding in the pattern to avoid moving the value mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time .label = first mutable borrow, by `{$name}`, occurs here diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index db62643bc24ac..25d0e736e599f 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -57,8 +57,8 @@ fluent_messages! { lint => "../locales/en-US/lint.ftl", metadata => "../locales/en-US/metadata.ftl", middle => "../locales/en-US/middle.ftl", - mir_dataflow => "../locales/en-US/mir_dataflow.ftl", mir_build => "../locales/en-US/mir_build.ftl", + mir_dataflow => "../locales/en-US/mir_dataflow.ftl", monomorphize => "../locales/en-US/monomorphize.ftl", parse => "../locales/en-US/parse.ftl", passes => "../locales/en-US/passes.ftl", diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index dd715fcfc6c58..f3bfafb37b77f 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,22 +1,24 @@ use crate::thir::pattern::MatchCheckCtxt; -use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; -use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; +use rustc_errors::Handler; +use rustc_errors::{ + error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan, +}; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; -use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::{symbol::Ident, Span}; #[derive(LintDiagnostic)] -#[diag(mir_build::unconditional_recursion)] +#[diag(mir_build_unconditional_recursion)] #[help] pub struct UnconditionalRecursion { #[label] pub span: Span, - #[label(mir_build::unconditional_recursion_call_site_label)] + #[label(mir_build_unconditional_recursion_call_site_label)] pub call_sites: Vec, } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> { #[label] @@ -25,7 +27,7 @@ pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)] #[note] pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { #[label] @@ -33,7 +35,7 @@ pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { #[label] @@ -41,7 +43,7 @@ pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { #[label] @@ -49,7 +51,7 @@ pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { #[label] @@ -57,7 +59,7 @@ pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { #[label] @@ -65,7 +67,7 @@ pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { #[label] @@ -73,7 +75,7 @@ pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_union_field_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { #[label] @@ -81,7 +83,7 @@ pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { #[label] @@ -89,14 +91,14 @@ pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)] pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { #[label] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)] #[note] pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> { #[label] @@ -104,8 +106,8 @@ pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> { pub function: &'a str, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::call_to_unsafe_fn_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = "E0133")] #[note] pub struct CallToUnsafeFunctionRequiresUnsafe<'a> { #[primary_span] @@ -114,8 +116,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafe<'a> { pub function: &'a str, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")] #[note] pub struct CallToUnsafeFunctionRequiresUnsafeNameless { #[primary_span] @@ -123,8 +125,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { #[primary_span] @@ -133,9 +135,9 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { pub function: &'a str, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag( - mir_build::call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed, + mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed, code = "E0133" )] #[note] @@ -145,8 +147,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::inline_assembly_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_inline_assembly_requires_unsafe, code = "E0133")] #[note] pub struct UseOfInlineAssemblyRequiresUnsafe { #[primary_span] @@ -154,8 +156,8 @@ pub struct UseOfInlineAssemblyRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] @@ -163,8 +165,8 @@ pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::initializing_type_with_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_initializing_type_with_requires_unsafe, code = "E0133")] #[note] pub struct InitializingTypeWithRequiresUnsafe { #[primary_span] @@ -172,9 +174,9 @@ pub struct InitializingTypeWithRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag( - mir_build::initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133" )] #[note] @@ -184,8 +186,8 @@ pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::mutable_static_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_mutable_static_requires_unsafe, code = "E0133")] #[note] pub struct UseOfMutableStaticRequiresUnsafe { #[primary_span] @@ -193,8 +195,8 @@ pub struct UseOfMutableStaticRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] @@ -202,8 +204,8 @@ pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::extern_static_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_extern_static_requires_unsafe, code = "E0133")] #[note] pub struct UseOfExternStaticRequiresUnsafe { #[primary_span] @@ -211,8 +213,8 @@ pub struct UseOfExternStaticRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] @@ -220,8 +222,8 @@ pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::deref_raw_pointer_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = "E0133")] #[note] pub struct DerefOfRawPointerRequiresUnsafe { #[primary_span] @@ -229,8 +231,8 @@ pub struct DerefOfRawPointerRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] @@ -238,8 +240,8 @@ pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::union_field_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_union_field_requires_unsafe, code = "E0133")] #[note] pub struct AccessToUnionFieldRequiresUnsafe { #[primary_span] @@ -247,8 +249,8 @@ pub struct AccessToUnionFieldRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] @@ -256,8 +258,8 @@ pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")] #[note] pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] @@ -265,9 +267,9 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag( - mir_build::mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133" )] #[note] @@ -277,8 +279,8 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllow pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")] #[note] pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] @@ -286,9 +288,9 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { pub span: Span, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag( - mir_build::borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133" )] #[note] @@ -298,8 +300,8 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::call_to_fn_with_requires_unsafe, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_call_to_fn_with_requires_unsafe, code = "E0133")] #[note] pub struct CallToFunctionWithRequiresUnsafe<'a> { #[primary_span] @@ -308,8 +310,8 @@ pub struct CallToFunctionWithRequiresUnsafe<'a> { pub function: &'a str, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] +#[derive(Diagnostic)] +#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")] #[note] pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { #[primary_span] @@ -319,7 +321,7 @@ pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { } #[derive(LintDiagnostic)] -#[diag(mir_build::unused_unsafe)] +#[diag(mir_build_unused_unsafe)] pub struct UnusedUnsafe { #[label] pub span: Span, @@ -327,14 +329,14 @@ pub struct UnusedUnsafe { pub enclosing: Option, } -#[derive(SessionSubdiagnostic)] +#[derive(Subdiagnostic)] pub enum UnusedUnsafeEnclosing { - #[label(mir_build::unused_unsafe_enclosing_block_label)] + #[label(mir_build_unused_unsafe_enclosing_block_label)] Block { #[primary_span] span: Span, }, - #[label(mir_build::unused_unsafe_enclosing_fn_label)] + #[label(mir_build_unused_unsafe_enclosing_fn_label)] Function { #[primary_span] span: Span, @@ -348,11 +350,11 @@ pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> { pub ty: Ty<'tcx>, } -impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.span_diagnostic.struct_span_err_with_code( +impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::mir_build::non_exhaustive_patterns_type_not_empty, + rustc_errors::fluent::mir_build_non_exhaustive_patterns_type_not_empty, error_code!(E0004), ); @@ -374,7 +376,7 @@ impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> let mut span: MultiSpan = def_span.into(); span.push_span_label(def_span, ""); - diag.span_note(span, rustc_errors::fluent::mir_build::def_note); + diag.span_note(span, rustc_errors::fluent::def_note); } let is_variant_list_non_exhaustive = match self.ty.kind() { @@ -385,14 +387,14 @@ impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> }; if is_variant_list_non_exhaustive { - diag.note(rustc_errors::fluent::mir_build::non_exhaustive_type_note); + diag.note(rustc_errors::fluent::non_exhaustive_type_note); } else { - diag.note(rustc_errors::fluent::mir_build::type_note); + diag.note(rustc_errors::fluent::type_note); } if let ty::Ref(_, sub_ty, _) = self.ty.kind() { - if self.cx.tcx.is_ty_uninhabited_from(self.cx.module, *sub_ty, self.cx.param_env) { - diag.note(rustc_errors::fluent::mir_build::reference_note); + if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) { + diag.note(rustc_errors::fluent::reference_note); } } @@ -418,88 +420,88 @@ impl<'a> SessionDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> if let Some((span, sugg)) = suggestion { diag.span_suggestion_verbose( span, - rustc_errors::fluent::mir_build::suggestion, + rustc_errors::fluent::suggestion, sugg, Applicability::HasPlaceholders, ); } else { - diag.help(rustc_errors::fluent::mir_build::help); + diag.help(rustc_errors::fluent::help); } diag } } -#[derive(SessionDiagnostic)] -#[diag(mir_build::static_in_pattern, code = "E0158")] +#[derive(Diagnostic)] +#[diag(mir_build_static_in_pattern, code = "E0158")] pub struct StaticInPattern { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::assoc_const_in_pattern, code = "E0158")] +#[derive(Diagnostic)] +#[diag(mir_build_assoc_const_in_pattern, code = "E0158")] pub struct AssocConstInPattern { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::const_param_in_pattern, code = "E0158")] +#[derive(Diagnostic)] +#[diag(mir_build_const_param_in_pattern, code = "E0158")] pub struct ConstParamInPattern { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::non_const_path, code = "E0080")] +#[derive(Diagnostic)] +#[diag(mir_build_non_const_path, code = "E0080")] pub struct NonConstPath { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(mir_build::unreachable_pattern)] +#[diag(mir_build_unreachable_pattern)] pub struct UnreachablePattern { #[label] pub span: Option, - #[label(mir_build::catchall_label)] + #[label(catchall_label)] pub catchall: Option, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::const_pattern_depends_on_generic_parameter)] +#[derive(Diagnostic)] +#[diag(mir_build_const_pattern_depends_on_generic_parameter)] pub struct ConstPatternDependsOnGenericParameter { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::could_not_eval_const_pattern)] +#[derive(Diagnostic)] +#[diag(mir_build_could_not_eval_const_pattern)] pub struct CouldNotEvalConstPattern { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")] +#[derive(Diagnostic)] +#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")] pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper { #[primary_span] #[label] pub span: Span, - #[note(mir_build::teach_note)] + #[note(teach_note)] pub teach: Option<()>, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::lower_range_bound_must_be_less_than_upper, code = "E0579")] +#[derive(Diagnostic)] +#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")] pub struct LowerRangeBoundMustBeLessThanUpper { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(mir_build::leading_irrefutable_let_patterns)] +#[diag(mir_build_leading_irrefutable_let_patterns)] #[note] #[help] pub struct LeadingIrrefutableLetPatterns { @@ -507,7 +509,7 @@ pub struct LeadingIrrefutableLetPatterns { } #[derive(LintDiagnostic)] -#[diag(mir_build::trailing_irrefutable_let_patterns)] +#[diag(mir_build_trailing_irrefutable_let_patterns)] #[note] #[help] pub struct TrailingIrrefutableLetPatterns { @@ -515,7 +517,7 @@ pub struct TrailingIrrefutableLetPatterns { } #[derive(LintDiagnostic)] -#[diag(mir_build::bindings_with_variant_name, code = "E0170")] +#[diag(mir_build_bindings_with_variant_name, code = "E0170")] pub struct BindingsWithVariantName { #[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")] pub suggestion: Option, @@ -524,7 +526,7 @@ pub struct BindingsWithVariantName { } #[derive(LintDiagnostic)] -#[diag(mir_build::irrefutable_let_patterns_generic_let)] +#[diag(mir_build_irrefutable_let_patterns_generic_let)] #[note] #[help] pub struct IrrefutableLetPatternsGenericLet { @@ -532,7 +534,7 @@ pub struct IrrefutableLetPatternsGenericLet { } #[derive(LintDiagnostic)] -#[diag(mir_build::irrefutable_let_patterns_if_let)] +#[diag(mir_build_irrefutable_let_patterns_if_let)] #[note] #[help] pub struct IrrefutableLetPatternsIfLet { @@ -540,7 +542,7 @@ pub struct IrrefutableLetPatternsIfLet { } #[derive(LintDiagnostic)] -#[diag(mir_build::irrefutable_let_patterns_if_let_guard)] +#[diag(mir_build_irrefutable_let_patterns_if_let_guard)] #[note] #[help] pub struct IrrefutableLetPatternsIfLetGuard { @@ -548,7 +550,7 @@ pub struct IrrefutableLetPatternsIfLetGuard { } #[derive(LintDiagnostic)] -#[diag(mir_build::irrefutable_let_patterns_let_else)] +#[diag(mir_build_irrefutable_let_patterns_let_else)] #[note] #[help] pub struct IrrefutableLetPatternsLetElse { @@ -556,22 +558,22 @@ pub struct IrrefutableLetPatternsLetElse { } #[derive(LintDiagnostic)] -#[diag(mir_build::irrefutable_let_patterns_while_let)] +#[diag(mir_build_irrefutable_let_patterns_while_let)] #[note] #[help] pub struct IrrefutableLetPatternsWhileLet { pub count: usize, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::borrow_of_moved_value)] +#[derive(Diagnostic)] +#[diag(mir_build_borrow_of_moved_value)] pub struct BorrowOfMovedValue<'tcx> { #[primary_span] pub span: Span, #[label] - #[label(mir_build::occurs_because_label)] + #[label(occurs_because_label)] pub binding_span: Span, - #[label(mir_build::value_borrowed_label)] + #[label(value_borrowed_label)] pub conflicts_ref: Vec, pub name: Ident, pub ty: Ty<'tcx>, @@ -579,33 +581,33 @@ pub struct BorrowOfMovedValue<'tcx> { pub suggest_borrowing: Option, } -#[derive(SessionDiagnostic)] -#[diag(mir_build::multiple_mut_borrows)] +#[derive(Diagnostic)] +#[diag(mir_build_multiple_mut_borrows)] pub struct MultipleMutBorrows { #[primary_span] pub span: Span, #[label] pub binding_span: Span, - #[subdiagnostic] + #[subdiagnostic(eager)] pub occurences: Vec, pub name: Ident, } -#[derive(SessionSubdiagnostic)] +#[derive(Subdiagnostic)] pub enum MultipleMutBorrowOccurence { - #[label(mir_build::mutable_borrow)] + #[label(mutable_borrow)] Mutable { #[primary_span] span: Span, name_mut: Ident, }, - #[label(mir_build::immutable_borrow)] + #[label(immutable_borrow)] Immutable { #[primary_span] span: Span, name_immut: Ident, }, - #[label(mir_build::moved)] + #[label(moved)] Moved { #[primary_span] span: Span, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 374942ee798b8..ddd52114ecfe6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -598,11 +598,6 @@ fn irrefutable_let_patterns( count: usize, span: Span, ) { - let span = match source { - LetSource::LetElse(span) => span, - _ => span, - }; - macro_rules! emit_diag { ($lint:tt) => {{ tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, id, span, $lint { count }); @@ -613,7 +608,7 @@ fn irrefutable_let_patterns( LetSource::GenericLet => emit_diag!(IrrefutableLetPatternsGenericLet), LetSource::IfLet => emit_diag!(IrrefutableLetPatternsIfLet), LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard), - LetSource::LetElse(..) => emit_diag!(IrrefutableLetPatternsLetElse), + LetSource::LetElse => emit_diag!(IrrefutableLetPatternsLetElse), LetSource::WhileLet => emit_diag!(IrrefutableLetPatternsWhileLet), } } @@ -968,7 +963,10 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa conflicts_ref, name, ty: typeck_results.node_type(pat.hir_id), - suggest_borrowing: pat.span.contains(binding_span).then(|| binding_span.shrink_to_lo()), + suggest_borrowing: pat + .span + .contains(binding_span) + .then(|| binding_span.shrink_to_lo()), }); } return; @@ -1001,16 +999,15 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. let mut occurences = vec![]; - for (span, name) in conflicts_mut_mut { - occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut: name }); + for (span, name_mut) in conflicts_mut_mut { + occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut }); } - for (span, name) in conflicts_mut_ref { - occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut: name }); + for (span, name_immut) in conflicts_mut_ref { + occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut }); } - for (span, name) in conflicts_move { - occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved: name }); + for (span, name_moved) in conflicts_move { + occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved }); } - sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name }); } else if !conflicts_mut_ref.is_empty() { // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 991b0292f9003..e2f798d921af3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -565,7 +565,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => bug!("Expected ConstKind::Param"), }, mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind, - mir::ConstKind::Unevaluated(_) => { + mir::ConstantKind::Unevaluated(..) => { // If we land here it means the const can't be evaluated because it's `TooGeneric`. self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); return PatKind::Wild; From 7d30472180855735929e42595aefb4344b4c8562 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Dec 2022 11:22:01 +1100 Subject: [PATCH 21/30] Remove `mk_name_value_item{,_str}`. There are better ways to create the meta items. - In the rustdoc tests, the commit adds `dummy_meta_item_name_value`, which matches the existing `dummy_meta_item_word` function and `dummy_meta_item_list` macro. - In `types.rs` the commit clones the existing meta item and then modifies the clone. --- compiler/rustc_ast/src/attr/mod.rs | 15 --------------- src/librustdoc/clean/cfg/tests.rs | 20 ++++++++++++++------ src/librustdoc/clean/types.rs | 14 ++++++-------- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 2ec126715e79e..c47b756c26ad1 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,6 +1,5 @@ //! Functions dealing with attributes and meta items. -use crate::ast; use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; @@ -321,20 +320,6 @@ impl Attribute { } } -/* Constructors */ - -pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem { - mk_name_value_item(ident, LitKind::Str(str, ast::StrStyle::Cooked), str_span) -} - -pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem { - let token_lit = kind.synthesize_token_lit(); - let lit = - MetaItemLit { symbol: token_lit.symbol, suffix: token_lit.suffix, kind, span: lit_span }; - let span = ident.span.to(lit_span); - MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span } -} - pub struct AttrIdGenerator(WorkerLocal>); #[cfg(debug_assertions)] diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 7f72d5d39a752..81f6767243683 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,9 +1,8 @@ use super::*; -use rustc_ast::attr; -use rustc_ast::Path; +use rustc_ast::{LitKind, MetaItemLit, Path, StrStyle}; use rustc_span::create_default_session_globals_then; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::DUMMY_SP; fn word_cfg(s: &str) -> Cfg { @@ -22,6 +21,15 @@ fn dummy_meta_item_word(name: &str) -> MetaItem { } } +fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem { + let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }; + MetaItem { + path: Path::from_ident(Ident::from_str(name)), + kind: MetaItemKind::NameValue(lit), + span: DUMMY_SP, + } +} + macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { @@ -242,8 +250,8 @@ fn test_parse_ok() { let mi = dummy_meta_item_word("all"); assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); - let mi = - attr::mk_name_value_item_str(Ident::from_str("all"), Symbol::intern("done"), DUMMY_SP); + let done = Symbol::intern("done"); + let mi = dummy_meta_item_name_value("all", done, LitKind::Str(done, StrStyle::Cooked)); assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); let mi = dummy_meta_item_list!(all, [a, b]); @@ -272,7 +280,7 @@ fn test_parse_ok() { #[test] fn test_parse_err() { create_default_session_globals_then(|| { - let mi = attr::mk_name_value_item(Ident::from_str("foo"), LitKind::Bool(false), DUMMY_SP); + let mi = dummy_meta_item_name_value("foo", kw::False, LitKind::Bool(false)); assert!(Cfg::parse(&mi).is_err()); let mi = dummy_meta_item_list!(not, [a, b]); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ed4e9508f4309..8c3b289d34628 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -10,7 +10,6 @@ use std::{cmp, fmt, iter}; use arrayvec::ArrayVec; use thin_vec::ThinVec; -use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; use rustc_ast::{self as ast, AttrStyle}; use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel}; @@ -27,7 +26,6 @@ use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, DefIdTree, TyCtxt, Visibility}; use rustc_session::Session; use rustc_span::hygiene::MacroKind; -use rustc_span::source_map::DUMMY_SP; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, FileName, Loc}; use rustc_target::abi::VariantIdx; @@ -979,12 +977,12 @@ impl AttributesExt for [ast::Attribute] { // #[doc(cfg(target_feature = "feat"))] attributes as well for attr in self.lists(sym::target_feature) { if attr.has_name(sym::enable) { - if let Some(feat) = attr.value_str() { - let meta = attr::mk_name_value_item_str( - Ident::with_dummy_span(sym::target_feature), - feat, - DUMMY_SP, - ); + if attr.value_str().is_some() { + // Clone `enable = "feat"`, change to `target_feature = "feat"`. + // Unwrap is safe because `value_str` succeeded above. + let mut meta = attr.meta_item().unwrap().clone(); + meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature)); + if let Ok(feat_cfg) = Cfg::parse(&meta) { cfg &= feat_cfg; } From 4ae956f600e72d62a6b17d95705148442841cef0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Dec 2022 14:16:41 +1100 Subject: [PATCH 22/30] Remove `ExtCtxt::expr_lit`. --- compiler/rustc_ast/src/util/literal.rs | 34 +++++++++++++------- compiler/rustc_expand/src/build.rs | 43 +++++++++++++------------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index a0a925d4700bd..4cc4b6367b48b 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -8,6 +8,26 @@ use rustc_span::Span; use std::ascii; use std::str; +// Escapes a string, represented as a symbol. Reuses the original symbol, +// avoiding interning, if no changes are required. +pub fn escape_string_symbol(symbol: Symbol) -> Symbol { + let s = symbol.as_str(); + let escaped = s.escape_default().to_string(); + if s == escaped { symbol } else { Symbol::intern(&escaped) } +} + +// Escapes a char. +pub fn escape_char_symbol(ch: char) -> Symbol { + let s: String = ch.escape_default().map(Into::::into).collect(); + Symbol::intern(&s) +} + +// Escapes a byte string. +pub fn escape_byte_str_symbol(bytes: &[u8]) -> Symbol { + let s = bytes.escape_ascii().to_string(); + Symbol::intern(&s) +} + #[derive(Debug)] pub enum LitError { LexerError, @@ -149,16 +169,11 @@ impl LitKind { pub fn synthesize_token_lit(&self) -> token::Lit { let (kind, symbol, suffix) = match *self { LitKind::Str(symbol, ast::StrStyle::Cooked) => { - // Don't re-intern unless the escaped string is different. - let s = symbol.as_str(); - let escaped = s.escape_default().to_string(); - let symbol = if s == escaped { symbol } else { Symbol::intern(&escaped) }; - (token::Str, symbol, None) + (token::Str, escape_string_symbol(symbol), None) } LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None), LitKind::ByteStr(ref bytes, ast::StrStyle::Cooked) => { - let string = bytes.escape_ascii().to_string(); - (token::ByteStr, Symbol::intern(&string), None) + (token::ByteStr, escape_byte_str_symbol(bytes), None) } LitKind::ByteStr(ref bytes, ast::StrStyle::Raw(n)) => { // Unwrap because raw byte string literals can only contain ASCII. @@ -169,10 +184,7 @@ impl LitKind { let string: String = ascii::escape_default(byte).map(Into::::into).collect(); (token::Byte, Symbol::intern(&string), None) } - LitKind::Char(ch) => { - let string: String = ch.escape_default().map(Into::::into).collect(); - (token::Char, Symbol::intern(&string), None) - } + LitKind::Char(ch) => (token::Char, escape_char_symbol(ch), None), LitKind::Int(n, ty) => { let suffix = match ty { ast::LitIntType::Unsigned(ty) => Some(ty.name()), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index d8245ff613a9d..2fec24a1aece8 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -1,8 +1,7 @@ use crate::base::ExtCtxt; -use rustc_ast::attr; use rustc_ast::ptr::P; use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp}; -use rustc_data_structures::sync::Lrc; +use rustc_ast::{attr, token, util::literal}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; @@ -332,36 +331,36 @@ impl<'a> ExtCtxt<'a> { self.expr_struct(span, self.path_ident(span, id), fields) } - fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { - let token_lit = lit_kind.synthesize_token_lit(); - self.expr(span, ast::ExprKind::Lit(token_lit)) + pub fn expr_usize(&self, span: Span, n: usize) -> P { + let suffix = Some(ast::UintTy::Usize.name()); + let lit = token::Lit::new(token::Integer, sym::integer(n), suffix); + self.expr(span, ast::ExprKind::Lit(lit)) } - pub fn expr_usize(&self, span: Span, i: usize) -> P { - self.expr_lit( - span, - ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)), - ) - } - - pub fn expr_u32(&self, sp: Span, u: u32) -> P { - self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32))) + pub fn expr_u32(&self, span: Span, n: u32) -> P { + let suffix = Some(ast::UintTy::U32.name()); + let lit = token::Lit::new(token::Integer, sym::integer(n), suffix); + self.expr(span, ast::ExprKind::Lit(lit)) } - pub fn expr_bool(&self, sp: Span, value: bool) -> P { - self.expr_lit(sp, ast::LitKind::Bool(value)) + pub fn expr_bool(&self, span: Span, value: bool) -> P { + let lit = token::Lit::new(token::Bool, if value { kw::True } else { kw::False }, None); + self.expr(span, ast::ExprKind::Lit(lit)) } - pub fn expr_str(&self, sp: Span, s: Symbol) -> P { - self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked)) + pub fn expr_str(&self, span: Span, s: Symbol) -> P { + let lit = token::Lit::new(token::Str, literal::escape_string_symbol(s), None); + self.expr(span, ast::ExprKind::Lit(lit)) } - pub fn expr_char(&self, sp: Span, ch: char) -> P { - self.expr_lit(sp, ast::LitKind::Char(ch)) + pub fn expr_char(&self, span: Span, ch: char) -> P { + let lit = token::Lit::new(token::Char, literal::escape_char_symbol(ch), None); + self.expr(span, ast::ExprKind::Lit(lit)) } - pub fn expr_byte_str(&self, sp: Span, bytes: Vec) -> P { - self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes), ast::StrStyle::Cooked)) + pub fn expr_byte_str(&self, span: Span, bytes: Vec) -> P { + let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None); + self.expr(span, ast::ExprKind::Lit(lit)) } /// `[expr1, expr2, ...]` From d887615b4c83d856cd3e40000968c047f2ff4019 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Dec 2022 14:39:56 +1100 Subject: [PATCH 23/30] Parameterise `Parser::{recover_unclosed_char,handle_missing_lit}`. These two methods both produce a `MetaItemLit`, and then some of the call sites convert the `MetaItemLit` to a `token::Lit` with `as_token_lit`. This commit parameterises these two methods with a `mk_lit_char` closure, which can be used to produce either `MetaItemLit` or `token::Lit` directly as necessary. --- compiler/rustc_parse/src/parser/expr.rs | 57 ++++++++++++++++--------- compiler/rustc_parse/src/parser/pat.rs | 22 ++++++---- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1c773bea000b2..07f03e0d582cb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1543,15 +1543,16 @@ impl<'a> Parser<'a> { && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma) || self.token.is_op()) { - let lit = self.recover_unclosed_char(label_.ident, |self_| { - self_.sess.create_err(UnexpectedTokenAfterLabel { - span: self_.token.span, - remove_label: None, - enclose_in_block: None, - }) - }); + let (lit, _) = + self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| { + self_.sess.create_err(UnexpectedTokenAfterLabel { + span: self_.token.span, + remove_label: None, + enclose_in_block: None, + }) + }); consume_colon = false; - Ok(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit()))) + Ok(self.mk_expr(lo, ExprKind::Lit(lit))) } else if !ate_colon && (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt)) { @@ -1626,12 +1627,13 @@ impl<'a> Parser<'a> { Ok(expr) } - /// Emit an error when a char is parsed as a lifetime because of a missing quote - pub(super) fn recover_unclosed_char( + /// Emit an error when a char is parsed as a lifetime because of a missing quote. + pub(super) fn recover_unclosed_char( &self, lifetime: Ident, + mk_lit_char: impl FnOnce(Symbol, Span) -> L, err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>, - ) -> ast::MetaItemLit { + ) -> L { if let Some(mut diag) = self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) { @@ -1653,12 +1655,7 @@ impl<'a> Parser<'a> { .emit(); } let name = lifetime.without_first_quote().name; - ast::MetaItemLit { - symbol: name, - suffix: None, - kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')), - span: lifetime.span, - } + mk_lit_char(name, lifetime.span) } /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead. @@ -1785,7 +1782,23 @@ impl<'a> Parser<'a> { } } - fn handle_missing_lit(&mut self) -> PResult<'a, MetaItemLit> { + pub(crate) fn mk_token_lit_char(name: Symbol, span: Span) -> (token::Lit, Span) { + (token::Lit { symbol: name, suffix: None, kind: token::Char }, span) + } + + fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit { + ast::MetaItemLit { + symbol: name, + suffix: None, + kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')), + span, + } + } + + fn handle_missing_lit( + &mut self, + mk_lit_char: impl FnOnce(Symbol, Span) -> L, + ) -> PResult<'a, L> { if let token::Interpolated(inner) = &self.token.kind { let expr = match inner.as_ref() { token::NtExpr(expr) => Some(expr), @@ -1809,7 +1822,7 @@ impl<'a> Parser<'a> { // On an error path, eagerly consider a lifetime to be an unclosed character lit if self.token.is_lifetime() { let lt = self.expect_lifetime(); - Ok(self.recover_unclosed_char(lt.ident, err)) + Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err)) } else { Err(err(self)) } @@ -1818,11 +1831,13 @@ impl<'a> Parser<'a> { pub(super) fn parse_token_lit(&mut self) -> PResult<'a, (token::Lit, Span)> { self.parse_opt_token_lit() .ok_or(()) - .or_else(|()| self.handle_missing_lit().map(|lit| (lit.as_token_lit(), lit.span))) + .or_else(|()| self.handle_missing_lit(Parser::mk_token_lit_char)) } pub(super) fn parse_meta_item_lit(&mut self) -> PResult<'a, MetaItemLit> { - self.parse_opt_meta_item_lit().ok_or(()).or_else(|()| self.handle_missing_lit()) + self.parse_opt_meta_item_lit() + .ok_or(()) + .or_else(|()| self.handle_missing_lit(Parser::mk_meta_item_lit_char)) } fn recover_after_dot(&mut self) -> Option { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index b5147158f708e..a1981e1147775 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -411,16 +411,20 @@ impl<'a> Parser<'a> { { // Recover a `'a` as a `'a'` literal let lt = self.expect_lifetime(); - let lit = self.recover_unclosed_char(lt.ident, |self_| { - let expected = expected.unwrap_or("pattern"); - let msg = - format!("expected {}, found {}", expected, super::token_descr(&self_.token)); + let (lit, _) = + self.recover_unclosed_char(lt.ident, Parser::mk_token_lit_char, |self_| { + let expected = expected.unwrap_or("pattern"); + let msg = format!( + "expected {}, found {}", + expected, + super::token_descr(&self_.token) + ); - let mut err = self_.struct_span_err(self_.token.span, &msg); - err.span_label(self_.token.span, format!("expected {}", expected)); - err - }); - PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit()))) + let mut err = self_.struct_span_err(self_.token.span, &msg); + err.span_label(self_.token.span, format!("expected {}", expected)); + err + }); + PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit))) } else { // Try to parse everything else as literal with optional minus match self.parse_literal_maybe_minus() { From 568e647047e2a3b817a3f39d2ecb25989a4981ce Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Dec 2022 15:23:27 +1100 Subject: [PATCH 24/30] Remove three uses of `LitKind::synthesize_token_lit`. --- compiler/rustc_ast/src/attr/mod.rs | 5 +++-- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 5 +++-- compiler/rustc_expand/src/proc_macro_server.rs | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index c47b756c26ad1..d99f6ed2c1cd3 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -3,12 +3,13 @@ use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; -use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID}; +use crate::ast::{Path, PathSegment, DUMMY_NODE_ID}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; +use crate::util::literal::escape_string_symbol; use rustc_data_structures::sync::WorkerLocal; use rustc_index::bit_set::GrowableBitSet; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -395,7 +396,7 @@ pub fn mk_attr_name_value_str( val: Symbol, span: Span, ) -> Attribute { - let lit = LitKind::Str(val, StrStyle::Cooked).synthesize_token_lit(); + let lit = token::Lit::new(token::Str, escape_string_symbol(val), None); let expr = P(Expr { id: DUMMY_NODE_ID, kind: ExprKind::Lit(lit), diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 7306b10d60ffb..a00837ec84303 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -2,6 +2,8 @@ use crate::pp::Breaks::Inconsistent; use crate::pprust::state::{AnnNode, IterDelimited, PrintState, State, INDENT_UNIT}; use rustc_ast::ptr::P; +use rustc_ast::token; +use rustc_ast::util::literal::escape_byte_str_symbol; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast::{self as ast, BlockCheckMode}; @@ -323,8 +325,7 @@ impl<'a> State<'a> { self.print_token_literal(*token_lit, expr.span); } ast::ExprKind::IncludedBytes(bytes) => { - let lit = ast::LitKind::ByteStr(bytes.clone(), ast::StrStyle::Cooked) - .synthesize_token_lit(); + let lit = token::Lit::new(token::ByteStr, escape_byte_str_symbol(bytes), None); self.print_token_literal(lit, expr.span) } ast::ExprKind::Cast(expr, ty) => { diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 255e5105ff4a9..768bdab8a5419 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -6,6 +6,7 @@ use pm::{Delimiter, Level, LineColumn}; use rustc_ast as ast; use rustc_ast::token; use rustc_ast::tokenstream::{self, Spacing::*, TokenStream}; +use rustc_ast::util::literal::escape_byte_str_symbol; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; @@ -526,8 +527,7 @@ impl server::TokenStream for Rustc<'_, '_> { Ok(tokenstream::TokenStream::token_alone(token::Literal(*token_lit), expr.span)) } ast::ExprKind::IncludedBytes(bytes) => { - let lit = ast::LitKind::ByteStr(bytes.clone(), ast::StrStyle::Cooked) - .synthesize_token_lit(); + let lit = token::Lit::new(token::ByteStr, escape_byte_str_symbol(bytes), None); Ok(tokenstream::TokenStream::token_alone(token::TokenKind::Literal(lit), expr.span)) } ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind { From 7e0c6dba0d83dbee96bbf7eac7b4cb563e297a5f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Dec 2022 16:09:45 +1100 Subject: [PATCH 25/30] Remove `LitKind::synthesize_token_lit`. It has a single call site in the HIR pretty printer, where the resulting token lit is immediately converted to a string. This commit replaces `LitKind::synthesize_token_lit` with a `Display` impl for `LitKind`, which can be used by the HIR pretty printer. --- compiler/rustc_ast/src/util/literal.rs | 83 ++++++++++++++------------ compiler/rustc_hir_pretty/src/lib.rs | 2 +- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 4cc4b6367b48b..762fd00e409fb 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -5,8 +5,7 @@ use crate::token::{self, Token}; use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use std::ascii; -use std::str; +use std::{ascii, fmt, str}; // Escapes a string, represented as a symbol. Reuses the original symbol, // avoiding interning, if no changes are required. @@ -162,54 +161,60 @@ impl LitKind { token::Err => LitKind::Err, }) } +} - /// Synthesizes a token from a semantic literal. - /// This function is used when the original token doesn't exist (e.g. the literal is created - /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn synthesize_token_lit(&self) -> token::Lit { - let (kind, symbol, suffix) = match *self { - LitKind::Str(symbol, ast::StrStyle::Cooked) => { - (token::Str, escape_string_symbol(symbol), None) +impl fmt::Display for LitKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + LitKind::Byte(b) => { + let b: String = ascii::escape_default(b).map(Into::::into).collect(); + write!(f, "b'{}'", b)?; } - LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None), - LitKind::ByteStr(ref bytes, ast::StrStyle::Cooked) => { - (token::ByteStr, escape_byte_str_symbol(bytes), None) + LitKind::Char(ch) => write!(f, "'{}'", escape_char_symbol(ch))?, + LitKind::Str(sym, StrStyle::Cooked) => write!(f, "\"{}\"", escape_string_symbol(sym))?, + LitKind::Str(sym, StrStyle::Raw(n)) => write!( + f, + "r{delim}\"{string}\"{delim}", + delim = "#".repeat(n as usize), + string = sym + )?, + LitKind::ByteStr(ref bytes, StrStyle::Cooked) => { + write!(f, "b\"{}\"", escape_byte_str_symbol(bytes))? } - LitKind::ByteStr(ref bytes, ast::StrStyle::Raw(n)) => { + LitKind::ByteStr(ref bytes, StrStyle::Raw(n)) => { // Unwrap because raw byte string literals can only contain ASCII. - let string = str::from_utf8(bytes).unwrap(); - (token::ByteStrRaw(n), Symbol::intern(&string), None) - } - LitKind::Byte(byte) => { - let string: String = ascii::escape_default(byte).map(Into::::into).collect(); - (token::Byte, Symbol::intern(&string), None) + let symbol = str::from_utf8(bytes).unwrap(); + write!( + f, + "br{delim}\"{string}\"{delim}", + delim = "#".repeat(n as usize), + string = symbol + )?; } - LitKind::Char(ch) => (token::Char, escape_char_symbol(ch), None), LitKind::Int(n, ty) => { - let suffix = match ty { - ast::LitIntType::Unsigned(ty) => Some(ty.name()), - ast::LitIntType::Signed(ty) => Some(ty.name()), - ast::LitIntType::Unsuffixed => None, - }; - (token::Integer, sym::integer(n), suffix) + write!(f, "{}", n)?; + match ty { + ast::LitIntType::Unsigned(ty) => write!(f, "{}", ty.name())?, + ast::LitIntType::Signed(ty) => write!(f, "{}", ty.name())?, + ast::LitIntType::Unsuffixed => {} + } } LitKind::Float(symbol, ty) => { - let suffix = match ty { - ast::LitFloatType::Suffixed(ty) => Some(ty.name()), - ast::LitFloatType::Unsuffixed => None, - }; - (token::Float, symbol, suffix) + write!(f, "{}", symbol)?; + match ty { + ast::LitFloatType::Suffixed(ty) => write!(f, "{}", ty.name())?, + ast::LitFloatType::Unsuffixed => {} + } } - LitKind::Bool(value) => { - let symbol = if value { kw::True } else { kw::False }; - (token::Bool, symbol, None) + LitKind::Bool(b) => write!(f, "{}", if b { "true" } else { "false" })?, + LitKind::Err => { + // This only shows up in places like `-Zunpretty=hir` output, so we + // don't bother to produce something useful. + write!(f, "")?; } - // This only shows up in places like `-Zunpretty=hir` output, so we - // don't bother to produce something useful. - LitKind::Err => (token::Err, Symbol::intern(""), None), - }; + } - token::Lit::new(kind, symbol, suffix) + Ok(()) } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 10b2265c522a0..81d933b8e7f0f 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1256,7 +1256,7 @@ impl<'a> State<'a> { fn print_literal(&mut self, lit: &hir::Lit) { self.maybe_print_comment(lit.span.lo()); - self.word(lit.node.synthesize_token_lit().to_string()) + self.word(lit.node.to_string()) } fn print_inline_asm(&mut self, asm: &hir::InlineAsm<'_>) { From 952bf87da1f817c767d61d01a365796b07c71fc4 Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Sat, 10 Dec 2022 16:04:00 +0100 Subject: [PATCH 26/30] doc: document remap matching behaviour in rustc flags --- src/doc/rustc/src/command-line-arguments.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index ef6eee75f1ce6..d4d26654ed114 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -434,6 +434,9 @@ replacement is purely textual, with no consideration of the current system's pathname syntax. For example `--remap-path-prefix foo=bar` will match `foo/lib.rs` but not `./foo/lib.rs`. +When multiple remappings are given and several of them match, the **last** +matching one is applied. + ## `--json`: configure json messages printed by the compiler From 9bc69925cb4a1391a9a41411c56ae059877bf8fb Mon Sep 17 00:00:00 2001 From: KaDiWa Date: Tue, 9 Aug 2022 02:14:43 +0200 Subject: [PATCH 27/30] compiler: remove unnecessary imports and qualified paths --- compiler/rustc_abi/src/lib.rs | 1 - compiler/rustc_apfloat/src/ieee.rs | 1 - compiler/rustc_arena/src/lib.rs | 2 +- compiler/rustc_ast/src/ast.rs | 1 - compiler/rustc_ast/src/ptr.rs | 1 - compiler/rustc_ast/src/tokenstream.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 4 ++-- compiler/rustc_builtin_macros/src/concat.rs | 2 -- compiler/rustc_codegen_ssa/src/base.rs | 1 - compiler/rustc_const_eval/src/const_eval/eval_queries.rs | 1 - compiler/rustc_const_eval/src/interpret/cast.rs | 1 - compiler/rustc_const_eval/src/interpret/intrinsics.rs | 2 -- .../src/interpret/intrinsics/caller_location.rs | 2 -- compiler/rustc_const_eval/src/interpret/operator.rs | 2 -- compiler/rustc_const_eval/src/interpret/util.rs | 1 - compiler/rustc_const_eval/src/interpret/validity.rs | 1 - compiler/rustc_const_eval/src/util/aggregate.rs | 1 - compiler/rustc_data_structures/src/fingerprint.rs | 1 - compiler/rustc_data_structures/src/graph/scc/mod.rs | 1 - compiler/rustc_data_structures/src/graph/vec_graph/mod.rs | 2 -- compiler/rustc_data_structures/src/owning_ref/mod.rs | 5 +---- compiler/rustc_data_structures/src/owning_ref/tests.rs | 4 ++-- compiler/rustc_data_structures/src/profiling.rs | 1 - compiler/rustc_data_structures/src/sorted_map.rs | 1 - compiler/rustc_data_structures/src/sorted_map/index_map.rs | 1 - compiler/rustc_data_structures/src/sso/either_iter.rs | 2 -- compiler/rustc_data_structures/src/sso/map.rs | 1 - compiler/rustc_data_structures/src/sso/set.rs | 1 - compiler/rustc_data_structures/src/sync.rs | 2 +- compiler/rustc_data_structures/src/tagged_ptr/drop.rs | 2 +- compiler/rustc_data_structures/src/vec_map.rs | 1 - compiler/rustc_driver/src/lib.rs | 1 - compiler/rustc_error_codes/src/error_codes/E0492.md | 1 - compiler/rustc_errors/src/diagnostic_impls.rs | 2 +- compiler/rustc_expand/src/base.rs | 1 - compiler/rustc_hir/src/pat_util.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 1 - compiler/rustc_incremental/src/persist/dirty_clean.rs | 2 -- compiler/rustc_incremental/src/persist/fs.rs | 7 +++---- compiler/rustc_index/src/vec.rs | 1 - compiler/rustc_interface/src/tests.rs | 1 - compiler/rustc_lexer/src/lib.rs | 1 - compiler/rustc_lint/src/types.rs | 3 +-- compiler/rustc_metadata/src/rmeta/table.rs | 1 - compiler/rustc_middle/src/mir/coverage.rs | 1 - compiler/rustc_middle/src/mir/interpret/mod.rs | 1 - compiler/rustc_middle/src/mir/interpret/pointer.rs | 1 - compiler/rustc_middle/src/mir/interpret/value.rs | 1 - compiler/rustc_middle/src/mir/mod.rs | 1 - compiler/rustc_middle/src/traits/query.rs | 1 - compiler/rustc_middle/src/ty/consts/int.rs | 1 - compiler/rustc_middle/src/ty/consts/kind.rs | 2 -- compiler/rustc_middle/src/ty/print/pretty.rs | 1 - compiler/rustc_middle/src/ty/vtable.rs | 1 - compiler/rustc_mir_build/src/build/matches/mod.rs | 1 - compiler/rustc_mir_build/src/build/matches/util.rs | 1 - .../rustc_mir_build/src/thir/pattern/deconstruct_pat.rs | 2 +- compiler/rustc_mir_dataflow/src/framework/lattice.rs | 2 +- compiler/rustc_mir_transform/src/simplify.rs | 1 - compiler/rustc_monomorphize/src/polymorphize.rs | 1 - compiler/rustc_parse/src/parser/attr.rs | 1 - compiler/rustc_parse/src/parser/attr_wrapper.rs | 1 - compiler/rustc_parse/src/parser/item.rs | 1 - compiler/rustc_query_system/src/dep_graph/graph.rs | 2 +- compiler/rustc_query_system/src/dep_graph/serialized.rs | 1 - compiler/rustc_query_system/src/query/caches.rs | 1 - compiler/rustc_query_system/src/query/job.rs | 6 +++--- compiler/rustc_save_analysis/src/lib.rs | 1 - compiler/rustc_serialize/src/opaque.rs | 1 - compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_session/src/filesearch.rs | 1 - compiler/rustc_span/src/source_map.rs | 3 +-- compiler/rustc_span/src/symbol.rs | 2 -- compiler/rustc_target/src/lib.rs | 1 - compiler/rustc_target/src/spec/mod.rs | 2 -- compiler/rustc_type_ir/src/sty.rs | 2 +- 76 files changed, 24 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index e14c9ea9a5d1a..4ca59144b2990 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,6 +1,5 @@ #![cfg_attr(feature = "nightly", feature(step_trait, rustc_attrs, min_specialization))] -use std::convert::{TryFrom, TryInto}; use std::fmt; #[cfg(feature = "nightly")] use std::iter::Step; diff --git a/compiler/rustc_apfloat/src/ieee.rs b/compiler/rustc_apfloat/src/ieee.rs index 3db8adb2a2444..2286712f02565 100644 --- a/compiler/rustc_apfloat/src/ieee.rs +++ b/compiler/rustc_apfloat/src/ieee.rs @@ -2,7 +2,6 @@ use crate::{Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO}; use crate::{Float, FloatConvert, ParseError, Round, Status, StatusAnd}; use core::cmp::{self, Ordering}; -use core::convert::TryFrom; use core::fmt::{self, Write}; use core::marker::PhantomData; use core::mem; diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 46dbbd83d1905..4fae5ef845f7d 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -28,7 +28,7 @@ use smallvec::SmallVec; use std::alloc::Layout; use std::cell::{Cell, RefCell}; use std::cmp; -use std::marker::{PhantomData, Send}; +use std::marker::PhantomData; use std::mem::{self, MaybeUninit}; use std::ptr::{self, NonNull}; use std::slice; diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4d80f904ac461..74a0c13b23f74 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -33,7 +33,6 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; -use std::convert::TryFrom; use std::fmt; use std::mem; use thin_vec::{thin_vec, ThinVec}; diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 30481eddf9160..4b2850336a03d 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -22,7 +22,6 @@ //! Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated. use std::fmt::{self, Debug, Display}; -use std::iter::FromIterator; use std::ops::{Deref, DerefMut}; use std::{slice, vec}; diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 482c302950f01..29a5eb4b7c509 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -362,7 +362,7 @@ impl TokenStream { } } -impl iter::FromIterator for TokenStream { +impl FromIterator for TokenStream { fn from_iter>(iter: I) -> Self { TokenStream::new(iter.into_iter().collect::>()) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4fa18907fcd46..5d7397977e984 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -456,8 +456,8 @@ pub fn lower_to_hir<'hir>(tcx: TyCtxt<'hir>, (): ()) -> hir::Crate<'hir> { } // Drop AST to free memory - std::mem::drop(ast_index); - sess.time("drop_ast", || std::mem::drop(krate)); + drop(ast_index); + sess.time("drop_ast", || drop(krate)); // Discard hygiene data, which isn't required after lowering to HIR. if !sess.opts.unstable_opts.keep_hygiene_data { diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index e2d71825d556f..c9dc6b847cdb5 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -4,8 +4,6 @@ use rustc_expand::base::{self, DummyResult}; use rustc_session::errors::report_lit_error; use rustc_span::symbol::Symbol; -use std::string::String; - pub fn expand_concat( cx: &mut base::ExtCtxt<'_>, sp: rustc_span::Span, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 4f396e970ad70..664697e0edaa4 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -41,7 +41,6 @@ use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType}; use rustc_target::abi::{Align, Size, VariantIdx}; use std::collections::BTreeSet; -use std::convert::TryFrom; use std::time::{Duration, Instant}; use itertools::Itertools; diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index c27790d8887a3..319f2b2c25ebf 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::convert::TryInto; use either::{Left, Right}; diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 269ae15d49745..b1fdeb01b100a 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,5 +1,4 @@ use std::assert_matches::assert_matches; -use std::convert::TryFrom; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::{Float, FloatConvert}; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 7940efcd2b11f..b9be7fa48000b 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -2,8 +2,6 @@ //! looking at their MIR. Intrinsics/functions supported here are shared by CTFE //! and miri. -use std::convert::TryFrom; - use rustc_hir::def_id::DefId; use rustc_middle::mir::{ self, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 7d94a22c43d71..77c7b4bacb8c8 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -1,5 +1,3 @@ -use std::convert::TryFrom; - use rustc_ast::Mutability; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::TerminatorKind; diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 1f1d0665139d0..949f95c5fa81c 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -1,5 +1,3 @@ -use std::convert::TryFrom; - use rustc_apfloat::Float; use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 2bc521d5bbe0b..e4f716c31945c 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,6 +1,5 @@ use rustc_middle::mir::interpret::InterpResult; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use std::convert::TryInto; use std::ops::ControlFlow; /// Checks whether a type contains generic parameters which require substitution. diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 0e85c7d11bce5..fc65306e440a9 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -4,7 +4,6 @@ //! That's useful because it means other passes (e.g. promotion) can rely on `const`s //! to be const-safe. -use std::convert::TryFrom; use std::fmt::{Display, Write}; use std::num::NonZeroUsize; diff --git a/compiler/rustc_const_eval/src/util/aggregate.rs b/compiler/rustc_const_eval/src/util/aggregate.rs index c43de3368c62f..10783c5ed1d1c 100644 --- a/compiler/rustc_const_eval/src/util/aggregate.rs +++ b/compiler/rustc_const_eval/src/util/aggregate.rs @@ -3,7 +3,6 @@ use rustc_middle::mir::*; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_target::abi::VariantIdx; -use std::convert::TryFrom; use std::iter::TrustedLen; /// Expand `lhs = Rvalue::Aggregate(kind, operands)` into assignments to the fields. diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index d98f4e43fe884..b6e866f15efe3 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,6 +1,5 @@ use crate::stable_hasher; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::convert::TryInto; use std::hash::{Hash, Hasher}; #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 7099ca7eb88c2..b31092eca9837 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -9,7 +9,6 @@ use crate::fx::FxHashSet; use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; use rustc_index::vec::{Idx, IndexVec}; -use std::cmp::Ord; use std::ops::Range; #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs index e8efbd09a2c38..94232bb7626ec 100644 --- a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs @@ -1,5 +1,3 @@ -use std::cmp::Ord; - use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; use rustc_index::vec::{Idx, IndexVec}; diff --git a/compiler/rustc_data_structures/src/owning_ref/mod.rs b/compiler/rustc_data_structures/src/owning_ref/mod.rs index 980a540ccba7a..d1d92b905b82e 100644 --- a/compiler/rustc_data_structures/src/owning_ref/mod.rs +++ b/compiler/rustc_data_structures/src/owning_ref/mod.rs @@ -867,11 +867,9 @@ where ///////////////////////////////////////////////////////////////////////////// use std::borrow::Borrow; -use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; -use std::convert::From; +use std::cmp::Ordering; use std::fmt::{self, Debug}; use std::hash::{Hash, Hasher}; -use std::marker::{Send, Sync}; impl Deref for OwningRef { type Target = T; @@ -1096,7 +1094,6 @@ where // std types integration and convenience type defs ///////////////////////////////////////////////////////////////////////////// -use std::boxed::Box; use std::cell::{Ref, RefCell, RefMut}; use std::rc::Rc; use std::sync::Arc; diff --git a/compiler/rustc_data_structures/src/owning_ref/tests.rs b/compiler/rustc_data_structures/src/owning_ref/tests.rs index 320c03d5139f4..a9b187c4ce0a7 100644 --- a/compiler/rustc_data_structures/src/owning_ref/tests.rs +++ b/compiler/rustc_data_structures/src/owning_ref/tests.rs @@ -3,7 +3,7 @@ mod owning_ref { use super::super::OwningRef; use super::super::{BoxRef, Erased, ErasedBoxRef, RcRef}; - use std::cmp::{Ord, Ordering, PartialEq, PartialOrd}; + use std::cmp::Ordering; use std::collections::hash_map::DefaultHasher; use std::collections::HashMap; use std::hash::{Hash, Hasher}; @@ -368,7 +368,7 @@ mod owning_handle { mod owning_ref_mut { use super::super::BoxRef; use super::super::{BoxRefMut, Erased, ErasedBoxRefMut, OwningRefMut}; - use std::cmp::{Ord, Ordering, PartialEq, PartialOrd}; + use std::cmp::Ordering; use std::collections::hash_map::DefaultHasher; use std::collections::HashMap; use std::hash::{Hash, Hasher}; diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index aa7a01eed15c9..1d4014f05acdc 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -86,7 +86,6 @@ use crate::fx::FxHashMap; use std::borrow::Borrow; use std::collections::hash_map::Entry; -use std::convert::Into; use std::error::Error; use std::fs; use std::path::Path; diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index d13313dfd0ebf..03ff5e5b3751f 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -1,7 +1,6 @@ use crate::stable_hasher::{HashStable, StableHasher, StableOrd}; use std::borrow::Borrow; use std::cmp::Ordering; -use std::iter::FromIterator; use std::mem; use std::ops::{Bound, Index, IndexMut, RangeBounds}; diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index c2f0ae328962b..7af5c14942adf 100644 --- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs @@ -1,7 +1,6 @@ //! A variant of `SortedMap` that preserves insertion order. use std::hash::{Hash, Hasher}; -use std::iter::FromIterator; use crate::stable_hasher::{HashStable, StableHasher}; use rustc_index::vec::{Idx, IndexVec}; diff --git a/compiler/rustc_data_structures/src/sso/either_iter.rs b/compiler/rustc_data_structures/src/sso/either_iter.rs index 131eeef4582de..bca6c0955b905 100644 --- a/compiler/rustc_data_structures/src/sso/either_iter.rs +++ b/compiler/rustc_data_structures/src/sso/either_iter.rs @@ -1,7 +1,5 @@ use std::fmt; -use std::iter::ExactSizeIterator; use std::iter::FusedIterator; -use std::iter::Iterator; /// Iterator which may contain instance of /// one of two specific implementations. diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index ec6a62016a87c..7cdac58197714 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -3,7 +3,6 @@ use crate::fx::FxHashMap; use arrayvec::ArrayVec; use std::fmt; use std::hash::Hash; -use std::iter::FromIterator; use std::ops::Index; // For pointer-sized arguments arrays diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs index 406f0270dcc1b..a4b40138933de 100644 --- a/compiler/rustc_data_structures/src/sso/set.rs +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -1,6 +1,5 @@ use std::fmt; use std::hash::Hash; -use std::iter::FromIterator; use super::map::SsoHashMap; diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index e4f47b22ac358..ed5341c40ef08 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -138,7 +138,7 @@ cfg_if! { } } - pub use std::iter::Iterator as ParallelIterator; + pub use Iterator as ParallelIterator; pub fn par_iter(t: T) -> T::IntoIter { t.into_iter() diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs index d44ccd368b3cb..b0315c93d934d 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs @@ -76,7 +76,7 @@ where fn drop(&mut self) { // No need to drop the tag, as it's Copy unsafe { - std::mem::drop(P::from_usize(self.raw.pointer_raw())); + drop(P::from_usize(self.raw.pointer_raw())); } } } diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index 86be0bd8775d7..2417df66bb9d8 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -1,6 +1,5 @@ use std::borrow::Borrow; use std::fmt::Debug; -use std::iter::FromIterator; use std::slice::Iter; use std::vec::IntoIter; diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index f06ca5a0733a5..711eed2b27231 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -45,7 +45,6 @@ use rustc_target::json::ToJson; use std::borrow::Cow; use std::cmp::max; -use std::default::Default; use std::env; use std::ffi::OsString; use std::fs; diff --git a/compiler/rustc_error_codes/src/error_codes/E0492.md b/compiler/rustc_error_codes/src/error_codes/E0492.md index 79e7c069a91c4..7c0719dc217d0 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0492.md +++ b/compiler/rustc_error_codes/src/error_codes/E0492.md @@ -55,7 +55,6 @@ wrapper: ``` use std::cell::Cell; -use std::marker::Sync; struct NotThreadSafe { value: Cell, diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 7155db32e53b7..88b4fffd46f61 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -59,7 +59,7 @@ into_diagnostic_arg_using_display!( i128, u128, std::io::Error, - std::boxed::Box, + Box, std::num::NonZeroU32, hir::Target, Edition, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 9d6a4f9a1fd7d..321c43a1aba8d 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -26,7 +26,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, FileName, RealFileName, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; -use std::default::Default; use std::iter; use std::path::PathBuf; use std::rc::Rc; diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index 6e2fbf96cbfb3..e870aa543d0b5 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -6,7 +6,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::Ident; use rustc_span::Span; -use std::iter::{Enumerate, ExactSizeIterator}; +use std::iter::Enumerate; pub struct EnumerateAndAdjust { enumerate: Enumerate, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b065ace6bf5e1..69eb96fe8e925 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -31,7 +31,6 @@ use rustc_trait_selection::traits::{ }; use std::cell::LazyCell; -use std::convert::TryInto; use std::iter; use std::ops::{ControlFlow, Deref}; diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index a8acaf6597aab..d1d328128bc15 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -30,8 +30,6 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; -use std::iter::FromIterator; -use std::vec::Vec; const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk; const EXCEPT: Symbol = sym::except; diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 97ebed0585579..1fd2b9b0d7b7b 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -113,7 +113,6 @@ use rustc_span::Symbol; use std::fs as std_fs; use std::io::{self, ErrorKind}; -use std::mem; use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -305,7 +304,7 @@ pub fn prepare_session_directory( } delete_session_dir_lock_file(sess, &lock_file_path); - mem::drop(directory_lock); + drop(directory_lock); } } } @@ -864,7 +863,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { // Let's make it explicit that the file lock is released at this point, // or rather, that we held on to it until here - mem::drop(lock); + drop(lock); } Err(_) => { debug!( @@ -898,7 +897,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { // Let's make it explicit that the file lock is released at this point, // or rather, that we held on to it until here - mem::drop(lock); + drop(lock); } Ok(()) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 39aa27a23c1d2..c18a911b2fbcd 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -4,7 +4,6 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; use std::fmt::Debug; use std::hash::Hash; -use std::iter::FromIterator; use std::marker::PhantomData; use std::ops::{Index, IndexMut, RangeBounds}; use std::slice; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2b8f6557c829b..e903cb86dd204 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -25,7 +25,6 @@ use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrate use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel}; use std::collections::{BTreeMap, BTreeSet}; -use std::iter::FromIterator; use std::num::NonZeroUsize; use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 3fbabbc6344a7..50d6d5b9bab91 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -34,7 +34,6 @@ pub use crate::cursor::Cursor; use self::LiteralKind::*; use self::TokenKind::*; use crate::cursor::EOF_CHAR; -use std::convert::TryFrom; /// Parsed token. /// It doesn't contain information about data that has been parsed, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 297b509d4023d..8446da6098ee9 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -16,7 +16,6 @@ use rustc_target::abi::{Abi, Size, WrappingRange}; use rustc_target::abi::{Integer, TagEncoding, Variants}; use rustc_target::spec::abi::Abi as SpecAbi; -use std::cmp; use std::iter; use std::ops::ControlFlow; @@ -531,7 +530,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { _ => {} }; - fn is_valid(binop: hir::BinOp, v: T, min: T, max: T) -> bool { + fn is_valid(binop: hir::BinOp, v: T, min: T, max: T) -> bool { match binop.node { hir::BinOpKind::Lt => v > min && v <= max, hir::BinOpKind::Le => v >= min && v < max, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 29fe6110797e3..716655c7f144d 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -7,7 +7,6 @@ use rustc_middle::ty::ParameterizedOverTcx; use rustc_serialize::opaque::FileEncoder; use rustc_serialize::Encoder as _; use rustc_span::hygiene::MacroKind; -use std::convert::TryInto; use std::marker::PhantomData; use std::num::NonZeroUsize; diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index efa9464529e71..0b55757eb0382 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -3,7 +3,6 @@ use rustc_macros::HashStable; use rustc_span::Symbol; -use std::cmp::Ord; use std::fmt::{self, Debug, Formatter}; rustc_index::newtype_index! { diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index d79cd8b7a8a4b..8fe349d9640da 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -95,7 +95,6 @@ mod pointer; mod queries; mod value; -use std::convert::TryFrom; use std::fmt; use std::io; use std::io::{Read, Write}; diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index 9c270ba1ec179..b083099107620 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -3,7 +3,6 @@ use super::{AllocId, InterpResult}; use rustc_macros::HashStable; use rustc_target::abi::{HasDataLayout, Size}; -use std::convert::{TryFrom, TryInto}; use std::fmt; //////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index e6636e50e6e7a..88fb14eb35942 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -1,4 +1,3 @@ -use std::convert::{TryFrom, TryInto}; use std::fmt; use either::{Either, Left, Right}; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index a513444e1e08b..db4fe6f886b25 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -36,7 +36,6 @@ use rustc_span::{Span, DUMMY_SP}; use either::Either; use std::borrow::Cow; -use std::convert::TryInto; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::ops::{ControlFlow, Index, IndexMut}; use std::{iter, mem}; diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index fb152b63f6344..d40d7de5f315f 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -12,7 +12,6 @@ use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir::def_id::DefId; use rustc_span::source_map::Span; -use std::iter::FromIterator; pub mod type_op { use crate::ty::fold::TypeFoldable; diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index f3186e1c30c3d..2a8a4d598882d 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -2,7 +2,6 @@ use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_target::abi::Size; -use std::convert::{TryFrom, TryInto}; use std::fmt; use std::num::NonZeroU8; diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index becc2b805dd1e..d9721863a58c8 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,5 +1,3 @@ -use std::convert::TryInto; - use super::Const; use crate::mir; use crate::mir::interpret::{AllocId, ConstValue, Scalar}; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5303341ba443c..01e96fa5c7ade 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -23,7 +23,6 @@ use smallvec::SmallVec; use std::cell::Cell; use std::char; use std::collections::BTreeMap; -use std::convert::TryFrom; use std::fmt::{self, Write as _}; use std::iter; use std::ops::{ControlFlow, Deref, DerefMut}; diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 6eae94511e4d6..802925dfb043e 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -1,4 +1,3 @@ -use std::convert::TryFrom; use std::fmt; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar}; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 691cbee2c7319..ba6bc41c6675c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -30,7 +30,6 @@ mod test; mod util; use std::borrow::Borrow; -use std::convert::TryFrom; use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index bd435f9ab0095..cbd494862a01f 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -7,7 +7,6 @@ use rustc_middle::thir::*; use rustc_middle::ty; use rustc_middle::ty::TypeVisitable; use smallvec::SmallVec; -use std::convert::TryInto; impl<'a, 'tcx> Builder<'a, 'tcx> { pub(crate) fn field_match_pairs<'pat>( diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index d60e8722cb61d..18e9c69c4870e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -45,7 +45,7 @@ use std::cell::Cell; use std::cmp::{self, max, min, Ordering}; use std::fmt; -use std::iter::{once, IntoIterator}; +use std::iter::once; use std::ops::RangeInclusive; use smallvec::{smallvec, SmallVec}; diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index f0e75c53ea15c..8fdac7b2cf501 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -26,7 +26,7 @@ //! ## `PartialOrd` //! //! Given that they represent partially ordered sets, you may be surprised that [`JoinSemiLattice`] -//! and [`MeetSemiLattice`] do not have [`PartialOrd`][std::cmp::PartialOrd] as a supertrait. This +//! and [`MeetSemiLattice`] do not have [`PartialOrd`] as a supertrait. This //! is because most standard library types use lexicographic ordering instead of set inclusion for //! their `PartialOrd` impl. Since we do not actually need to compare lattice elements to run a //! dataflow analysis, there's no need for a newtype wrapper with a custom `PartialOrd` impl. The diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 475e2ec9a1dea..8212a7b523bbc 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -35,7 +35,6 @@ use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Vis use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use smallvec::SmallVec; -use std::convert::TryInto; pub struct SimplifyCfg { label: String, diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 650076c2213a3..703ed09a254a9 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -20,7 +20,6 @@ use rustc_middle::ty::{ Const, Ty, TyCtxt, }; use rustc_span::symbol::sym; -use std::convert::TryInto; use std::ops::ControlFlow; use crate::errors::UnusedGenericParams; diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index c7d239b647f35..686454a8f1811 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -6,7 +6,6 @@ use rustc_ast::attr; use rustc_ast::token::{self, Delimiter, Nonterminal}; use rustc_errors::{error_code, fluent, Diagnostic, IntoDiagnostic, PResult}; use rustc_span::{sym, BytePos, Span}; -use std::convert::TryInto; // Public for rustfmt usage #[derive(Debug)] diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index a084a70108859..b97f22417cb7b 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -8,7 +8,6 @@ use rustc_errors::PResult; use rustc_session::parse::ParseSess; use rustc_span::{sym, Span, DUMMY_SP}; -use std::convert::TryInto; use std::ops::Range; /// A wrapper type to ensure that the parser handles outer attributes correctly. diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 03f25392a7c1f..7ebcda249e23a 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -21,7 +21,6 @@ use rustc_span::lev_distance::lev_distance; use rustc_span::source_map::{self, Span}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::DUMMY_SP; -use std::convert::TryFrom; use std::mem; use thin_vec::ThinVec; use tracing::debug; diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 38c7c6cce6765..0e7d628c1eb63 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -46,7 +46,7 @@ impl DepNodeIndex { pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1); } -impl std::convert::From for QueryInvocationId { +impl From for QueryInvocationId { #[inline] fn from(dep_node_index: DepNodeIndex) -> Self { QueryInvocationId(dep_node_index.as_u32()) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 3b20ec70d73cb..d292f4beef2eb 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -22,7 +22,6 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable}; use smallvec::SmallVec; -use std::convert::TryInto; // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits // unused so that we can store multiple index types in `CompressedHybridIndex`, diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 4c4680b5d8ea8..f65846fc77f6e 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -9,7 +9,6 @@ use rustc_data_structures::sharded::Sharded; use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::WorkerLocal; use rustc_index::vec::{Idx, IndexVec}; -use std::default::Default; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 49bbcf5780459..701bbde6ad23f 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -22,8 +22,8 @@ use { rustc_data_structures::{jobserver, OnDrop}, rustc_rayon_core as rayon_core, rustc_span::DUMMY_SP, - std::iter::{self, FromIterator}, - std::{mem, process}, + std::iter, + std::process, }; /// Represents a span and a query key. @@ -247,7 +247,7 @@ impl QueryLatch { jobserver::release_thread(); waiter.condvar.wait(&mut info); // Release the lock before we potentially block in `acquire_thread` - mem::drop(info); + drop(info); jobserver::acquire_thread(); } } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 7735c571310dd..6c310abf10ac5 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -36,7 +36,6 @@ use rustc_span::symbol::Ident; use rustc_span::*; use std::cell::Cell; -use std::default::Default; use std::env; use std::fs::File; use std::io::BufWriter; diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 0afeb86fceb24..0e0ebc79eb2e3 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -1,6 +1,5 @@ use crate::leb128::{self, largest_max_leb128_len}; use crate::serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::convert::TryInto; use std::fs::File; use std::io::{self, Write}; use std::mem::MaybeUninit; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7a20100fd3133..6de564a3a0692 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -32,7 +32,7 @@ use std::collections::btree_map::{ use std::collections::{BTreeMap, BTreeSet}; use std::fmt; use std::hash::Hash; -use std::iter::{self, FromIterator}; +use std::iter; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 1b66773be6f08..1855a49c1ecdf 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -3,7 +3,6 @@ use smallvec::{smallvec, SmallVec}; use std::env; use std::fs; -use std::iter::FromIterator; use std::path::{Path, PathBuf}; use crate::search_paths::{PathKind, SearchPath}; diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 2ae57d9e56d7c..43a3172270733 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -15,11 +15,10 @@ pub use crate::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock}; +use std::cmp; use std::hash::Hash; use std::path::{Path, PathBuf}; use std::sync::atomic::Ordering; -use std::{clone::Clone, cmp}; -use std::{convert::TryFrom, unreachable}; use std::fs; use std::io; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1fcf8c7a8bf13..d0fe598ce086e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -9,7 +9,6 @@ use rustc_data_structures::sync::Lock; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::cmp::{Ord, PartialEq, PartialOrd}; use std::fmt; use std::hash::{Hash, Hasher}; use std::str; @@ -1974,7 +1973,6 @@ pub mod kw { /// For example `sym::rustfmt` or `sym::u8`. pub mod sym { use super::Symbol; - use std::convert::TryInto; #[doc(inline)] pub use super::sym_generated::*; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index b69a0a645a415..dc2cc23ffb1e4 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -18,7 +18,6 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -use std::iter::FromIterator; use std::path::{Path, PathBuf}; #[macro_use] diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 1db1d7e85adcc..be994eda14c00 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -45,9 +45,7 @@ use rustc_span::symbol::{sym, Symbol}; use serde_json::Value; use std::borrow::Cow; use std::collections::BTreeMap; -use std::convert::TryFrom; use std::hash::{Hash, Hasher}; -use std::iter::FromIterator; use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; use std::str::FromStr; diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 3ed616d709b1e..9aa2be124e294 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -1,6 +1,6 @@ #![allow(rustc::usage_of_ty_tykind)] -use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use std::cmp::Ordering; use std::{fmt, hash}; use crate::DebruijnIndex; From e81ad69331dd5fafc9f89756c08a3882680b70e7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Dec 2022 21:01:48 +0100 Subject: [PATCH 28/30] Don't take into account hashtag prepended lines if not in rust code block --- src/librustdoc/html/markdown.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5ce62224d35e5..1e1c657b0bf22 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -246,8 +246,6 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { _ => {} } } - let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); - let text = lines.intersperse("\n".into()).collect::(); let parse_result = match kind { CodeBlockKind::Fenced(ref lang) => { @@ -260,7 +258,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> {
{}
\ ", lang, - Escape(&text), + Escape(&origtext), ) .into(), )); @@ -270,6 +268,9 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { CodeBlockKind::Indented => Default::default(), }; + let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); + let text = lines.intersperse("\n".into()).collect::(); + compile_fail = parse_result.compile_fail; should_panic = parse_result.should_panic; ignore = parse_result.ignore; From bc63c0edc0d1e82302305a479f53aa1137e96179 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Dec 2022 21:02:08 +0100 Subject: [PATCH 29/30] Add test for non-rust code block hashtag prepended lines --- src/librustdoc/html/markdown/tests.rs | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index e4f72a057892f..68b31a6ee083d 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -309,3 +309,40 @@ fn test_find_testable_code_line() { t("```rust\n```\n```rust\n```", &[1, 3]); t("```rust\n```\n ```rust\n```", &[1, 3]); } + +#[test] +fn test_ascii_with_prepending_hashtag() { + fn t(input: &str, expect: &str) { + let mut map = IdMap::new(); + let output = Markdown { + content: input, + links: &[], + ids: &mut map, + error_codes: ErrorCodes::Yes, + edition: DEFAULT_EDITION, + playground: &None, + heading_offset: HeadingOffset::H2, + } + .into_string(); + assert_eq!(output, expect, "original: {}", input); + } + + t( + r#"```ascii +#..#.####.#....#.....##.. +#..#.#....#....#....#..#. +####.###..#....#....#..#. +#..#.#....#....#....#..#. +#..#.#....#....#....#..#. +#..#.####.####.####..##.. +```"#, + "
\
+#..#.####.#....#.....##..
+#..#.#....#....#....#..#.
+####.###..#....#....#..#.
+#..#.#....#....#....#..#.
+#..#.#....#....#....#..#.
+#..#.####.####.####..##..
+
", + ); +} From 0f5f163a949717eb0361b2ad4d31c731171d100e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 11 Dec 2022 10:57:56 +0900 Subject: [PATCH 30/30] Add some regression tests for #44454 Signed-off-by: Yuki Okushi --- src/test/ui/traits/object/issue-44454-1.rs | 22 +++++++++++++ .../ui/traits/object/issue-44454-1.stderr | 10 ++++++ src/test/ui/traits/object/issue-44454-2.rs | 22 +++++++++++++ .../ui/traits/object/issue-44454-2.stderr | 17 ++++++++++ src/test/ui/traits/object/issue-44454-3.rs | 33 +++++++++++++++++++ .../ui/traits/object/issue-44454-3.stderr | 11 +++++++ 6 files changed, 115 insertions(+) create mode 100644 src/test/ui/traits/object/issue-44454-1.rs create mode 100644 src/test/ui/traits/object/issue-44454-1.stderr create mode 100644 src/test/ui/traits/object/issue-44454-2.rs create mode 100644 src/test/ui/traits/object/issue-44454-2.stderr create mode 100644 src/test/ui/traits/object/issue-44454-3.rs create mode 100644 src/test/ui/traits/object/issue-44454-3.stderr diff --git a/src/test/ui/traits/object/issue-44454-1.rs b/src/test/ui/traits/object/issue-44454-1.rs new file mode 100644 index 0000000000000..bbaf3188a8963 --- /dev/null +++ b/src/test/ui/traits/object/issue-44454-1.rs @@ -0,0 +1,22 @@ +// Taken from https://github.com/rust-lang/rust/issues/44454#issue-256435333 + +trait Animal: 'static {} + +fn foo() +where + Y: Animal + ?Sized, +{ + // `Y` implements `Animal` so `Y` is 'static. + baz::() +} + +fn bar<'a>(_arg: &'a i32) { + foo::, &'a i32>() //~ ERROR: lifetime may not live long enough +} + +fn baz() {} + +fn main() { + let a = 5; + bar(&a); +} diff --git a/src/test/ui/traits/object/issue-44454-1.stderr b/src/test/ui/traits/object/issue-44454-1.stderr new file mode 100644 index 0000000000000..859487f50ac1e --- /dev/null +++ b/src/test/ui/traits/object/issue-44454-1.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/issue-44454-1.rs:14:5 + | +LL | fn bar<'a>(_arg: &'a i32) { + | -- lifetime `'a` defined here +LL | foo::, &'a i32>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/traits/object/issue-44454-2.rs b/src/test/ui/traits/object/issue-44454-2.rs new file mode 100644 index 0000000000000..f5178bcdbe224 --- /dev/null +++ b/src/test/ui/traits/object/issue-44454-2.rs @@ -0,0 +1,22 @@ +// Taken from https://github.com/rust-lang/rust/issues/44454#issuecomment-1175925928 + +trait Trait: 'static { + type Assoc: AsRef; +} + +fn hr(x: T::Assoc) -> Box + 'static> +where + T: Trait +{ + Box::new(x) +} + +fn extend_lt<'a>(x: &'a str) -> Box + 'static> { + type DynTrait = dyn for<'a> Trait<&'a str, Assoc = &'a str>; + hr::(x) //~ ERROR: borrowed data escapes outside of function +} + +fn main() { + let extended = extend_lt(&String::from("hello")); + println!("{}", extended.as_ref().as_ref()); +} diff --git a/src/test/ui/traits/object/issue-44454-2.stderr b/src/test/ui/traits/object/issue-44454-2.stderr new file mode 100644 index 0000000000000..7f574769b7f60 --- /dev/null +++ b/src/test/ui/traits/object/issue-44454-2.stderr @@ -0,0 +1,17 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/issue-44454-2.rs:16:5 + | +LL | fn extend_lt<'a>(x: &'a str) -> Box + 'static> { + | -- - `x` is a reference that is only valid in the function body + | | + | lifetime `'a` defined here +LL | type DynTrait = dyn for<'a> Trait<&'a str, Assoc = &'a str>; +LL | hr::(x) + | ^^^^^^^^^^^^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/traits/object/issue-44454-3.rs b/src/test/ui/traits/object/issue-44454-3.rs new file mode 100644 index 0000000000000..bff7270353464 --- /dev/null +++ b/src/test/ui/traits/object/issue-44454-3.rs @@ -0,0 +1,33 @@ +// Taken from https://github.com/rust-lang/rust/issues/44454#issuecomment-1332781290 + +use std::any::Any; + +trait Animal: 'static {} + +trait Projector { + type Foo; +} + +impl Projector for dyn Animal { + type Foo = X; +} + +fn make_static<'a, T>(t: &'a T) -> &'static T { + let x: as Projector>::Foo = t; + let any = generic::, &'a T>(x); + //~^ ERROR: lifetime may not live long enough + any.downcast_ref::<&'static T>().unwrap() +} + +fn generic + ?Sized, U>(x: ::Foo) -> Box { + make_static_any(x) +} + +fn make_static_any(u: U) -> Box { + Box::new(u) +} + +fn main() { + let a = make_static(&"salut".to_string()); + println!("{}", *a); +} diff --git a/src/test/ui/traits/object/issue-44454-3.stderr b/src/test/ui/traits/object/issue-44454-3.stderr new file mode 100644 index 0000000000000..294684d26bdfc --- /dev/null +++ b/src/test/ui/traits/object/issue-44454-3.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-44454-3.rs:17:15 + | +LL | fn make_static<'a, T>(t: &'a T) -> &'static T { + | -- lifetime `'a` defined here +LL | let x: as Projector>::Foo = t; +LL | let any = generic::, &'a T>(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error +