diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index f93f3e72f83e7..7851ea3e363a4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1856,6 +1856,7 @@ mod __test { doc_tests: DocTests::No, bless: false, compare_mode: None, + rustfix_coverage: false, }; let build = Build::new(config); @@ -1897,6 +1898,7 @@ mod __test { doc_tests: DocTests::No, bless: false, compare_mode: None, + rustfix_coverage: false, }; let build = Build::new(config); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 0f9a4271ac062..a1f89d6c86f1d 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -56,6 +56,7 @@ pub enum Subcommand { rustc_args: Vec, fail_fast: bool, doc_tests: DocTests, + rustfix_coverage: bool, }, Bench { paths: Vec, @@ -188,6 +189,12 @@ To learn more about a subcommand, run `./x.py -h`" "mode describing what file the actual ui output will be compared to", "COMPARE MODE", ); + opts.optflag( + "", + "rustfix-coverage", + "enable this to generate a Rustfix coverage file, which is saved in \ + `//rustfix_missing_coverage.txt`", + ); } "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); @@ -363,6 +370,7 @@ Arguments: test_args: matches.opt_strs("test-args"), rustc_args: matches.opt_strs("rustc-args"), fail_fast: !matches.opt_present("no-fail-fast"), + rustfix_coverage: matches.opt_present("rustfix-coverage"), doc_tests: if matches.opt_present("doc") { DocTests::Only } else if matches.opt_present("no-doc") { @@ -467,6 +475,13 @@ impl Subcommand { } } + pub fn rustfix_coverage(&self) -> bool { + match *self { + Subcommand::Test { rustfix_coverage, .. } => rustfix_coverage, + _ => false, + } + } + pub fn compare_mode(&self) -> Option<&str> { match *self { Subcommand::Test { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index bbe1872d3958d..41c73f307b6d0 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1284,6 +1284,10 @@ impl Step for Compiletest { cmd.arg("--android-cross-path").arg(""); } + if builder.config.cmd.rustfix_coverage() { + cmd.arg("--rustfix-coverage"); + } + builder.ci_env.force_coloring_in_ci(&mut cmd); let _folder = builder.fold_output(|| format!("test_{}", suite)); diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 231a1f199bdd6..896710609642a 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -190,7 +190,7 @@ impl<'a> VaList<'a> { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] - pub unsafe fn copy(&self, f: F) -> R + pub unsafe fn with_copy(&self, f: F) -> R where F: for<'copy> FnOnce(VaList<'copy>) -> R { #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 3fcae6b94b06d..01da5518868a1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -112,6 +112,24 @@ nonzero_integers! { #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize); } +macro_rules! from_str_radix_nzint_impl { + ($($t:ty)*) => {$( + #[stable(feature = "nonzero_parse", since = "1.35.0")] + impl FromStr for $t { + type Err = ParseIntError; + fn from_str(src: &str) -> Result { + Self::new(from_str_radix(src, 10)?) + .ok_or(ParseIntError { + kind: IntErrorKind::Zero + }) + } + } + )*} +} + +from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize + NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize } + /// Provides intentionally-wrapped arithmetic on `T`. /// /// Operations like `+` on `u32` values is intended to never overflow, @@ -4768,6 +4786,11 @@ pub enum IntErrorKind { Overflow, /// Integer is too small to store in target integer type. Underflow, + /// Value was Zero + /// + /// This variant will be emitted when the parsing string has a value of zero, which + /// would be illegal for non-zero types. + Zero, } impl ParseIntError { @@ -4790,6 +4813,7 @@ impl ParseIntError { IntErrorKind::InvalidDigit => "invalid digit found in string", IntErrorKind::Overflow => "number too large to fit in target type", IntErrorKind::Underflow => "number too small to fit in target type", + IntErrorKind::Zero => "number would be zero for non-zero type", } } } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 08dda4bcc3d24..2ed25a341021b 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -31,6 +31,7 @@ #![feature(slice_internals)] #![feature(slice_partition_dedup)] #![feature(copy_within)] +#![feature(int_error_matching)] extern crate core; extern crate test; diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index 4532568ee0c16..77e484601bc22 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -1,6 +1,5 @@ -use core::num::{NonZeroU32, NonZeroI32}; -use core::option::Option; -use core::option::Option::{Some, None}; +use core::num::{IntErrorKind, NonZeroI32, NonZeroI8, NonZeroU32, NonZeroU8}; +use core::option::Option::{self, None, Some}; use std::mem::size_of; #[test] @@ -126,3 +125,24 @@ fn test_from_signed_nonzero() { let num: i32 = nz.into(); assert_eq!(num, 1i32); } + +#[test] +fn test_from_str() { + assert_eq!("123".parse::(), Ok(NonZeroU8::new(123).unwrap())); + assert_eq!( + "0".parse::().err().map(|e| e.kind().clone()), + Some(IntErrorKind::Zero) + ); + assert_eq!( + "-1".parse::().err().map(|e| e.kind().clone()), + Some(IntErrorKind::InvalidDigit) + ); + assert_eq!( + "-129".parse::().err().map(|e| e.kind().clone()), + Some(IntErrorKind::Underflow) + ); + assert_eq!( + "257".parse::().err().map(|e| e.kind().clone()), + Some(IntErrorKind::Overflow) + ); +} diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 9c6d03af9f51b..1f4f7d344245d 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -85,11 +85,6 @@ macro_rules! is_anon_attr { ($attr:ident) => (false); } -macro_rules! is_input_attr { - (input) => (true); - ($attr:ident) => (false); -} - macro_rules! is_eval_always_attr { (eval_always) => (true); ($attr:ident) => (false); @@ -99,10 +94,6 @@ macro_rules! contains_anon_attr { ($($attr:ident),*) => ({$(is_anon_attr!($attr) | )* false}); } -macro_rules! contains_input_attr { - ($($attr:ident),*) => ({$(is_input_attr!($attr) | )* false}); -} - macro_rules! contains_eval_always_attr { ($($attr:ident),*) => ({$(is_eval_always_attr!($attr) | )* false}); } @@ -151,7 +142,7 @@ macro_rules! define_dep_nodes { } } - // FIXME: Make `is_anon`, `is_input`, `is_eval_always` and `has_params` properties + // FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties // of queries #[inline(always)] pub fn is_anon(&self) -> bool { @@ -162,15 +153,6 @@ macro_rules! define_dep_nodes { } } - #[inline(always)] - pub fn is_input(&self) -> bool { - match *self { - $( - DepKind :: $variant => { contains_input_attr!($($attr),*) } - )* - } - } - #[inline(always)] pub fn is_eval_always(&self) -> bool { match *self { @@ -438,17 +420,17 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain // access to the krate, but you must remember to add suitable // edges yourself for the individual items that you read. - [input] Krate, + [eval_always] Krate, // Represents the body of a function or method. The def-id is that of the // function/method. - [input] HirBody(DefId), + [eval_always] HirBody(DefId), // Represents the HIR node with the given node-id - [input] Hir(DefId), + [eval_always] Hir(DefId), // Represents metadata from an extern crate. - [input] CrateMetadata(CrateNum), + [eval_always] CrateMetadata(CrateNum), // Represents different phases in the compiler. [] RegionScopeTree(DefId), @@ -481,7 +463,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] CollectModItemTypes(DefId), [] Reachability, - [eval_always] CrateVariances, + [] CrateVariances, // Nodes representing bits of computed IR in the tcx. Each shared // table in the tcx (or elsewhere) maps to one of these @@ -534,7 +516,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> // The set of impls for a given trait. [] TraitImpls(DefId), - [input] AllLocalTraitImpls, + [eval_always] AllLocalTraitImpls, [anon] TraitSelect, @@ -546,7 +528,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> // to make type debuginfo to be source location independent. Declaring // DefSpan an input makes sure that changes to these are always detected // regardless of HIR hashing. - [input] DefSpan(DefId), + [eval_always] DefSpan(DefId), [] LookupStability(DefId), [] LookupDeprecationEntry(DefId), [] ConstIsRvaluePromotableToStatic(DefId), @@ -564,10 +546,10 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] IsCompilerBuiltins(CrateNum), [] HasGlobalAllocator(CrateNum), [] HasPanicHandler(CrateNum), - [input] ExternCrate(DefId), + [eval_always] ExternCrate(DefId), [] Specializes { impl1: DefId, impl2: DefId }, - [input] InScopeTraits(DefIndex), - [input] ModuleExports(DefId), + [eval_always] InScopeTraits(DefIndex), + [eval_always] ModuleExports(DefId), [] IsSanitizerRuntime(CrateNum), [] IsProfilerRuntime(CrateNum), [] GetPanicStrategy(CrateNum), @@ -580,10 +562,10 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] EntryFn(CrateNum), [] PluginRegistrarFn(CrateNum), [] ProcMacroDeclsStatic(CrateNum), - [input] CrateDisambiguator(CrateNum), - [input] CrateHash(CrateNum), - [input] OriginalCrateName(CrateNum), - [input] ExtraFileName(CrateNum), + [eval_always] CrateDisambiguator(CrateNum), + [eval_always] CrateHash(CrateNum), + [eval_always] OriginalCrateName(CrateNum), + [eval_always] ExtraFileName(CrateNum), [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId }, [] AllTraitImplementations(CrateNum), @@ -592,7 +574,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] IsDllimportForeignItem(DefId), [] IsStaticallyIncludedForeignItem(DefId), [] NativeLibraryKind(DefId), - [input] LinkArgs, + [eval_always] LinkArgs, [] ResolveLifetimes(CrateNum), [] NamedRegion(DefIndex), @@ -600,8 +582,8 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] ObjectLifetimeDefaults(DefIndex), [] Visibility(DefId), - [input] DepKind(CrateNum), - [input] CrateName(CrateNum), + [eval_always] DepKind(CrateNum), + [eval_always] CrateName(CrateNum), [] ItemChildren(DefId), [] ExternModStmtCnum(DefId), [eval_always] GetLibFeatures, @@ -610,24 +592,24 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] DefinedLangItems(CrateNum), [] MissingLangItems(CrateNum), [] VisibleParentMap, - [input] MissingExternCrateItem(CrateNum), - [input] UsedCrateSource(CrateNum), - [input] PostorderCnums, - - [input] Freevars(DefId), - [input] MaybeUnusedTraitImport(DefId), - [input] MaybeUnusedExternCrates, - [input] NamesImportedByGlobUse(DefId), + [eval_always] MissingExternCrateItem(CrateNum), + [eval_always] UsedCrateSource(CrateNum), + [eval_always] PostorderCnums, + + [eval_always] Freevars(DefId), + [eval_always] MaybeUnusedTraitImport(DefId), + [eval_always] MaybeUnusedExternCrates, + [eval_always] NamesImportedByGlobUse(DefId), [eval_always] StabilityIndex, [eval_always] AllTraits, - [input] AllCrateNums, + [eval_always] AllCrateNums, [] ExportedSymbols(CrateNum), [eval_always] CollectAndPartitionMonoItems, [] IsCodegenedItem(DefId), [] CodegenUnit(InternedString), [] BackendOptimizationLevel(CrateNum), [] CompileCodegenUnit(InternedString), - [input] OutputFilenames, + [eval_always] OutputFilenames, [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>), [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>), [] ImpliedOutlivesBounds(CanonicalTyGoal<'tcx>), @@ -646,11 +628,11 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] SubstituteNormalizeAndTestPredicates { key: (DefId, SubstsRef<'tcx>) }, [] MethodAutoderefSteps(CanonicalTyGoal<'tcx>), - [input] TargetFeaturesWhitelist, + [eval_always] TargetFeaturesWhitelist, [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> }, - [input] Features, + [eval_always] Features, [] ForeignModules(CrateNum), diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 8a2f79e6793c0..db81a9d826f8c 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -388,10 +388,7 @@ impl DepGraph { |_| None, |data, key, fingerprint, _| { let mut current = data.borrow_mut(); - let krate_idx = current.node_to_node_index[ - &DepNode::new_no_params(DepKind::Krate) - ]; - current.alloc_node(key, smallvec![krate_idx], fingerprint) + current.alloc_node(key, smallvec![], fingerprint) }, hash_result) } @@ -576,7 +573,7 @@ impl DepGraph { tcx: TyCtxt<'_, '_, '_>, dep_node: &DepNode ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { - debug_assert!(!dep_node.kind.is_input()); + debug_assert!(!dep_node.kind.is_eval_always()); // Return None if the dep graph is disabled let data = self.data.as_ref()?; @@ -620,8 +617,8 @@ impl DepGraph { debug_assert!(data.colors.get(prev_dep_node_index).is_none()); } - // We never try to mark inputs as green - debug_assert!(!dep_node.kind.is_input()); + // We never try to mark eval_always nodes as green + debug_assert!(!dep_node.kind.is_eval_always()); debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node); @@ -658,8 +655,8 @@ impl DepGraph { let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index); // We don't know the state of this dependency. If it isn't - // an input node, let's try to mark it green recursively. - if !dep_dep_node.kind.is_input() { + // an eval_always node, let's try to mark it green recursively. + if !dep_dep_node.kind.is_eval_always() { debug!("try_mark_previous_green({:?}) --- state of dependency {:?} \ is unknown, trying to mark it green", dep_node, dep_dep_node); @@ -694,7 +691,7 @@ impl DepGraph { } } _ => { - // For other kinds of inputs it's OK to be + // For other kinds of nodes it's OK to be // forced. } } @@ -1017,33 +1014,11 @@ impl CurrentDepGraph { task_deps: TaskDeps, fingerprint: Fingerprint ) -> DepNodeIndex { - // If this is an input node, we expect that it either has no - // dependencies, or that it just depends on DepKind::CrateMetadata - // or DepKind::Krate. This happens for some "thin wrapper queries" - // like `crate_disambiguator` which sometimes have zero deps (for - // when called for LOCAL_CRATE) or they depend on a CrateMetadata - // node. - if cfg!(debug_assertions) { - if node.kind.is_input() && task_deps.reads.len() > 0 && - // FIXME(mw): Special case for DefSpan until Spans are handled - // better in general. - node.kind != DepKind::DefSpan && - task_deps.reads.iter().any(|&i| { - !(self.data[i].node.kind == DepKind::CrateMetadata || - self.data[i].node.kind == DepKind::Krate) - }) - { - bug!("Input node {:?} with unexpected reads: {:?}", - node, - task_deps.reads.iter().map(|&i| self.data[i].node).collect::>()) - } - } - self.alloc_node(node, task_deps.reads, fingerprint) } fn complete_anon_task(&mut self, kind: DepKind, task_deps: TaskDeps) -> DepNodeIndex { - debug_assert!(!kind.is_input()); + debug_assert!(!kind.is_eval_always()); let mut fingerprint = self.anon_id_seed; let mut hasher = StableHasher::new(); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index f906ff9963d9a..c0579ef0f7a96 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -153,7 +153,7 @@ impl Forest { &self.krate } - /// This is internally in the depedency tracking system. + /// This is used internally in the dependency tracking system. /// Use the `krate` method to ensure your dependency on the /// crate is tracked. pub fn untracked_krate<'hir>(&'hir self) -> &'hir Crate { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 0a0a1dee7f07c..8e8543dd334f6 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -98,8 +98,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn lookup_and_handle_method(&mut self, id: hir::HirId) { - if let Some(def) = self.tables.type_dependent_defs().get(id) { - self.check_def_id(def.def_id()); + if let Some(def_id) = self.tables.type_dependent_def_id(id) { + self.check_def_id(def_id); } else { bug!("no type-dependent def for method"); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 6c8d9fe29d7a0..01e57273e54a1 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -559,8 +559,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } ty::Error => { } _ => { - if let Some(def) = self.mc.tables.type_dependent_defs().get(call.hir_id) { - let def_id = def.def_id(); + if let Some(def_id) = self.mc.tables.type_dependent_def_id(call.hir_id) { let call_scope = region::Scope { id: call.hir_id.local_id, data: region::ScopeData::Node diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index b57f96f2d469d..b55e840596b85 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -97,7 +97,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(self.tables.qpath_def(qpath, expr.hir_id)) } hir::ExprKind::MethodCall(..) => { - self.tables.type_dependent_defs().get(expr.hir_id).cloned() + self.tables.type_dependent_def(expr.hir_id) } _ => None }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0ae7c10cf5630..eb629dc44c156 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1706,6 +1706,12 @@ pub fn rustc_short_optgroups() -> Vec { "Specify the name of the crate being built", "NAME", ), + opt::opt_s( + "", + "edition", + "Specify which edition of the compiler to use when compiling code.", + EDITION_NAME_LIST, + ), opt::multi_s( "", "emit", @@ -1808,12 +1814,6 @@ pub fn rustc_optgroups() -> Vec { `expanded,identified` (fully parenthesized, AST nodes with IDs).", "TYPE", ), - opt::opt_s( - "", - "edition", - "Specify which edition of the compiler to use when compiling code.", - EDITION_NAME_LIST, - ), opt::multi_s( "", "remap-path-prefix", diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6de0a39c91b51..ea003ba1ac701 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -482,6 +482,15 @@ impl<'tcx> TypeckTables<'tcx> { } } + pub fn type_dependent_def(&self, id: HirId) -> Option { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.type_dependent_defs.get(&id.local_id).cloned() + } + + pub fn type_dependent_def_id(&self, id: HirId) -> Option { + self.type_dependent_def(id).map(|def| def.def_id()) + } + pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut<'_, Def> { LocalTableInContextMut { local_id_root: self.local_id_root, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index b2b141fd0f514..c35cea7883f00 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -414,7 +414,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return result; } - if !dep_node.kind.is_input() { + if !dep_node.kind.is_eval_always() { // The diagnostics for this query will be // promoted to the current session during // try_mark_green(), so we can ignore them here. @@ -601,9 +601,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub(super) fn ensure_query>(self, key: Q::Key) -> () { let dep_node = Q::to_dep_node(self, &key); - // Ensuring an "input" or anonymous query makes no sense + if dep_node.kind.is_eval_always() { + let _ = self.get_query::(DUMMY_SP, key); + return; + } + + // Ensuring an anonymous query makes no sense assert!(!dep_node.kind.is_anon()); - assert!(!dep_node.kind.is_input()); if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() { // A None return from `try_mark_green_and_read` means that this is either // a new dep node or that the dep node has already been marked red. diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 8efa025e3dd9d..042a8c60cfaab 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -22,6 +22,7 @@ use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def::CtorKind; use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::ich::NodeIdHashingMode; +use rustc::mir::interpret::truncate; use rustc_data_structures::fingerprint::Fingerprint; use rustc::ty::Instance; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; @@ -1368,7 +1369,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { let value = (i.as_u32() as u128) .wrapping_sub(niche_variants.start().as_u32() as u128) .wrapping_add(niche_start); - let value = value & ((1u128 << niche.value.size(cx).bits()) - 1); + let value = truncate(value, niche.value.size(cx)); Some(value as u64) }; diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 7f1aebace8fc6..a0e2dcd646df8 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -152,17 +152,20 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { LinkerFlavor::PtxLinker => "rust-ptx-linker", }), flavor)), (Some(linker), None) => { - let stem = if linker.extension().and_then(|ext| ext.to_str()) == Some("exe") { - linker.file_stem().and_then(|stem| stem.to_str()) - } else { - linker.to_str() - }.unwrap_or_else(|| { - sess.fatal("couldn't extract file stem from specified linker"); - }).to_owned(); + let stem = linker + .file_stem() + .and_then(|stem| stem.to_str()) + .unwrap_or_else(|| { + sess.fatal("couldn't extract file stem from specified linker") + }); let flavor = if stem == "emcc" { LinkerFlavor::Em - } else if stem == "gcc" || stem.ends_with("-gcc") { + } else if stem == "gcc" + || stem.ends_with("-gcc") + || stem == "clang" + || stem.ends_with("-clang") + { LinkerFlavor::Gcc } else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") { LinkerFlavor::Ld diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 244505976b6c2..c99fc17dd89a1 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -160,7 +160,16 @@ impl<'a> GccLinker<'a> { } fn takes_hints(&self) -> bool { - !self.sess.target.target.options.is_like_osx + // Really this function only returns true if the underlying linker + // configured for a compiler is binutils `ld.bfd` and `ld.gold`. We + // don't really have a foolproof way to detect that, so rule out some + // platforms where currently this is guaranteed to *not* be the case: + // + // * On OSX they have their own linker, not binutils' + // * For WebAssembly the only functional linker is LLD, which doesn't + // support hint flags + !self.sess.target.target.options.is_like_osx && + self.sess.target.target.arch != "wasm32" } // Some platforms take hints about whether a library is static or dynamic. @@ -375,6 +384,13 @@ impl<'a> Linker for GccLinker<'a> { return } + // Symbol visibility takes care of this for the WebAssembly. + // Additionally the only known linker, LLD, doesn't support the script + // arguments just yet + if self.sess.target.target.arch == "wasm32" { + return; + } + let mut arg = OsString::new(); let path = tmpdir.join("list"); @@ -441,13 +457,13 @@ impl<'a> Linker for GccLinker<'a> { } fn group_start(&mut self) { - if !self.sess.target.target.options.is_like_osx { + if self.takes_hints() { self.linker_arg("--start-group"); } } fn group_end(&mut self) { - if !self.sess.target.target.options.is_like_osx { + if self.takes_hints() { self.linker_arg("--end-group"); } } @@ -862,59 +878,7 @@ pub struct WasmLd<'a> { } impl<'a> WasmLd<'a> { - fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { - // There have been reports in the wild (rustwasm/wasm-bindgen#119) of - // using threads causing weird hangs and bugs. Disable it entirely as - // this isn't yet the bottleneck of compilation at all anyway. - cmd.arg("--no-threads"); - - // By default LLD only gives us one page of stack (64k) which is a - // little small. Default to a larger stack closer to other PC platforms - // (1MB) and users can always inject their own link-args to override this. - cmd.arg("-z").arg("stack-size=1048576"); - - // By default LLD's memory layout is: - // - // 1. First, a blank page - // 2. Next, all static data - // 3. Finally, the main stack (which grows down) - // - // This has the unfortunate consequence that on stack overflows you - // corrupt static data and can cause some exceedingly weird bugs. To - // help detect this a little sooner we instead request that the stack is - // placed before static data. - // - // This means that we'll generate slightly larger binaries as references - // to static data will take more bytes in the ULEB128 encoding, but - // stack overflow will be guaranteed to trap as it underflows instead of - // corrupting static data. - cmd.arg("--stack-first"); - - // FIXME we probably shouldn't pass this but instead pass an explicit - // whitelist of symbols we'll allow to be undefined. Unfortunately - // though we can't handle symbols like `log10` that LLVM injects at a - // super late date without actually parsing object files. For now let's - // stick to this and hopefully fix it before stabilization happens. - cmd.arg("--allow-undefined"); - - // For now we just never have an entry symbol - cmd.arg("--no-entry"); - - // Rust code should never have warnings, and warnings are often - // indicative of bugs, let's prevent them. - cmd.arg("--fatal-warnings"); - - // The symbol visibility story is a bit in flux right now with LLD. - // It's... not entirely clear to me what's going on, but this looks to - // make everything work when `export_symbols` isn't otherwise called for - // things like executables. - cmd.arg("--export-dynamic"); - - // LLD only implements C++-like demangling, which doesn't match our own - // mangling scheme. Tell LLD to not demangle anything and leave it up to - // us to demangle these symbols later. - cmd.arg("--no-demangle"); - + fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { WasmLd { cmd, sess, info } } } @@ -1010,6 +974,7 @@ impl<'a> Linker for WasmLd<'a> { } fn build_dylib(&mut self, _out_filename: &Path) { + self.cmd.arg("--no-entry"); } fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index ebbd27798419b..37c147d93d85c 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } }, hir::ExprKind::MethodCall(..) => { - cx.tables.type_dependent_defs().get(expr.hir_id).cloned() + cx.tables.type_dependent_def(expr.hir_id) }, _ => None }; diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index fac75989aa590..95701204cab6d 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -19,6 +19,7 @@ use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; +use syntax::source_map::CompilerDesugaringKind; use super::borrow_set::BorrowData; use super::{Context, MirBorrowckCtxt}; @@ -154,6 +155,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { span, format!("value moved{} here, in previous iteration of loop", move_msg), ); + if Some(CompilerDesugaringKind::ForLoop) == span.compiler_desugaring_kind() { + if let Ok(snippet) = self.infcx.tcx.sess.source_map() + .span_to_snippet(span) + { + err.span_suggestion( + move_span, + "consider borrowing this to avoid moving it into the for loop", + format!("&{}", snippet), + Applicability::MaybeIncorrect, + ); + } + } is_loop_move = true; } else if move_site.traversed_back_edge { err.span_label( @@ -291,8 +304,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { format!("move occurs due to use{}", move_spans.describe()) ); - self.explain_why_borrow_contains_point(context, borrow, None) - .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + self.explain_why_borrow_contains_point( + context, + borrow, + None, + ).add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", Some(borrow_span)); err.buffer(&mut self.errors_buffer); } @@ -329,7 +345,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { }); self.explain_why_borrow_contains_point(context, borrow, None) - .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None); err.buffer(&mut self.errors_buffer); } @@ -542,8 +558,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { )); } - explanation - .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc); + explanation.add_explanation_to_diagnostic( + self.infcx.tcx, + self.mir, + &mut err, + first_borrow_desc, + None, + ); err.buffer(&mut self.errors_buffer); } @@ -866,7 +887,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if let BorrowExplanation::MustBeValidFor { .. } = explanation { } else { - explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + explanation.add_explanation_to_diagnostic( + self.infcx.tcx, + self.mir, + &mut err, + "", + None, + ); } } else { err.span_label(borrow_span, "borrowed value does not live long enough"); @@ -886,7 +913,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { format!("value captured here{}", within), ); - explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None); } err @@ -946,7 +973,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => {} } - explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None); err.buffer(&mut self.errors_buffer); } @@ -1027,7 +1054,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } _ => {} } - explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None); let within = if borrow_spans.for_generator() { " by generator" @@ -1367,7 +1394,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); self.explain_why_borrow_contains_point(context, loan, None) - .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, ""); + .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None); err.buffer(&mut self.errors_buffer); } diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index dfa5af444d37e..67b77605f3c92 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -56,17 +56,23 @@ impl BorrowExplanation { mir: &Mir<'tcx>, err: &mut DiagnosticBuilder<'_>, borrow_desc: &str, + borrow_span: Option, ) { match *self { BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => { let message = match later_use_kind { - LaterUseKind::TraitCapture => "borrow later captured here by trait object", - LaterUseKind::ClosureCapture => "borrow later captured here by closure", - LaterUseKind::Call => "borrow later used by call", - LaterUseKind::FakeLetRead => "borrow later stored here", - LaterUseKind::Other => "borrow later used here", + LaterUseKind::TraitCapture => "captured here by trait object", + LaterUseKind::ClosureCapture => "captured here by closure", + LaterUseKind::Call => "used by call", + LaterUseKind::FakeLetRead => "stored here", + LaterUseKind::Other => "used here", }; - err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message)); + if !borrow_span.map(|sp| sp.overlaps(var_or_use_span)).unwrap_or(false) { + err.span_label( + var_or_use_span, + format!("{}borrow later {}", borrow_desc, message), + ); + } } BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => { let message = match later_use_kind { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 2ca44ecaba220..e4f92f81e9ff6 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -834,13 +834,11 @@ fn method_callee<'a, 'gcx, 'tcx>( let (def_id, substs, user_ty) = match overloaded_callee { Some((def_id, substs)) => (def_id, substs, None), None => { - let type_dependent_defs = cx.tables().type_dependent_defs(); - let def = type_dependent_defs - .get(expr.hir_id) + let def = cx.tables().type_dependent_def(expr.hir_id) .unwrap_or_else(|| { span_bug!(expr.span, "no type-dependent def for method callee") }); - let user_ty = user_substs_applied_to_def(cx, expr.hir_id, def); + let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def); debug!("method_callee: user_ty={:?}", user_ty); (def.def_id(), cx.tables().node_substs(expr.hir_id), user_ty) } diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 71eb6ed7e0517..a0a0d7be1b95d 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -405,8 +405,7 @@ fn check_expr_kind<'a, 'tcx>( for index in hirvec.iter() { method_call_result &= v.check_expr(index); } - if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) { - let def_id = def.def_id(); + if let Some(def_id) = v.tables.type_dependent_def_id(e.hir_id) { match v.tcx.associated_item(def_id).container { ty::ImplContainer(_) => method_call_result & v.handle_const_fn_call(def_id), ty::TraitContainer(_) => NotPromotable, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f155beaaff220..adb1a4b130887 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1053,8 +1053,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { hir::ExprKind::MethodCall(_, span, _) => { // Method calls have to be checked specially. self.span = span; - if let Some(def) = self.tables.type_dependent_defs().get(expr.hir_id) { - if self.visit(self.tcx.type_of(def.def_id())) { + if let Some(def_id) = self.tables.type_dependent_def_id(expr.hir_id) { + if self.visit(self.tcx.type_of(def_id)) { return; } } else { @@ -1083,7 +1083,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { _ => None, } hir::QPath::TypeRelative(..) => { - self.tables.type_dependent_defs().get(id).cloned() + self.tables.type_dependent_def(id) } }; if let Some(def) = def { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 828ef802dd714..898ea62046d48 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -573,8 +573,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ExprKind::MethodCall(ref seg, ..) => { let expr_hir_id = self.tcx.hir().definitions().node_to_hir_id(expr.id); - let method_id = match self.tables.type_dependent_defs().get(expr_hir_id) { - Some(id) => id.def_id(), + let method_id = match self.tables.type_dependent_def_id(expr_hir_id) { + Some(id) => id, None => { debug!("Could not resolve method id for {:?}", expr); return None; diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index fdb1db645c3c4..401b81ee98723 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -66,6 +66,7 @@ mod l4re_base; mod fuchsia_base; mod redox_base; mod riscv_base; +mod wasm32_base; #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs new file mode 100644 index 0000000000000..c7e75b4fa0903 --- /dev/null +++ b/src/librustc_target/spec/wasm32_base.rs @@ -0,0 +1,123 @@ +use std::collections::BTreeMap; +use super::{LldFlavor, TargetOptions, PanicStrategy, LinkerFlavor}; + +pub fn options() -> TargetOptions { + let mut lld_args = Vec::new(); + let mut clang_args = Vec::new(); + let mut arg = |arg: &str| { + lld_args.push(arg.to_string()); + clang_args.push(format!("-Wl,{}", arg)); + }; + + // There have been reports in the wild (rustwasm/wasm-bindgen#119) of + // using threads causing weird hangs and bugs. Disable it entirely as + // this isn't yet the bottleneck of compilation at all anyway. + // + // FIXME: we should file an upstream issue with LLD about this + arg("--no-threads"); + + // By default LLD only gives us one page of stack (64k) which is a + // little small. Default to a larger stack closer to other PC platforms + // (1MB) and users can always inject their own link-args to override this. + arg("-z"); + arg("stack-size=1048576"); + + // By default LLD's memory layout is: + // + // 1. First, a blank page + // 2. Next, all static data + // 3. Finally, the main stack (which grows down) + // + // This has the unfortunate consequence that on stack overflows you + // corrupt static data and can cause some exceedingly weird bugs. To + // help detect this a little sooner we instead request that the stack is + // placed before static data. + // + // This means that we'll generate slightly larger binaries as references + // to static data will take more bytes in the ULEB128 encoding, but + // stack overflow will be guaranteed to trap as it underflows instead of + // corrupting static data. + arg("--stack-first"); + + // FIXME we probably shouldn't pass this but instead pass an explicit + // whitelist of symbols we'll allow to be undefined. We don't currently have + // a mechanism of knowing, however, which symbols are intended to be + // imported from the environment and which are intended to be imported from + // other objects linked elsewhere. This is a coarse approximation but is + // sure to hide some bugs and frustrate someone at some point, so we should + // ideally work towards a world where we can explicitly list symbols that + // are supposed to be imported and have all other symbols generate errors if + // they remain undefined. + arg("--allow-undefined"); + + // Rust code should never have warnings, and warnings are often + // indicative of bugs, let's prevent them. + arg("--fatal-warnings"); + + // LLD only implements C++-like demangling, which doesn't match our own + // mangling scheme. Tell LLD to not demangle anything and leave it up to + // us to demangle these symbols later. Currently rustc does not perform + // further demangling, but tools like twiggy and wasm-bindgen are intended + // to do so. + arg("--no-demangle"); + + // The symbol visibility story is a bit in flux right now with LLD. + // It's... not entirely clear to me what's going on, but this looks to + // make everything work when `export_symbols` isn't otherwise called for + // things like executables. + // + // This is really only here to get things working. If it can be removed and + // basic tests still work, then sounds like it should be removed! + arg("--export-dynamic"); + + let mut pre_link_args = BTreeMap::new(); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Wasm), lld_args); + pre_link_args.insert(LinkerFlavor::Gcc, clang_args); + + TargetOptions { + // we allow dynamic linking, but only cdylibs. Basically we allow a + // final library artifact that exports some symbols (a wasm module) but + // we don't allow intermediate `dylib` crate types + dynamic_linking: true, + only_cdylib: true, + + // This means we'll just embed a `start` function in the wasm module + executables: true, + + // relatively self-explanatory! + exe_suffix: ".wasm".to_string(), + dll_prefix: String::new(), + dll_suffix: ".wasm".to_string(), + linker_is_gnu: false, + + max_atomic_width: Some(64), + + // Unwinding doesn't work right now, so the whole target unconditionally + // defaults to panic=abort. Note that this is guaranteed to change in + // the future once unwinding is implemented. Don't rely on this as we're + // basically guaranteed to change it once WebAssembly supports + // exceptions. + panic_strategy: PanicStrategy::Abort, + + // Wasm doesn't have atomics yet, so tell LLVM that we're in a single + // threaded model which will legalize atomics to normal operations. + singlethread: true, + + // no dynamic linking, no need for default visibility! + default_hidden_visibility: true, + + // we use the LLD shipped with the Rust toolchain by default + linker: Some("rust-lld".to_owned()), + lld_flavor: LldFlavor::Wasm, + + // No need for indirection here, simd types can always be passed by + // value as the whole module either has simd or not, which is different + // from x86 (for example) where programs can have functions that don't + // enable simd features. + simd_types_indirect: false, + + pre_link_args, + + .. Default::default() + } +} diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs index ee2160c472080..909527d2b6120 100644 --- a/src/librustc_target/spec/wasm32_unknown_unknown.rs +++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs @@ -1,70 +1,48 @@ -// The wasm32-unknown-unknown target is currently an experimental version of a -// wasm-based target which does *not* use the Emscripten toolchain. Instead -// this toolchain is based purely on LLVM's own toolchain, using LLVM's native -// WebAssembly backend as well as LLD for a native linker. -// -// There's some trickery below on crate types supported and various defaults -// (aka panic=abort by default), but otherwise this is in general a relatively -// standard target. - -use super::{LldFlavor, LinkerFlavor, Target, TargetOptions, PanicStrategy}; +//! A "bare wasm" target representing a WebAssembly output that makes zero +//! assumptions about its environment. +//! +//! The `wasm32-unknown-unknown` target is intended to encapsulate use cases +//! that do not rely on any imported functionality. The binaries generated are +//! entirely self-contained by default when using the standard library. Although +//! the standard library is available, most of it returns an error immediately +//! (e.g. trying to create a TCP stream or something like that). +//! +//! This target is more or less managed by the Rust and WebAssembly Working +//! Group nowadays at https://github.com/rustwasm. + +use super::{LldFlavor, LinkerFlavor, Target}; +use super::wasm32_base; pub fn target() -> Result { - let opts = TargetOptions { - // we allow dynamic linking, but only cdylibs. Basically we allow a - // final library artifact that exports some symbols (a wasm module) but - // we don't allow intermediate `dylib` crate types - dynamic_linking: true, - only_cdylib: true, - - // This means we'll just embed a `start` function in the wasm module - executables: true, - - // relatively self-explanatory! - exe_suffix: ".wasm".to_string(), - dll_prefix: String::new(), - dll_suffix: ".wasm".to_string(), - linker_is_gnu: false, - - max_atomic_width: Some(64), - - // Unwinding doesn't work right now, so the whole target unconditionally - // defaults to panic=abort. Note that this is guaranteed to change in - // the future once unwinding is implemented. Don't rely on this. - panic_strategy: PanicStrategy::Abort, - - // Wasm doesn't have atomics yet, so tell LLVM that we're in a single - // threaded model which will legalize atomics to normal operations. - singlethread: true, + let mut options = wasm32_base::options(); + let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); - // no dynamic linking, no need for default visibility! - default_hidden_visibility: true, + // Make sure clang uses LLD as its linker and is configured appropriately + // otherwise + clang_args.push("--target=wasm32-unknown-unknown".to_string()); - // we use the LLD shipped with the Rust toolchain by default - linker: Some("rust-lld".to_owned()), - lld_flavor: LldFlavor::Wasm, + // Disable attempting to link crt1.o since it typically isn't present and + // isn't needed currently. + clang_args.push("-nostdlib".to_string()); - // No need for indirection here, simd types can always be passed by - // value as the whole module either has simd or not, which is different - // from x86 (for example) where programs can have functions that don't - // enable simd features. - simd_types_indirect: false, + // For now this target just never has an entry symbol no matter the output + // type, so unconditionally pass this. + clang_args.push("-Wl,--no-entry".to_string()); + options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)) + .unwrap() + .push("--no-entry".to_string()); - .. Default::default() - }; Ok(Target { llvm_target: "wasm32-unknown-unknown".to_string(), target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - // This is basically guaranteed to change in the future, don't rely on - // this. Use `not(target_os = "emscripten")` for now. target_os: "unknown".to_string(), target_env: String::new(), target_vendor: "unknown".to_string(), data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm), - options: opts, + options, }) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3d904d518ca8e..5c49892337965 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4802,10 +4802,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (self.to_ty(qself), qself, segment) } }; - if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) { + if let Some(cached_def) = self.tables.borrow().type_dependent_def(hir_id) { // Return directly on cache hit. This is useful to avoid doubly reporting // errors with default match binding modes. See #44614. - return (*cached_def, Some(ty), slice::from_ref(&**item_segment)) + return (cached_def, Some(ty), slice::from_ref(&**item_segment)) } let item_name = item_segment.ident; let def = match self.resolve_ufcs(span, item_name, ty, hir_id) { diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs index 96a238afaec05..163d50c4e4b4a 100644 --- a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs +++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs @@ -62,7 +62,7 @@ pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { continue_if!(ap.arg::() == 16); continue_if!(ap.arg::() == 'A' as c_char); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!")); - ap.copy(|mut ap| { + ap.with_copy(|mut ap| { if compare_c_str(ap.arg::<*const c_char>(), "Correct") { 0 } else { diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index e0e45d55a9e73..1a120dcb18654 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(intra_doc_link_resolution_failure)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr index d273ec019752c..cebb14cba7c11 100644 --- a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(intra_doc_link_resolution_failure)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index 93c05a0c4dd29..7ee9ca4792395 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(intra_doc_link_resolution_failure)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index 62537f2ce2dc9..8ccc04a4c0bcd 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -5,7 +5,7 @@ LL | /// [error] | ^^^^^ cannot be resolved, ignoring | = note: #[warn(intra_doc_link_resolution_failure)] on by default - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error1]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning-crlf.rs:12:11 @@ -13,7 +13,7 @@ warning: `[error1]` cannot be resolved, ignoring it... LL | /// docs [error1] | ^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error2]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning-crlf.rs:14:11 @@ -21,7 +21,7 @@ warning: `[error2]` cannot be resolved, ignoring it... LL | /// docs [error2] | ^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning-crlf.rs:21:20 @@ -29,5 +29,5 @@ warning: `[error]` cannot be resolved, ignoring it... LL | * It also has an [error]. | ^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 60fc131dbda17..1eec3c57b68de 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -5,7 +5,7 @@ LL | //! Test with [Foo::baz], [Bar::foo], ... | ^^^^^^^^ cannot be resolved, ignoring | = note: #[warn(intra_doc_link_resolution_failure)] on by default - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[Bar::foo]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:3:35 @@ -13,7 +13,7 @@ warning: `[Bar::foo]` cannot be resolved, ignoring it... LL | //! Test with [Foo::baz], [Bar::foo], ... | ^^^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[Uniooon::X]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:4:13 @@ -21,7 +21,7 @@ warning: `[Uniooon::X]` cannot be resolved, ignoring it... LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[Qux::Z]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:4:30 @@ -29,7 +29,7 @@ warning: `[Qux::Z]` cannot be resolved, ignoring it... LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[Uniooon::X]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:6:14 @@ -37,7 +37,7 @@ warning: `[Uniooon::X]` cannot be resolved, ignoring it... LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[Qux::Z]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:6:31 @@ -45,7 +45,7 @@ warning: `[Qux::Z]` cannot be resolved, ignoring it... LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[Qux:Y]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:8:13 @@ -53,7 +53,7 @@ warning: `[Qux:Y]` cannot be resolved, ignoring it... LL | /// [Qux:Y] | ^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:51:30 @@ -61,7 +61,7 @@ warning: `[error]` cannot be resolved, ignoring it... LL | * time to introduce a link [error]*/ | ^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:57:30 @@ -69,7 +69,7 @@ warning: `[error]` cannot be resolved, ignoring it... LL | * time to introduce a link [error] | ^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:61:1 @@ -81,19 +81,19 @@ LL | #[doc = "single line [error]"] single line [error] ^^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:64:1 | -LL | #[doc = "single line with /"escaping/" [error]"] +LL | #[doc = "single line with \"escaping\" [error]"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: single line with "escaping" [error] ^^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:67:1 @@ -107,7 +107,7 @@ LL | | /// [error] [error] ^^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error1]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:73:11 @@ -115,7 +115,7 @@ warning: `[error1]` cannot be resolved, ignoring it... LL | /// docs [error1] | ^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[error2]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:75:11 @@ -123,7 +123,7 @@ warning: `[error2]` cannot be resolved, ignoring it... LL | /// docs [error2] | ^^^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[BarA]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:14:10 @@ -131,7 +131,7 @@ warning: `[BarA]` cannot be resolved, ignoring it... LL | /// bar [BarA] bar | ^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[BarB]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:20:9 @@ -139,7 +139,7 @@ warning: `[BarB]` cannot be resolved, ignoring it... LL | * bar [BarB] bar | ^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[BarC]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:27:6 @@ -147,19 +147,19 @@ warning: `[BarC]` cannot be resolved, ignoring it... LL | bar [BarC] bar | ^^^^ cannot be resolved, ignoring | - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[BarD]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:38:1 | -LL | #[doc = "Foo/nbar [BarD] bar/nbaz"] +LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: bar [BarD] bar ^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` warning: `[BarF]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:43:9 @@ -167,12 +167,12 @@ warning: `[BarF]` cannot be resolved, ignoring it... LL | #[doc = $f] | ^^^^^^^^^^^ ... -LL | f!("Foo/nbar [BarF] bar/nbaz"); +LL | f!("Foo\nbar [BarF] bar\nbaz"); | ------------------------------- in this macro invocation | = note: the link appears in this line: bar [BarF] bar ^^^^ - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr index 10800380a05d3..b4ed747b44c81 100644 --- a/src/test/rustdoc-ui/invalid-syntax.stderr +++ b/src/test/rustdoc-ui/invalid-syntax.stderr @@ -3,11 +3,11 @@ warning: could not parse code block as Rust code | LL | /// ``` | _____^ -LL | | /// /__________pkt->size___________/ /_result->size_/ /__pkt->size__/ +LL | | /// \__________pkt->size___________/ \_result->size_/ \__pkt->size__/ LL | | /// ``` | |_______^ | - = note: error from rustc: unknown start of token: / + = note: error from rustc: unknown start of token: \ help: mark blocks that do not contain Rust code as text | LL | /// ```text @@ -35,11 +35,11 @@ warning: could not parse code block as Rust code | LL | /// ``` | _____^ -LL | | /// /_ +LL | | /// \_ LL | | /// ``` | |_______^ | - = note: error from rustc: unknown start of token: / + = note: error from rustc: unknown start of token: \ help: mark blocks that do not contain Rust code as text | LL | /// ```text @@ -50,21 +50,21 @@ warning: could not parse code block as Rust code | LL | /// ```rust | _____^ -LL | | /// /_ +LL | | /// \_ LL | | /// ``` | |_______^ | - = note: error from rustc: unknown start of token: / + = note: error from rustc: unknown start of token: \ warning: could not parse code block as Rust code --> $DIR/invalid-syntax.rs:41:9 | LL | /// code with bad syntax | _________^ -LL | | /// /_ +LL | | /// \_ | |__________^ | - = note: error from rustc: unknown start of token: / + = note: error from rustc: unknown start of token: \ warning: could not parse code block as Rust code --> $DIR/invalid-syntax.rs:55:9 @@ -79,17 +79,17 @@ warning: could not parse code block as Rust code | LL | /// ```edition2018 | _____^ -LL | | /// /_ +LL | | /// \_ LL | | /// ``` | |_______^ | - = note: error from rustc: unknown start of token: / + = note: error from rustc: unknown start of token: \ warning: doc comment contains an invalid Rust code block --> $DIR/invalid-syntax.rs:63:1 | LL | / #[doc = "```"] -LL | | /// /_ +LL | | /// \_ LL | | #[doc = "```"] | |______________^ | diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 76a9133147eac..24db3453ec509 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -27,7 +27,7 @@ note: lint level defined here LL | #![deny(rustdoc)] | ^^^^^^^ = note: #[deny(intra_doc_link_resolution_failure)] implied by #[deny(rustdoc)] - = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]` error: Missing code example in this documentation --> $DIR/lint-group.rs:16:1 diff --git a/src/test/ui/augmented-assignments.nll.stderr b/src/test/ui/augmented-assignments.nll.stderr index 08f06e90162b4..e205e2a87810f 100644 --- a/src/test/ui/augmented-assignments.nll.stderr +++ b/src/test/ui/augmented-assignments.nll.stderr @@ -1,18 +1,11 @@ error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/augmented-assignments.rs:16:5 | -LL | x - | - - | | - | _____borrow of `x` occurs here - | | -LL | | -LL | | += -LL | | x; - | | ^ - | | | - | |_____move out of `x` occurs here - | borrow later used here +LL | x + | - borrow of `x` occurs here +... +LL | x; + | ^ move out of `x` occurs here error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/augmented-assignments.rs:21:5 diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs index 9101be5645646..1c77479d02f40 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.rs +++ b/src/test/ui/c-variadic/variadic-ffi-4.rs @@ -13,7 +13,7 @@ pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { } pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime + let _ = ap.with_copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime } pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index a3e3f81b73d80..311e2173702c8 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -15,29 +15,29 @@ LL | ap | ^^ lifetime `'static` required error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:16:28 + --> $DIR/variadic-ffi-4.rs:16:33 | -LL | let _ = ap.copy(|ap| { ap }); - | ^^ +LL | let _ = ap.with_copy(|ap| { ap }); + | ^^ | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:21... - --> $DIR/variadic-ffi-4.rs:16:21 +note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:26... + --> $DIR/variadic-ffi-4.rs:16:26 | -LL | let _ = ap.copy(|ap| { ap }); - | ^^^^^^^^^^^ +LL | let _ = ap.with_copy(|ap| { ap }); + | ^^^^^^^^^^^ = note: ...so that the expression is assignable: expected core::ffi::VaList<'_> found core::ffi::VaList<'_> note: but, the lifetime must be valid for the method call at 16:13... --> $DIR/variadic-ffi-4.rs:16:13 | -LL | let _ = ap.copy(|ap| { ap }); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _ = ap.with_copy(|ap| { ap }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...so type `core::ffi::VaList<'_>` of expression is valid during the expression --> $DIR/variadic-ffi-4.rs:16:13 | -LL | let _ = ap.copy(|ap| { ap }); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _ = ap.with_copy(|ap| { ap }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/variadic-ffi-4.rs:20:12 diff --git a/src/test/ui/c-variadic/variadic-ffi-5.rs b/src/test/ui/c-variadic/variadic-ffi-5.rs index d96482ff4d17a..fcc80d9b0cca0 100644 --- a/src/test/ui/c-variadic/variadic-ffi-5.rs +++ b/src/test/ui/c-variadic/variadic-ffi-5.rs @@ -16,7 +16,7 @@ pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { } pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.copy(|ap| { ap }); //~ ERROR: lifetime may not live long enough + let _ = ap.with_copy(|ap| { ap }); //~ ERROR: lifetime may not live long enough } pub unsafe extern "C" fn no_escape3(_: usize, ap0: &mut VaList, mut ap1: ...) { diff --git a/src/test/ui/c-variadic/variadic-ffi-5.stderr b/src/test/ui/c-variadic/variadic-ffi-5.stderr index 2ad1964b6fc7b..8f1dfe8ba9b63 100644 --- a/src/test/ui/c-variadic/variadic-ffi-5.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-5.stderr @@ -15,13 +15,13 @@ LL | ap | ^^ lifetime `'static` required error: lifetime may not live long enough - --> $DIR/variadic-ffi-5.rs:19:28 + --> $DIR/variadic-ffi-5.rs:19:33 | -LL | let _ = ap.copy(|ap| { ap }); - | --- ^^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is core::ffi::VaList<'2> - | has type `core::ffi::VaList<'1>` +LL | let _ = ap.with_copy(|ap| { ap }); + | --- ^^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is core::ffi::VaList<'2> + | has type `core::ffi::VaList<'1>` error: lifetime may not live long enough --> $DIR/variadic-ffi-5.rs:23:5 diff --git a/src/test/ui/cast_char.stderr b/src/test/ui/cast_char.stderr index 570ca7cba8635..f0c9b8988903b 100644 --- a/src/test/ui/cast_char.stderr +++ b/src/test/ui/cast_char.stderr @@ -2,7 +2,7 @@ error: only u8 can be cast into char --> $DIR/cast_char.rs:4:23 | LL | const XYZ: char = 0x1F888 as char; - | ^^^^^^^^^^^^^^^ help: use a char literal instead: `'/u{1F888}'` + | ^^^^^^^^^^^^^^^ help: use a char literal instead: `'\u{1F888}'` | note: lint level defined here --> $DIR/cast_char.rs:1:9 @@ -14,7 +14,7 @@ error: only u8 can be cast into char --> $DIR/cast_char.rs:6:22 | LL | const XY: char = 129160 as char; - | ^^^^^^^^^^^^^^ help: use a char literal instead: `'/u{1F888}'` + | ^^^^^^^^^^^^^^ help: use a char literal instead: `'\u{1F888}'` error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0648.stderr b/src/test/ui/error-codes/E0648.stderr index f682b4f41e521..1a65825c7b6c6 100644 --- a/src/test/ui/error-codes/E0648.stderr +++ b/src/test/ui/error-codes/E0648.stderr @@ -1,7 +1,7 @@ error[E0648]: `export_name` may not contain null characters --> $DIR/E0648.rs:1:1 | -LL | #[export_name="/0foo"] +LL | #[export_name="\0foo"] | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/fmt/format-string-error-2.stderr b/src/test/ui/fmt/format-string-error-2.stderr index baab8529940c5..66d35a1b854d3 100644 --- a/src/test/ui/fmt/format-string-error-2.stderr +++ b/src/test/ui/fmt/format-string-error-2.stderr @@ -1,10 +1,10 @@ error: incorrect unicode escape sequence --> $DIR/format-string-error-2.rs:77:20 | -LL | println!("/x7B}/u8 {", 1); +LL | println!("\x7B}\u8 {", 1); | ^^- | | - | help: format of unicode escape sequences uses braces: `/u{8}` + | help: format of unicode escape sequences uses braces: `\u{8}` error: invalid format string: expected `'}'`, found `'a'` --> $DIR/format-string-error-2.rs:5:5 @@ -19,7 +19,7 @@ LL | a"); error: invalid format string: expected `'}'`, found `'b'` --> $DIR/format-string-error-2.rs:9:5 | -LL | format!("{ / +LL | format!("{ \ | - because of this opening brace LL | LL | b"); @@ -27,20 +27,20 @@ LL | b"); | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'/'` +error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:11:18 | -LL | format!(r#"{ / +LL | format!(r#"{ \ | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'/'` +error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:15:18 | -LL | format!(r#"{ /n +LL | format!(r#"{ \n | - ^ expected `}` in format string | | | because of this opening brace @@ -50,9 +50,9 @@ LL | format!(r#"{ /n error: invalid format string: expected `'}'`, found `'e'` --> $DIR/format-string-error-2.rs:21:5 | -LL | format!("{ /n +LL | format!("{ \n | - because of this opening brace -LL | /n +LL | \n LL | e"); | ^ expected `}` in format string | @@ -81,9 +81,9 @@ LL | a error: invalid format string: expected `'}'`, found `'b'` --> $DIR/format-string-error-2.rs:35:5 | -LL | { / +LL | { \ | - because of this opening brace -LL | / +LL | \ LL | b"); | ^ expected `}` in format string | @@ -92,28 +92,28 @@ LL | b"); error: invalid format string: expected `'}'`, found `'b'` --> $DIR/format-string-error-2.rs:40:5 | -LL | { / +LL | { \ | - because of this opening brace -LL | / -LL | b / +LL | \ +LL | b \ | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'/'` +error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:45:8 | -LL | raw { / +LL | raw { \ | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'/'` +error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:50:8 | -LL | raw { /n +LL | raw { \n | - ^ expected `}` in format string | | | because of this opening brace @@ -123,9 +123,9 @@ LL | raw { /n error: invalid format string: expected `'}'`, found `'e'` --> $DIR/format-string-error-2.rs:57:5 | -LL | { /n +LL | { \n | - because of this opening brace -LL | /n +LL | \n LL | e"); | ^ expected `}` in format string | @@ -144,13 +144,13 @@ LL | asdf} error: 1 positional argument in format string, but no arguments were given --> $DIR/format-string-error-2.rs:70:17 | -LL | println!("/t{}"); +LL | println!("\t{}"); | ^^ error: invalid format string: expected `'}'` but string was terminated --> $DIR/format-string-error-2.rs:74:27 | -LL | println!("/x7B}/u{8} {", 1); +LL | println!("\x7B}\u{8} {", 1); | -^ expected `'}'` in format string | | | because of this opening brace @@ -160,7 +160,7 @@ LL | println!("/x7B}/u{8} {", 1); error: argument never used --> $DIR/format-string-error-2.rs:77:28 | -LL | println!("/x7B}/u8 {", 1); +LL | println!("\x7B}\u8 {", 1); | ------------ ^ argument never used | | | formatting specifier missing @@ -168,7 +168,7 @@ LL | println!("/x7B}/u8 {", 1); error: invalid format string: unmatched `}` found --> $DIR/format-string-error-2.rs:82:21 | -LL | println!(r#"/x7B}/u{8} {"#, 1); +LL | println!(r#"\x7B}\u{8} {"#, 1); | ^ unmatched `}` in format string | = note: if you intended to print `}`, you can escape it using `}}` @@ -176,7 +176,7 @@ LL | println!(r#"/x7B}/u{8} {"#, 1); error: invalid format string: unmatched `}` found --> $DIR/format-string-error-2.rs:85:21 | -LL | println!(r#"/x7B}/u8 {"#, 1); +LL | println!(r#"\x7B}\u8 {"#, 1); | ^ unmatched `}` in format string | = note: if you intended to print `}`, you can escape it using `}}` diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr index 86ab163591e0d..3dc122a7399dd 100644 --- a/src/test/ui/fmt/format-string-error.stderr +++ b/src/test/ui/fmt/format-string-error.stderr @@ -50,10 +50,10 @@ LL | let _ = format!("}"); | = note: if you intended to print `}`, you can escape it using `}}` -error: invalid format string: expected `'}'`, found `'/'` +error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error.rs:17:23 | -LL | let _ = format!("{/}"); +LL | let _ = format!("{\}"); | -^ expected `}` in format string | | | because of this opening brace @@ -63,7 +63,7 @@ LL | let _ = format!("{/}"); error: invalid format string: expected `'}'` but string was terminated --> $DIR/format-string-error.rs:19:35 | -LL | let _ = format!("/n/n/n{/n/n/n"); +LL | let _ = format!("\n\n\n{\n\n\n"); | - ^ expected `'}'` in format string | | | because of this opening brace diff --git a/src/test/ui/issues/issue-13727.stderr b/src/test/ui/issues/issue-13727.stderr index 0c2ce9f8b488e..4d1066516249b 100644 --- a/src/test/ui/issues/issue-13727.stderr +++ b/src/test/ui/issues/issue-13727.stderr @@ -1,7 +1,7 @@ error: unreachable pattern --> $DIR/issue-13727.rs:7:5 | -LL | 512 => print!("0b1111/n"), +LL | 512 => print!("0b1111\n"), | ^^^ | note: lint level defined here diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index 87cadada3c782..e2f2f14dce319 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -1,7 +1,7 @@ error: multiple unused formatting arguments --> $DIR/format-foreign.rs:2:30 | -LL | println!("%.*3$s %s!/n", "Hello,", "World", 4); +LL | println!("%.*3$s %s!\n", "Hello,", "World", 4); | -------------- ^^^^^^^^ ^^^^^^^ ^ argument never used | | | | | | | argument never used @@ -11,7 +11,7 @@ LL | println!("%.*3$s %s!/n", "Hello,", "World", 4); = note: printf formatting not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | -LL | println!("{:.2$} {}!/n", "Hello,", "World", 4); +LL | println!("{:.2$} {}!\n", "Hello,", "World", 4); | ^^^^^^ ^^ error: argument never used @@ -29,7 +29,7 @@ error: multiple unused formatting arguments | LL | println!(r###"%.*3$s | ______________- -LL | | %s!/n +LL | | %s!\n LL | | "###, "Hello,", "World", 4); | | - ^^^^^^^^ ^^^^^^^ ^ argument never used | | | | | @@ -41,7 +41,7 @@ LL | | "###, "Hello,", "World", 4); help: format specifiers use curly braces | LL | println!(r###"{:.2$} -LL | {}!/n +LL | {}!\n | error: argument never used diff --git a/src/test/ui/macros/macro-backtrace-println.stderr b/src/test/ui/macros/macro-backtrace-println.stderr index 573184b63b1ed..209ff09aea41b 100644 --- a/src/test/ui/macros/macro-backtrace-println.stderr +++ b/src/test/ui/macros/macro-backtrace-println.stderr @@ -1,7 +1,7 @@ error: 1 positional argument in format string, but no arguments were given --> $DIR/macro-backtrace-println.rs:14:30 | -LL | ($fmt:expr) => (myprint!(concat!($fmt, "/n"))); +LL | ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); | ^^^^^^^^^^^^^^^^^^^ ... LL | myprintln!("{}"); diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr index 7524c4eccd98a..8a981e8d62e2b 100644 --- a/src/test/ui/parser/ascii-only-character-escape.stderr +++ b/src/test/ui/parser/ascii-only-character-escape.stderr @@ -1,19 +1,19 @@ -error: this form of character escape may only be used with characters in the range [/x00-/x7f] +error: this form of character escape may only be used with characters in the range [\x00-\x7f] --> $DIR/ascii-only-character-escape.rs:4:16 | -LL | let x = "/x80"; +LL | let x = "\x80"; | ^^ -error: this form of character escape may only be used with characters in the range [/x00-/x7f] +error: this form of character escape may only be used with characters in the range [\x00-\x7f] --> $DIR/ascii-only-character-escape.rs:5:16 | -LL | let y = "/xff"; +LL | let y = "\xff"; | ^^ -error: this form of character escape may only be used with characters in the range [/x00-/x7f] +error: this form of character escape may only be used with characters in the range [\x00-\x7f] --> $DIR/ascii-only-character-escape.rs:6:16 | -LL | let z = "/xe2"; +LL | let z = "\xe2"; | ^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr index eb048b08c71b0..8e96ea22771b8 100644 --- a/src/test/ui/parser/bad-char-literals.stderr +++ b/src/test/ui/parser/bad-char-literals.stderr @@ -4,7 +4,7 @@ error: character constant must be escaped: ' LL | '''; | ^ -error: character constant must be escaped: /n +error: character constant must be escaped: \n --> $DIR/bad-char-literals.rs:11:6 | LL | ' @@ -12,13 +12,13 @@ LL | ' LL | | '; | |_ -error: character constant must be escaped: /r +error: character constant must be escaped: \r --> $DIR/bad-char-literals.rs:16:6 | LL | ' '; | ^ -error: character constant must be escaped: /t +error: character constant must be escaped: \t --> $DIR/bad-char-literals.rs:19:6 | LL | ' '; diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr index 4edeccfe47556..28385f34f2ab2 100644 --- a/src/test/ui/parser/byte-literals.stderr +++ b/src/test/ui/parser/byte-literals.stderr @@ -1,22 +1,22 @@ error: unknown byte escape: f --> $DIR/byte-literals.rs:6:21 | -LL | static FOO: u8 = b'/f'; +LL | static FOO: u8 = b'\f'; | ^ unknown byte escape error: unknown byte escape: f --> $DIR/byte-literals.rs:9:8 | -LL | b'/f'; +LL | b'\f'; | ^ unknown byte escape error: invalid character in numeric character escape: Z --> $DIR/byte-literals.rs:10:10 | -LL | b'/x0Z'; +LL | b'\x0Z'; | ^ -error: byte constant must be escaped: /t +error: byte constant must be escaped: \t --> $DIR/byte-literals.rs:11:7 | LL | b' '; @@ -28,7 +28,7 @@ error: byte constant must be escaped: ' LL | b'''; | ^ -error: byte constant must be ASCII. Use a /xHH escape for a non-ASCII byte +error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte --> $DIR/byte-literals.rs:13:7 | LL | b'é'; diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr index 45c1a94b519a3..6701cfd8e66c2 100644 --- a/src/test/ui/parser/byte-string-literals.stderr +++ b/src/test/ui/parser/byte-string-literals.stderr @@ -1,22 +1,22 @@ error: unknown byte escape: f --> $DIR/byte-string-literals.rs:6:32 | -LL | static FOO: &'static [u8] = b"/f"; +LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape error: unknown byte escape: f --> $DIR/byte-string-literals.rs:9:8 | -LL | b"/f"; +LL | b"\f"; | ^ unknown byte escape error: invalid character in numeric character escape: Z --> $DIR/byte-string-literals.rs:10:10 | -LL | b"/x0Z"; +LL | b"\x0Z"; | ^ -error: byte constant must be ASCII. Use a /xHH escape for a non-ASCII byte +error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte --> $DIR/byte-string-literals.rs:11:7 | LL | b"é"; diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr index 669a6d26905d1..295ba3b73e861 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr +++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr @@ -1,118 +1,118 @@ error: unicode escape sequences cannot be used as a byte or in a byte string --> $DIR/issue-23620-invalid-escapes.rs:4:15 | -LL | let _ = b"/u{a66e}"; +LL | let _ = b"\u{a66e}"; | ^^^^^^^^ error: unicode escape sequences cannot be used as a byte or in a byte string --> $DIR/issue-23620-invalid-escapes.rs:7:15 | -LL | let _ = b'/u{a66e}'; +LL | let _ = b'\u{a66e}'; | ^^^^^^^^ error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:10:15 | -LL | let _ = b'/u'; +LL | let _ = b'\u'; | ^^ incorrect unicode escape sequence | - = help: format of unicode escape sequences is `/u{...}` + = help: format of unicode escape sequences is `\u{...}` error: unicode escape sequences cannot be used as a byte or in a byte string --> $DIR/issue-23620-invalid-escapes.rs:10:15 | -LL | let _ = b'/u'; +LL | let _ = b'\u'; | ^^ error: numeric character escape is too short --> $DIR/issue-23620-invalid-escapes.rs:14:17 | -LL | let _ = b'/x5'; +LL | let _ = b'\x5'; | ^ error: invalid character in numeric character escape: x --> $DIR/issue-23620-invalid-escapes.rs:17:17 | -LL | let _ = b'/xxy'; +LL | let _ = b'\xxy'; | ^ error: invalid character in numeric character escape: y --> $DIR/issue-23620-invalid-escapes.rs:17:18 | -LL | let _ = b'/xxy'; +LL | let _ = b'\xxy'; | ^ error: numeric character escape is too short --> $DIR/issue-23620-invalid-escapes.rs:21:16 | -LL | let _ = '/x5'; +LL | let _ = '\x5'; | ^ error: invalid character in numeric character escape: x --> $DIR/issue-23620-invalid-escapes.rs:24:16 | -LL | let _ = '/xxy'; +LL | let _ = '\xxy'; | ^ error: invalid character in numeric character escape: y --> $DIR/issue-23620-invalid-escapes.rs:24:17 | -LL | let _ = '/xxy'; +LL | let _ = '\xxy'; | ^ error: unicode escape sequences cannot be used as a byte or in a byte string --> $DIR/issue-23620-invalid-escapes.rs:28:15 | -LL | let _ = b"/u{a4a4} /xf /u"; +LL | let _ = b"\u{a4a4} \xf \u"; | ^^^^^^^^ error: invalid character in numeric character escape: --> $DIR/issue-23620-invalid-escapes.rs:28:27 | -LL | let _ = b"/u{a4a4} /xf /u"; +LL | let _ = b"\u{a4a4} \xf \u"; | ^ error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:28:28 | -LL | let _ = b"/u{a4a4} /xf /u"; +LL | let _ = b"\u{a4a4} \xf \u"; | ^^ incorrect unicode escape sequence | - = help: format of unicode escape sequences is `/u{...}` + = help: format of unicode escape sequences is `\u{...}` error: unicode escape sequences cannot be used as a byte or in a byte string --> $DIR/issue-23620-invalid-escapes.rs:28:28 | -LL | let _ = b"/u{a4a4} /xf /u"; +LL | let _ = b"\u{a4a4} \xf \u"; | ^^ error: invalid character in numeric character escape: --> $DIR/issue-23620-invalid-escapes.rs:34:17 | -LL | let _ = "/xf /u"; +LL | let _ = "\xf \u"; | ^ -error: this form of character escape may only be used with characters in the range [/x00-/x7f] +error: this form of character escape may only be used with characters in the range [\x00-\x7f] --> $DIR/issue-23620-invalid-escapes.rs:34:16 | -LL | let _ = "/xf /u"; +LL | let _ = "\xf \u"; | ^^ error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:34:18 | -LL | let _ = "/xf /u"; +LL | let _ = "\xf \u"; | ^^ incorrect unicode escape sequence | - = help: format of unicode escape sequences is `/u{...}` + = help: format of unicode escape sequences is `\u{...}` error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:39:14 | -LL | let _ = "/u8f"; +LL | let _ = "\u8f"; | ^^-- | | - | help: format of unicode escape sequences uses braces: `/u{8f}` + | help: format of unicode escape sequences uses braces: `\u{8f}` error: aborting due to 18 previous errors diff --git a/src/test/ui/parser/issue-43692.stderr b/src/test/ui/parser/issue-43692.stderr index 9408182f9527b..69a54af3d82ed 100644 --- a/src/test/ui/parser/issue-43692.stderr +++ b/src/test/ui/parser/issue-43692.stderr @@ -1,7 +1,7 @@ error: invalid start of unicode escape --> $DIR/issue-43692.rs:2:9 | -LL | '/u{_10FFFF}'; +LL | '\u{_10FFFF}'; | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/lex-bad-char-literals-1.stderr b/src/test/ui/parser/lex-bad-char-literals-1.stderr index e6b71108086df..414ad81512ae5 100644 --- a/src/test/ui/parser/lex-bad-char-literals-1.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-1.stderr @@ -1,25 +1,25 @@ error: numeric character escape is too short --> $DIR/lex-bad-char-literals-1.rs:3:8 | -LL | '/x1' +LL | '\x1' | ^ error: numeric character escape is too short --> $DIR/lex-bad-char-literals-1.rs:7:8 | -LL | "/x1" +LL | "\x1" | ^ -error: unknown character escape: /u{25cf} +error: unknown character escape: \u{25cf} --> $DIR/lex-bad-char-literals-1.rs:11:7 | -LL | '/●' +LL | '\●' | ^ unknown character escape -error: unknown character escape: /u{25cf} +error: unknown character escape: \u{25cf} --> $DIR/lex-bad-char-literals-1.rs:15:7 | -LL | "/●" +LL | "\●" | ^ unknown character escape error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/lex-bad-char-literals-5.stderr b/src/test/ui/parser/lex-bad-char-literals-5.stderr index ef02973310153..97c6338820d73 100644 --- a/src/test/ui/parser/lex-bad-char-literals-5.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-5.stderr @@ -1,21 +1,21 @@ error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-5.rs:1:18 | -LL | static c: char = '/x10/x10'; +LL | static c: char = '\x10\x10'; | ^^^^^^^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | static c: char = "/x10/x10"; +LL | static c: char = "\x10\x10"; | ^^^^^^^^^^ error: character literal may only contain one codepoint --> $DIR/lex-bad-char-literals-5.rs:5:20 | -LL | let ch: &str = '/x10/x10'; +LL | let ch: &str = '\x10\x10'; | ^^^^^^^^^^ help: if you meant to write a `str` literal, use double quotes | -LL | let ch: &str = "/x10/x10"; +LL | let ch: &str = "\x10\x10"; | ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/lex-bad-token.stderr b/src/test/ui/parser/lex-bad-token.stderr index c0c2e542058bb..43c43721b19f2 100644 --- a/src/test/ui/parser/lex-bad-token.stderr +++ b/src/test/ui/parser/lex-bad-token.stderr @@ -1,4 +1,4 @@ -error: unknown start of token: /u{25cf} +error: unknown start of token: \u{25cf} --> $DIR/lex-bad-token.rs:1:1 | LL | ● diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr index b4d538bf61312..7d944569ca9c4 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr @@ -22,22 +22,22 @@ error: bare CR not allowed in block doc-comment LL | /*! block doc comment with bare CR: ' ' */ | ^ -error: bare CR not allowed in string, use /r instead +error: bare CR not allowed in string, use \r instead --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:21:18 | LL | let _s = "foo bar"; | ^ -error: bare CR not allowed in raw string, use /r instead +error: bare CR not allowed in raw string, use \r instead --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:24:14 | LL | let _s = r"bar foo"; | ^^^^^ -error: unknown character escape: /r +error: unknown character escape: \r --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:27:19 | -LL | let _s = "foo/ bar"; +LL | let _s = "foo\ bar"; | ^ unknown character escape | = help: this is an isolated carriage return; consider checking your editor and version control settings diff --git a/src/test/ui/parser/lex-stray-backslash.stderr b/src/test/ui/parser/lex-stray-backslash.stderr index 7ce061b8be079..06dc0f2b537ba 100644 --- a/src/test/ui/parser/lex-stray-backslash.stderr +++ b/src/test/ui/parser/lex-stray-backslash.stderr @@ -1,7 +1,7 @@ -error: unknown start of token: / +error: unknown start of token: \ --> $DIR/lex-stray-backslash.rs:1:1 | -LL | / +LL | \ | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr index 5a191735307a9..a8da50951ddf3 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.stderr +++ b/src/test/ui/parser/new-unicode-escapes-1.stderr @@ -1,7 +1,7 @@ error: unterminated unicode escape (needed a `}`) --> $DIR/new-unicode-escapes-1.rs:2:21 | -LL | let s = "/u{2603"; +LL | let s = "\u{2603"; | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr index 0fb8befa45b0c..ede49cdf7e1d1 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.stderr +++ b/src/test/ui/parser/new-unicode-escapes-2.stderr @@ -1,7 +1,7 @@ error: overlong unicode escape (must have at most 6 hex digits) --> $DIR/new-unicode-escapes-2.rs:2:17 | -LL | let s = "/u{260311111111}"; +LL | let s = "\u{260311111111}"; | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr index 427426788f6f8..59cfb988f2897 100644 --- a/src/test/ui/parser/new-unicode-escapes-3.stderr +++ b/src/test/ui/parser/new-unicode-escapes-3.stderr @@ -1,7 +1,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:2:14 | -LL | let s1 = "/u{d805}"; +LL | let s1 = "\u{d805}"; | ^^^^^^^^^^ | = help: unicode escape must not be a surrogate @@ -9,7 +9,7 @@ LL | let s1 = "/u{d805}"; error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:3:14 | -LL | let s2 = "/u{ffffff}"; +LL | let s2 = "\u{ffffff}"; | ^^^^^^^^^^^^ | = help: unicode escape must be at most 10FFFF diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr index c8dbe027184de..ca96b00aa7bc5 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.stderr +++ b/src/test/ui/parser/new-unicode-escapes-4.stderr @@ -1,7 +1,7 @@ error: invalid character in unicode escape: l --> $DIR/new-unicode-escapes-4.rs:4:17 | -LL | let s = "/u{lol}"; +LL | let s = "\u{lol}"; | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/raw-byte-string-literals.stderr b/src/test/ui/parser/raw-byte-string-literals.stderr index 5670ed6590a18..a7f1af0a3474c 100644 --- a/src/test/ui/parser/raw-byte-string-literals.stderr +++ b/src/test/ui/parser/raw-byte-string-literals.stderr @@ -1,4 +1,4 @@ -error: raw byte string must be ASCII: /u{e9} +error: raw byte string must be ASCII: \u{e9} --> $DIR/raw-byte-string-literals.rs:5:8 | LL | br"é"; diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr index f70f8ac8d7751..3687b9dd282d1 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.stderr +++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr @@ -1,7 +1,7 @@ -error: unknown character escape: /r +error: unknown character escape: \r --> $DIR/trailing-carriage-return-in-string.rs:10:25 | -LL | let bad = "This is / a test"; +LL | let bad = "This is \ a test"; | ^ unknown character escape | = help: this is an isolated carriage return; consider checking your editor and version control settings diff --git a/src/test/ui/parser/unicode-chars.stderr b/src/test/ui/parser/unicode-chars.stderr index 3a360d8f4681f..76bf6627a4bc4 100644 --- a/src/test/ui/parser/unicode-chars.stderr +++ b/src/test/ui/parser/unicode-chars.stderr @@ -1,4 +1,4 @@ -error: unknown start of token: /u{37e} +error: unknown start of token: \u{37e} --> $DIR/unicode-chars.rs:2:14 | LL | let y = 0; diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr index 315e20cf854cd..4a09ed75605e4 100644 --- a/src/test/ui/parser/unicode-quote-chars.stderr +++ b/src/test/ui/parser/unicode-quote-chars.stderr @@ -1,4 +1,4 @@ -error: unknown start of token: /u{201c} +error: unknown start of token: \u{201c} --> $DIR/unicode-quote-chars.rs:4:14 | LL | println!(“hello world”); diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr index 346eba04c6500..1406b795ba8c3 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr @@ -1,7 +1,7 @@ error: unknown character escape: { --> $DIR/wrong-escape-of-curly-braces.rs:3:17 | -LL | let bad = "/{it is wrong/}"; +LL | let bad = "\{it is wrong\}"; | ^ unknown character escape | = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` @@ -9,7 +9,7 @@ LL | let bad = "/{it is wrong/}"; error: unknown character escape: } --> $DIR/wrong-escape-of-curly-braces.rs:3:30 | -LL | let bad = "/{it is wrong/}"; +LL | let bad = "\{it is wrong\}"; | ^ unknown character escape | = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` diff --git a/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr b/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr index bce310bafaa92..d455902ee8c07 100644 --- a/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr +++ b/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr @@ -14,11 +14,10 @@ error[E0505]: cannot move out of `f` because it is borrowed --> $DIR/region-bound-on-closure-outlives-call.rs:3:25 | LL | (|x| f(x))(call_rec(f)) - | ---------- ^ move out of `f` occurs here - | || | - | || borrow occurs due to use in closure - | |borrow of `f` occurs here - | borrow later used by call + | --- - ^ move out of `f` occurs here + | | | + | | borrow occurs due to use in closure + | borrow of `f` occurs here error: aborting due to previous error diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr index 80dc3ef2f80f2..1a5ab7a7d56a0 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr @@ -42,7 +42,6 @@ LL | f(Box::new(|a| { | - ^^^ move out of `f` occurs here | | | borrow of `f` occurs here - | borrow later used by call LL | foo(f); | - move occurs due to use in closure diff --git a/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr b/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr index 6450f7f52a47b..96dbdec7074a9 100644 --- a/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr +++ b/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr @@ -2,10 +2,7 @@ error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/borrow-for-loop-head.rs:4:18 | LL | for i in &a { - | -- - | | - | borrow of `a` occurs here - | borrow later used here + | -- borrow of `a` occurs here LL | for j in a { | ^ move out of `a` occurs here @@ -17,6 +14,10 @@ LL | let a = vec![1, 2, 3]; LL | for i in &a { LL | for j in a { | ^ value moved here, in previous iteration of loop +help: consider borrowing this to avoid moving it into the for loop + | +LL | for j in &a { + | ^^ error: aborting due to 2 previous errors diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index c1920dde5b1fe..089cbc7b78a3c 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -246,6 +246,11 @@ pub struct Config { /// mode describing what file the actual ui output will be compared to pub compare_mode: Option, + /// If true, this will generate a coverage file with UI test files that run `MachineApplicable` + /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is + /// created in `//rustfix_missing_coverage.txt` + pub rustfix_coverage: bool, + // Configuration for various run-make tests frobbing things like C compilers // or querying about various LLVM component information. pub cc: String, diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index d91710dda5239..dfc023da9736b 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -233,6 +233,12 @@ pub fn parse_config(args: Vec) -> Config { "mode describing what file the actual ui output will be compared to", "COMPARE MODE", ) + .optflag( + "", + "rustfix-coverage", + "enable this to generate a Rustfix coverage file, which is saved in \ + `.//rustfix_missing_coverage.txt`", + ) .optflag("h", "help", "show this message"); let (argv0, args_) = args.split_first().unwrap(); @@ -336,6 +342,7 @@ pub fn parse_config(args: Vec) -> Config { color, remote_test_client: matches.opt_str("remote-test-client").map(PathBuf::from), compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse), + rustfix_coverage: matches.opt_present("rustfix-coverage"), cc: matches.opt_str("cc").unwrap(), cxx: matches.opt_str("cxx").unwrap(), @@ -475,6 +482,19 @@ pub fn run_tests(config: &Config) { let _ = fs::remove_dir_all("tmp/partitioning-tests"); } + // If we want to collect rustfix coverage information, + // we first make sure that the coverage file does not exist. + // It will be created later on. + if config.rustfix_coverage { + let mut coverage_file_path = config.build_base.clone(); + coverage_file_path.push("rustfix_missing_coverage.txt"); + if coverage_file_path.exists() { + if let Err(e) = fs::remove_file(&coverage_file_path) { + panic!("Could not delete {} due to {}", coverage_file_path.display(), e) + } + } + } + let opts = test_opts(config); let tests = make_tests(config); // sadly osx needs some file descriptor limits raised for running tests in diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 3e3499edf60f0..35f8dca79b5dc 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -10,7 +10,7 @@ use crate::errors::{self, Error, ErrorKind}; use filetime::FileTime; use crate::header::TestProps; use crate::json; -use regex::Regex; +use regex::{Captures, Regex}; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; use crate::util::{logv, PathBufExt}; @@ -19,7 +19,7 @@ use std::collections::{HashMap, HashSet, VecDeque}; use std::env; use std::ffi::{OsStr, OsString}; use std::fmt; -use std::fs::{self, create_dir_all, File}; +use std::fs::{self, create_dir_all, File, OpenOptions}; use std::hash::{Hash, Hasher}; use std::io::prelude::*; use std::io::{self, BufReader}; @@ -2818,6 +2818,31 @@ impl<'test> TestCx<'test> { if self.config.compare_mode.is_some() { // don't test rustfix with nll right now + } else if self.config.rustfix_coverage { + // Find out which tests have `MachineApplicable` suggestions but are missing + // `run-rustfix` or `run-rustfix-only-machine-applicable` headers + let suggestions = get_suggestions_from_json( + &proc_res.stderr, + &HashSet::new(), + Filter::MachineApplicableOnly + ).unwrap(); + if suggestions.len() > 0 + && !self.props.run_rustfix + && !self.props.rustfix_only_machine_applicable { + let mut coverage_file_path = self.config.build_base.clone(); + coverage_file_path.push("rustfix_missing_coverage.txt"); + debug!("coverage_file_path: {}", coverage_file_path.display()); + + let mut file = OpenOptions::new() + .create(true) + .append(true) + .open(coverage_file_path.as_path()) + .expect("could not create or open file"); + + if let Err(_) = writeln!(file, "{}", self.testpaths.file.display()) { + panic!("couldn't write to {}", coverage_file_path.display()); + } + } } else if self.props.run_rustfix { // Apply suggestions from rustc to the code itself let unfixed_code = self @@ -3147,10 +3172,8 @@ impl<'test> TestCx<'test> { normalized = Regex::new("SRC_DIR(.+):\\d+:\\d+").unwrap() .replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned(); - normalized = normalized.replace("\\\\", "\\") // denormalize for paths on windows - .replace("\\", "/") // normalize for paths on windows - .replace("\r\n", "\n") // normalize for linebreaks on windows - .replace("\t", "\\t"); // makes tabs visible + normalized = Self::normalize_platform_differences(&normalized); + normalized = normalized.replace("\t", "\\t"); // makes tabs visible // Remove test annotations like `//~ ERROR text` from the output, // since they duplicate actual errors and make the output hard to read. @@ -3164,6 +3187,36 @@ impl<'test> TestCx<'test> { normalized } + /// Normalize output differences across platforms. Generally changes Windows output to be more + /// Unix-like. + /// + /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings + /// with LF. + fn normalize_platform_differences(output: &str) -> String { + lazy_static! { + /// Used to find Windows paths. + /// + /// It's not possible to detect paths in the error messages generally, but this is a + /// decent enough heuristic. + static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x) + (?: + # Match paths that don't include spaces. + (?:\\[\pL\pN\.\-_']+)+\.\pL+ + | + # If the path starts with a well-known root, then allow spaces. + \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+ + )"# + ).unwrap(); + } + + let output = output.replace(r"\\", r"\"); + + PATH_BACKSLASH_RE.replace_all(&output, |caps: &Captures<'_>| { + println!("{}", &caps[0]); + caps[0].replace(r"\", "/") + }).replace("\r\n", "\n") + } + fn expected_output_path(&self, kind: &str) -> PathBuf { let mut path = expected_output_path( &self.testpaths, @@ -3495,3 +3548,68 @@ fn read2_abbreviated(mut child: Child) -> io::Result { stderr: stderr.into_bytes(), }) } + +#[cfg(test)] +mod tests { + use super::TestCx; + + #[test] + fn normalize_platform_differences() { + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\foo.rs"), + "$DIR/foo.rs" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$BUILD_DIR\..\parser.rs"), + "$BUILD_DIR/../parser.rs" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"), + r"$DIR/bar.rs hello\nworld" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"), + r"either bar/baz.rs or bar/baz/mod.rs", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"`.\some\path.rs`"), + r"`./some/path.rs`", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"`some\path.rs`"), + r"`some/path.rs`", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\path-with-dashes.rs"), + r"$DIR/path-with-dashes.rs" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\path_with_underscores.rs"), + r"$DIR/path_with_underscores.rs", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"), + "$DIR/path with spaces 'n' quotes", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"), + "$DIR/file_with/no_extension", + ); + + assert_eq!(TestCx::normalize_platform_differences(r"\n"), r"\n"); + assert_eq!(TestCx::normalize_platform_differences(r"{ \n"), r"{ \n"); + assert_eq!(TestCx::normalize_platform_differences(r"`\]`"), r"`\]`"); + assert_eq!(TestCx::normalize_platform_differences(r#""\{""#), r#""\{""#); + assert_eq!( + TestCx::normalize_platform_differences(r#"write!(&mut v, "Hello\n")"#), + r#"write!(&mut v, "Hello\n")"# + ); + assert_eq!( + TestCx::normalize_platform_differences(r#"println!("test\ntest")"#), + r#"println!("test\ntest")"#, + ); + } +}