diff --git a/Cargo.lock b/Cargo.lock index d03e1cd743263..73ebc8b4616f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -269,6 +269,7 @@ version = "0.40.0" dependencies = [ "atty", "bytesize", + "cargo-platform", "cargo-test-macro", "cargo-test-support", "clap", @@ -278,7 +279,7 @@ dependencies = [ "crypto-hash", "curl", "curl-sys", - "env_logger", + "env_logger 0.7.0", "failure", "filetime", "flate2", @@ -325,6 +326,13 @@ dependencies = [ "winapi 0.3.6", ] +[[package]] +name = "cargo-platform" +version = "0.1.0" +dependencies = [ + "serde", +] + [[package]] name = "cargo-test-macro" version = "0.1.0" @@ -526,7 +534,7 @@ name = "compiletest" version = "0.0.0" dependencies = [ "diff", - "env_logger", + "env_logger 0.6.2", "getopts", "lazy_static 1.3.0", "libc", @@ -938,6 +946,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ecdb7dd54465526f0a56d666e3b2dd5f3a218665a030b6e4ad9e70fa95d8fa" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "error-chain" version = "0.12.0" @@ -1339,9 +1360,9 @@ checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" [[package]] name = "humantime" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ "quick-error", ] @@ -1866,7 +1887,7 @@ dependencies = [ "chrono", "clap", "elasticlunr-rs", - "env_logger", + "env_logger 0.6.2", "error-chain", "handlebars", "itertools 0.8.0", @@ -1891,7 +1912,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77d1f0ba4d1e6b86fa18e8853d026d7d76a97eb7eb5eb052ed80901e43b7fc10" dependencies = [ - "env_logger", + "env_logger 0.6.2", "failure", "log", "mdbook", @@ -2084,7 +2105,7 @@ dependencies = [ "colored", "compiletest_rs", "directories", - "env_logger", + "env_logger 0.6.2", "getrandom", "hex 0.3.2", "log", @@ -2493,7 +2514,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" dependencies = [ "chrono", - "env_logger", + "env_logger 0.6.2", "log", ] @@ -2620,7 +2641,7 @@ dependencies = [ "bitflags", "clap", "derive_more", - "env_logger", + "env_logger 0.6.2", "humantime", "lazy_static 1.3.0", "log", @@ -2914,7 +2935,7 @@ dependencies = [ "clippy_lints", "crossbeam-channel", "difference", - "env_logger", + "env_logger 0.6.2", "failure", "futures", "heck", @@ -2998,7 +3019,7 @@ name = "rls-rustc" version = "0.6.0" dependencies = [ "clippy_lints", - "env_logger", + "env_logger 0.6.2", "failure", "futures", "log", @@ -3399,7 +3420,7 @@ dependencies = [ name = "rustc_driver" version = "0.0.0" dependencies = [ - "env_logger", + "env_logger 0.6.2", "graphviz", "lazy_static 1.3.0", "log", @@ -3781,7 +3802,7 @@ dependencies = [ "derive-new", "diff", "dirs", - "env_logger", + "env_logger 0.6.2", "failure", "getopts", "ignore", diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f6b872623d789..1e05018007a8d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2184,9 +2184,7 @@ impl<'a> LoweringContext<'a> { match decl.output { FunctionRetTy::Ty(ref ty) => match in_band_ty_params { Some((def_id, _)) if impl_trait_return_allow => { - hir::Return(self.lower_ty(ty, - ImplTraitContext::OpaqueTy(Some(def_id)) - )) + hir::Return(self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(def_id)))) } _ => { hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed())) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index c9fd3392a962d..129cfc8bcb23f 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -988,7 +988,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { value.fold_with(&mut BottomUpFolder { tcx, ty_op: |ty| { - if let ty::Opaque(def_id, substs) = ty.sty { + if ty.references_error() { + return tcx.types.err; + } else if let ty::Opaque(def_id, substs) = ty.sty { // Check that this is `impl Trait` type is // declared by `parent_def_id` -- i.e., one whose // value we are inferring. At present, this is @@ -1155,6 +1157,15 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { ); debug!("instantiate_opaque_types: ty_var={:?}", ty_var); + for predicate in &bounds.predicates { + if let ty::Predicate::Projection(projection) = &predicate { + if projection.skip_binder().ty.references_error() { + // No point on adding these obligations since there's a type error involved. + return ty_var; + } + } + } + self.obligations.reserve(bounds.predicates.len()); for predicate in bounds.predicates { // Change the predicate to refer to the type variable, diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 96b99fe4cdce2..8b2bf55ccc120 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -1,64 +1,10 @@ -//! Resolution of mixing rlibs and dylibs +//! Type definitions for learning about the dependency formats of all upstream +//! crates (rlibs/dylibs/oh my). //! -//! When producing a final artifact, such as a dynamic library, the compiler has -//! a choice between linking an rlib or linking a dylib of all upstream -//! dependencies. The linking phase must guarantee, however, that a library only -//! show up once in the object file. For example, it is illegal for library A to -//! be statically linked to B and C in separate dylibs, and then link B and C -//! into a crate D (because library A appears twice). -//! -//! The job of this module is to calculate what format each upstream crate -//! should be used when linking each output type requested in this session. This -//! generally follows this set of rules: -//! -//! 1. Each library must appear exactly once in the output. -//! 2. Each rlib contains only one library (it's just an object file) -//! 3. Each dylib can contain more than one library (due to static linking), -//! and can also bring in many dynamic dependencies. -//! -//! With these constraints in mind, it's generally a very difficult problem to -//! find a solution that's not "all rlibs" or "all dylibs". I have suspicions -//! that NP-ness may come into the picture here... -//! -//! The current selection algorithm below looks mostly similar to: -//! -//! 1. If static linking is required, then require all upstream dependencies -//! to be available as rlibs. If not, generate an error. -//! 2. If static linking is requested (generating an executable), then -//! attempt to use all upstream dependencies as rlibs. If any are not -//! found, bail out and continue to step 3. -//! 3. Static linking has failed, at least one library must be dynamically -//! linked. Apply a heuristic by greedily maximizing the number of -//! dynamically linked libraries. -//! 4. Each upstream dependency available as a dynamic library is -//! registered. The dependencies all propagate, adding to a map. It is -//! possible for a dylib to add a static library as a dependency, but it -//! is illegal for two dylibs to add the same static library as a -//! dependency. The same dylib can be added twice. Additionally, it is -//! illegal to add a static dependency when it was previously found as a -//! dylib (and vice versa) -//! 5. After all dynamic dependencies have been traversed, re-traverse the -//! remaining dependencies and add them statically (if they haven't been -//! added already). -//! -//! While not perfect, this algorithm should help support use-cases such as leaf -//! dependencies being static while the larger tree of inner dependencies are -//! all dynamic. This isn't currently very well battle tested, so it will likely -//! fall short in some use cases. -//! -//! Currently, there is no way to specify the preference of linkage with a -//! particular library (other than a global dynamic/static switch). -//! Additionally, the algorithm is geared towards finding *any* solution rather -//! than finding a number of solutions (there are normally quite a few). - -use crate::hir::def_id::CrateNum; +//! For all the gory details, see the provider of the `dependency_formats` +//! query. use crate::session::config; -use crate::ty::TyCtxt; -use crate::middle::cstore::{self, DepKind}; -use crate::middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; -use crate::util::nodemap::FxHashMap; -use rustc_target::spec::PanicStrategy; /// A list of dependencies for a certain crate type. /// @@ -71,324 +17,12 @@ pub type DependencyList = Vec; /// A mapping of all required dependencies for a particular flavor of output. /// /// This is local to the tcx, and is generally relevant to one session. -pub type Dependencies = FxHashMap; +pub type Dependencies = Vec<(config::CrateType, DependencyList)>; -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Debug, HashStable)] pub enum Linkage { NotLinked, IncludedFromDylib, Static, Dynamic, } - -pub fn calculate(tcx: TyCtxt<'_>) { - let sess = &tcx.sess; - let fmts = sess.crate_types.borrow().iter().map(|&ty| { - let linkage = calculate_type(tcx, ty); - verify_ok(tcx, &linkage); - (ty, linkage) - }).collect::>(); - sess.abort_if_errors(); - sess.dependency_formats.set(fmts); -} - -fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { - let sess = &tcx.sess; - - if !sess.opts.output_types.should_codegen() { - return Vec::new(); - } - - let preferred_linkage = match ty { - // cdylibs must have all static dependencies. - config::CrateType::Cdylib => Linkage::Static, - - // Generating a dylib without `-C prefer-dynamic` means that we're going - // to try to eagerly statically link all dependencies. This is normally - // done for end-product dylibs, not intermediate products. - config::CrateType::Dylib if !sess.opts.cg.prefer_dynamic => Linkage::Static, - config::CrateType::Dylib => Linkage::Dynamic, - - // If the global prefer_dynamic switch is turned off, or the final - // executable will be statically linked, prefer static crate linkage. - config::CrateType::Executable if !sess.opts.cg.prefer_dynamic || - sess.crt_static() => Linkage::Static, - config::CrateType::Executable => Linkage::Dynamic, - - // proc-macro crates are mostly cdylibs, but we also need metadata. - config::CrateType::ProcMacro => Linkage::Static, - - // No linkage happens with rlibs, we just needed the metadata (which we - // got long ago), so don't bother with anything. - config::CrateType::Rlib => Linkage::NotLinked, - - // staticlibs must have all static dependencies. - config::CrateType::Staticlib => Linkage::Static, - }; - - if preferred_linkage == Linkage::NotLinked { - // If the crate is not linked, there are no link-time dependencies. - return Vec::new(); - } - - if preferred_linkage == Linkage::Static { - // Attempt static linkage first. For dylibs and executables, we may be - // able to retry below with dynamic linkage. - if let Some(v) = attempt_static(tcx) { - return v; - } - - // Staticlibs, cdylibs, and static executables must have all static - // dependencies. If any are not found, generate some nice pretty errors. - if ty == config::CrateType::Cdylib || ty == config::CrateType::Staticlib || - (ty == config::CrateType::Executable && sess.crt_static() && - !sess.target.target.options.crt_static_allows_dylibs) { - for &cnum in tcx.crates().iter() { - if tcx.dep_kind(cnum).macros_only() { continue } - let src = tcx.used_crate_source(cnum); - if src.rlib.is_some() { continue } - sess.err(&format!("crate `{}` required to be available in rlib format, \ - but was not found in this form", - tcx.crate_name(cnum))); - } - return Vec::new(); - } - } - - let mut formats = FxHashMap::default(); - - // Sweep all crates for found dylibs. Add all dylibs, as well as their - // dependencies, ensuring there are no conflicts. The only valid case for a - // dependency to be relied upon twice is for both cases to rely on a dylib. - for &cnum in tcx.crates().iter() { - if tcx.dep_kind(cnum).macros_only() { continue } - let name = tcx.crate_name(cnum); - let src = tcx.used_crate_source(cnum); - if src.dylib.is_some() { - info!("adding dylib: {}", name); - add_library(tcx, cnum, RequireDynamic, &mut formats); - let deps = tcx.dylib_dependency_formats(cnum); - for &(depnum, style) in deps.iter() { - info!("adding {:?}: {}", style, tcx.crate_name(depnum)); - add_library(tcx, depnum, style, &mut formats); - } - } - } - - // Collect what we've got so far in the return vector. - let last_crate = tcx.crates().len(); - let mut ret = (1..last_crate+1).map(|cnum| { - match formats.get(&CrateNum::new(cnum)) { - Some(&RequireDynamic) => Linkage::Dynamic, - Some(&RequireStatic) => Linkage::IncludedFromDylib, - None => Linkage::NotLinked, - } - }).collect::>(); - - // Run through the dependency list again, and add any missing libraries as - // static libraries. - // - // If the crate hasn't been included yet and it's not actually required - // (e.g., it's an allocator) then we skip it here as well. - for &cnum in tcx.crates().iter() { - let src = tcx.used_crate_source(cnum); - if src.dylib.is_none() && - !formats.contains_key(&cnum) && - tcx.dep_kind(cnum) == DepKind::Explicit { - assert!(src.rlib.is_some() || src.rmeta.is_some()); - info!("adding staticlib: {}", tcx.crate_name(cnum)); - add_library(tcx, cnum, RequireStatic, &mut formats); - ret[cnum.as_usize() - 1] = Linkage::Static; - } - } - - // We've gotten this far because we're emitting some form of a final - // artifact which means that we may need to inject dependencies of some - // form. - // - // Things like allocators and panic runtimes may not have been activated - // quite yet, so do so here. - activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret, - &|cnum| tcx.is_panic_runtime(cnum)); - - // When dylib B links to dylib A, then when using B we must also link to A. - // It could be the case, however, that the rlib for A is present (hence we - // found metadata), but the dylib for A has since been removed. - // - // For situations like this, we perform one last pass over the dependencies, - // making sure that everything is available in the requested format. - for (cnum, kind) in ret.iter().enumerate() { - let cnum = CrateNum::new(cnum + 1); - let src = tcx.used_crate_source(cnum); - match *kind { - Linkage::NotLinked | - Linkage::IncludedFromDylib => {} - Linkage::Static if src.rlib.is_some() => continue, - Linkage::Dynamic if src.dylib.is_some() => continue, - kind => { - let kind = match kind { - Linkage::Static => "rlib", - _ => "dylib", - }; - sess.err(&format!("crate `{}` required to be available in {} format, \ - but was not found in this form", - tcx.crate_name(cnum), kind)); - } - } - } - - ret -} - -fn add_library( - tcx: TyCtxt<'_>, - cnum: CrateNum, - link: LinkagePreference, - m: &mut FxHashMap, -) { - match m.get(&cnum) { - Some(&link2) => { - // If the linkages differ, then we'd have two copies of the library - // if we continued linking. If the linkages are both static, then we - // would also have two copies of the library (static from two - // different locations). - // - // This error is probably a little obscure, but I imagine that it - // can be refined over time. - if link2 != link || link == RequireStatic { - tcx.sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \ - shows up once", tcx.crate_name(cnum))) - .help("having upstream crates all available in one format \ - will likely make this go away") - .emit(); - } - } - None => { m.insert(cnum, link); } - } -} - -fn attempt_static(tcx: TyCtxt<'_>) -> Option { - let sess = &tcx.sess; - let crates = cstore::used_crates(tcx, RequireStatic); - if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) { - return None - } - - // All crates are available in an rlib format, so we're just going to link - // everything in explicitly so long as it's actually required. - let last_crate = tcx.crates().len(); - let mut ret = (1..last_crate+1).map(|cnum| { - if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit { - Linkage::Static - } else { - Linkage::NotLinked - } - }).collect::>(); - - // Our allocator/panic runtime may not have been linked above if it wasn't - // explicitly linked, which is the case for any injected dependency. Handle - // that here and activate them. - activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret, - &|cnum| tcx.is_panic_runtime(cnum)); - - Some(ret) -} - -// Given a list of how to link upstream dependencies so far, ensure that an -// injected dependency is activated. This will not do anything if one was -// transitively included already (e.g., via a dylib or explicitly so). -// -// If an injected dependency was not found then we're guaranteed the -// metadata::creader module has injected that dependency (not listed as -// a required dependency) in one of the session's field. If this field is not -// set then this compilation doesn't actually need the dependency and we can -// also skip this step entirely. -fn activate_injected_dep(injected: Option, - list: &mut DependencyList, - replaces_injected: &dyn Fn(CrateNum) -> bool) { - for (i, slot) in list.iter().enumerate() { - let cnum = CrateNum::new(i + 1); - if !replaces_injected(cnum) { - continue - } - if *slot != Linkage::NotLinked { - return - } - } - if let Some(injected) = injected { - let idx = injected.as_usize() - 1; - assert_eq!(list[idx], Linkage::NotLinked); - list[idx] = Linkage::Static; - } -} - -// After the linkage for a crate has been determined we need to verify that -// there's only going to be one allocator in the output. -fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { - let sess = &tcx.sess; - if list.len() == 0 { - return - } - let mut panic_runtime = None; - for (i, linkage) in list.iter().enumerate() { - if let Linkage::NotLinked = *linkage { - continue - } - let cnum = CrateNum::new(i + 1); - - if tcx.is_panic_runtime(cnum) { - if let Some((prev, _)) = panic_runtime { - let prev_name = tcx.crate_name(prev); - let cur_name = tcx.crate_name(cnum); - sess.err(&format!("cannot link together two \ - panic runtimes: {} and {}", - prev_name, cur_name)); - } - panic_runtime = Some((cnum, tcx.panic_strategy(cnum))); - } - } - - // If we found a panic runtime, then we know by this point that it's the - // only one, but we perform validation here that all the panic strategy - // compilation modes for the whole DAG are valid. - if let Some((cnum, found_strategy)) = panic_runtime { - let desired_strategy = sess.panic_strategy(); - - // First up, validate that our selected panic runtime is indeed exactly - // our same strategy. - if found_strategy != desired_strategy { - sess.err(&format!("the linked panic runtime `{}` is \ - not compiled with this crate's \ - panic strategy `{}`", - tcx.crate_name(cnum), - desired_strategy.desc())); - } - - // Next up, verify that all other crates are compatible with this panic - // strategy. If the dep isn't linked, we ignore it, and if our strategy - // is abort then it's compatible with everything. Otherwise all crates' - // panic strategy must match our own. - for (i, linkage) in list.iter().enumerate() { - if let Linkage::NotLinked = *linkage { - continue - } - if desired_strategy == PanicStrategy::Abort { - continue - } - let cnum = CrateNum::new(i + 1); - let found_strategy = tcx.panic_strategy(cnum); - let is_compiler_builtins = tcx.is_compiler_builtins(cnum); - if is_compiler_builtins || desired_strategy == found_strategy { - continue - } - - sess.err(&format!("the crate `{}` is compiled with the \ - panic strategy `{}` which is \ - incompatible with this crate's \ - strategy of `{}`", - tcx.crate_name(cnum), - found_strategy.desc(), - desired_strategy.desc())); - } - } -} diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index c7260945295a6..6cd1be460d7c6 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -244,6 +244,10 @@ rustc_queries! { desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) } } + query asyncness(key: DefId) -> hir::IsAsync { + desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) } + } + /// Returns `true` if calls to the function may be promoted. /// /// This is either because the function is e.g., a tuple-struct or tuple-variant @@ -630,6 +634,12 @@ rustc_queries! { -> &'tcx [(CrateNum, LinkagePreference)] { desc { "dylib dependency formats of crate" } } + + query dependency_formats(_: CrateNum) + -> Lrc + { + desc { "get the linkage format of all dependencies" } + } } Codegen { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5eda3df378126..a9a20a924347c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -687,7 +687,7 @@ pub enum EntryFnType { impl_stable_hash_via_hash!(EntryFnType); -#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)] +#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, HashStable)] pub enum CrateType { Executable, Dylib, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 49342d95fdb03..8e9c2735c3913 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fingerprint::Fingerprint; use crate::lint; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::middle::dependency_format; use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath}; use crate::session::search_paths::{PathKind, SearchPath}; use crate::util::nodemap::{FxHashMap, FxHashSet}; @@ -91,7 +90,6 @@ pub struct Session { pub plugin_llvm_passes: OneThread>>, pub plugin_attributes: Lock>, pub crate_types: Once>, - pub dependency_formats: Once, /// The `crate_disambiguator` is constructed out of all the `-C metadata` /// arguments passed to the compiler. Its value together with the crate-name /// forms a unique global identifier for the crate. It is used to allow @@ -1248,7 +1246,6 @@ fn build_session_( plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), plugin_attributes: Lock::new(Vec::new()), crate_types: Once::new(), - dependency_formats: Once::new(), crate_disambiguator: Once::new(), features: Once::new(), recursion_limit: Once::new(), diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index aff866fa76d5f..08fea75739978 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1432,8 +1432,11 @@ impl<'tcx> TyCtxt<'tcx> { } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>, - body_id: Option) { + fn maybe_report_ambiguity( + &self, + obligation: &PredicateObligation<'tcx>, + body_id: Option, + ) { // Unable to successfully determine, probably means // insufficient type information, but could mean // ambiguous impls. The latter *ought* to be a @@ -1442,9 +1445,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let predicate = self.resolve_vars_if_possible(&obligation.predicate); let span = obligation.cause.span; - debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})", - predicate, - obligation); + debug!( + "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})", + predicate, + obligation, + body_id, + obligation.cause.code, + ); // Ambiguity errors are often caused as fallout from earlier // errors. So just ignore them if this infcx is tainted. @@ -1456,6 +1463,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::Predicate::Trait(ref data) => { let trait_ref = data.to_poly_trait_ref(); let self_ty = trait_ref.self_ty(); + debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.sty, trait_ref); + if predicate.references_error() { return; } @@ -1480,24 +1489,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // be ignoring the fact that we don't KNOW the type works // out. Though even that would probably be harmless, given that // we're only talking about builtin traits, which are known to be - // inhabited. But in any case I just threw in this check for - // has_errors() to be sure that compilation isn't happening - // anyway. In that case, why inundate the user. - if !self.tcx.sess.has_errors() { - if - self.tcx.lang_items().sized_trait() - .map_or(false, |sized_id| sized_id == trait_ref.def_id()) - { - self.need_type_info_err(body_id, span, self_ty).emit(); - } else { - let mut err = struct_span_err!(self.tcx.sess, - span, E0283, - "type annotations required: \ - cannot resolve `{}`", - predicate); - self.note_obligation_cause(&mut err, obligation); - err.emit(); - } + // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // avoid inundating the user with unnecessary errors, but we now + // check upstream for type errors and dont add the obligations to + // begin with in those cases. + if + self.tcx.lang_items().sized_trait() + .map_or(false, |sized_id| sized_id == trait_ref.def_id()) + { + self.need_type_info_err(body_id, span, self_ty).emit(); + } else { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0283, + "type annotations needed: cannot resolve `{}`", + predicate, + ); + self.note_obligation_cause(&mut err, obligation); + err.emit(); } } @@ -1524,11 +1534,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => { if !self.tcx.sess.has_errors() { - let mut err = struct_span_err!(self.tcx.sess, - obligation.cause.span, E0284, - "type annotations required: \ - cannot resolve `{}`", - predicate); + let mut err = struct_span_err!( + self.tcx.sess, + obligation.cause.span, + E0284, + "type annotations needed: cannot resolve `{}`", + predicate, + ); self.note_obligation_cause(&mut err, obligation); err.emit(); } @@ -1766,7 +1778,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { but not on the corresponding trait method", predicate)); } - ObligationCauseCode::ReturnType(_) | + ObligationCauseCode::ReturnType | + ObligationCauseCode::ReturnValue(_) | ObligationCauseCode::BlockTailExpression(_) => (), ObligationCauseCode::TrivialBound => { err.help("see issue #48214"); diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 1123422ad6008..accbbe3643ea1 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -212,14 +212,14 @@ pub enum ObligationCauseCode<'tcx> { /// Constant expressions must be sized. ConstSized, - /// static items must have `Sync` type + /// Static items must have `Sync` type SharedStatic, BuiltinDerivedObligation(DerivedObligationCause<'tcx>), ImplDerivedObligation(DerivedObligationCause<'tcx>), - /// error derived when matching traits/impls; see ObligationCause for more details + /// Error derived when matching traits/impls; see ObligationCause for more details CompareImplMethodObligation { item_name: ast::Name, impl_item_def_id: DefId, @@ -248,17 +248,20 @@ pub enum ObligationCauseCode<'tcx> { /// `start` has wrong type StartFunctionType, - /// intrinsic has wrong type + /// Intrinsic has wrong type IntrinsicType, - /// method receiver + /// Method receiver MethodReceiver, /// `return` with no expression ReturnNoExpression, /// `return` with an expression - ReturnType(hir::HirId), + ReturnValue(hir::HirId), + + /// Return type of this function + ReturnType, /// Block implicit return BlockTailExpression(hir::HirId), diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index a54bc05f16961..386a5677f5f17 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -214,7 +214,7 @@ pub struct SelectionCache<'tcx> { /// of type variables - it just means the obligation isn't sufficiently /// elaborated. In that case we report an ambiguity, and the caller can /// try again after more type information has been gathered or report a -/// "type annotations required" error. +/// "type annotations needed" error. /// /// However, with type parameters, this can be a real problem - type /// parameters don't unify with regular types, but they *can* unify diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 68c97226f89cf..c0d8230999dd8 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -485,7 +485,8 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { super::TupleInitializerSized => Some(super::TupleInitializerSized), super::StructInitializerSized => Some(super::StructInitializerSized), super::VariableType(id) => Some(super::VariableType(id)), - super::ReturnType(id) => Some(super::ReturnType(id)), + super::ReturnValue(id) => Some(super::ReturnValue(id)), + super::ReturnType => Some(super::ReturnType), super::SizedArgumentType => Some(super::SizedArgumentType), super::SizedReturnType => Some(super::SizedReturnType), super::SizedYieldType => Some(super::SizedYieldType), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0155803e30580..c03dbb2b1ed0e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1510,9 +1510,9 @@ impl<'tcx> TyCtxt<'tcx> { CrateType::Executable | CrateType::Staticlib | CrateType::ProcMacro | + CrateType::Dylib | CrateType::Cdylib => false, - CrateType::Rlib | - CrateType::Dylib => true, + CrateType::Rlib => true, } }) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 8bb9648e031ef..ef8bdfb583edf 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -438,7 +438,7 @@ bitflags! { /// `true` if there are "names" of types and regions and so forth /// that are local to a particular fn - const HAS_FREE_LOCAL_NAMES = 1 << 9; + const HAS_FREE_LOCAL_NAMES = 1 << 9; /// Present if the type belongs in a local type context. /// Only set for Infer other than Fresh. @@ -446,11 +446,11 @@ bitflags! { /// Does this have any `ReLateBound` regions? Used to check /// if a global bound is safe to evaluate. - const HAS_RE_LATE_BOUND = 1 << 11; + const HAS_RE_LATE_BOUND = 1 << 11; const HAS_TY_PLACEHOLDER = 1 << 12; - const HAS_CT_INFER = 1 << 13; + const HAS_CT_INFER = 1 << 13; const HAS_CT_PLACEHOLDER = 1 << 14; const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | @@ -3353,6 +3353,22 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { } } +/// Check if a function is async. +fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(|| { + bug!("asyncness: expected local `DefId`, got `{:?}`", def_id) + }); + + let node = tcx.hir().get(hir_id); + + let fn_like = hir::map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| { + bug!("asyncness: expected fn-like node but got `{:?}`", def_id); + }); + + fn_like.asyncness() +} + + pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); erase_regions::provide(providers); @@ -3360,6 +3376,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { util::provide(providers); constness::provide(providers); *providers = ty::query::Providers { + asyncness, associated_item, associated_item_def_ids, adt_sized_constraint, diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 9b044d9b45377..3b7ae5e33d5e7 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -219,15 +219,24 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB (linker.to_path_buf(), cmd) } -pub fn each_linked_rlib(sess: &Session, - info: &CrateInfo, - f: &mut dyn FnMut(CrateNum, &Path)) -> Result<(), String> { +pub fn each_linked_rlib( + info: &CrateInfo, + f: &mut dyn FnMut(CrateNum, &Path), +) -> Result<(), String> { let crates = info.used_crates_static.iter(); - let fmts = sess.dependency_formats.borrow(); - let fmts = fmts.get(&config::CrateType::Executable) - .or_else(|| fmts.get(&config::CrateType::Staticlib)) - .or_else(|| fmts.get(&config::CrateType::Cdylib)) - .or_else(|| fmts.get(&config::CrateType::ProcMacro)); + let mut fmts = None; + for (ty, list) in info.dependency_formats.iter() { + match ty { + config::CrateType::Executable | + config::CrateType::Staticlib | + config::CrateType::Cdylib | + config::CrateType::ProcMacro => { + fmts = Some(list); + break; + } + _ => {} + } + } let fmts = match fmts { Some(f) => f, None => return Err("could not find formats for rlibs".to_string()) @@ -406,7 +415,7 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, tempdir); let mut all_native_libs = vec![]; - let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| { + let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| { let name = &codegen_results.crate_info.crate_name[&cnum]; let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; @@ -1294,11 +1303,13 @@ pub fn add_local_native_libraries(cmd: &mut dyn Linker, // Rust crates are not considered at all when creating an rlib output. All // dependencies will be linked when producing the final output (instead of // the intermediate rlib version) -fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, - sess: &'a Session, - codegen_results: &CodegenResults, - crate_type: config::CrateType, - tmpdir: &Path) { +fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( + cmd: &mut dyn Linker, + sess: &'a Session, + codegen_results: &CodegenResults, + crate_type: config::CrateType, + tmpdir: &Path, +) { // All of the heavy lifting has previously been accomplished by the // dependency_format module of the compiler. This is just crawling the // output of that module, adding crates as necessary. @@ -1307,8 +1318,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // will slurp up the object files inside), and linking to a dynamic library // involves just passing the right -l flag. - let formats = sess.dependency_formats.borrow(); - let data = formats.get(&crate_type).unwrap(); + let (_, data) = codegen_results.crate_info.dependency_formats + .iter() + .find(|(ty, _)| *ty == crate_type) + .expect("failed to find crate type in dependency format list"); // Invoke get_used_crates to ensure that we get a topological sorting of // crates. @@ -1620,10 +1633,12 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // generic function calls a native function, then the generic function must // be instantiated in the target crate, meaning that the native symbol must // also be resolved in the target crate. -pub fn add_upstream_native_libraries(cmd: &mut dyn Linker, - sess: &Session, - codegen_results: &CodegenResults, - crate_type: config::CrateType) { +pub fn add_upstream_native_libraries( + cmd: &mut dyn Linker, + sess: &Session, + codegen_results: &CodegenResults, + crate_type: config::CrateType, +) { // Be sure to use a topological sorting of crates because there may be // interdependencies between native libraries. When passing -nodefaultlibs, // for example, almost all native libraries depend on libc, so we have to @@ -1633,8 +1648,10 @@ pub fn add_upstream_native_libraries(cmd: &mut dyn Linker, // This passes RequireStatic, but the actual requirement doesn't matter, // we're just getting an ordering of crate numbers, we're not worried about // the paths. - let formats = sess.dependency_formats.borrow(); - let data = formats.get(&crate_type).unwrap(); + let (_, data) = codegen_results.crate_info.dependency_formats + .iter() + .find(|(ty, _)| *ty == crate_type) + .expect("failed to find crate type in dependency format list"); let crates = &codegen_results.crate_info.used_crates_static; for &(cnum, _) in crates { diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index c42cd024926dc..ff87f0b1547ce 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -14,6 +14,7 @@ use rustc::middle::dependency_format::Linkage; use rustc::session::Session; use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, LinkerPluginLto, Lto}; +use rustc::middle::exported_symbols::ExportedSymbol; use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; use rustc_serialize::{json, Encoder}; @@ -1092,18 +1093,41 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { } } - let formats = tcx.sess.dependency_formats.borrow(); - let deps = formats[&crate_type].iter(); + let formats = tcx.dependency_formats(LOCAL_CRATE); + let deps = formats.iter().filter_map(|(t, list)| { + if *t == crate_type { + Some(list) + } else { + None + } + }).next().unwrap(); - for (index, dep_format) in deps.enumerate() { + for (index, dep_format) in deps.iter().enumerate() { let cnum = CrateNum::new(index + 1); // For each dependency that we are linking to statically ... if *dep_format == Linkage::Static { // ... we add its symbol list to our export list. for &(symbol, level) in tcx.exported_symbols(cnum).iter() { - if level.is_below_threshold(export_threshold) { - symbols.push(symbol.symbol_name(tcx).to_string()); + if !level.is_below_threshold(export_threshold) { + continue; } + + // Do not export generic symbols from upstream crates in linked + // artifact (notably the `dylib` crate type). The main reason + // for this is that `symbol_name` is actually wrong for generic + // symbols because it guesses the name we'd give them locally + // rather than the name it has upstream (depending on + // `share_generics` settings and such). + // + // To fix that issue we just say that linked artifacts, aka + // `dylib`s, never export generic symbols and they aren't + // available to downstream crates. (the not available part is + // handled elsewhere). + if let ExportedSymbol::Generic(..) = symbol { + continue; + } + + symbols.push(symbol.symbol_name(tcx).to_string()); } } } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 7e700e6819426..3e4b7695447c8 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -298,7 +298,7 @@ fn upstream_monomorphizations_provider( }; for &cnum in cnums.iter() { - for &(ref exported_symbol, _) in tcx.exported_symbols(cnum).iter() { + for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() { if let &ExportedSymbol::Generic(def_id, substs) = exported_symbol { let substs_map = instances.entry(def_id).or_default(); diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 1bba479c1fd5d..1a2c23ae0d4f7 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1048,7 +1048,7 @@ fn start_executing_work( }).expect("failed to spawn helper thread"); let mut each_linked_rlib_for_lto = Vec::new(); - drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| { + drop(link::each_linked_rlib(crate_info, &mut |cnum, path| { if link::ignored_for_lto(sess, crate_info, cnum) { return } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 4acbe0356b47c..98d3022a4185d 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -539,7 +539,7 @@ pub fn codegen_crate( // linkage, then it's already got an allocator shim and we'll be using that // one instead. If nothing exists then it's our job to generate the // allocator! - let any_dynamic_crate = tcx.sess.dependency_formats.borrow() + let any_dynamic_crate = tcx.dependency_formats(LOCAL_CRATE) .iter() .any(|(_, list)| { use rustc::middle::dependency_format::Linkage; @@ -731,6 +731,7 @@ impl CrateInfo { used_crate_source: Default::default(), lang_item_to_crate: Default::default(), missing_lang_items: Default::default(), + dependency_formats: tcx.dependency_formats(LOCAL_CRATE), }; let lang_items = tcx.lang_items(); diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 1708d7235b45b..161d3ce61f0a6 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -33,6 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::svh::Svh; use rustc::middle::cstore::{LibSource, CrateSource, NativeLibrary}; +use rustc::middle::dependency_format::Dependencies; use syntax_pos::symbol::Symbol; mod error_codes; @@ -142,6 +143,7 @@ pub struct CrateInfo { pub used_crates_dynamic: Vec<(CrateNum, LibSource)>, pub lang_item_to_crate: FxHashMap, pub missing_lang_items: FxHashMap>, + pub dependency_formats: Lrc, } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 33de518c59675..56db695f25411 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -1075,10 +1075,6 @@ pub fn start_codegen<'tcx>( tcx.print_debug_stats(); } - time(tcx.sess, "resolving dependency formats", || { - middle::dependency_format::calculate(tcx) - }); - let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding and writing", || { encode_and_write_metadata(tcx, outputs) }); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index a1e3bbcbf8ea9..11121ee875dda 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -10,6 +10,7 @@ use rustc::middle::cstore::{CrateStore, DepKind, EncodedMetadata, NativeLibraryKind}; use rustc::middle::exported_symbols::ExportedSymbol; use rustc::middle::stability::DeprecationEntry; +use rustc::middle::dependency_format::Linkage; use rustc::hir::def; use rustc::hir; use rustc::session::{CrateDisambiguator, Session}; @@ -133,6 +134,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, fn_sig => { cdata.fn_sig(def_id.index, tcx) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) } + asyncness => { cdata.asyncness(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } static_mutability => { cdata.static_mutability(def_id.index) } def_kind => { cdata.def_kind(def_id.index) } @@ -239,7 +241,30 @@ provide! { <'tcx> tcx, def_id, other, cdata, used_crate_source => { Lrc::new(cdata.source.clone()) } - exported_symbols => { Arc::new(cdata.exported_symbols(tcx)) } + exported_symbols => { + let mut syms = cdata.exported_symbols(tcx); + + // When linked into a dylib crates don't export their generic symbols, + // so if that's happening then we can't load upstream monomorphizations + // from this crate. + let formats = tcx.dependency_formats(LOCAL_CRATE); + let remove_generics = formats.iter().any(|(_ty, list)| { + match list.get(def_id.krate.as_usize() - 1) { + Some(Linkage::IncludedFromDylib) | Some(Linkage::Dynamic) => true, + _ => false, + } + }); + if remove_generics { + syms.retain(|(sym, _threshold)| { + match sym { + ExportedSymbol::Generic(..) => false, + _ => return true, + } + }); + } + + Arc::new(syms) + } } pub fn provide(providers: &mut Providers<'_>) { @@ -370,6 +395,11 @@ pub fn provide(providers: &mut Providers<'_>) { tcx.arena.alloc(visible_parent_map) }, + dependency_formats: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + Lrc::new(crate::dependency_format::calculate(tcx)) + }, + ..*providers }; } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 34c84b1d79d4b..247748eb3eba5 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1212,6 +1212,15 @@ impl<'a, 'tcx> CrateMetadata { constness == hir::Constness::Const } + pub fn asyncness(&self, id: DefIndex) -> hir::IsAsync { + match self.entry(id).kind { + EntryKind::Fn(data) => data.decode(self).asyncness, + EntryKind::Method(data) => data.decode(self).fn_data.asyncness, + EntryKind::ForeignFn(data) => data.decode(self).asyncness, + _ => bug!("asyncness: expect functions entry."), + } + } + pub fn is_foreign_item(&self, id: DefIndex) -> bool { match self.entry(id).kind { EntryKind::ForeignImmStatic | diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs new file mode 100644 index 0000000000000..9a30623b33d62 --- /dev/null +++ b/src/librustc_metadata/dependency_format.rs @@ -0,0 +1,370 @@ +//! Resolution of mixing rlibs and dylibs +//! +//! When producing a final artifact, such as a dynamic library, the compiler has +//! a choice between linking an rlib or linking a dylib of all upstream +//! dependencies. The linking phase must guarantee, however, that a library only +//! show up once in the object file. For example, it is illegal for library A to +//! be statically linked to B and C in separate dylibs, and then link B and C +//! into a crate D (because library A appears twice). +//! +//! The job of this module is to calculate what format each upstream crate +//! should be used when linking each output type requested in this session. This +//! generally follows this set of rules: +//! +//! 1. Each library must appear exactly once in the output. +//! 2. Each rlib contains only one library (it's just an object file) +//! 3. Each dylib can contain more than one library (due to static linking), +//! and can also bring in many dynamic dependencies. +//! +//! With these constraints in mind, it's generally a very difficult problem to +//! find a solution that's not "all rlibs" or "all dylibs". I have suspicions +//! that NP-ness may come into the picture here... +//! +//! The current selection algorithm below looks mostly similar to: +//! +//! 1. If static linking is required, then require all upstream dependencies +//! to be available as rlibs. If not, generate an error. +//! 2. If static linking is requested (generating an executable), then +//! attempt to use all upstream dependencies as rlibs. If any are not +//! found, bail out and continue to step 3. +//! 3. Static linking has failed, at least one library must be dynamically +//! linked. Apply a heuristic by greedily maximizing the number of +//! dynamically linked libraries. +//! 4. Each upstream dependency available as a dynamic library is +//! registered. The dependencies all propagate, adding to a map. It is +//! possible for a dylib to add a static library as a dependency, but it +//! is illegal for two dylibs to add the same static library as a +//! dependency. The same dylib can be added twice. Additionally, it is +//! illegal to add a static dependency when it was previously found as a +//! dylib (and vice versa) +//! 5. After all dynamic dependencies have been traversed, re-traverse the +//! remaining dependencies and add them statically (if they haven't been +//! added already). +//! +//! While not perfect, this algorithm should help support use-cases such as leaf +//! dependencies being static while the larger tree of inner dependencies are +//! all dynamic. This isn't currently very well battle tested, so it will likely +//! fall short in some use cases. +//! +//! Currently, there is no way to specify the preference of linkage with a +//! particular library (other than a global dynamic/static switch). +//! Additionally, the algorithm is geared towards finding *any* solution rather +//! than finding a number of solutions (there are normally quite a few). + +use rustc::hir::def_id::CrateNum; +use rustc::middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; +use rustc::middle::cstore::{self, DepKind}; +use rustc::middle::dependency_format::{DependencyList, Dependencies, Linkage}; +use rustc::session::config; +use rustc::ty::TyCtxt; +use rustc::util::nodemap::FxHashMap; +use rustc_target::spec::PanicStrategy; + +pub fn calculate(tcx: TyCtxt<'_>) -> Dependencies { + tcx.sess.crate_types.borrow().iter().map(|&ty| { + let linkage = calculate_type(tcx, ty); + verify_ok(tcx, &linkage); + (ty, linkage) + }).collect::>() +} + +fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { + let sess = &tcx.sess; + + if !sess.opts.output_types.should_codegen() { + return Vec::new(); + } + + let preferred_linkage = match ty { + // cdylibs must have all static dependencies. + config::CrateType::Cdylib => Linkage::Static, + + // Generating a dylib without `-C prefer-dynamic` means that we're going + // to try to eagerly statically link all dependencies. This is normally + // done for end-product dylibs, not intermediate products. + config::CrateType::Dylib if !sess.opts.cg.prefer_dynamic => Linkage::Static, + config::CrateType::Dylib => Linkage::Dynamic, + + // If the global prefer_dynamic switch is turned off, or the final + // executable will be statically linked, prefer static crate linkage. + config::CrateType::Executable if !sess.opts.cg.prefer_dynamic || + sess.crt_static() => Linkage::Static, + config::CrateType::Executable => Linkage::Dynamic, + + // proc-macro crates are mostly cdylibs, but we also need metadata. + config::CrateType::ProcMacro => Linkage::Static, + + // No linkage happens with rlibs, we just needed the metadata (which we + // got long ago), so don't bother with anything. + config::CrateType::Rlib => Linkage::NotLinked, + + // staticlibs must have all static dependencies. + config::CrateType::Staticlib => Linkage::Static, + }; + + if preferred_linkage == Linkage::NotLinked { + // If the crate is not linked, there are no link-time dependencies. + return Vec::new(); + } + + if preferred_linkage == Linkage::Static { + // Attempt static linkage first. For dylibs and executables, we may be + // able to retry below with dynamic linkage. + if let Some(v) = attempt_static(tcx) { + return v; + } + + // Staticlibs, cdylibs, and static executables must have all static + // dependencies. If any are not found, generate some nice pretty errors. + if ty == config::CrateType::Cdylib || ty == config::CrateType::Staticlib || + (ty == config::CrateType::Executable && sess.crt_static() && + !sess.target.target.options.crt_static_allows_dylibs) { + for &cnum in tcx.crates().iter() { + if tcx.dep_kind(cnum).macros_only() { continue } + let src = tcx.used_crate_source(cnum); + if src.rlib.is_some() { continue } + sess.err(&format!("crate `{}` required to be available in rlib format, \ + but was not found in this form", + tcx.crate_name(cnum))); + } + return Vec::new(); + } + } + + let mut formats = FxHashMap::default(); + + // Sweep all crates for found dylibs. Add all dylibs, as well as their + // dependencies, ensuring there are no conflicts. The only valid case for a + // dependency to be relied upon twice is for both cases to rely on a dylib. + for &cnum in tcx.crates().iter() { + if tcx.dep_kind(cnum).macros_only() { continue } + let name = tcx.crate_name(cnum); + let src = tcx.used_crate_source(cnum); + if src.dylib.is_some() { + log::info!("adding dylib: {}", name); + add_library(tcx, cnum, RequireDynamic, &mut formats); + let deps = tcx.dylib_dependency_formats(cnum); + for &(depnum, style) in deps.iter() { + log::info!("adding {:?}: {}", style, tcx.crate_name(depnum)); + add_library(tcx, depnum, style, &mut formats); + } + } + } + + // Collect what we've got so far in the return vector. + let last_crate = tcx.crates().len(); + let mut ret = (1..last_crate+1).map(|cnum| { + match formats.get(&CrateNum::new(cnum)) { + Some(&RequireDynamic) => Linkage::Dynamic, + Some(&RequireStatic) => Linkage::IncludedFromDylib, + None => Linkage::NotLinked, + } + }).collect::>(); + + // Run through the dependency list again, and add any missing libraries as + // static libraries. + // + // If the crate hasn't been included yet and it's not actually required + // (e.g., it's an allocator) then we skip it here as well. + for &cnum in tcx.crates().iter() { + let src = tcx.used_crate_source(cnum); + if src.dylib.is_none() && + !formats.contains_key(&cnum) && + tcx.dep_kind(cnum) == DepKind::Explicit { + assert!(src.rlib.is_some() || src.rmeta.is_some()); + log::info!("adding staticlib: {}", tcx.crate_name(cnum)); + add_library(tcx, cnum, RequireStatic, &mut formats); + ret[cnum.as_usize() - 1] = Linkage::Static; + } + } + + // We've gotten this far because we're emitting some form of a final + // artifact which means that we may need to inject dependencies of some + // form. + // + // Things like allocators and panic runtimes may not have been activated + // quite yet, so do so here. + activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret, + &|cnum| tcx.is_panic_runtime(cnum)); + + // When dylib B links to dylib A, then when using B we must also link to A. + // It could be the case, however, that the rlib for A is present (hence we + // found metadata), but the dylib for A has since been removed. + // + // For situations like this, we perform one last pass over the dependencies, + // making sure that everything is available in the requested format. + for (cnum, kind) in ret.iter().enumerate() { + let cnum = CrateNum::new(cnum + 1); + let src = tcx.used_crate_source(cnum); + match *kind { + Linkage::NotLinked | + Linkage::IncludedFromDylib => {} + Linkage::Static if src.rlib.is_some() => continue, + Linkage::Dynamic if src.dylib.is_some() => continue, + kind => { + let kind = match kind { + Linkage::Static => "rlib", + _ => "dylib", + }; + sess.err(&format!("crate `{}` required to be available in {} format, \ + but was not found in this form", + tcx.crate_name(cnum), kind)); + } + } + } + + ret +} + +fn add_library( + tcx: TyCtxt<'_>, + cnum: CrateNum, + link: LinkagePreference, + m: &mut FxHashMap, +) { + match m.get(&cnum) { + Some(&link2) => { + // If the linkages differ, then we'd have two copies of the library + // if we continued linking. If the linkages are both static, then we + // would also have two copies of the library (static from two + // different locations). + // + // This error is probably a little obscure, but I imagine that it + // can be refined over time. + if link2 != link || link == RequireStatic { + tcx.sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \ + shows up once", tcx.crate_name(cnum))) + .help("having upstream crates all available in one format \ + will likely make this go away") + .emit(); + } + } + None => { m.insert(cnum, link); } + } +} + +fn attempt_static(tcx: TyCtxt<'_>) -> Option { + let sess = &tcx.sess; + let crates = cstore::used_crates(tcx, RequireStatic); + if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) { + return None + } + + // All crates are available in an rlib format, so we're just going to link + // everything in explicitly so long as it's actually required. + let last_crate = tcx.crates().len(); + let mut ret = (1..last_crate+1).map(|cnum| { + if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit { + Linkage::Static + } else { + Linkage::NotLinked + } + }).collect::>(); + + // Our allocator/panic runtime may not have been linked above if it wasn't + // explicitly linked, which is the case for any injected dependency. Handle + // that here and activate them. + activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret, + &|cnum| tcx.is_panic_runtime(cnum)); + + Some(ret) +} + +// Given a list of how to link upstream dependencies so far, ensure that an +// injected dependency is activated. This will not do anything if one was +// transitively included already (e.g., via a dylib or explicitly so). +// +// If an injected dependency was not found then we're guaranteed the +// metadata::creader module has injected that dependency (not listed as +// a required dependency) in one of the session's field. If this field is not +// set then this compilation doesn't actually need the dependency and we can +// also skip this step entirely. +fn activate_injected_dep(injected: Option, + list: &mut DependencyList, + replaces_injected: &dyn Fn(CrateNum) -> bool) { + for (i, slot) in list.iter().enumerate() { + let cnum = CrateNum::new(i + 1); + if !replaces_injected(cnum) { + continue + } + if *slot != Linkage::NotLinked { + return + } + } + if let Some(injected) = injected { + let idx = injected.as_usize() - 1; + assert_eq!(list[idx], Linkage::NotLinked); + list[idx] = Linkage::Static; + } +} + +// After the linkage for a crate has been determined we need to verify that +// there's only going to be one allocator in the output. +fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { + let sess = &tcx.sess; + if list.len() == 0 { + return + } + let mut panic_runtime = None; + for (i, linkage) in list.iter().enumerate() { + if let Linkage::NotLinked = *linkage { + continue + } + let cnum = CrateNum::new(i + 1); + + if tcx.is_panic_runtime(cnum) { + if let Some((prev, _)) = panic_runtime { + let prev_name = tcx.crate_name(prev); + let cur_name = tcx.crate_name(cnum); + sess.err(&format!("cannot link together two \ + panic runtimes: {} and {}", + prev_name, cur_name)); + } + panic_runtime = Some((cnum, tcx.panic_strategy(cnum))); + } + } + + // If we found a panic runtime, then we know by this point that it's the + // only one, but we perform validation here that all the panic strategy + // compilation modes for the whole DAG are valid. + if let Some((cnum, found_strategy)) = panic_runtime { + let desired_strategy = sess.panic_strategy(); + + // First up, validate that our selected panic runtime is indeed exactly + // our same strategy. + if found_strategy != desired_strategy { + sess.err(&format!("the linked panic runtime `{}` is \ + not compiled with this crate's \ + panic strategy `{}`", + tcx.crate_name(cnum), + desired_strategy.desc())); + } + + // Next up, verify that all other crates are compatible with this panic + // strategy. If the dep isn't linked, we ignore it, and if our strategy + // is abort then it's compatible with everything. Otherwise all crates' + // panic strategy must match our own. + for (i, linkage) in list.iter().enumerate() { + if let Linkage::NotLinked = *linkage { + continue + } + if desired_strategy == PanicStrategy::Abort { + continue + } + let cnum = CrateNum::new(i + 1); + let found_strategy = tcx.panic_strategy(cnum); + let is_compiler_builtins = tcx.is_compiler_builtins(cnum); + if is_compiler_builtins || desired_strategy == found_strategy { + continue + } + + sess.err(&format!("the crate `{}` is compiled with the \ + panic strategy `{}` which is \ + incompatible with this crate's \ + strategy of `{}`", + tcx.crate_name(cnum), + found_strategy.desc(), + desired_strategy.desc())); + } + } +} diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index f430f01542efe..965a8658c9592 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -875,7 +875,7 @@ impl EncodeContext<'tcx> { EntryKind::AssocConst(container, const_qualif, rendered_const) } ty::AssocKind::Method => { - let fn_data = if let hir::TraitItemKind::Method(_, ref m) = ast_item.node { + let fn_data = if let hir::TraitItemKind::Method(method_sig, m) = &ast_item.node { let param_names = match *m { hir::TraitMethod::Required(ref names) => { self.encode_fn_param_names(names) @@ -885,6 +885,7 @@ impl EncodeContext<'tcx> { } }; FnData { + asyncness: method_sig.header.asyncness, constness: hir::Constness::NotConst, param_names, sig: self.lazy(&tcx.fn_sig(def_id)), @@ -982,6 +983,7 @@ impl EncodeContext<'tcx> { ty::AssocKind::Method => { let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node { FnData { + asyncness: sig.header.asyncness, constness: sig.header.constness, param_names: self.encode_fn_param_names_for_body(body), sig: self.lazy(&tcx.fn_sig(def_id)), @@ -1128,6 +1130,7 @@ impl EncodeContext<'tcx> { } hir::ItemKind::Fn(_, header, .., body) => { let data = FnData { + asyncness: header.asyncness, constness: header.constness, param_names: self.encode_fn_param_names_for_body(body), sig: self.lazy(tcx.fn_sig(def_id)), @@ -1649,20 +1652,22 @@ impl EncodeContext<'tcx> { } fn encode_dylib_dependency_formats(&mut self) -> Lazy<[Option]> { - match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) { - Some(arr) => { - self.lazy(arr.iter().map(|slot| { - match *slot { - Linkage::NotLinked | - Linkage::IncludedFromDylib => None, - - Linkage::Dynamic => Some(LinkagePreference::RequireDynamic), - Linkage::Static => Some(LinkagePreference::RequireStatic), - } - })) + let formats = self.tcx.dependency_formats(LOCAL_CRATE); + for (ty, arr) in formats.iter() { + if *ty != config::CrateType::Dylib { + continue; } - None => Lazy::empty(), + return self.lazy(arr.iter().map(|slot| { + match *slot { + Linkage::NotLinked | + Linkage::IncludedFromDylib => None, + + Linkage::Dynamic => Some(LinkagePreference::RequireDynamic), + Linkage::Static => Some(LinkagePreference::RequireStatic), + } + })); } + Lazy::empty() } fn encode_info_for_foreign_item(&mut self, @@ -1675,6 +1680,7 @@ impl EncodeContext<'tcx> { let kind = match nitem.node { hir::ForeignItemKind::Fn(_, ref names, _) => { let data = FnData { + asyncness: hir::IsAsync::NotAsync, constness: hir::Constness::NotConst, param_names: self.encode_fn_param_names(names), sig: self.lazy(tcx.fn_sig(def_id)), diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index e6104e629e9fb..9273b064ba9ce 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -32,6 +32,7 @@ mod schema; mod native_libs; mod link_args; mod foreign_modules; +mod dependency_format; pub mod creader; pub mod cstore; diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 1a5f0e17ba7ce..92534ab056a8b 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -295,6 +295,7 @@ pub struct MacroDef { #[derive(RustcEncodable, RustcDecodable)] pub struct FnData<'tcx> { + pub asyncness: hir::IsAsync, pub constness: hir::Constness, pub param_names: Lazy<[ast::Name]>, pub sig: Lazy>, diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index ba299e9463b8d..196bcf147f8f8 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -1993,6 +1993,69 @@ fn get_owned_iterator() -> IntoIter { ``` "##, +E0524: r##" +A variable which requires unique access is being used in more than one closure +at the same time. + +Erroneous code example: + +```compile_fail,E0524 +fn set(x: &mut isize) { + *x += 4; +} + +fn dragoooon(x: &mut isize) { + let mut c1 = || set(x); + let mut c2 = || set(x); // error! + + c2(); + c1(); +} +``` + +To solve this issue, multiple solutions are available. First, is it required +for this variable to be used in more than one closure at a time? If it is the +case, use reference counted types such as `Rc` (or `Arc` if it runs +concurrently): + +``` +use std::rc::Rc; +use std::cell::RefCell; + +fn set(x: &mut isize) { + *x += 4; +} + +fn dragoooon(x: &mut isize) { + let x = Rc::new(RefCell::new(x)); + let y = Rc::clone(&x); + let mut c1 = || { let mut x2 = x.borrow_mut(); set(&mut x2); }; + let mut c2 = || { let mut x2 = y.borrow_mut(); set(&mut x2); }; // ok! + + c2(); + c1(); +} +``` + +If not, just run closures one at a time: + +``` +fn set(x: &mut isize) { + *x += 4; +} + +fn dragoooon(x: &mut isize) { + { // This block isn't necessary since non-lexical lifetimes, it's just to + // make it more clear. + let mut c1 = || set(&mut *x); + c1(); + } // `c1` has been dropped here so we're free to use `x` again! + let mut c2 = || set(&mut *x); + c2(); +} +``` +"##, + E0595: r##" #### Note: this error code is no longer emitted by the compiler. @@ -2393,7 +2456,6 @@ There are some known bugs that trigger this message. // E0385, // {} in an aliasable location E0493, // destructors cannot be evaluated at compile-time E0521, // borrowed data escapes outside of closure - E0524, // two closures require unique access to `..` at the same time E0526, // shuffle indices are not constant E0594, // cannot assign to {} // E0598, // lifetime of {} is too short to guarantee its contents can be... diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d98e1f3e1283f..dc536329251ca 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1253,7 +1253,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expression.map(|expr| (expr, blk_id)), ); } - ObligationCauseCode::ReturnType(id) => { + ObligationCauseCode::ReturnValue(id) => { db = self.report_return_mismatched_types( cause, expected, found, err, fcx, id, None); } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index e34a2c6f61c24..6b694bfc8da25 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -664,12 +664,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ret_ty = ret_coercion.borrow().expected_ty(); let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone()); - ret_coercion.borrow_mut() - .coerce(self, - &self.cause(return_expr.span, - ObligationCauseCode::ReturnType(return_expr.hir_id)), - return_expr, - return_expr_ty); + ret_coercion.borrow_mut().coerce( + self, + &self.cause(return_expr.span, ObligationCauseCode::ReturnValue(return_expr.hir_id)), + return_expr, + return_expr_ty, + ); } /// Type check assignment expression `expr` of form `lhs = rhs`. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6c8c5ae512358..02f4f2a3744c6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2698,30 +2698,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { traits::ObligationCause::new(span, self.body_id, code)); } - pub fn require_type_is_sized(&self, - ty: Ty<'tcx>, - span: Span, - code: traits::ObligationCauseCode<'tcx>) - { - let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None); - self.require_type_meets(ty, span, code, lang_item); + pub fn require_type_is_sized( + &self, + ty: Ty<'tcx>, + span: Span, + code: traits::ObligationCauseCode<'tcx>, + ) { + if !ty.references_error() { + let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None); + self.require_type_meets(ty, span, code, lang_item); + } } - pub fn require_type_is_sized_deferred(&self, - ty: Ty<'tcx>, - span: Span, - code: traits::ObligationCauseCode<'tcx>) - { - self.deferred_sized_obligations.borrow_mut().push((ty, span, code)); + pub fn require_type_is_sized_deferred( + &self, + ty: Ty<'tcx>, + span: Span, + code: traits::ObligationCauseCode<'tcx>, + ) { + if !ty.references_error() { + self.deferred_sized_obligations.borrow_mut().push((ty, span, code)); + } } - pub fn register_bound(&self, - ty: Ty<'tcx>, - def_id: DefId, - cause: traits::ObligationCause<'tcx>) - { - self.fulfillment_cx.borrow_mut() - .register_bound(self, self.param_env, ty, def_id, cause); + pub fn register_bound( + &self, + ty: Ty<'tcx>, + def_id: DefId, + cause: traits::ObligationCause<'tcx>, + ) { + if !ty.references_error() { + self.fulfillment_cx.borrow_mut() + .register_bound(self, self.param_env, ty, def_id, cause); + } } pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> { @@ -2780,22 +2789,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Registers an obligation for checking later, during regionck, that the type `ty` must /// outlive the region `r`. - pub fn register_wf_obligation(&self, - ty: Ty<'tcx>, - span: Span, - code: traits::ObligationCauseCode<'tcx>) - { + pub fn register_wf_obligation( + &self, + ty: Ty<'tcx>, + span: Span, + code: traits::ObligationCauseCode<'tcx>, + ) { // WF obligations never themselves fail, so no real need to give a detailed cause: let cause = traits::ObligationCause::new(span, self.body_id, code); - self.register_predicate(traits::Obligation::new(cause, - self.param_env, - ty::Predicate::WellFormed(ty))); + self.register_predicate( + traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)), + ); } /// Registers obligations that all types appearing in `substs` are well-formed. pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) { for ty in substs.types() { - self.register_wf_obligation(ty, expr.span, traits::MiscObligation); + if !ty.references_error() { + self.register_wf_obligation(ty, expr.span, traits::MiscObligation); + } } } @@ -2834,12 +2846,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(arielb1): use this instead of field.ty everywhere // Only for fields! Returns for methods> // Indifferent to privacy flags - pub fn field_ty(&self, - span: Span, - field: &'tcx ty::FieldDef, - substs: SubstsRef<'tcx>) - -> Ty<'tcx> - { + pub fn field_ty( + &self, + span: Span, + field: &'tcx ty::FieldDef, + substs: SubstsRef<'tcx>, + ) -> Ty<'tcx> { self.normalize_associated_types_in(span, &field.ty(self.tcx, substs)) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index f7e766bb84d57..265d0676fa8d1 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -596,7 +596,7 @@ fn check_fn_or_method<'fcx, 'tcx>( } implied_bounds.extend(sig.inputs()); - fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::ReturnType); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 031e77ff1dbe0..479c8c3728305 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -217,7 +217,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function { } else { hir::Constness::NotConst }; - + let asyncness = cx.tcx.asyncness(did); let predicates = cx.tcx.predicates_of(did); let (generics, decl) = clean::enter_impl_trait(cx, || { ((cx.tcx.generics_of(did), &predicates).clean(cx), (did, sig).clean(cx)) @@ -230,7 +230,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function { unsafety: sig.unsafety(), abi: sig.abi(), constness, - asyncness: hir::IsAsync::NotAsync, + asyncness, }, all_types, ret_types, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 197c09ba759e7..d1a9b740d62ab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2403,6 +2403,7 @@ impl Clean for ty::AssocItem { } else { hir::Constness::NotConst }; + let asyncness = cx.tcx.asyncness(self.def_id); let defaultness = match self.container { ty::ImplContainer(_) => Some(self.defaultness), ty::TraitContainer(_) => None, @@ -2414,7 +2415,7 @@ impl Clean for ty::AssocItem { unsafety: sig.unsafety(), abi: sig.abi(), constness, - asyncness: hir::IsAsync::NotAsync, + asyncness, }, defaultness, all_types, diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index f85b5d632f16b..e92c0d1c58e41 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -236,8 +236,8 @@ impl LocalKey { #[stable(feature = "rust1", since = "1.0.0")] pub fn with(&'static self, f: F) -> R where F: FnOnce(&T) -> R { - self.try_with(f).expect("cannot access a TLS value during or \ - after it is destroyed") + self.try_with(f).expect("cannot access a Thread Local Storage value \ + during or after destruction") } /// Acquires a reference to the value in this TLS key. diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 5cdea3aabbe11..2423e1070fc3e 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -112,6 +112,13 @@ impl Emitter for JsonEmitter { panic!("failed to print notification: {:?}", e); } } + + fn should_show_explain(&self) -> bool { + match self.json_rendered { + HumanReadableErrorType::Short(_) => false, + _ => true, + } + } } // The following data types are provided just for serialisation. diff --git a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs index d50a7910fe0b3..9050e8f1671d9 100644 --- a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs +++ b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs @@ -1,4 +1,5 @@ // compile-flags:-Zshare-generics=yes +// no-prefer-dynamic #![crate_type="rlib"] diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs index 010412b8baeb3..58e485be00321 100644 --- a/src/test/codegen-units/partitioning/shared-generics.rs +++ b/src/test/codegen-units/partitioning/shared-generics.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +// no-prefer-dynamic // compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Zincremental=tmp/partitioning-tests/shared-generics-exe #![crate_type="rlib"] diff --git a/src/test/compile-fail/two-panic-runtimes.rs b/src/test/compile-fail/two-panic-runtimes.rs index 66b184e521abc..671d44564e66f 100644 --- a/src/test/compile-fail/two-panic-runtimes.rs +++ b/src/test/compile-fail/two-panic-runtimes.rs @@ -5,6 +5,7 @@ // aux-build:panic-runtime-lang-items.rs #![no_std] +#![no_main] extern crate panic_runtime_unwind; extern crate panic_runtime_unwind2; diff --git a/src/test/run-make-fulldeps/issue-64319/Makefile b/src/test/run-make-fulldeps/issue-64319/Makefile new file mode 100644 index 0000000000000..b2c6b8b3cbbf2 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-64319/Makefile @@ -0,0 +1,39 @@ +-include ../tools.mk + +# Different optimization levels imply different values for `-Zshare-generics`, +# so try out a whole bunch of combinations to make sure everything is compatible +all: + # First up, try some defaults + $(RUSTC) --crate-type rlib foo.rs + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 + + # Next try mixing up some things explicitly + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no + $(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes + + # Now combine a whole bunch of options together + $(RUSTC) --crate-type rlib foo.rs + $(RUSTC) --crate-type dylib bar.rs + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 + $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 + $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=s + $(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=yes + $(RUSTC) --crate-type dylib bar.rs -C opt-level=z + $(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=no + $(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=yes diff --git a/src/test/run-make-fulldeps/issue-64319/bar.rs b/src/test/run-make-fulldeps/issue-64319/bar.rs new file mode 100644 index 0000000000000..3895c0b6cdbb3 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-64319/bar.rs @@ -0,0 +1,5 @@ +extern crate foo; + +pub fn bar() { + foo::foo(); +} diff --git a/src/test/run-make-fulldeps/issue-64319/foo.rs b/src/test/run-make-fulldeps/issue-64319/foo.rs new file mode 100644 index 0000000000000..c54a238e9add7 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-64319/foo.rs @@ -0,0 +1,9 @@ +pub fn foo() { + bar::(); +} + +pub fn bar() { + baz(); +} + +fn baz() {} diff --git a/src/test/run-make-fulldeps/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile index 7901866015bf2..840fe801a953c 100644 --- a/src/test/run-make-fulldeps/symbol-visibility/Makefile +++ b/src/test/run-make-fulldeps/symbol-visibility/Makefile @@ -79,12 +79,12 @@ all: # Check that a Rust dylib exports its monomorphic functions, including generics this time [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rust_dylib)" -eq "1" ] [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rust_dylib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rust_dylib)" -eq "0" ] # Check that a Rust dylib exports the monomorphic functions from its dependencies [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rlib)" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rlib)" -eq "0" ] # Check that an executable does not export any dynamic symbols [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_c_function_from_rlib)" -eq "0" ] diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs index 21c733a9bc98e..913ba8f2a1649 100644 --- a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs +++ b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs @@ -1,3 +1,5 @@ +// edition:2018 + use std::ops::Deref; pub fn func<'a>(_x: impl Clone + Into> + 'a) {} @@ -11,8 +13,16 @@ pub fn func3(_x: impl Iterator> + Clone) {} pub fn func4>(_x: T) {} +pub async fn async_fn() {} + pub struct Foo; impl Foo { pub fn method<'a>(_x: impl Clone + Into> + 'a) {} } + +pub struct Bar; + +impl Bar { + pub async fn async_foo(&self) {} +} diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs index b1e3f8d145b5f..6f4a48c83c05b 100644 --- a/src/test/rustdoc/inline_cross/impl_trait.rs +++ b/src/test/rustdoc/inline_cross/impl_trait.rs @@ -1,4 +1,5 @@ // aux-build:impl_trait_aux.rs +// edition:2018 extern crate impl_trait_aux; @@ -20,13 +21,20 @@ pub use impl_trait_aux::func2; // @!has - '//pre[@class="rust fn"]' 'where' pub use impl_trait_aux::func3; - // @has impl_trait/fn.func4.html // @has - '//pre[@class="rust fn"]' "func4(" // @has - '//pre[@class="rust fn"]' "T: Iterator," pub use impl_trait_aux::func4; +// @has impl_trait/fn.async_fn.html +// @has - '//pre[@class="rust fn"]' "pub async fn async_fn()" +pub use impl_trait_aux::async_fn; + // @has impl_trait/struct.Foo.html // @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into> + 'a)" // @!has - '//code[@id="method.v"]' 'where' pub use impl_trait_aux::Foo; + +// @has impl_trait/struct.Bar.html +// @has - '//*[@id="method.async_foo"]' "pub async fn async_foo(" +pub use impl_trait_aux::Bar; diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.rs b/src/test/ui/associated-types/associated-types-overridden-binding.rs index fa1889389fd5c..9a64a06c31bad 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding.rs +++ b/src/test/ui/associated-types/associated-types-overridden-binding.rs @@ -1,10 +1,10 @@ #![feature(trait_alias)] trait Foo: Iterator {} -trait Bar: Foo {} //~ ERROR type annotations required +trait Bar: Foo {} //~ ERROR type annotations needed trait I32Iterator = Iterator; -trait U32Iterator = I32Iterator; +trait U32Iterator = I32Iterator; //~ ERROR type annotations needed fn main() { let _: &dyn I32Iterator; diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr index a7238541cd96e..5ef1b23cbcd21 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr +++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr @@ -1,4 +1,4 @@ -error[E0284]: type annotations required: cannot resolve `::Item == i32` +error[E0284]: type annotations needed: cannot resolve `::Item == i32` --> $DIR/associated-types-overridden-binding.rs:4:1 | LL | trait Foo: Iterator {} @@ -6,6 +6,13 @@ LL | trait Foo: Iterator {} LL | trait Bar: Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0282]: type annotations needed + --> $DIR/associated-types-overridden-binding.rs:7:1 + | +LL | trait U32Iterator = I32Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0282, E0284. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/associated-types/associated-types-unconstrained.rs b/src/test/ui/associated-types/associated-types-unconstrained.rs index 99424836ece2f..b97d4af184f92 100644 --- a/src/test/ui/associated-types/associated-types-unconstrained.rs +++ b/src/test/ui/associated-types/associated-types-unconstrained.rs @@ -12,5 +12,5 @@ impl Foo for isize { pub fn main() { let x: isize = Foo::bar(); - //~^ ERROR type annotations required + //~^ ERROR type annotations needed } diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr index da14a69ae306a..4e9e54d368805 100644 --- a/src/test/ui/associated-types/associated-types-unconstrained.stderr +++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr @@ -1,4 +1,4 @@ -error[E0284]: type annotations required: cannot resolve `<_ as Foo>::A == _` +error[E0284]: type annotations needed: cannot resolve `<_ as Foo>::A == _` --> $DIR/associated-types-unconstrained.rs:14:20 | LL | let x: isize = Foo::bar(); diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs index 24e06e3c4e666..d7e187a2b3958 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.rs @@ -1,10 +1,6 @@ // Tests that two closures cannot simultaneously have mutable // and immutable access to the variable. Issue #6801. -fn get(x: &isize) -> isize { - *x -} - fn set(x: &mut isize) { *x = 4; } diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr index 3be7d725eda3a..784b903a5896a 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr @@ -1,17 +1,17 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference - --> $DIR/borrowck-closures-mut-of-imm.rs:13:25 + --> $DIR/borrowck-closures-mut-of-imm.rs:9:25 | LL | let mut c1 = || set(&mut *x); | ^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference - --> $DIR/borrowck-closures-mut-of-imm.rs:15:25 + --> $DIR/borrowck-closures-mut-of-imm.rs:11:25 | LL | let mut c2 = || set(&mut *x); | ^^^^^^^ cannot borrow as mutable error[E0524]: two closures require unique access to `x` at the same time - --> $DIR/borrowck-closures-mut-of-imm.rs:15:18 + --> $DIR/borrowck-closures-mut-of-imm.rs:11:18 | LL | let mut c1 = || set(&mut *x); | -- - first borrow occurs due to use of `x` in closure @@ -28,4 +28,5 @@ LL | c2(); c1(); error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0596`. +Some errors have detailed explanations: E0524, E0596. +For more information about an error, try `rustc --explain E0524`. diff --git a/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr b/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr index a174388712158..471173e595f47 100644 --- a/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr @@ -15,3 +15,4 @@ LL | c2(); c1(); error: aborting due to previous error +For more information about this error, try `rustc --explain E0524`. diff --git a/src/test/ui/borrowck/borrowck-closures-unique.stderr b/src/test/ui/borrowck/borrowck-closures-unique.stderr index 9b53af4c01f59..2ed08b83c58b9 100644 --- a/src/test/ui/borrowck/borrowck-closures-unique.stderr +++ b/src/test/ui/borrowck/borrowck-closures-unique.stderr @@ -50,4 +50,5 @@ LL | let c1 = |y: &'static mut isize| x = y; error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0500`. +Some errors have detailed explanations: E0500, E0524. +For more information about an error, try `rustc --explain E0500`. diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index 1d99f99c62383..aba649d83ec01 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `_: Generator` +error[E0283]: type annotations needed: cannot resolve `_: Generator` --> $DIR/E0283.rs:18:21 | LL | fn create() -> u32; diff --git a/src/test/ui/error-codes/E0401.rs b/src/test/ui/error-codes/E0401.rs index a120198b7284d..c30e5f4718871 100644 --- a/src/test/ui/error-codes/E0401.rs +++ b/src/test/ui/error-codes/E0401.rs @@ -8,7 +8,7 @@ fn foo(x: T) { W: Fn()> (y: T) { //~ ERROR E0401 } - bfnr(x); + bfnr(x); //~ ERROR type annotations needed } diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 1d9dfe46722ec..485b76a09a3c4 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -32,6 +32,13 @@ LL | fn helper(sel: &Self) -> u8 { | use of generic parameter from outer function | use a type here instead -error: aborting due to 3 previous errors +error[E0282]: type annotations needed + --> $DIR/E0401.rs:11:5 + | +LL | bfnr(x); + | ^^^^ cannot infer type for `U` + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0401`. +Some errors have detailed explanations: E0282, E0401. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/error-codes/E0661.rs b/src/test/ui/error-codes/E0661.rs index 2440e3a446eb4..5ac0c415ae1b2 100644 --- a/src/test/ui/error-codes/E0661.rs +++ b/src/test/ui/error-codes/E0661.rs @@ -3,7 +3,7 @@ #![feature(asm)] fn main() { - let a; + let a; //~ ERROR type annotations needed asm!("nop" : "r"(a)); //~^ ERROR E0661 } diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr index 58f7e7fa0f919..3537e0bc3a4c6 100644 --- a/src/test/ui/error-codes/E0661.stderr +++ b/src/test/ui/error-codes/E0661.stderr @@ -4,5 +4,12 @@ error[E0661]: output operand constraint lacks '=' or '+' LL | asm!("nop" : "r"(a)); | ^^^ -error: aborting due to previous error +error[E0282]: type annotations needed + --> $DIR/E0661.rs:6:9 + | +LL | let a; + | ^ consider giving `a` a type + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs index 9eac6b714de37..65c4b78bf6a40 100644 --- a/src/test/ui/impl-trait/where-allowed.rs +++ b/src/test/ui/impl-trait/where-allowed.rs @@ -11,8 +11,9 @@ fn in_return() -> impl Debug { panic!() } // Allowed fn in_adt_in_parameters(_: Vec) { panic!() } -// Allowed +// Disallowed fn in_adt_in_return() -> Vec { panic!() } +//~^ ERROR type annotations needed // Disallowed fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } @@ -58,7 +59,8 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } // Disallowed fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types -//~^^ ERROR nested `impl Trait` is not allowed +//~| ERROR nested `impl Trait` is not allowed +//~| ERROR type annotations needed // Disallowed fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index 1332fff84f50a..dfb6e6524d9a5 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -1,5 +1,5 @@ error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:50:51 + --> $DIR/where-allowed.rs:51:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | --------^^^^^^^^^^- @@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:59:57 + --> $DIR/where-allowed.rs:60:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | --------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | outer `impl Trait` error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:122:5 + --> $DIR/where-allowed.rs:124:5 | LL | type Out = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Out = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:158:1 + --> $DIR/where-allowed.rs:160:1 | LL | type InTypeAlias = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,205 +35,205 @@ LL | type InTypeAlias = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:18:40 + --> $DIR/where-allowed.rs:19:40 | LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:22:42 + --> $DIR/where-allowed.rs:23:42 | LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:26:38 + --> $DIR/where-allowed.rs:27:38 | LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:30:40 + --> $DIR/where-allowed.rs:31:40 | LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:34:49 + --> $DIR/where-allowed.rs:35:49 | LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:38:51 + --> $DIR/where-allowed.rs:39:51 | LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:42:55 + --> $DIR/where-allowed.rs:43:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:46:57 + --> $DIR/where-allowed.rs:47:57 | LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:50:51 + --> $DIR/where-allowed.rs:51:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:55:53 + --> $DIR/where-allowed.rs:56:53 | LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:59:57 + --> $DIR/where-allowed.rs:60:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:64:59 + --> $DIR/where-allowed.rs:66:59 | LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:68:38 + --> $DIR/where-allowed.rs:70:38 | LL | fn in_Fn_parameter_in_generics (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:72:40 + --> $DIR/where-allowed.rs:74:40 | LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:85:32 + --> $DIR/where-allowed.rs:87:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:89:41 + --> $DIR/where-allowed.rs:91:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:93:27 + --> $DIR/where-allowed.rs:95:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:98:25 + --> $DIR/where-allowed.rs:100:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:100:20 + --> $DIR/where-allowed.rs:102:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:111:23 + --> $DIR/where-allowed.rs:113:23 | LL | fn in_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:129:34 + --> $DIR/where-allowed.rs:131:34 | LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:142:33 + --> $DIR/where-allowed.rs:144:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:145:31 + --> $DIR/where-allowed.rs:147:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:162:39 + --> $DIR/where-allowed.rs:164:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:166:16 + --> $DIR/where-allowed.rs:168:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:171:24 + --> $DIR/where-allowed.rs:173:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:176:6 + --> $DIR/where-allowed.rs:178:6 | LL | impl impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:182:24 + --> $DIR/where-allowed.rs:184:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:188:11 + --> $DIR/where-allowed.rs:190:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:195:15 + --> $DIR/where-allowed.rs:197:15 | LL | where Vec: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:202:24 + --> $DIR/where-allowed.rs:204:24 | LL | where T: PartialEq | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:209:17 + --> $DIR/where-allowed.rs:211:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:216:22 + --> $DIR/where-allowed.rs:218:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:222:29 + --> $DIR/where-allowed.rs:224:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ @@ -241,24 +241,36 @@ LL | let _in_local_variable: impl Fn() = || {}; = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:224:46 + --> $DIR/where-allowed.rs:226:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ +error[E0282]: type annotations needed + --> $DIR/where-allowed.rs:15:30 + | +LL | fn in_adt_in_return() -> Vec { panic!() } + | ^^^^^^^^^^ cannot infer type + +error[E0282]: type annotations needed + --> $DIR/where-allowed.rs:60:49 + | +LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } + | ^^^^^^^^^^^^^^^^^^^ cannot infer type + error: could not find defining uses - --> $DIR/where-allowed.rs:158:1 + --> $DIR/where-allowed.rs:160:1 | LL | type InTypeAlias = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/where-allowed.rs:122:5 + --> $DIR/where-allowed.rs:124:5 | LL | type Out = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 41 previous errors +error: aborting due to 43 previous errors -Some errors have detailed explanations: E0562, E0658. -For more information about an error, try `rustc --explain E0562`. +Some errors have detailed explanations: E0282, E0562, E0658. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-12028.rs b/src/test/ui/issues/issue-12028.rs index 7c2b0d69c8b25..7503766ff2084 100644 --- a/src/test/ui/issues/issue-12028.rs +++ b/src/test/ui/issues/issue-12028.rs @@ -24,7 +24,7 @@ trait StreamHash: Hash { impl Hash for u8 { fn hash2(&self, hasher: &H) -> u64 { let mut stream = hasher.stream(); - self.input_stream(&mut stream); //~ ERROR type annotations required + self.input_stream(&mut stream); //~ ERROR type annotations needed Stream::result(&stream) } } diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr index 24aa88c3fa379..ff92d01a69ed2 100644 --- a/src/test/ui/issues/issue-12028.stderr +++ b/src/test/ui/issues/issue-12028.stderr @@ -1,4 +1,4 @@ -error[E0284]: type annotations required: cannot resolve `<_ as StreamHasher>::S == ::S` +error[E0284]: type annotations needed: cannot resolve `<_ as StreamHasher>::S == ::S` --> $DIR/issue-12028.rs:27:14 | LL | self.input_stream(&mut stream); diff --git a/src/test/ui/issues/issue-21974.rs b/src/test/ui/issues/issue-21974.rs index f49eb230b4083..0cbe38d6ec0b6 100644 --- a/src/test/ui/issues/issue-21974.rs +++ b/src/test/ui/issues/issue-21974.rs @@ -7,7 +7,7 @@ trait Foo { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required +fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed where &'a T : Foo, &'b T : Foo { diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr index a6cce7846e81d..7ceb2bd23f6cd 100644 --- a/src/test/ui/issues/issue-21974.stderr +++ b/src/test/ui/issues/issue-21974.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `&'a T: Foo` +error[E0283]: type annotations needed: cannot resolve `&'a T: Foo` --> $DIR/issue-21974.rs:10:1 | LL | trait Foo { diff --git a/src/test/ui/issues/issue-24424.rs b/src/test/ui/issues/issue-24424.rs index 8b8c5bc23e48b..9b74cd1230e8a 100644 --- a/src/test/ui/issues/issue-24424.rs +++ b/src/test/ui/issues/issue-24424.rs @@ -2,6 +2,6 @@ trait Trait1<'l0, T0> {} trait Trait0<'l0> {} impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} -//~^ ERROR type annotations required: cannot resolve `T0: Trait0<'l0>` +//~^ ERROR type annotations needed: cannot resolve `T0: Trait0<'l0>` fn main() {} diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr index 7ff019a30a864..8c539f7cedd19 100644 --- a/src/test/ui/issues/issue-24424.stderr +++ b/src/test/ui/issues/issue-24424.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>` +error[E0283]: type annotations needed: cannot resolve `T0: Trait0<'l0>` --> $DIR/issue-24424.rs:4:1 | LL | trait Trait0<'l0> {} diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr index 0dc9b0c9e10cd..c9dd92fca7dc8 100644 --- a/src/test/ui/issues/issue-29147.stderr +++ b/src/test/ui/issues/issue-29147.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `S5<_>: Foo` +error[E0283]: type annotations needed: cannot resolve `S5<_>: Foo` --> $DIR/issue-29147.rs:21:13 | LL | trait Foo { fn xxx(&self); } diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs index 40045bc758cff..9e9f92ed9ace5 100644 --- a/src/test/ui/issues/issue-54954.rs +++ b/src/test/ui/issues/issue-54954.rs @@ -1,7 +1,7 @@ #![feature(const_fn)] const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); -//~^ ERROR constant contains unimplemented expression type +//~^ ERROR type annotations needed trait Tt { const fn const_val() -> usize { @@ -11,6 +11,8 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + //~^ ERROR evaluation of constant value failed + //~| ERROR evaluation of constant value failed z } diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr index 29edb506c4b1c..56ccdaf7aac40 100644 --- a/src/test/ui/issues/issue-54954.stderr +++ b/src/test/ui/issues/issue-54954.stderr @@ -4,13 +4,28 @@ error[E0379]: trait fns cannot be declared const LL | const fn const_val() -> usize { | ^^^^^ trait fns cannot be const -error[E0019]: constant contains unimplemented expression type +error[E0283]: type annotations needed: cannot resolve `_: Tt` --> $DIR/issue-54954.rs:3:24 | LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | const fn const_val() -> usize { + | --------- - required by this bound in `Tt::const_val` + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-54954.rs:13:15 + | +LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + | ^^^^^^^ referenced constant has errors + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-54954.rs:13:34 + | +LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + | ^^^^^^^ referenced constant has errors -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0019, E0379. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0080, E0283, E0379. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json-short.stderr index 0a1fb567714fb..d9f68023ce76d 100644 --- a/src/test/ui/json-short.stderr +++ b/src/test/ui/json-short.stderr @@ -15,5 +15,3 @@ started: https://doc.rust-lang.org/book/ "} {"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error "} -{"message":"For more information about this error, try `rustc --explain E0601`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0601`. -"} diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs index e33f23c64dbe1..49fe7d1324ca8 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs @@ -15,7 +15,7 @@ impl Foo for Vec { } // This is very hokey: we have heuristics to suppress messages about -// type annotations required. But placing these two bits of code into +// type annotations needed. But placing these two bits of code into // distinct functions, in this order, causes us to print out both // errors I'd like to see. diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 7603f9650b54a..0b15d9bcfe68c 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -27,5 +27,5 @@ LL | v.push(|| *x = String::new()); error: aborting due to 3 previous errors -Some errors have detailed explanations: E0382, E0499. +Some errors have detailed explanations: E0382, E0499, E0524. For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/panic-runtime/transitive-link-a-bunch.rs b/src/test/ui/panic-runtime/transitive-link-a-bunch.rs index 9b083a640a6d3..5d72771c2dcff 100644 --- a/src/test/ui/panic-runtime/transitive-link-a-bunch.rs +++ b/src/test/ui/panic-runtime/transitive-link-a-bunch.rs @@ -7,9 +7,8 @@ // ignore-wasm32-bare compiled with panic=abort by default #![no_std] +#![no_main] extern crate wants_panic_runtime_unwind; extern crate wants_panic_runtime_abort; extern crate panic_runtime_lang_items; - -fn main() {} diff --git a/src/test/ui/panic-runtime/want-unwind-got-abort.rs b/src/test/ui/panic-runtime/want-unwind-got-abort.rs index c9ee8a032a3d3..4c25c09d6438f 100644 --- a/src/test/ui/panic-runtime/want-unwind-got-abort.rs +++ b/src/test/ui/panic-runtime/want-unwind-got-abort.rs @@ -4,8 +4,7 @@ // ignore-wasm32-bare compiled with panic=abort by default #![no_std] +#![no_main] extern crate panic_runtime_abort; extern crate panic_runtime_lang_items; - -fn main() {} diff --git a/src/test/ui/panic-runtime/want-unwind-got-abort2.rs b/src/test/ui/panic-runtime/want-unwind-got-abort2.rs index 5219826eec62f..478af451e7f65 100644 --- a/src/test/ui/panic-runtime/want-unwind-got-abort2.rs +++ b/src/test/ui/panic-runtime/want-unwind-got-abort2.rs @@ -5,8 +5,7 @@ // ignore-wasm32-bare compiled with panic=abort by default #![no_std] +#![no_main] extern crate wants_panic_runtime_abort; extern crate panic_runtime_lang_items; - -fn main() {} diff --git a/src/test/ui/parser/raw/raw-literal-self.rs b/src/test/ui/parser/raw/raw-literal-self.rs index 123a11b6f8543..a0c9e24c235d6 100644 --- a/src/test/ui/parser/raw/raw-literal-self.rs +++ b/src/test/ui/parser/raw/raw-literal-self.rs @@ -1,4 +1,4 @@ fn main() { - let r#self; + let r#self: (); //~^ ERROR `self` cannot be a raw identifier } diff --git a/src/test/ui/parser/raw/raw-literal-self.stderr b/src/test/ui/parser/raw/raw-literal-self.stderr index 9a330fcdf2aae..2a40dfe200cde 100644 --- a/src/test/ui/parser/raw/raw-literal-self.stderr +++ b/src/test/ui/parser/raw/raw-literal-self.stderr @@ -1,7 +1,7 @@ error: `self` cannot be a raw identifier --> $DIR/raw-literal-self.rs:2:9 | -LL | let r#self; +LL | let r#self: (); | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw-literal-underscore.rs b/src/test/ui/parser/raw/raw-literal-underscore.rs index 6d15f1e7f0afd..a9d9e13a9d9ec 100644 --- a/src/test/ui/parser/raw/raw-literal-underscore.rs +++ b/src/test/ui/parser/raw/raw-literal-underscore.rs @@ -1,4 +1,4 @@ fn main() { - let r#_; + let r#_: (); //~^ ERROR `_` cannot be a raw identifier } diff --git a/src/test/ui/parser/raw/raw-literal-underscore.stderr b/src/test/ui/parser/raw/raw-literal-underscore.stderr index d96b14f55a39b..d7a364d8579ef 100644 --- a/src/test/ui/parser/raw/raw-literal-underscore.stderr +++ b/src/test/ui/parser/raw/raw-literal-underscore.stderr @@ -1,7 +1,7 @@ error: `_` cannot be a raw identifier --> $DIR/raw-literal-underscore.rs:2:9 | -LL | let r#_; +LL | let r#_: (); | ^^^ error: aborting due to previous error diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs index 36a45a3ccdc4b..31620216e82e1 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -31,6 +31,7 @@ fn rest_patterns() { // Ident patterns: let x @ ..; //~ ERROR `..` patterns are not allowed here + //~^ ERROR type annotations needed let ref x @ ..; //~ ERROR `..` patterns are not allowed here let ref mut x @ ..; //~ ERROR `..` patterns are not allowed here diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr index 826f76b356cf1..be484e3a4d417 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -58,7 +58,7 @@ LL | let x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:34:17 + --> $DIR/rest-pat-semantic-disallowed.rs:35:17 | LL | let ref x @ ..; | ^^ @@ -66,7 +66,7 @@ LL | let ref x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:35:21 + --> $DIR/rest-pat-semantic-disallowed.rs:36:21 | LL | let ref mut x @ ..; | ^^ @@ -74,7 +74,7 @@ LL | let ref mut x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:42:9 + --> $DIR/rest-pat-semantic-disallowed.rs:43:9 | LL | .., | -- previously used here @@ -82,7 +82,7 @@ LL | .., | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:43:9 + --> $DIR/rest-pat-semantic-disallowed.rs:44:9 | LL | .., | -- previously used here @@ -91,7 +91,7 @@ LL | .. | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:48:9 + --> $DIR/rest-pat-semantic-disallowed.rs:49:9 | LL | .., | -- previously used here @@ -100,7 +100,7 @@ LL | .. | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:58:9 + --> $DIR/rest-pat-semantic-disallowed.rs:59:9 | LL | .., | -- previously used here @@ -108,7 +108,7 @@ LL | .., | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:59:9 + --> $DIR/rest-pat-semantic-disallowed.rs:60:9 | LL | .., | -- previously used here @@ -117,7 +117,7 @@ LL | .. | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:64:9 + --> $DIR/rest-pat-semantic-disallowed.rs:65:9 | LL | .., | -- previously used here @@ -126,7 +126,7 @@ LL | .. | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:72:9 + --> $DIR/rest-pat-semantic-disallowed.rs:73:9 | LL | .., | -- previously used here @@ -134,7 +134,7 @@ LL | .., | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:73:9 + --> $DIR/rest-pat-semantic-disallowed.rs:74:9 | LL | .., | -- previously used here @@ -143,7 +143,7 @@ LL | .. | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:77:17 + --> $DIR/rest-pat-semantic-disallowed.rs:78:17 | LL | .., | -- previously used here @@ -151,7 +151,7 @@ LL | ref x @ .., | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:78:21 + --> $DIR/rest-pat-semantic-disallowed.rs:79:21 | LL | .., | -- previously used here @@ -160,7 +160,7 @@ LL | ref mut y @ .., | ^^ can only be used once per slice pattern error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:79:18 + --> $DIR/rest-pat-semantic-disallowed.rs:80:18 | LL | (ref z @ ..), | ^^ @@ -168,7 +168,7 @@ LL | (ref z @ ..), = note: only allowed in tuple, tuple struct, and slice patterns error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:80:9 + --> $DIR/rest-pat-semantic-disallowed.rs:81:9 | LL | .., | -- previously used here @@ -184,5 +184,12 @@ LL | fn foo(..: u8) {} | = note: only allowed in tuple, tuple struct, and slice patterns -error: aborting due to 22 previous errors +error[E0282]: type annotations needed + --> $DIR/rest-pat-semantic-disallowed.rs:33:9 + | +LL | let x @ ..; + | ^^^^^^ consider giving this pattern a type + +error: aborting due to 23 previous errors +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/question-mark-type-infer.rs b/src/test/ui/question-mark-type-infer.rs index 2e7a342b95e17..95ee01a70cead 100644 --- a/src/test/ui/question-mark-type-infer.rs +++ b/src/test/ui/question-mark-type-infer.rs @@ -9,7 +9,7 @@ fn f(x: &i32) -> Result { fn g() -> Result, ()> { let l = [1, 2, 3, 4]; - l.iter().map(f).collect()? //~ ERROR type annotations required: cannot resolve + l.iter().map(f).collect()? //~ ERROR type annotations needed: cannot resolve } fn main() { diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr index f62a540572c93..53a170e7d431c 100644 --- a/src/test/ui/question-mark-type-infer.stderr +++ b/src/test/ui/question-mark-type-infer.stderr @@ -1,4 +1,4 @@ -error[E0284]: type annotations required: cannot resolve `<_ as std::ops::Try>::Ok == _` +error[E0284]: type annotations needed: cannot resolve `<_ as std::ops::Try>::Ok == _` --> $DIR/question-mark-type-infer.rs:12:5 | LL | l.iter().map(f).collect()? diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs index 9f4e2710dc420..e2680446f851a 100644 --- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs +++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs @@ -20,7 +20,7 @@ type Alias = extern "C" fn(#[id] u8, #[id] ...); fn free(#[id] arg1: u8) { //~^ ERROR expected an inert attribute, found an attribute macro - let lam = |#[id] W(x), #[id] y| (); + let lam = |#[id] W(x), #[id] y: usize| (); //~^ ERROR expected an inert attribute, found an attribute macro //~| ERROR expected an inert attribute, found an attribute macro } diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr index b4946fa74943f..4654dc1b496f2 100644 --- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr +++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr @@ -37,13 +37,13 @@ LL | fn free(#[id] arg1: u8) { error: expected an inert attribute, found an attribute macro --> $DIR/proc-macro-cannot-be-used.rs:23:16 | -LL | let lam = |#[id] W(x), #[id] y| (); +LL | let lam = |#[id] W(x), #[id] y: usize| (); | ^^^^^ error: expected an inert attribute, found an attribute macro --> $DIR/proc-macro-cannot-be-used.rs:23:28 | -LL | let lam = |#[id] W(x), #[id] y| (); +LL | let lam = |#[id] W(x), #[id] y: usize| (); | ^^^^^ error: expected an inert attribute, found an attribute macro diff --git a/src/test/ui/traits/trait-static-method-generic-inference.rs b/src/test/ui/traits/trait-static-method-generic-inference.rs index c08bd5cb13566..759416d1901db 100644 --- a/src/test/ui/traits/trait-static-method-generic-inference.rs +++ b/src/test/ui/traits/trait-static-method-generic-inference.rs @@ -22,7 +22,7 @@ mod base { pub fn foo() { let _f: base::Foo = base::HasNew::new(); - //~^ ERROR type annotations required + //~^ ERROR type annotations needed } fn main() { } diff --git a/src/test/ui/traits/trait-static-method-generic-inference.stderr b/src/test/ui/traits/trait-static-method-generic-inference.stderr index a99536d31ef84..22931c5ba32e9 100644 --- a/src/test/ui/traits/trait-static-method-generic-inference.stderr +++ b/src/test/ui/traits/trait-static-method-generic-inference.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `_: base::HasNew` +error[E0283]: type annotations needed: cannot resolve `_: base::HasNew` --> $DIR/trait-static-method-generic-inference.rs:24:25 | LL | fn new() -> T; diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs index ddf16f7699517..3b1521d5c028b 100644 --- a/src/test/ui/type/type-annotation-needed.rs +++ b/src/test/ui/type/type-annotation-needed.rs @@ -4,5 +4,5 @@ fn foo>(x: i32) {} fn main() { foo(42); - //~^ ERROR type annotations required + //~^ ERROR type annotations needed } diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr index 01287b727d2f8..460bbe9dbc4f9 100644 --- a/src/test/ui/type/type-annotation-needed.stderr +++ b/src/test/ui/type/type-annotation-needed.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `_: std::convert::Into` +error[E0283]: type annotations needed: cannot resolve `_: std::convert::Into` --> $DIR/type-annotation-needed.rs:6:5 | LL | fn foo>(x: i32) {} diff --git a/src/test/ui/type/type-check/issue-40294.rs b/src/test/ui/type/type-check/issue-40294.rs index c73acdc467ee2..7e6429ccfbe30 100644 --- a/src/test/ui/type/type-check/issue-40294.rs +++ b/src/test/ui/type/type-check/issue-40294.rs @@ -2,7 +2,7 @@ trait Foo: Sized { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required +fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed where &'a T : Foo, &'b T : Foo { diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr index 732a81c8a244a..508783aaf2b0e 100644 --- a/src/test/ui/type/type-check/issue-40294.stderr +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations required: cannot resolve `&'a T: Foo` +error[E0283]: type annotations needed: cannot resolve `&'a T: Foo` --> $DIR/issue-40294.rs:5:1 | LL | trait Foo: Sized { diff --git a/src/test/ui/type/type-path-err-node-types.rs b/src/test/ui/type/type-path-err-node-types.rs index a2cc5070db482..15adfebb33400 100644 --- a/src/test/ui/type/type-path-err-node-types.rs +++ b/src/test/ui/type/type-path-err-node-types.rs @@ -20,7 +20,7 @@ fn method() { } fn closure() { - let _ = |a, b: _| -> _ { 0 }; // OK + let _ = |a, b: _| -> _ { 0 }; //~ ERROR type annotations needed } fn main() {} diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr index ed744478f26f8..cd93525c76219 100644 --- a/src/test/ui/type/type-path-err-node-types.stderr +++ b/src/test/ui/type/type-path-err-node-types.stderr @@ -22,7 +22,13 @@ error[E0425]: cannot find value `nonexistent` in this scope LL | nonexistent.nonexistent::(); | ^^^^^^^^^^^ not found in this scope -error: aborting due to 4 previous errors +error[E0282]: type annotations needed + --> $DIR/type-path-err-node-types.rs:23:14 + | +LL | let _ = |a, b: _| -> _ { 0 }; + | ^ consider giving this closure parameter a type + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0412, E0425, E0433. -For more information about an error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0282, E0412, E0425, E0433. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/tools/cargo b/src/tools/cargo index b6c6f685b38d5..aa6b7e01abce3 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit b6c6f685b38d523580813b0031677c2298f458ea +Subproject commit aa6b7e01abce30091cc594cb23a15c46cead6e24