diff options
Diffstat (limited to 'compiler')
41 files changed, 305 insertions, 199 deletions
diff --git a/compiler/rustc_apfloat/tests/ieee.rs b/compiler/rustc_apfloat/tests/ieee.rs index 22641064315..f8fac0c2358 100644 --- a/compiler/rustc_apfloat/tests/ieee.rs +++ b/compiler/rustc_apfloat/tests/ieee.rs @@ -552,7 +552,7 @@ fn fma() { assert!(f1.is_negative() && f1.is_zero()); } - // Test x87 extended precision case from http://llvm.org/PR20728. + // Test x87 extended precision case from https://llvm.org/PR20728. { let mut m1 = X87DoubleExtended::from_u128(1).value; let m2 = X87DoubleExtended::from_u128(1).value; diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index d3f5a37fd6e..03282fd5164 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1935,6 +1935,7 @@ bitflags::bitflags! { const NORETURN = 1 << 4; const NOSTACK = 1 << 5; const ATT_SYNTAX = 1 << 6; + const RAW = 1 << 7; } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3d2785faad6..ffee5cdc331 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2284,6 +2284,9 @@ impl<'a> State<'a> { if opts.contains(InlineAsmOptions::ATT_SYNTAX) { options.push("att_syntax"); } + if opts.contains(InlineAsmOptions::RAW) { + options.push("raw"); + } s.commasep(Inconsistent, &options, |s, &opt| { s.word(opt); }); diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index b28c6f0d99c..97e07d52cc3 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -356,6 +356,8 @@ fn parse_options<'a>( try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK); } else if p.eat_keyword(sym::att_syntax) { try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX); + } else if p.eat_keyword(kw::Raw) { + try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW); } else { return p.unexpected(); } @@ -467,6 +469,14 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl } } + // Don't treat raw asm as a format string. + if args.options.contains(ast::InlineAsmOptions::RAW) { + template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string())); + let template_num_lines = 1 + template_str.matches('\n').count(); + line_spans.extend(std::iter::repeat(template_sp).take(template_num_lines)); + continue; + } + let mut parser = parse::Parser::new( template_str, str_style, diff --git a/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs b/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs index 983839d48d2..2643fae0a81 100644 --- a/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs +++ b/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs @@ -1,4 +1,4 @@ -#![feature(rustc_private)] +#![feature(rustc_private, once_cell)] extern crate rustc_data_structures; extern crate rustc_driver; @@ -6,12 +6,33 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_target; +use std::panic; +use std::lazy::SyncLazy; + use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_interface::interface; use rustc_session::config::ErrorOutputType; use rustc_session::early_error; use rustc_target::spec::PanicStrategy; +const BUG_REPORT_URL: &str = "https://github.com/bjorn3/rustc_codegen_cranelift/issues/new"; + +static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = + SyncLazy::new(|| { + let hook = panic::take_hook(); + panic::set_hook(Box::new(|info| { + // Invoke the default handler, which prints the actual panic message and optionally a backtrace + (*DEFAULT_HOOK)(info); + + // Separate the output with an empty line + eprintln!(); + + // Print the ICE message + rustc_driver::report_ice(info, BUG_REPORT_URL); + })); + hook + }); + #[derive(Default)] pub struct CraneliftPassesCallbacks { time_passes: bool, @@ -37,7 +58,7 @@ fn main() { let start_rss = get_resident_set_size(); rustc_driver::init_rustc_env_logger(); let mut callbacks = CraneliftPassesCallbacks::default(); - rustc_driver::install_ice_hook(); + SyncLazy::force(&DEFAULT_HOOK); // Install ice hook let exit_code = rustc_driver::catch_with_exit_code(|| { let args = std::env::args_os() .enumerate() diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index c8cf0116c64..582c9354041 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -606,7 +606,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // According to LLVM [1] building a nontemporal store must // *always* point to a metadata value of the integer 1. // - // [1]: http://llvm.org/docs/LangRef.html#store-instruction + // [1]: https://llvm.org/docs/LangRef.html#store-instruction let one = self.cx.const_i32(1); let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1); llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 6aa952462fa..7415a570453 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -71,7 +71,7 @@ pub struct CodegenCx<'ll, 'tcx> { pub statics_to_rauw: RefCell<Vec<(&'ll Value, &'ll Value)>>, /// Statics that will be placed in the llvm.used variable - /// See <http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details + /// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details pub used_statics: RefCell<Vec<&'ll Value>>, pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'ll Type>>, diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 38d56f87211..c1521a760b0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -102,7 +102,7 @@ pub fn SetFunctionCallConv(fn_: &'a Value, cc: CallConv) { // example happen for generics when using multiple codegen units. This function simply uses the // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the // function. -// For more details on COMDAT sections see e.g., http://www.airs.com/blog/archives/52 +// For more details on COMDAT sections see e.g., https://www.airs.com/blog/archives/52 pub fn SetUniqueComdat(llmod: &Module, val: &'a Value) { unsafe { let name = get_value_name(val); diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 0dd3d2ae15b..cb9c6269b66 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -3,13 +3,17 @@ use crate::{llvm, llvm_util}; use libc::c_int; use rustc_codegen_ssa::target_features::supported_target_features; use rustc_data_structures::fx::FxHashSet; +use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_middle::bug; use rustc_session::config::PrintRequest; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; use std::ffi::{CStr, CString}; +use tracing::debug; +use std::mem; +use std::path::Path; use std::ptr; use std::slice; use std::str; @@ -129,6 +133,16 @@ unsafe fn configure_llvm(sess: &Session) { llvm::LLVMInitializePasses(); + for plugin in &sess.opts.debugging_opts.llvm_plugins { + let path = Path::new(plugin); + let res = DynamicLibrary::open(path); + match res { + Ok(_) => debug!("LLVM plugin loaded succesfully {} ({})", path.display(), plugin), + Err(e) => bug!("couldn't load plugin: {}", e), + } + mem::forget(res); + } + rustc_llvm::initialize_available_targets(); llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()); diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 87bc829b488..35a6495946f 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1167,23 +1167,26 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = SyncLazy::new(|| { let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| report_ice(info, BUG_REPORT_URL))); + panic::set_hook(Box::new(|info| { + // Invoke the default handler, which prints the actual panic message and optionally a backtrace + (*DEFAULT_HOOK)(info); + + // Separate the output with an empty line + eprintln!(); + + // Print the ICE message + report_ice(info, BUG_REPORT_URL); + })); hook }); -/// Prints the ICE message, including backtrace and query stack. +/// Prints the ICE message, including query stack, but without backtrace. /// /// The message will point the user at `bug_report_url` to report the ICE. /// /// When `install_ice_hook` is called, this function will be called as the panic /// hook. pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { - // Invoke the default handler, which prints the actual panic message and optionally a backtrace - (*DEFAULT_HOOK)(info); - - // Separate the output with an empty line - eprintln!(); - let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index a2b4f3fcf73..bf131914b97 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -293,18 +293,6 @@ struct TypedAnnotation<'tcx> { maybe_typeck_results: Cell<Option<&'tcx ty::TypeckResults<'tcx>>>, } -impl<'tcx> TypedAnnotation<'tcx> { - /// Gets the type-checking results for the current body. - /// As this will ICE if called outside bodies, only call when working with - /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies). - #[track_caller] - fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> { - self.maybe_typeck_results - .get() - .expect("`TypedAnnotation::typeck_results` called outside of body") - } -} - impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> { fn sess(&self) -> &Session { &self.tcx.sess @@ -336,10 +324,20 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { } fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { if let pprust_hir::AnnNode::Expr(expr) = node { - s.s.space(); - s.s.word("as"); - s.s.space(); - s.s.word(self.typeck_results().expr_ty(expr).to_string()); + let typeck_results = self.maybe_typeck_results.get().or_else(|| { + self.tcx + .hir() + .maybe_body_owned_by(self.tcx.hir().local_def_id_to_hir_id(expr.hir_id.owner)) + .map(|body_id| self.tcx.typeck_body(body_id)) + }); + + if let Some(typeck_results) = typeck_results { + s.s.space(); + s.s.word("as"); + s.s.space(); + s.s.word(typeck_results.expr_ty(expr).to_string()); + } + s.pclose(); } } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index abad190b072..a255b4f83ac 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -11,7 +11,7 @@ use crate::mbe::transcribe::transcribe; use rustc_ast as ast; use rustc_ast::token::{self, NonterminalKind, NtTT, Token, TokenKind::*}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; -use rustc_ast::NodeId; +use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::FxHashMap; @@ -471,7 +471,7 @@ pub fn compile_declarative_macro( ) .pop() .unwrap(); - valid &= check_lhs_nt_follows(&sess.parse_sess, features, &def.attrs, &tt); + valid &= check_lhs_nt_follows(&sess.parse_sess, features, &def, &tt); return tt; } } @@ -540,13 +540,13 @@ pub fn compile_declarative_macro( fn check_lhs_nt_follows( sess: &ParseSess, features: &Features, - attrs: &[ast::Attribute], + def: &ast::Item, lhs: &mbe::TokenTree, ) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. if let mbe::TokenTree::Delimited(_, ref tts) = *lhs { - check_matcher(sess, features, attrs, &tts.tts) + check_matcher(sess, features, def, &tts.tts) } else { let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; sess.span_diagnostic.span_err(lhs.span(), msg); @@ -604,13 +604,13 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool { fn check_matcher( sess: &ParseSess, features: &Features, - attrs: &[ast::Attribute], + def: &ast::Item, matcher: &[mbe::TokenTree], ) -> bool { let first_sets = FirstSets::new(matcher); let empty_suffix = TokenSet::empty(); let err = sess.span_diagnostic.err_count(); - check_matcher_core(sess, features, attrs, &first_sets, matcher, &empty_suffix); + check_matcher_core(sess, features, def, &first_sets, matcher, &empty_suffix); err == sess.span_diagnostic.err_count() } @@ -857,7 +857,7 @@ impl TokenSet { fn check_matcher_core( sess: &ParseSess, features: &Features, - attrs: &[ast::Attribute], + def: &ast::Item, first_sets: &FirstSets, matcher: &[mbe::TokenTree], follow: &TokenSet, @@ -903,7 +903,7 @@ fn check_matcher_core( } TokenTree::Delimited(span, ref d) => { let my_suffix = TokenSet::singleton(d.close_tt(span)); - check_matcher_core(sess, features, attrs, first_sets, &d.tts, &my_suffix); + check_matcher_core(sess, features, def, first_sets, &d.tts, &my_suffix); // don't track non NT tokens last.replace_with_irrelevant(); @@ -936,7 +936,7 @@ fn check_matcher_core( // `my_suffix` is some TokenSet that we can use // for checking the interior of `seq_rep`. let next = - check_matcher_core(sess, features, attrs, first_sets, &seq_rep.tts, my_suffix); + check_matcher_core(sess, features, def, first_sets, &seq_rep.tts, my_suffix); if next.maybe_empty { last.add_all(&next); } else { @@ -956,29 +956,31 @@ fn check_matcher_core( for token in &last.tokens { if let TokenTree::MetaVarDecl(span, name, Some(kind)) = *token { for next_token in &suffix_first.tokens { - // Check if the old pat is used and the next token is `|`. - if let NonterminalKind::PatParam { inferred: true } = kind { - if let TokenTree::Token(token) = next_token { - if let BinOp(token) = token.kind { - if let token::BinOpToken::Or = token { - // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param. - let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( - span, - name, - Some(NonterminalKind::PatParam { inferred: false }), - )); - sess.buffer_lint_with_diagnostic( - &OR_PATTERNS_BACK_COMPAT, - span, - ast::CRATE_NODE_ID, - &*format!("the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro",), - BuiltinLintDiagnostics::OrPatternsBackCompat( - span, suggestion, - ), - ); - } - } - } + // Check if the old pat is used and the next token is `|` + // to warn about incompatibility with Rust 2021. + // We only emit this lint if we're parsing the original + // definition of this macro_rules, not while (re)parsing + // the macro when compiling another crate that is using the + // macro. (See #86567.) + // Macros defined in the current crate have a real node id, + // whereas macros from an external crate have a dummy id. + if def.id != DUMMY_NODE_ID + && matches!(kind, NonterminalKind::PatParam { inferred: true }) + && matches!(next_token, TokenTree::Token(token) if token.kind == BinOp(token::BinOpToken::Or)) + { + // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param. + let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( + span, + name, + Some(NonterminalKind::PatParam { inferred: false }), + )); + sess.buffer_lint_with_diagnostic( + &OR_PATTERNS_BACK_COMPAT, + span, + ast::CRATE_NODE_ID, + "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro", + BuiltinLintDiagnostics::OrPatternsBackCompat(span, suggestion), + ); } match is_in_follow(next_token, kind) { IsInFollow::Yes => {} diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index db70beb5914..27390fd2e4d 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -1,11 +1,11 @@ -//! Generate files suitable for use with [Graphviz](http://www.graphviz.org/) +//! Generate files suitable for use with [Graphviz](https://www.graphviz.org/) //! //! The `render` function generates output (e.g., an `output.dot` file) for -//! use with [Graphviz](http://www.graphviz.org/) by walking a labeled +//! use with [Graphviz](https://www.graphviz.org/) by walking a labeled //! graph. (Graphviz can then automatically lay out the nodes and edges //! of the graph, and also optionally render the graph as an image or //! other [output formats]( -//! http://www.graphviz.org/content/output-formats), such as SVG.) +//! https://www.graphviz.org/content/output-formats), such as SVG.) //! //! Rather than impose some particular graph data structure on clients, //! this library exposes two traits that clients can implement on their @@ -13,8 +13,8 @@ //! //! Note: This library does not yet provide access to the full //! expressiveness of the [DOT language]( -//! http://www.graphviz.org/doc/info/lang.html). For example, there are -//! many [attributes](http://www.graphviz.org/content/attrs) related to +//! https://www.graphviz.org/doc/info/lang.html). For example, there are +//! many [attributes](https://www.graphviz.org/content/attrs) related to //! providing layout hints (e.g., left-to-right versus top-down, which //! algorithm to use, etc). The current intention of this library is to //! emit a human-readable .dot file with very regular structure suitable @@ -267,9 +267,9 @@ //! //! # References //! -//! * [Graphviz](http://www.graphviz.org/) +//! * [Graphviz](https://www.graphviz.org/) //! -//! * [DOT language](http://www.graphviz.org/doc/info/lang.html) +//! * [DOT language](https://www.graphviz.org/doc/info/lang.html) #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", @@ -292,7 +292,7 @@ pub enum LabelText<'a> { LabelStr(Cow<'a, str>), /// This kind of label uses the graphviz label escString type: - /// <http://www.graphviz.org/content/attrs#kescString> + /// <https://www.graphviz.org/content/attrs#kescString> /// /// Occurrences of backslashes (`\`) are not escaped; instead they /// are interpreted as initiating an escString escape sequence. @@ -307,12 +307,12 @@ pub enum LabelText<'a> { /// printed exactly as given, but between `<` and `>`. **No /// escaping is performed.** /// - /// [html]: http://www.graphviz.org/content/node-shapes#html + /// [html]: https://www.graphviz.org/content/node-shapes#html HtmlStr(Cow<'a, str>), } /// The style for a node or edge. -/// See <http://www.graphviz.org/doc/info/attrs.html#k:style> for descriptions. +/// See <https://www.graphviz.org/doc/info/attrs.html#k:style> for descriptions. /// Note that some of these are not valid for edges. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Style { @@ -439,7 +439,7 @@ pub trait Labeller<'a> { /// Maps `n` to one of the [graphviz `shape` names][1]. If `None` /// is returned, no `shape` attribute is specified. /// - /// [1]: http://www.graphviz.org/content/node-shapes + /// [1]: https://www.graphviz.org/content/node-shapes fn node_shape(&'a self, _node: &Self::Node) -> Option<LabelText<'a>> { None } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d11dca1cba4..3211c7c5621 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1444,6 +1444,9 @@ impl<'a> State<'a> { if opts.contains(ast::InlineAsmOptions::ATT_SYNTAX) { options.push("att_syntax"); } + if opts.contains(ast::InlineAsmOptions::RAW) { + options.push("raw"); + } s.commasep(Inconsistent, &options, |s, &opt| { s.word(opt); }); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 9e3e96df3a7..4abc4b29b50 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -581,7 +581,7 @@ fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<PathBuf> { fn escape_dep_filename(filename: &String) -> String { // Apparently clang and gcc *only* escape spaces: - // http://llvm.org/klaus/clang/commit/9d50634cfc268ecc9a7250226dd5ca0e945240d4 + // https://llvm.org/klaus/clang/commit/9d50634cfc268ecc9a7250226dd5ca0e945240d4 filename.replace(" ", "\\ ") } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 52b3076a443..ebd18630e4e 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -715,6 +715,7 @@ fn test_debugging_options_tracking_hash() { tracked!(instrument_coverage, Some(InstrumentCoverage::All)); tracked!(instrument_mcount, true); tracked!(link_only, true); + tracked!(llvm_plugins, vec![String::from("plugin_name")]); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_opt_level, Some(4)); diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index 0b5bd39f7f9..77741c7240b 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -3,8 +3,10 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_middle::ty; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; -use rustc_session::lint::FutureBreakage; +use rustc_session::lint::FutureIncompatibilityReason; +use rustc_span::edition::Edition; use rustc_span::symbol::sym; +use rustc_span::Span; declare_lint! { /// The `array_into_iter` lint detects calling `into_iter` on arrays. @@ -20,37 +22,44 @@ declare_lint! { /// /// ### Explanation /// - /// In the future, it is planned to add an `IntoIter` implementation for - /// arrays such that it will iterate over *values* of the array instead of - /// references. Due to how method resolution works, this will change - /// existing code that uses `into_iter` on arrays. The solution to avoid - /// this warning is to use `iter()` instead of `into_iter()`. - /// - /// This is a [future-incompatible] lint to transition this to a hard error - /// in the future. See [issue #66145] for more details and a more thorough - /// description of the lint. - /// - /// [issue #66145]: https://github.com/rust-lang/rust/issues/66145 - /// [future-incompatible]: ../index.md#future-incompatible-lints + /// Since Rust 1.53, arrays implement `IntoIterator`. However, to avoid + /// breakage, `array.into_iter()` in Rust 2015 and 2018 code will still + /// behave as `(&array).into_iter()`, returning an iterator over + /// references, just like in Rust 1.52 and earlier. + /// This only applies to the method call syntax `array.into_iter()`, not to + /// any other syntax such as `for _ in array` or `IntoIterator::into_iter(array)`. pub ARRAY_INTO_ITER, Warn, - "detects calling `into_iter` on arrays", + "detects calling `into_iter` on arrays in Rust 2015 and 2018", @future_incompatible = FutureIncompatibleInfo { reference: "issue #66145 <https://github.com/rust-lang/rust/issues/66145>", - edition: None, - future_breakage: Some(FutureBreakage { - date: None - }) + reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), }; } -declare_lint_pass!( - /// Checks for instances of calling `into_iter` on arrays. - ArrayIntoIter => [ARRAY_INTO_ITER] -); +#[derive(Copy, Clone, Default)] +pub struct ArrayIntoIter { + for_expr_span: Span, +} + +impl_lint_pass!(ArrayIntoIter => [ARRAY_INTO_ITER]); impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + // Save the span of expressions in `for _ in expr` syntax, + // so we can give a better suggestion for those later. + if let hir::ExprKind::Match(arg, [_], hir::MatchSource::ForLoopDesugar) = &expr.kind { + if let hir::ExprKind::Call(path, [arg]) = &arg.kind { + if let hir::ExprKind::Path(hir::QPath::LangItem( + hir::LangItem::IntoIterIntoIter, + _, + )) = &path.kind + { + self.for_expr_span = arg.span; + } + } + } + // We only care about method call expressions. if let hir::ExprKind::MethodCall(call, span, args, _) = &expr.kind { if call.ident.name != sym::into_iter { @@ -106,19 +115,37 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter { _ => bug!("array type coerced to something other than array or slice"), }; cx.struct_span_lint(ARRAY_INTO_ITER, *span, |lint| { - lint.build(&format!( - "this method call currently resolves to `<&{} as IntoIterator>::into_iter` (due \ - to autoref coercions), but that might change in the future when \ - `IntoIterator` impls for arrays are added.", - target, - )) - .span_suggestion( + let mut diag = lint.build(&format!( + "this method call resolves to `<&{} as IntoIterator>::into_iter` \ + (due to backwards compatibility), \ + but will resolve to <{} as IntoIterator>::into_iter in Rust 2021.", + target, target, + )); + diag.span_suggestion( call.ident.span, "use `.iter()` instead of `.into_iter()` to avoid ambiguity", "iter".into(), Applicability::MachineApplicable, - ) - .emit(); + ); + if self.for_expr_span == expr.span { + let expr_span = expr.span.ctxt().outer_expn_data().call_site; + diag.span_suggestion( + receiver_arg.span.shrink_to_hi().to(expr_span.shrink_to_hi()), + "or remove `.into_iter()` to iterate by value", + String::new(), + Applicability::MaybeIncorrect, + ); + } else { + diag.multipart_suggestion( + "or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value", + vec![ + (expr.span.shrink_to_lo(), "IntoIterator::into_iter(".into()), + (receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), ")".into()), + ], + Applicability::MaybeIncorrect, + ); + } + diag.emit(); }) } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f6a84966f7a..5479af1dc30 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -47,6 +47,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::Instance; use rustc_middle::ty::{self, layout::LayoutError, Ty, TyCtxt}; +use rustc_session::lint::FutureIncompatibilityReason; use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; @@ -874,7 +875,7 @@ declare_lint! { "detects anonymous parameters", @future_incompatible = FutureIncompatibleInfo { reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>", - edition: Some(Edition::Edition2018), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), }; } @@ -1663,7 +1664,7 @@ declare_lint! { "`...` range patterns are deprecated", @future_incompatible = FutureIncompatibleInfo { reference: "issue #80165 <https://github.com/rust-lang/rust/issues/80165>", - edition: Some(Edition::Edition2021), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), }; } @@ -1891,7 +1892,7 @@ declare_lint! { "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>", - edition: Some(Edition::Edition2018), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), }; } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index a8df1b0952c..2dc04d57d1e 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -209,8 +209,8 @@ impl LintStore { bug!("duplicate specification of lint {}", lint.name_lower()) } - if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible { - if let Some(edition) = edition { + if let Some(FutureIncompatibleInfo { reason, .. }) = lint.future_incompatible { + if let Some(edition) = reason.edition() { self.lint_groups .entry(edition.lint_name()) .or_insert(LintGroup { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 4f59460aa82..89f9809d643 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -163,7 +163,7 @@ macro_rules! late_lint_passes { // FIXME: Turn the computation of types which implement Debug into a query // and change this to a module lint pass MissingDebugImplementations: MissingDebugImplementations::default(), - ArrayIntoIter: ArrayIntoIter, + ArrayIntoIter: ArrayIntoIter::default(), ClashingExternDeclarations: ClashingExternDeclarations::new(), DropTraitConstraints: DropTraitConstraints, TemporaryCStringAsPtr: TemporaryCStringAsPtr, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a2f60142ffc..53970b485ee 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -6,7 +6,7 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::{declare_lint, declare_lint_pass, FutureBreakage}; +use crate::{declare_lint, declare_lint_pass, FutureBreakage, FutureIncompatibilityReason}; use rustc_span::edition::Edition; declare_lint! { @@ -41,7 +41,6 @@ declare_lint! { "applying forbid to lint-groups", @future_incompatible = FutureIncompatibleInfo { reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>", - edition: None, }; } @@ -77,7 +76,6 @@ declare_lint! { "ill-formed attribute inputs that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>", - edition: None, }; crate_level_only } @@ -114,7 +112,6 @@ declare_lint! { "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { reference: "issue #68585 <https://github.com/rust-lang/rust/issues/68585>", - edition: None, }; } @@ -293,7 +290,6 @@ declare_lint! { "constant evaluation encountered erroneous expression", @future_incompatible = FutureIncompatibleInfo { reference: "issue #71800 <https://github.com/rust-lang/rust/issues/71800>", - edition: None, }; report_in_external_macro } @@ -900,7 +896,6 @@ declare_lint! { "detect private items in public interfaces not caught by the old implementation", @future_incompatible = FutureIncompatibleInfo { reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>", - edition: None, }; } @@ -980,7 +975,6 @@ declare_lint! { "detect public re-exports of private extern crates", @future_incompatible = FutureIncompatibleInfo { reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>", - edition: None, }; } @@ -1010,7 +1004,6 @@ declare_lint! { "type parameter default erroneously allowed in invalid location", @future_incompatible = FutureIncompatibleInfo { reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>", - edition: None, }; } @@ -1078,7 +1071,6 @@ declare_lint! { "detects unaligned references to fields of packed structs", @future_incompatible = FutureIncompatibleInfo { reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>", - edition: None, }; report_in_external_macro } @@ -1200,7 +1192,6 @@ declare_lint! { "patterns in functions without body were erroneously allowed", @future_incompatible = FutureIncompatibleInfo { reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>", - edition: None, }; } @@ -1244,7 +1235,6 @@ declare_lint! { "detects missing fragment specifiers in unused `macro_rules!` patterns", @future_incompatible = FutureIncompatibleInfo { reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>", - edition: None, }; } @@ -1286,7 +1276,6 @@ declare_lint! { "detects generic lifetime arguments in path segments with late bound lifetime parameters", @future_incompatible = FutureIncompatibleInfo { reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>", - edition: None, }; } @@ -1322,7 +1311,6 @@ declare_lint! { "trait-object types were treated as different depending on marker-trait order", @future_incompatible = FutureIncompatibleInfo { reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>", - edition: None, }; } @@ -1362,7 +1350,6 @@ declare_lint! { "distinct impls distinguished only by the leak-check code", @future_incompatible = FutureIncompatibleInfo { reference: "issue #56105 <https://github.com/rust-lang/rust/issues/56105>", - edition: None, }; } @@ -1554,7 +1541,7 @@ declare_lint! { "raw pointer to an inference variable", @future_incompatible = FutureIncompatibleInfo { reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>", - edition: Some(Edition::Edition2018), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), }; } @@ -1621,7 +1608,7 @@ declare_lint! { "suggest using `dyn Trait` for trait objects", @future_incompatible = FutureIncompatibleInfo { reference: "issue #80165 <https://github.com/rust-lang/rust/issues/80165>", - edition: Some(Edition::Edition2021), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), }; } @@ -1676,7 +1663,7 @@ declare_lint! { instead of `crate`, `self`, or an extern crate name", @future_incompatible = FutureIncompatibleInfo { reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>", - edition: Some(Edition::Edition2018), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), }; } @@ -1725,7 +1712,6 @@ declare_lint! { "floating-point literals cannot be used in patterns", @future_incompatible = FutureIncompatibleInfo { reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>", - edition: None, }; } @@ -1769,7 +1755,6 @@ declare_lint! { "detects name collision with an existing but unstable method", @future_incompatible = FutureIncompatibleInfo { reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>", - edition: None, // Note: this item represents future incompatibility of all unstable functions in the // standard library, and thus should never be removed or changed to an error. }; @@ -1873,7 +1858,6 @@ declare_lint! { "checks the object safety of where clauses", @future_incompatible = FutureIncompatibleInfo { reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>", - edition: None, }; } @@ -1940,7 +1924,6 @@ declare_lint! { "detects proc macro derives using inaccessible names from parent modules", @future_incompatible = FutureIncompatibleInfo { reference: "issue #83583 <https://github.com/rust-lang/rust/issues/83583>", - edition: None, }; } @@ -2043,7 +2026,6 @@ declare_lint! { cannot be referred to by absolute paths", @future_incompatible = FutureIncompatibleInfo { reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>", - edition: None, }; crate_level_only } @@ -2134,7 +2116,6 @@ declare_lint! { "constant used in pattern contains value of non-structural-match type in a field or a variant", @future_incompatible = FutureIncompatibleInfo { reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>", - edition: None, }; } @@ -2190,7 +2171,6 @@ declare_lint! { "pointers are not structural-match", @future_incompatible = FutureIncompatibleInfo { reference: "issue #62411 <https://github.com/rust-lang/rust/issues/70861>", - edition: None, }; } @@ -2229,7 +2209,6 @@ declare_lint! { expression contains values of non-structural-match types", @future_incompatible = FutureIncompatibleInfo { reference: "issue #73448 <https://github.com/rust-lang/rust/issues/73448>", - edition: None, }; } @@ -2287,7 +2266,6 @@ declare_lint! { "ambiguous associated items", @future_incompatible = FutureIncompatibleInfo { reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>", - edition: None, }; } @@ -2318,7 +2296,6 @@ declare_lint! { "reservation of a two-phased borrow conflicts with other shared borrows", @future_incompatible = FutureIncompatibleInfo { reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>", - edition: None, }; } @@ -2360,7 +2337,6 @@ declare_lint! { "a feature gate that doesn't break dependent crates", @future_incompatible = FutureIncompatibleInfo { reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>", - edition: None, }; } @@ -2589,7 +2565,6 @@ declare_lint! { "a C-like enum implementing Drop is cast", @future_incompatible = FutureIncompatibleInfo { reference: "issue #73333 <https://github.com/rust-lang/rust/issues/73333>", - edition: None, }; } @@ -2629,7 +2604,6 @@ declare_lint! { "detects a generic constant is used in a type without a emitting a warning", @future_incompatible = FutureIncompatibleInfo { reference: "issue #76200 <https://github.com/rust-lang/rust/issues/76200>", - edition: None, }; } @@ -2688,7 +2662,6 @@ declare_lint! { "uninhabited static", @future_incompatible = FutureIncompatibleInfo { reference: "issue #74840 <https://github.com/rust-lang/rust/issues/74840>", - edition: None, }; } @@ -2758,7 +2731,6 @@ declare_lint! { "unsupported naked function definitions", @future_incompatible = FutureIncompatibleInfo { reference: "issue #32408 <https://github.com/rust-lang/rust/issues/32408>", - edition: None, }; } @@ -2831,7 +2803,6 @@ declare_lint! { "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>", - edition: None, }; } @@ -3154,7 +3125,6 @@ declare_lint! { "detects invalid `#[doc(...)]` attributes", @future_incompatible = FutureIncompatibleInfo { reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>", - edition: None, }; } @@ -3201,7 +3171,6 @@ declare_lint! { "detects usage of old versions of certain proc-macro crates", @future_incompatible = FutureIncompatibleInfo { reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>", - edition: None, future_breakage: Some(FutureBreakage { date: None }) @@ -3242,7 +3211,7 @@ declare_lint! { "detects usage of old versions of or-patterns", @future_incompatible = FutureIncompatibleInfo { reference: "issue #84869 <https://github.com/rust-lang/rust/issues/84869>", - edition: Some(Edition::Edition2021), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), }; } @@ -3280,7 +3249,7 @@ declare_lint! { /// /// In Rust 2021, one of the important introductions is the [prelude changes], which add /// `TryFrom`, `TryInto`, and `FromIterator` into the standard library's prelude. Since this - /// results in an amiguity as to which method/function to call when an existing `try_into` + /// results in an ambiguity as to which method/function to call when an existing `try_into` /// method is called via dot-call syntax or a `try_from`/`from_iter` associated function /// is called directly on a type. /// @@ -3291,6 +3260,6 @@ declare_lint! { prelude in future editions", @future_incompatible = FutureIncompatibleInfo { reference: "issue #85684 <https://github.com/rust-lang/rust/issues/85684>", - edition: Some(Edition::Edition2021), + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index f1c4e5fb4a3..b3d98747dcf 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -142,15 +142,39 @@ pub struct Lint { pub struct FutureIncompatibleInfo { /// e.g., a URL for an issue/PR/RFC or error code pub reference: &'static str, - /// If this is an edition fixing lint, the edition in which - /// this lint becomes obsolete - pub edition: Option<Edition>, + /// The reason for the lint used by diagnostics to provide + /// the right help message + pub reason: FutureIncompatibilityReason, /// Information about a future breakage, which will /// be emitted in JSON messages to be displayed by Cargo /// for upstream deps pub future_breakage: Option<FutureBreakage>, } +/// The reason for future incompatibility +#[derive(Copy, Clone, Debug)] +pub enum FutureIncompatibilityReason { + /// This will be an error in a future release + /// for all editions + FutureReleaseError, + /// Previously accepted code that will become an + /// error in the provided edition + EditionError(Edition), + /// Code that changes meaning in some way in + /// the provided edition + EditionSemanticsChange(Edition), +} + +impl FutureIncompatibilityReason { + pub fn edition(self) -> Option<Edition> { + match self { + Self::EditionError(e) => Some(e), + Self::EditionSemanticsChange(e) => Some(e), + _ => None, + } + } +} + #[derive(Copy, Clone, Debug)] pub struct FutureBreakage { pub date: Option<&'static str>, @@ -158,7 +182,11 @@ pub struct FutureBreakage { impl FutureIncompatibleInfo { pub const fn default_fields_for_macro() -> Self { - FutureIncompatibleInfo { reference: "", edition: None, future_breakage: None } + FutureIncompatibleInfo { + reference: "", + reason: FutureIncompatibilityReason::FutureReleaseError, + future_breakage: None, + } } } diff --git a/compiler/rustc_metadata/src/dynamic_lib.rs b/compiler/rustc_metadata/src/dynamic_lib.rs index 1a900ccbf65..e8929cd5c02 100644 --- a/compiler/rustc_metadata/src/dynamic_lib.rs +++ b/compiler/rustc_metadata/src/dynamic_lib.rs @@ -70,13 +70,12 @@ mod dl { use std::sync::{Mutex, MutexGuard}; pub fn lock() -> MutexGuard<'static, Guard> { - static LOCK: SyncLazy<Mutex<Guard>> = SyncLazy::new(|| Mutex::new(Guard { _priv: () })); + static LOCK: SyncLazy<Mutex<Guard>> = SyncLazy::new(|| Mutex::new(Guard)); LOCK.lock().unwrap() } - pub struct Guard { - _priv: (), - } + #[non_exhaustive] + pub struct Guard; impl Guard { pub fn get(&mut self) -> Result<(), String> { diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 4c7ea937ceb..8180d853f60 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -7,7 +7,7 @@ use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir::HirId; use rustc_session::lint::{ builtin::{self, FORBIDDEN_LINT_GROUPS}, - Level, Lint, LintId, + FutureIncompatibilityReason, Level, Lint, LintId, }; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; @@ -292,7 +292,7 @@ pub fn struct_lint_level<'s, 'd>( // if this lint occurs in the expansion of a macro from an external crate, // allow individual lints to opt-out from being reported. let not_future_incompatible = - future_incompatible.map(|f| f.edition.is_some()).unwrap_or(true); + future_incompatible.map(|f| f.reason.edition().is_some()).unwrap_or(true); if not_future_incompatible && !lint.report_in_external_macro { err.cancel(); // Don't continue further, since we don't want to have @@ -373,9 +373,6 @@ pub fn struct_lint_level<'s, 'd>( err.code(DiagnosticId::Lint { name, has_future_breakage }); if let Some(future_incompatible) = future_incompatible { - const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \ - it will become a hard error"; - let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) { "once this associated item is added to the standard library, the ambiguity may \ cause an error or change in behavior!" @@ -384,10 +381,22 @@ pub fn struct_lint_level<'s, 'd>( "this borrowing pattern was not meant to be accepted, and may become a hard error \ in the future" .to_owned() - } else if let Some(edition) = future_incompatible.edition { - format!("{} in the {} edition!", STANDARD_MESSAGE, edition) + } else if let FutureIncompatibilityReason::EditionError(edition) = + future_incompatible.reason + { + let current_edition = sess.edition(); + format!( + "this is accepted in the current edition (Rust {}) but is a hard error in Rust {}!", + current_edition, edition + ) + } else if let FutureIncompatibilityReason::EditionSemanticsChange(edition) = + future_incompatible.reason + { + format!("this changes meaning in Rust {}", edition) } else { - format!("{} in a future release!", STANDARD_MESSAGE) + "this was previously accepted by the compiler but is being phased out; \ + it will become a hard error in a future release!" + .to_owned() }; let citation = format!("for more information, see {}", future_incompatible.reference); err.warn(&explanation); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a74070100f4..77f955e93b9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -43,7 +43,8 @@ use rustc_hir::definitions::Definitions; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ - Constness, HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate, + Constness, ExprKind, HirId, ImplItemKind, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, + Node, TraitCandidate, TraitItemKind, }; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; @@ -1498,18 +1499,14 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> { - // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`. + // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures. let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); match self.hir().get(hir_id) { - Node::Item(item) => { - match item.kind { - ItemKind::Fn(..) => { /* `type_of_def_id()` will work */ } - _ => { - return None; - } - } - } - _ => { /* `type_of_def_id()` will work or panic */ } + Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {} + Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {} + Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {} + Node::Expr(&hir::Expr { kind: ExprKind::Closure(..), .. }) => {} + _ => return None, } let ret_ty = self.type_of(scope_def_id); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1d9ff512288..5dc5080712e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1370,8 +1370,8 @@ pub type Region<'tcx> = &'tcx RegionKind; /// happen, you can use `leak_check`. This is more clearly explained /// by the [rustc dev guide]. /// -/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ -/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ +/// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ +/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord)] pub enum RegionKind { diff --git a/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs index dded7a7e3cf..0306782bfe4 100644 --- a/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs @@ -1380,7 +1380,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// terms that the "longer free region" `'a` outlived the "shorter free region" `'b`. /// /// More details can be found in this blog post by Niko: - /// <http://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/> + /// <https://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/> /// /// In the canonical example /// diff --git a/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs index 465832c89fd..5c6c158d46e 100644 --- a/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs @@ -24,6 +24,7 @@ fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> { /// discriminant is read from. Otherwise, returns None. fn get_switched_on_type<'tcx>( block_data: &BasicBlockData<'tcx>, + tcx: TyCtxt<'tcx>, body: &Body<'tcx>, ) -> Option<Ty<'tcx>> { let terminator = block_data.terminator(); @@ -36,12 +37,9 @@ fn get_switched_on_type<'tcx>( if let Some(StatementKind::Assign(box (l, Rvalue::Discriminant(place)))) = stmt_before_term { if l.as_local() == Some(local) { - if let Some(r_local) = place.as_local() { - let ty = body.local_decls[r_local].ty; - - if ty.is_enum() { - return Some(ty); - } + let ty = place.ty(body, tcx).ty; + if ty.is_enum() { + return Some(ty); } } } @@ -86,7 +84,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { trace!("processing block {:?}", bb); let discriminant_ty = - if let Some(ty) = get_switched_on_type(&body.basic_blocks()[bb], body) { + if let Some(ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) { ty } else { continue; diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index 40e2e34aa05..3eebc088f3f 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -1,5 +1,5 @@ // Characters and their corresponding confusables were collected from -// http://www.unicode.org/Public/security/10.0.0/confusables.txt +// https://www.unicode.org/Public/security/10.0.0/confusables.txt use super::StringReader; use crate::token; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e85392cf0bd..d0795841c53 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -97,6 +97,7 @@ impl CheckAttrVisitor<'tcx> { | sym::rustc_dirty | sym::rustc_if_this_changed | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr), + sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target), _ => true, }; // lint-only checks @@ -234,6 +235,25 @@ impl CheckAttrVisitor<'tcx> { } } + /// Checks if `#[cmse_nonsecure_entry]` is applied to a function definition. + fn check_cmse_nonsecure_entry(&self, attr: &Attribute, span: &Span, target: Target) -> bool { + match target { + Target::Fn + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + _ => { + self.tcx + .sess + .struct_span_err( + attr.span, + "attribute should be applied to a function definition", + ) + .span_label(*span, "not a function definition") + .emit(); + false + } + } + } + /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid. fn check_track_caller( &self, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index f5dd8992c29..e144c8f168e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1129,6 +1129,8 @@ options! { "link native libraries in the linker invocation (default: yes)"), link_only: bool = (false, parse_bool, [TRACKED], "link the `.rlink` file generated by `-Z no-link` (default: no)"), + llvm_plugins: Vec<String> = (Vec::new(), parse_list, [TRACKED], + "a list LLVM plugins to enable (space separated)"), llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], "generate JSON tracing data file from LLVM data (default: no)"), ls: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_target/src/abi/call/msp430.rs b/compiler/rustc_target/src/abi/call/msp430.rs index 3004bb9ff5d..0ba73657b5b 100644 --- a/compiler/rustc_target/src/abi/call/msp430.rs +++ b/compiler/rustc_target/src/abi/call/msp430.rs @@ -1,5 +1,5 @@ // Reference: MSP430 Embedded Application Binary Interface -// http://www.ti.com/lit/an/slaa534/slaa534.pdf +// https://www.ti.com/lit/an/slaa534a/slaa534a.pdf use crate::abi::call::{ArgAbi, FnAbi}; diff --git a/compiler/rustc_target/src/abi/call/nvptx.rs b/compiler/rustc_target/src/abi/call/nvptx.rs index 693337f0e52..428dd95bbcd 100644 --- a/compiler/rustc_target/src/abi/call/nvptx.rs +++ b/compiler/rustc_target/src/abi/call/nvptx.rs @@ -1,5 +1,5 @@ // Reference: PTX Writer's Guide to Interoperability -// http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability +// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability use crate::abi::call::{ArgAbi, FnAbi}; diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs index b9c9296dbac..16f331b16d5 100644 --- a/compiler/rustc_target/src/abi/call/nvptx64.rs +++ b/compiler/rustc_target/src/abi/call/nvptx64.rs @@ -1,5 +1,5 @@ // Reference: PTX Writer's Guide to Interoperability -// http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability +// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability use crate::abi::call::{ArgAbi, FnAbi}; diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs index 713b4100a33..ff8849e1cf8 100644 --- a/compiler/rustc_target/src/abi/call/x86.rs +++ b/compiler/rustc_target/src/abi/call/x86.rs @@ -38,7 +38,7 @@ where // small structs are returned as integers. // // Some links: - // http://www.angelcode.com/dev/callconv/callconv.html + // https://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let t = cx.target_spec(); if t.abi_return_struct_as_int { diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index e3a721fc736..9a24edf1a42 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -16,7 +16,7 @@ use rustc_span::Span; pub mod call; -/// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout) +/// Parsed [Data layout](https://llvm.org/docs/LangRef.html#data-layout) /// for a target, which contains everything needed to compute layouts. pub struct TargetDataLayout { pub endian: Endian, diff --git a/compiler/rustc_target/src/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs index eaf3a2dbcf8..d00883ae71a 100644 --- a/compiler/rustc_target/src/spec/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs @@ -6,7 +6,7 @@ use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::android_base::opts(); base.max_atomic_width = Some(128); - // As documented in http://developer.android.com/ndk/guides/cpu-features.html + // As documented in https://developer.android.com/ndk/guides/cpu-features.html // the neon (ASIMD) and FP must exist on all android aarch64 targets. base.features = "+neon,+fp-armv8".to_string(); base.supported_sanitizers = SanitizerSet::HWADDRESS; diff --git a/compiler/rustc_target/src/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs index 19d7b3c95cf..640f9e42f4a 100644 --- a/compiler/rustc_target/src/spec/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/i686_linux_android.rs @@ -8,7 +8,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); - // http://developer.android.com/ndk/guides/abis.html#x86 + // https://developer.android.com/ndk/guides/abis.html#x86 base.cpu = "pentiumpro".to_string(); base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".to_string(); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0736ffb52f7..0bf89c3f93b 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -25,7 +25,7 @@ //! //! # Defining a new target //! -//! Targets are defined using [JSON](http://json.org/). The `Target` struct in +//! Targets are defined using [JSON](https://json.org/). The `Target` struct in //! this module defines the format the JSON file should take, though each //! underscore in the field names should be replaced with a hyphen (`-`) in the //! JSON file. Some fields are required in every target specification, such as @@ -950,7 +950,7 @@ pub struct Target { /// Architecture to use for ABI considerations. Valid options include: "x86", /// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others. pub arch: String, - /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. + /// [Data layout](https://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, /// Optional settings with defaults. pub options: TargetOptions, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 39890fd5b05..a838172d664 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -8,7 +8,7 @@ //! ## `Ty` lowering //! Much of the `Ty` lowering is 1:1 with Chalk. (Or will be eventually). A //! helpful table for what types lower to what can be found in the -//! [Chalk book](http://rust-lang.github.io/chalk/book/types/rust_types.html). +//! [Chalk book](https://rust-lang.github.io/chalk/book/types/rust_types.html). //! The most notable difference lies with `Param`s. To convert from rustc to //! Chalk, we eagerly and deeply convert `Param`s to placeholders (in goals) or //! bound variables (for clause generation through functions in `db`). diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 78fa8074a64..ee84974cb73 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -492,7 +492,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { x => tcx.ty_error_with_message( DUMMY_SP, - &format!("unexpected const parent in type_of_def_id(): {:?}", x), + &format!("unexpected const parent in type_of(): {:?}", x), ), } } @@ -504,7 +504,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { }, x => { - bug!("unexpected sort of node in type_of_def_id(): {:?}", x); + bug!("unexpected sort of node in type_of(): {:?}", x); } } } |
