diff --git a/src/doc/unstable-book/src/language-features/extern-in-paths.md b/src/doc/unstable-book/src/language-features/extern-in-paths.md deleted file mode 100644 index 9979d7742291e..0000000000000 --- a/src/doc/unstable-book/src/language-features/extern-in-paths.md +++ /dev/null @@ -1,40 +0,0 @@ -# `extern_in_paths` - -The tracking issue for this feature is: [#44660] - -[#44660]: https://github.com/rust-lang/rust/issues/44660 - ------------------------- - -The `extern_in_paths` feature allows to refer to names from other crates "inline", without -introducing `extern crate` items, using keyword `extern`. - -For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`. - -Absolute paths on 2018 edition (e.g. `::my_crate::a::b`) provide the same effect -and resolve to extern crates (built-in or passed with `--extern`). - -```rust,ignore -#![feature(extern_in_paths)] - -// Suppose we have a dependency crate `xcrate` available through `Cargo.toml`, or `--extern` -// options, or standard Rust distribution, or some other means. - -use extern::xcrate::Z; - -fn f() { - use extern::xcrate; - use extern::xcrate as ycrate; - let s = xcrate::S; - assert_eq!(format!("{:?}", s), "S"); - let z = ycrate::Z; - assert_eq!(format!("{:?}", z), "Z"); -} - -fn main() { - let s = extern::xcrate::S; - assert_eq!(format!("{:?}", s), "S"); - let z = Z; - assert_eq!(format!("{:?}", z), "Z"); -} -``` diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index e1c5ab15bb5ce..ba3b3dfbfc2e1 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -819,6 +819,8 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn set_len(&mut self, new_len: usize) { + debug_assert!(new_len <= self.capacity()); + self.len = new_len; } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index c431dc77f782f..9168bbf907f1e 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -140,7 +140,7 @@ pub enum ExternCrateSource { ), // Crate is loaded by `use`. Use, - /// Crate is implicitly loaded by an absolute or an `extern::` path. + /// Crate is implicitly loaded by an absolute path. Path, } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index fa0dfc4b38c8c..7363b8b3a78fa 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -69,8 +69,6 @@ pub struct Session { pub parse_sess: ParseSess, /// For a library crate, this is always none pub entry_fn: Once>, - pub plugin_registrar_fn: Once>, - pub proc_macro_decls_static: Once>, pub sysroot: PathBuf, /// The name of the root source file of the crate, in the local file system. /// `None` means that there is no source file. @@ -1177,8 +1175,6 @@ pub fn build_session_( parse_sess: p_s, // For a library crate, this is always none entry_fn: Once::new(), - plugin_registrar_fn: Once::new(), - proc_macro_decls_static: Once::new(), sysroot, local_crate_source_file, working_dir, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 32d4070dfed2a..562cd75a75ff4 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -402,7 +402,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // expensive for some DepKinds. if !self.dep_graph.is_fully_enabled() { let null_dep_node = DepNode::new_no_params(::dep_graph::DepKind::Null); - return self.force_query_with_job::(key, job, null_dep_node).map(|(v, _)| v); + return Ok(self.force_query_with_job::(key, job, null_dep_node).0); } let dep_node = Q::to_dep_node(self, &key); @@ -436,20 +436,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if !dep_node.kind.is_input() { if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) { - return self.load_from_disk_and_cache_in_memory::(key, - job, - dep_node_index, - &dep_node) + return Ok(self.load_from_disk_and_cache_in_memory::( + key, + job, + dep_node_index, + &dep_node + )) } } - match self.force_query_with_job::(key, job, dep_node) { - Ok((result, dep_node_index)) => { - self.dep_graph.read_index(dep_node_index); - Ok(result) - } - Err(e) => Err(e) - } + let (result, dep_node_index) = self.force_query_with_job::(key, job, dep_node); + self.dep_graph.read_index(dep_node_index); + Ok(result) } fn load_from_disk_and_cache_in_memory>( @@ -458,7 +456,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { job: JobOwner<'a, 'gcx, Q>, dep_node_index: DepNodeIndex, dep_node: &DepNode - ) -> Result>> + ) -> Q::Value { // Note this function can be called concurrently from the same query // We must ensure that this is handled correctly @@ -523,7 +521,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { job.complete(&result, dep_node_index); - Ok(result) + result } #[inline(never)] @@ -563,7 +561,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { key: Q::Key, job: JobOwner<'_, 'gcx, Q>, dep_node: DepNode) - -> Result<(Q::Value, DepNodeIndex), Box>> { + -> (Q::Value, DepNodeIndex) { // If the following assertion triggers, it can have two reasons: // 1. Something is wrong with DepNode creation, either here or // in DepGraph::try_mark_green() @@ -610,7 +608,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { job.complete(&result, dep_node_index); - Ok((result, dep_node_index)) + (result, dep_node_index) } /// Ensure that either this query has all green inputs or been executed. @@ -657,11 +655,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Ensure that only one of them runs the query let job = match JobOwner::try_get(self, span, &key) { TryGetJob::NotYetStarted(job) => job, - TryGetJob::JobCompleted(_) => return, + TryGetJob::JobCompleted(result) => { + if let Err(e) = result { + self.report_cycle(e).emit(); + } + return + } }; - if let Err(e) = self.force_query_with_job::(key, job, dep_node) { - self.report_cycle(e).emit(); - } + self.force_query_with_job::(key, job, dep_node); } pub(super) fn try_get_query>( diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 928e171fe0fdc..bf69089a254a4 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -147,14 +147,12 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) .collect(); - if let Some(id) = *tcx.sess.proc_macro_decls_static.get() { - let def_id = tcx.hir().local_def_id(id); - reachable_non_generics.insert(def_id, SymbolExportLevel::C); + if let Some(id) = tcx.proc_macro_decls_static(LOCAL_CRATE) { + reachable_non_generics.insert(id, SymbolExportLevel::C); } - if let Some(id) = *tcx.sess.plugin_registrar_fn.get() { - let def_id = tcx.hir().local_def_id(id); - reachable_non_generics.insert(def_id, SymbolExportLevel::C); + if let Some(id) = tcx.plugin_registrar_fn(LOCAL_CRATE) { + reachable_non_generics.insert(id, SymbolExportLevel::C); } Lrc::new(reachable_non_generics) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 5a5d1b20b2151..9267f14f24234 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -242,12 +242,12 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let node_id = tcx.hir().as_local_node_id(def_id); - if let Some(id) = node_id { - if *tcx.sess.plugin_registrar_fn.get() == Some(id) { + if def_id.is_local() { + if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); return tcx.sess.generate_plugin_registrar_symbol(disambiguator); } - if *tcx.sess.proc_macro_decls_static.get() == Some(id) { + if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); return tcx.sess.generate_proc_macro_decls_symbol(disambiguator); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 380f9afd68de6..3b7de37ae4b3f 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1158,6 +1158,8 @@ where } pub fn default_provide(providers: &mut ty::query::Providers) { + proc_macro_decls::provide(providers); + plugin::build::provide(providers); hir::provide(providers); borrowck::provide(providers); mir::provide(providers); @@ -1212,13 +1214,6 @@ where middle::entry::find_entry_point(sess, &hir_map, name) }); - sess.plugin_registrar_fn - .set(time(sess, "looking for plugin registrar", || { - plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map) - })); - sess.proc_macro_decls_static - .set(proc_macro_decls::find(&hir_map)); - let mut local_providers = ty::query::Providers::default(); default_provide(&mut local_providers); codegen_backend.provide(&mut local_providers); @@ -1248,6 +1243,14 @@ where // tcx available. time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); + time(sess, "looking for plugin registrar", || { + plugin::build::find_plugin_registrar(tcx) + }); + + time(sess, "looking for derive registrar", || { + proc_macro_decls::find(tcx) + }); + time(sess, "loop checking", || loops::check_crate(tcx)); time(sess, "attribute checking", || { diff --git a/src/librustc_driver/proc_macro_decls.rs b/src/librustc_driver/proc_macro_decls.rs index bb2ea6c2a97ca..093d15b7e3c57 100644 --- a/src/librustc_driver/proc_macro_decls.rs +++ b/src/librustc_driver/proc_macro_decls.rs @@ -1,15 +1,25 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; -use rustc::hir::map::Map; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; +use rustc::ty::TyCtxt; +use rustc::ty::query::Providers; use syntax::ast; use syntax::attr; -pub fn find(hir_map: &Map) -> Option { - let krate = hir_map.krate(); +pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option { + tcx.proc_macro_decls_static(LOCAL_CRATE) +} + +fn proc_macro_decls_static<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + cnum: CrateNum, +) -> Option { + assert_eq!(cnum, LOCAL_CRATE); let mut finder = Finder { decls: None }; - krate.visit_all_item_likes(&mut finder); - finder.decls + tcx.hir().krate().visit_all_item_likes(&mut finder); + + finder.decls.map(|id| tcx.hir().local_def_id(id)) } struct Finder { @@ -30,3 +40,9 @@ impl<'v> ItemLikeVisitor<'v> for Finder { } } +pub(crate) fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + proc_macro_decls_static, + ..*providers + }; +} diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5678f30dabccd..72bcf8edfdd21 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -19,7 +19,7 @@ //! a `pub fn new()`. use rustc::hir::def::Def; -use rustc::hir::def_id::DefId; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::{self, Ty}; use hir::Node; use util::nodemap::NodeSet; @@ -860,7 +860,7 @@ impl LintPass for PluginAsLibrary { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary { fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { - if cx.sess().plugin_registrar_fn.get().is_some() { + if cx.tcx.plugin_registrar_fn(LOCAL_CRATE).is_some() { // We're compiling a plugin; it's fine to link other plugins. return; } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 032a4656efcda..2de1637fb0d9d 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -482,13 +482,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { has_global_allocator: has_global_allocator, has_panic_handler: has_panic_handler, has_default_lib_allocator: has_default_lib_allocator, - plugin_registrar_fn: tcx.sess - .plugin_registrar_fn - .get() - .map(|id| tcx.hir().local_def_id(id).index), + plugin_registrar_fn: tcx.plugin_registrar_fn(LOCAL_CRATE).map(|id| id.index), proc_macro_decls_static: if is_proc_macro { - let id = tcx.sess.proc_macro_decls_static.get().unwrap(); - Some(tcx.hir().local_def_id(id).index) + let id = tcx.proc_macro_decls_static(LOCAL_CRATE).unwrap(); + Some(id.index) } else { None }, diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs index eca2736ee5292..46c452668c3c8 100644 --- a/src/librustc_plugin/build.rs +++ b/src/librustc_plugin/build.rs @@ -2,11 +2,12 @@ use syntax::ast; use syntax::attr; -use errors; use syntax_pos::Span; -use rustc::hir::map::Map; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc::ty::TyCtxt; +use rustc::ty::query::Providers; struct RegistrarFinder { registrars: Vec<(ast::NodeId, Span)> , @@ -30,21 +31,27 @@ impl<'v> ItemLikeVisitor<'v> for RegistrarFinder { } /// Find the function marked with `#[plugin_registrar]`, if any. -pub fn find_plugin_registrar(diagnostic: &errors::Handler, - hir_map: &Map) - -> Option { - let krate = hir_map.krate(); +pub fn find_plugin_registrar<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option { + tcx.plugin_registrar_fn(LOCAL_CRATE) +} + +fn plugin_registrar_fn<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + cnum: CrateNum, +) -> Option { + assert_eq!(cnum, LOCAL_CRATE); let mut finder = RegistrarFinder { registrars: Vec::new() }; - krate.visit_all_item_likes(&mut finder); + tcx.hir().krate().visit_all_item_likes(&mut finder); match finder.registrars.len() { 0 => None, 1 => { let (node_id, _) = finder.registrars.pop().unwrap(); - Some(node_id) + Some(tcx.hir().local_def_id(node_id)) }, _ => { + let diagnostic = tcx.sess.diagnostic(); let mut e = diagnostic.struct_err("multiple plugin registration functions found"); for &(_, span) in &finder.registrars { e.span_note(span, "one is here"); @@ -55,3 +62,11 @@ pub fn find_plugin_registrar(diagnostic: &errors::Handler, } } } + + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + plugin_registrar_fn, + ..*providers + }; +} diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c29b639984d81..a25009ccfb49c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1015,7 +1015,7 @@ enum ModuleOrUniformRoot<'a> { CrateRootAndExternPrelude, /// Virtual module that denotes resolution in extern prelude. - /// Used for paths starting with `::` on 2018 edition or `extern::`. + /// Used for paths starting with `::` on 2018 edition. ExternPrelude, /// Virtual module that denotes resolution in current scope. @@ -3836,8 +3836,7 @@ impl<'a> Resolver<'a> { self.resolve_self(&mut ctxt, self.current_module))); continue; } - if name == keywords::Extern.name() || - name == keywords::PathRoot.name() && ident.span.rust_2018() { + if name == keywords::PathRoot.name() && ident.span.rust_2018() { module = Some(ModuleOrUniformRoot::ExternPrelude); continue; } @@ -4004,8 +4003,8 @@ impl<'a> Resolver<'a> { }; // We're only interested in `use` paths which should start with - // `{{root}}` or `extern` currently. - if first_name != keywords::Extern.name() && first_name != keywords::PathRoot.name() { + // `{{root}}` currently. + if first_name != keywords::PathRoot.name() { return } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index fbba89164e6db..3f185ba194903 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -257,10 +257,28 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { .emit(); } CastError::CastToBool => { - struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`") - .span_label(self.span, "unsupported cast") - .help("compare with zero instead") - .emit(); + let mut err = + struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`"); + + if self.expr_ty.is_numeric() { + match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) { + Ok(snippet) => { + err.span_suggestion_with_applicability( + self.span, + "compare with zero instead", + format!("{} != 0", snippet), + Applicability::MachineApplicable, + ); + } + Err(_) => { + err.span_help(self.span, "compare with zero instead"); + } + } + } else { + err.span_label(self.span, "unsupported cast"); + } + + err.emit(); } CastError::CastToChar => { type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0604, diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 92145907b95f6..c55dd049ec60f 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -410,9 +410,16 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { - Intersection { - iter: self.iter(), - other, + if self.len() <= other.len() { + Intersection { + iter: self.iter(), + other, + } + } else { + Intersection { + iter: other.iter(), + other: self, + } } } @@ -436,7 +443,15 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { - Union { iter: self.iter().chain(other.difference(self)) } + if self.len() <= other.len() { + Union { + iter: self.iter().chain(other.difference(self)), + } + } else { + Union { + iter: other.iter().chain(self.difference(other)), + } + } } /// Returns the number of elements in the set. @@ -584,7 +599,11 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_disjoint(&self, other: &HashSet) -> bool { - self.iter().all(|v| !other.contains(v)) + if self.len() <= other.len() { + self.iter().all(|v| !other.contains(v)) + } else { + other.iter().all(|v| !self.contains(v)) + } } /// Returns `true` if the set is a subset of another, @@ -1494,6 +1513,7 @@ mod test_set { fn test_intersection() { let mut a = HashSet::new(); let mut b = HashSet::new(); + assert!(a.intersection(&b).next().is_none()); assert!(a.insert(11)); assert!(a.insert(1)); @@ -1518,6 +1538,22 @@ mod test_set { i += 1 } assert_eq!(i, expected.len()); + + assert!(a.insert(9)); // make a bigger than b + + i = 0; + for x in a.intersection(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + + i = 0; + for x in b.intersection(&a) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); } #[test] @@ -1573,11 +1609,11 @@ mod test_set { fn test_union() { let mut a = HashSet::new(); let mut b = HashSet::new(); + assert!(a.union(&b).next().is_none()); + assert!(b.union(&a).next().is_none()); assert!(a.insert(1)); assert!(a.insert(3)); - assert!(a.insert(5)); - assert!(a.insert(9)); assert!(a.insert(11)); assert!(a.insert(16)); assert!(a.insert(19)); @@ -1597,6 +1633,23 @@ mod test_set { i += 1 } assert_eq!(i, expected.len()); + + assert!(a.insert(9)); // make a bigger than b + assert!(a.insert(5)); + + i = 0; + for x in a.union(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + + i = 0; + for x in b.union(&a) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); } #[test] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ac20a62f11787..ed278e834cbc7 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -25,9 +25,9 @@ use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler}; use visit::{self, FnKind, Visitor}; use parse::ParseSess; -use symbol::{keywords, Symbol}; +use symbol::Symbol; -use std::{env}; +use std::env; macro_rules! set { ($field: ident) => {{ @@ -372,9 +372,6 @@ declare_features! ( // Generic associated types (RFC 1598) (active, generic_associated_types, "1.23.0", Some(44265), None), - // `extern` in paths - (active, extern_in_paths, "1.23.0", Some(55600), None), - // Infer static outlives requirements (RFC 2093). (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), @@ -503,6 +500,9 @@ declare_features! ( // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`. (removed, custom_derive, "1.0.0", Some(29644), None, Some("subsumed by `#[proc_macro_derive]`")), + // Paths of the form: `extern::foo::bar` + (removed, extern_in_paths, "1.33.0", Some(55600), None, + Some("subsumed by `::foo::bar` paths")), ); declare_features! ( @@ -1827,25 +1827,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_impl_item(self, ii); } - fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) { - for segment in &path.segments { - // Identifiers we are going to check could come from a legacy macro (e.g., `#[test]`). - // For such macros identifiers must have empty context, because this context is - // used during name resolution and produced names must be unhygienic for compatibility. - // On the other hand, we need the actual non-empty context for feature gate checking - // because it's hygienic even for legacy macros. As previously stated, such context - // cannot be kept in identifiers, so it's kept in paths instead and we take it from - // there while keeping location info from the ident span. - let span = segment.ident.span.with_ctxt(path.span.ctxt()); - if segment.ident.name == keywords::Extern.name() { - gate_feature_post!(&self, extern_in_paths, span, - "`extern` in paths is experimental"); - } - } - - visit::walk_path(self, path); - } - fn visit_vis(&mut self, vis: &'a ast::Visibility) { if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node { gate_feature_post!(&self, crate_visibility_modifier, vis.span, diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ecb34e43c590c..0e1c3b4b61f3a 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -299,7 +299,7 @@ impl<'a> StringReader<'a> { /// Report a lexical error with a given span. fn err_span(&self, sp: Span, m: &str) { - self.sess.span_diagnostic.span_err(sp, m) + self.sess.span_diagnostic.struct_span_err(sp, m).emit(); } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ba5676a65d7eb..ea205530ca5cc 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -520,6 +520,7 @@ fn filtered_float_lit(data: Symbol, suffix: Option, diag: Option<(Span, } else { let msg = format!("invalid suffix `{}` for float literal", suf); diag.struct_span_err(span, &msg) + .span_label(span, format!("invalid suffix `{}`", suf)) .help("valid suffixes are `f32` and `f64`") .emit(); } @@ -673,7 +674,11 @@ fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) _ => None, }; if let Some(err) = err { - err!(diag, |span, diag| diag.span_err(span, err)); + err!(diag, |span, diag| { + diag.struct_span_err(span, err) + .span_label(span, "not supported") + .emit(); + }); } return filtered_float_lit(Symbol::intern(s), Some(suf), diag) } @@ -712,6 +717,7 @@ fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) } else { let msg = format!("invalid suffix `{}` for numeric literal", suf); diag.struct_span_err(span, &msg) + .span_label(span, format!("invalid suffix `{}`", suf)) .help("the suffix must be one of the integral types \ (`u32`, `isize`, etc)") .emit(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5c8ed94731afb..823c786bded26 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1012,7 +1012,10 @@ impl<'a> Parser<'a> { if text.is_empty() { self.span_bug(sp, "found empty literal suffix in Some") } - self.span_err(sp, &format!("{} with a suffix is invalid", kind)); + let msg = format!("{} with a suffix is invalid", kind); + self.struct_span_err(sp, &msg) + .span_label(sp, msg) + .emit(); } } } @@ -1299,7 +1302,7 @@ impl<'a> Parser<'a> { fn token_is_bare_fn_keyword(&mut self) -> bool { self.check_keyword(keywords::Fn) || self.check_keyword(keywords::Unsafe) || - self.check_keyword(keywords::Extern) && self.is_extern_non_path() + self.check_keyword(keywords::Extern) } /// parse a `TyKind::BareFn` type: @@ -1768,9 +1771,11 @@ impl<'a> Parser<'a> { Mutability::Immutable } else { let span = self.prev_span; - self.span_err(span, - "expected mut or const in raw pointer type (use \ - `*mut T` or `*const T` as appropriate)"); + let msg = "expected mut or const in raw pointer type"; + self.struct_span_err(span, msg) + .span_label(span, msg) + .help("use `*mut T` or `*const T` as appropriate") + .emit(); Mutability::Immutable }; let t = self.parse_ty_no_plus()?; @@ -3815,8 +3820,12 @@ impl<'a> Parser<'a> { ddpos = Some(fields.len()); } else { // Emit a friendly error, ignore `..` and continue parsing - self.span_err(self.prev_span, - "`..` can only be used once per tuple or tuple struct pattern"); + self.struct_span_err( + self.prev_span, + "`..` can only be used once per tuple or tuple struct pattern", + ) + .span_label(self.prev_span, "can only be used once per pattern") + .emit(); } } else if !self.check(&token::CloseDelim(token::Paren)) { fields.push(self.parse_pat(None)?); @@ -3832,7 +3841,10 @@ impl<'a> Parser<'a> { if ddpos == Some(fields.len()) && trailing_comma { // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed. - self.span_err(self.prev_span, "trailing comma is not permitted after `..`"); + let msg = "trailing comma is not permitted after `..`"; + self.struct_span_err(self.prev_span, msg) + .span_label(self.prev_span, msg) + .emit(); } Ok((fields, ddpos, trailing_comma)) @@ -4605,10 +4617,6 @@ impl<'a> Parser<'a> { self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep) } - fn is_extern_non_path(&self) -> bool { - self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep) - } - fn is_existential_type_decl(&self) -> bool { self.token.is_keyword(keywords::Existential) && self.look_ahead(1, |t| t.is_keyword(keywords::Type)) @@ -4712,12 +4720,10 @@ impl<'a> Parser<'a> { // like a path (1 token), but it fact not a path. // `union::b::c` - path, `union U { ... }` - not a path. // `crate::b::c` - path, `crate struct S;` - not a path. - // `extern::b::c` - path, `extern crate c;` - not a path. } else if self.token.is_path_start() && !self.token.is_qpath_start() && !self.is_union_item() && !self.is_crate_vis() && - !self.is_extern_non_path() && !self.is_existential_type_decl() && !self.is_auto_trait_item() { let pth = self.parse_path(PathStyle::Expr)?; @@ -5256,8 +5262,12 @@ impl<'a> Parser<'a> { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" }; - self.span_err(attrs[0].span, - &format!("trailing attribute after {} parameters", param_kind)); + self.struct_span_err( + attrs[0].span, + &format!("trailing attribute after {} parameters", param_kind), + ) + .span_label(attrs[0].span, "attributes must go before parameters") + .emit(); } break } @@ -5315,19 +5325,28 @@ impl<'a> Parser<'a> { /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, /// possibly including trailing comma. - fn parse_generic_args(&mut self) - -> PResult<'a, (Vec, Vec)> { + fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { let mut args = Vec::new(); let mut bindings = Vec::new(); let mut seen_type = false; let mut seen_binding = false; + let mut first_type_or_binding_span: Option = None; + let mut bad_lifetime_pos = vec![]; + let mut last_comma_span = None; + let mut suggestions = vec![]; loop { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. args.push(GenericArg::Lifetime(self.expect_lifetime())); if seen_type || seen_binding { - self.span_err(self.prev_span, - "lifetime parameters must be declared prior to type parameters"); + let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); + bad_lifetime_pos.push(self.prev_span); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { + suggestions.push((remove_sp, String::new())); + suggestions.push(( + first_type_or_binding_span.unwrap().shrink_to_lo(), + format!("{}, ", snippet))); + } } } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { // Parse associated type binding. @@ -5335,19 +5354,33 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; self.bump(); let ty = self.parse_ty()?; + let span = lo.to(self.prev_span); bindings.push(TypeBinding { id: ast::DUMMY_NODE_ID, ident, ty, - span: lo.to(self.prev_span), + span, }); seen_binding = true; + if first_type_or_binding_span.is_none() { + first_type_or_binding_span = Some(span); + } } else if self.check_type() { // Parse type argument. let ty_param = self.parse_ty()?; if seen_binding { - self.span_err(ty_param.span, - "type parameters must be declared prior to associated type bindings"); + self.struct_span_err( + ty_param.span, + "type parameters must be declared prior to associated type bindings" + ) + .span_label( + ty_param.span, + "must be declared prior to associated type bindings", + ) + .emit(); + } + if first_type_or_binding_span.is_none() { + first_type_or_binding_span = Some(ty_param.span); } args.push(GenericArg::Type(ty_param)); seen_type = true; @@ -5357,8 +5390,30 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break + } else { + last_comma_span = Some(self.prev_span); } } + if !bad_lifetime_pos.is_empty() { + let mut err = self.struct_span_err( + bad_lifetime_pos.clone(), + "lifetime parameters must be declared prior to type parameters" + ); + for sp in &bad_lifetime_pos { + err.span_label(*sp, "must be declared prior to type parameters"); + } + if !suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + &format!( + "move the lifetime parameter{} prior to the first type parameter", + if bad_lifetime_pos.len() > 1 { "s" } else { "" }, + ), + suggestions, + Applicability::MachineApplicable, + ); + } + err.emit(); + } Ok((args, bindings)) } @@ -5386,8 +5441,12 @@ impl<'a> Parser<'a> { // change we parse those generics now, but report an error. if self.choose_generics_over_qpath() { let generics = self.parse_generics()?; - self.span_err(generics.span, - "generic parameters on `where` clauses are reserved for future use"); + self.struct_span_err( + generics.span, + "generic parameters on `where` clauses are reserved for future use", + ) + .span_label(generics.span, "currently unsupported") + .emit(); } loop { @@ -5587,15 +5646,20 @@ impl<'a> Parser<'a> { // *mut self // *not_self // Emit special error for `self` cases. + let msg = "cannot pass `self` by raw pointer"; (if isolated_self(self, 1) { self.bump(); - self.span_err(self.span, "cannot pass `self` by raw pointer"); + self.struct_span_err(self.span, msg) + .span_label(self.span, msg) + .emit(); SelfKind::Value(Mutability::Immutable) } else if self.look_ahead(1, |t| t.is_mutability()) && isolated_self(self, 2) { self.bump(); self.bump(); - self.span_err(self.span, "cannot pass `self` by raw pointer"); + self.struct_span_err(self.span, msg) + .span_label(self.span, msg) + .emit(); SelfKind::Value(Mutability::Immutable) } else { return Ok(None); @@ -5932,7 +5996,10 @@ impl<'a> Parser<'a> { tps.where_clause = self.parse_where_clause()?; self.expect(&token::Semi)?; if unsafety != Unsafety::Normal { - self.span_err(self.prev_span, "trait aliases cannot be unsafe"); + let msg = "trait aliases cannot be unsafe"; + self.struct_span_err(self.prev_span, msg) + .span_label(self.prev_span, msg) + .emit(); } Ok((ident, ItemKind::TraitAlias(tps, bounds), None)) } else { @@ -6048,7 +6115,13 @@ impl<'a> Parser<'a> { Some(ty_second) => { // impl Trait for Type if !has_for { - self.span_err(missing_for_span, "missing `for` in a trait impl"); + self.struct_span_err(missing_for_span, "missing `for` in a trait impl") + .span_suggestion_short_with_applicability( + missing_for_span, + "add `for` here", + " for ".to_string(), + Applicability::MachineApplicable, + ).emit(); } let ty_first = ty_first.into_inner(); @@ -6409,41 +6482,52 @@ impl<'a> Parser<'a> { } } + fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { + if self.eat(&token::Semi) { + let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`"); + err.span_suggestion_short_with_applicability( + self.prev_span, + "remove this semicolon", + String::new(), + Applicability::MachineApplicable, + ); + if !items.is_empty() { + let previous_item = &items[items.len()-1]; + let previous_item_kind_name = match previous_item.node { + // say "braced struct" because tuple-structs and + // braceless-empty-struct declarations do take a semicolon + ItemKind::Struct(..) => Some("braced struct"), + ItemKind::Enum(..) => Some("enum"), + ItemKind::Trait(..) => Some("trait"), + ItemKind::Union(..) => Some("union"), + _ => None, + }; + if let Some(name) = previous_item_kind_name { + err.help(&format!("{} declarations are not followed by a semicolon", name)); + } + } + err.emit(); + true + } else { + false + } + } + /// Given a termination token, parse all of the items in a module fn parse_mod_items(&mut self, term: &token::Token, inner_lo: Span) -> PResult<'a, Mod> { let mut items = vec![]; while let Some(item) = self.parse_item()? { items.push(item); + self.maybe_consume_incorrect_semicolon(&items); } if !self.eat(term) { let token_str = self.this_token_descr(); - let mut err = self.fatal(&format!("expected item, found {}", token_str)); - if self.token == token::Semi { - let msg = "consider removing this semicolon"; - err.span_suggestion_short_with_applicability( - self.span, msg, String::new(), Applicability::MachineApplicable - ); - if !items.is_empty() { // Issue #51603 - let previous_item = &items[items.len()-1]; - let previous_item_kind_name = match previous_item.node { - // say "braced struct" because tuple-structs and - // braceless-empty-struct declarations do take a semicolon - ItemKind::Struct(..) => Some("braced struct"), - ItemKind::Enum(..) => Some("enum"), - ItemKind::Trait(..) => Some("trait"), - ItemKind::Union(..) => Some("union"), - _ => None, - }; - if let Some(name) = previous_item_kind_name { - err.help(&format!("{} declarations are not followed by a semicolon", - name)); - } - } - } else { + if !self.maybe_consume_incorrect_semicolon(&items) { + let mut err = self.fatal(&format!("expected item, found {}", token_str)); err.span_label(self.span, "expected item"); + return Err(err); } - return Err(err); } let hi = if self.span.is_dummy() { @@ -6939,7 +7023,7 @@ impl<'a> Parser<'a> { fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> { let mut variants = Vec::new(); let mut all_nullary = true; - let mut any_disr = None; + let mut any_disr = vec![]; while self.token != token::CloseDelim(token::Brace) { let variant_attrs = self.parse_outer_attributes()?; let vlo = self.span; @@ -6961,7 +7045,9 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, value: self.parse_expr()?, }); - any_disr = disr_expr.as_ref().map(|c| c.value.span); + if let Some(sp) = disr_expr.as_ref().map(|c| c.value.span) { + any_disr.push(sp); + } struct_def = VariantData::Unit(ast::DUMMY_NODE_ID); } else { struct_def = VariantData::Unit(ast::DUMMY_NODE_ID); @@ -6978,11 +7064,15 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break; } } self.expect(&token::CloseDelim(token::Brace))?; - match any_disr { - Some(disr_span) if !all_nullary => - self.span_err(disr_span, - "discriminator values can only be used with a field-less enum"), - _ => () + if !any_disr.is_empty() && !all_nullary { + let mut err =self.struct_span_err( + any_disr.clone(), + "discriminator values can only be used with a field-less enum", + ); + for sp in any_disr { + err.span_label(sp, "only valid in field-less enums"); + } + err.emit(); } Ok(ast::EnumDef { variants }) @@ -7113,8 +7203,7 @@ impl<'a> Parser<'a> { return Ok(Some(item)); } - if self.check_keyword(keywords::Extern) && self.is_extern_non_path() { - self.bump(); // `extern` + if self.eat_keyword(keywords::Extern) { if self.eat_keyword(keywords::Crate) { return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?)); } @@ -7623,7 +7712,7 @@ impl<'a> Parser<'a> { fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>, at_end: &mut bool) -> PResult<'a, Option> { - if self.token.is_path_start() && !self.is_extern_non_path() { + if self.token.is_path_start() { let prev_span = self.prev_span; let lo = self.span; let pth = self.parse_path(PathStyle::Mod)?; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 76d47f421b3de..e741b79bd4c45 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -478,7 +478,6 @@ impl Ident { self.name == keywords::Super.name() || self.name == keywords::SelfLower.name() || self.name == keywords::SelfUpper.name() || - self.name == keywords::Extern.name() || self.name == keywords::Crate.name() || self.name == keywords::PathRoot.name() || self.name == keywords::DollarCrate.name() diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile index 2b931d89f1fec..bf98fcd10cfde 100644 --- a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile +++ b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile @@ -1,12 +1,9 @@ -include ../tools.mk -all: extern_absolute_paths.rs extern_in_paths.rs krate2 +all: extern_absolute_paths.rs krate2 $(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 \ -Z unstable-options --extern krate2 cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py - $(RUSTC) extern_in_paths.rs -Zsave-analysis --edition=2018 \ - -Z unstable-options --extern krate2 - cat $(TMPDIR)/save-analysis/extern_in_paths.json | "$(PYTHON)" validate_json.py krate2: krate2.rs $(RUSTC) $< diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/extern_in_paths.rs b/src/test/run-make-fulldeps/save-analysis-rfc2126/extern_in_paths.rs deleted file mode 100644 index 299b96621ac32..0000000000000 --- a/src/test/run-make-fulldeps/save-analysis-rfc2126/extern_in_paths.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![feature(extern_in_paths)] - -use extern::krate2; - -fn main() { - extern::krate2::hello(); -} diff --git a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/extern.rs b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/extern.rs deleted file mode 100644 index 165a753c8a434..0000000000000 --- a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/extern.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -#![allow(dead_code)] -// aux-build:xcrate.rs -// compile-flags:--extern xcrate - -#![feature(extern_in_paths)] - -use extern::xcrate::Z; - -type A = extern::xcrate::S; -type B = for<'a> extern::xcrate::Tr<'a>; - -fn f() { - use extern::xcrate; - use extern::xcrate as ycrate; - let s = xcrate::S; - assert_eq!(format!("{:?}", s), "S"); - let z = ycrate::Z; - assert_eq!(format!("{:?}", z), "Z"); -} - -fn main() { - let s = extern::xcrate::S; - assert_eq!(format!("{:?}", s), "S"); - let z = Z; - assert_eq!(format!("{:?}", z), "Z"); - assert_eq!(A {}, extern::xcrate::S {}); -} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr index 75c0d91ee1791..c4c0cee5ccc31 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr @@ -2,7 +2,7 @@ error: trailing attribute after lifetime parameters --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25 | LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { - | ^^^^^^^ + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr index 7585c6dd738a2..9099d74ce1be9 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr @@ -2,7 +2,7 @@ error: trailing attribute after type parameters --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35 | LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} - | ^^^^^^^ + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs index 343a2d7a563d1..e9f908d479f64 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs @@ -5,12 +5,8 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); fn hof_lt(_: Q) - where Q: for <#[rustc_1] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 + where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 //~^ ERROR trailing attribute after lifetime parameters -{ +{} -} - -fn main() { - -} +fn main() {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr index 91960510de4db..452f0ea5e1753 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr @@ -1,8 +1,8 @@ error: trailing attribute after lifetime parameters - --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:38 + --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:44 | -LL | where Q: for <#[rustc_1] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 - | ^^^^^^^ +LL | where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/cast/cast-as-bool.rs b/src/test/ui/cast/cast-as-bool.rs index 7a0bd0ec098e3..8130f4dedc9aa 100644 --- a/src/test/ui/cast/cast-as-bool.rs +++ b/src/test/ui/cast/cast-as-bool.rs @@ -1,4 +1,9 @@ fn main() { - let u = 5 as bool; - //~^ ERROR cannot cast as `bool` + let u = 5 as bool; //~ ERROR cannot cast as `bool` + //~| HELP compare with zero instead + //~| SUGGESTION 5 != 0 + let t = (1 + 2) as bool; //~ ERROR cannot cast as `bool` + //~| HELP compare with zero instead + //~| SUGGESTION (1 + 2) != 0 + let v = "hello" as bool; //~ ERROR cannot cast as `bool` } diff --git a/src/test/ui/cast/cast-as-bool.stderr b/src/test/ui/cast/cast-as-bool.stderr index 086d08a569a28..6099a4195b329 100644 --- a/src/test/ui/cast/cast-as-bool.stderr +++ b/src/test/ui/cast/cast-as-bool.stderr @@ -1,11 +1,21 @@ error[E0054]: cannot cast as `bool` --> $DIR/cast-as-bool.rs:2:13 | -LL | let u = 5 as bool; - | ^^^^^^^^^ unsupported cast +LL | let u = 5 as bool; //~ ERROR cannot cast as `bool` + | ^^^^^^^^^ help: compare with zero instead: `5 != 0` + +error[E0054]: cannot cast as `bool` + --> $DIR/cast-as-bool.rs:5:13 + | +LL | let t = (1 + 2) as bool; //~ ERROR cannot cast as `bool` + | ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0` + +error[E0054]: cannot cast as `bool` + --> $DIR/cast-as-bool.rs:8:13 | - = help: compare with zero instead +LL | let v = "hello" as bool; //~ ERROR cannot cast as `bool` + | ^^^^^^^^^^^^^^^ unsupported cast -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0054`. diff --git a/src/test/ui/cast/cast-rfc0401-2.stderr b/src/test/ui/cast/cast-rfc0401-2.stderr index 3bf6e5367f06d..52f6af78a9be5 100644 --- a/src/test/ui/cast/cast-rfc0401-2.stderr +++ b/src/test/ui/cast/cast-rfc0401-2.stderr @@ -2,9 +2,7 @@ error[E0054]: cannot cast as `bool` --> $DIR/cast-rfc0401-2.rs:6:13 | LL | let _ = 3 as bool; - | ^^^^^^^^^ unsupported cast - | - = help: compare with zero instead + | ^^^^^^^^^ help: compare with zero instead: `3 != 0` error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0054.stderr b/src/test/ui/error-codes/E0054.stderr index 416029c5f868b..cce32fa294407 100644 --- a/src/test/ui/error-codes/E0054.stderr +++ b/src/test/ui/error-codes/E0054.stderr @@ -2,9 +2,7 @@ error[E0054]: cannot cast as `bool` --> $DIR/E0054.rs:3:24 | LL | let x_is_nonzero = x as bool; //~ ERROR E0054 - | ^^^^^^^^^ unsupported cast - | - = help: compare with zero instead + | ^^^^^^^^^ help: compare with zero instead: `x != 0` error: aborting due to previous error diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index a600ff14d3b87..ff6504e9688e5 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -52,9 +52,7 @@ error[E0054]: cannot cast as `bool` --> $DIR/error-festival.rs:33:24 | LL | let x_is_nonzero = x as bool; - | ^^^^^^^^^ unsupported cast - | - = help: compare with zero instead + | ^^^^^^^^^ help: compare with zero instead: `x != 0` error[E0606]: casting `&u8` as `u32` is invalid --> $DIR/error-festival.rs:37:18 diff --git a/src/test/ui/feature-gates/feature-gate-extern_in_paths.rs b/src/test/ui/feature-gates/feature-gate-extern_in_paths.rs deleted file mode 100644 index 2d23d13d2472b..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_in_paths.rs +++ /dev/null @@ -1,5 +0,0 @@ -struct S; - -fn main() { - let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental -} diff --git a/src/test/ui/feature-gates/feature-gate-extern_in_paths.stderr b/src/test/ui/feature-gates/feature-gate-extern_in_paths.stderr deleted file mode 100644 index 6b5963b8559af..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_in_paths.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: `extern` in paths is experimental (see issue #55600) - --> $DIR/feature-gate-extern_in_paths.rs:4:13 - | -LL | let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental - | ^^^^^^ - | - = help: add #![feature(extern_in_paths)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-46186.rs b/src/test/ui/issues/issue-46186.rs index de7d13a228084..9dfd61fdf3f20 100644 --- a/src/test/ui/issues/issue-46186.rs +++ b/src/test/ui/issues/issue-46186.rs @@ -1,5 +1,6 @@ struct Struct { a: usize, -}; //~ ERROR expected item, found `;` +}; +//~^ ERROR expected item, found `;` fn main() {} diff --git a/src/test/ui/issues/issue-46186.stderr b/src/test/ui/issues/issue-46186.stderr index 11a1fc072c974..eb0dbb8aa41b8 100644 --- a/src/test/ui/issues/issue-46186.stderr +++ b/src/test/ui/issues/issue-46186.stderr @@ -1,8 +1,8 @@ error: expected item, found `;` --> $DIR/issue-46186.rs:3:2 | -LL | }; //~ ERROR expected item, found `;` - | ^ help: consider removing this semicolon +LL | }; + | ^ help: remove this semicolon | = help: braced struct declarations are not followed by a semicolon diff --git a/src/test/ui/issues/issue-49040.rs b/src/test/ui/issues/issue-49040.rs index 7c8d3d0ee69a9..a5f05d2824eb8 100644 --- a/src/test/ui/issues/issue-49040.rs +++ b/src/test/ui/issues/issue-49040.rs @@ -1,2 +1,2 @@ #![allow(unused_variables)]; //~ ERROR expected item, found `;` -fn main() {} +fn foo() {} diff --git a/src/test/ui/issues/issue-49040.stderr b/src/test/ui/issues/issue-49040.stderr index eec88f0c3f3b3..12e78e2f3bc95 100644 --- a/src/test/ui/issues/issue-49040.stderr +++ b/src/test/ui/issues/issue-49040.stderr @@ -2,7 +2,12 @@ error: expected item, found `;` --> $DIR/issue-49040.rs:1:28 | LL | #![allow(unused_variables)]; //~ ERROR expected item, found `;` - | ^ help: consider removing this semicolon + | ^ help: remove this semicolon -error: aborting due to previous error +error[E0601]: `main` function not found in crate `issue_49040` + | + = note: consider adding a `main` function to `$DIR/issue-49040.rs` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.rs b/src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.rs new file mode 100644 index 0000000000000..b738eb4c70350 --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.rs @@ -0,0 +1,3 @@ +fn main() { + let s = extern::foo::Bar; //~ ERROR expected expression, found keyword `extern` +} diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.stderr new file mode 100644 index 0000000000000..150fc88e7efc2 --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.stderr @@ -0,0 +1,8 @@ +error: expected expression, found keyword `extern` + --> $DIR/keyword-extern-as-identifier-expr.rs:2:13 + | +LL | let s = extern::foo::Bar; //~ ERROR expected expression, found keyword `extern` + | ^^^^^^ expected expression + +error: aborting due to previous error + diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs new file mode 100644 index 0000000000000..f9b6bad7c2552 --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs @@ -0,0 +1,3 @@ +fn main() { + let extern = 0; //~ ERROR expected pattern, found keyword `extern` +} diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr new file mode 100644 index 0000000000000..426b4eef0569c --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr @@ -0,0 +1,8 @@ +error: expected pattern, found keyword `extern` + --> $DIR/keyword-extern-as-identifier-pat.rs:2:9 + | +LL | let extern = 0; //~ ERROR expected pattern, found keyword `extern` + | ^^^^^^ expected pattern + +error: aborting due to previous error + diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs new file mode 100644 index 0000000000000..3845a9aa017ce --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs @@ -0,0 +1,3 @@ +type A = extern::foo::bar; //~ ERROR expected `fn`, found `::` + +fn main() {} diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr new file mode 100644 index 0000000000000..97b641fbea557 --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr @@ -0,0 +1,8 @@ +error: expected `fn`, found `::` + --> $DIR/keyword-extern-as-identifier-type.rs:1:16 + | +LL | type A = extern::foo::bar; //~ ERROR expected `fn`, found `::` + | ^^ expected `fn` here + +error: aborting due to previous error + diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.rs b/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.rs new file mode 100644 index 0000000000000..b07de3e341c41 --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.rs @@ -0,0 +1,3 @@ +use extern::foo; //~ ERROR expected identifier, found keyword `extern` + +fn main() {} diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr new file mode 100644 index 0000000000000..31b575a92e0c8 --- /dev/null +++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr @@ -0,0 +1,12 @@ +error: expected identifier, found keyword `extern` + --> $DIR/keyword-extern-as-identifier-use.rs:1:5 + | +LL | use extern::foo; //~ ERROR expected identifier, found keyword `extern` + | ^^^^^^ expected identifier, found keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | use r#extern::foo; //~ ERROR expected identifier, found keyword `extern` + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/keyword/keyword-extern-as-identifier.rs b/src/test/ui/keyword/keyword-extern-as-identifier.rs deleted file mode 100644 index 6775290a26bd5..0000000000000 --- a/src/test/ui/keyword/keyword-extern-as-identifier.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(extern_in_paths)] - -fn main() { - let extern = 0; //~ ERROR cannot find unit struct/variant or constant `extern` in this scope -} diff --git a/src/test/ui/keyword/keyword-extern-as-identifier.stderr b/src/test/ui/keyword/keyword-extern-as-identifier.stderr deleted file mode 100644 index ef2a4b3ff3c30..0000000000000 --- a/src/test/ui/keyword/keyword-extern-as-identifier.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0531]: cannot find unit struct/variant or constant `extern` in this scope - --> $DIR/keyword-extern-as-identifier.rs:4:9 - | -LL | let extern = 0; //~ ERROR cannot find unit struct/variant or constant `extern` in this scope - | ^^^^^^ not found in this scope - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0531`. diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr index fbe5e6d409934..76091f2d09ed4 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.stderr +++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr @@ -90,17 +90,13 @@ error[E0054]: cannot cast as `bool` --> $DIR/cast-rfc0401.rs:39:13 | LL | let _ = 3_i32 as bool; //~ ERROR cannot cast - | ^^^^^^^^^^^^^ unsupported cast - | - = help: compare with zero instead + | ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0` error[E0054]: cannot cast as `bool` --> $DIR/cast-rfc0401.rs:40:13 | LL | let _ = E::A as bool; //~ ERROR cannot cast | ^^^^^^^^^^^^ unsupported cast - | - = help: compare with zero instead error[E0604]: only `u8` can be cast as `char`, not `u32` --> $DIR/cast-rfc0401.rs:41:13 diff --git a/src/test/ui/old-suffixes-are-really-forbidden.stderr b/src/test/ui/old-suffixes-are-really-forbidden.stderr index 557e7ef6794cd..c54b72a3585d1 100644 --- a/src/test/ui/old-suffixes-are-really-forbidden.stderr +++ b/src/test/ui/old-suffixes-are-really-forbidden.stderr @@ -2,7 +2,7 @@ error: invalid suffix `is` for numeric literal --> $DIR/old-suffixes-are-really-forbidden.rs:2:13 | LL | let a = 1_is; //~ ERROR invalid suffix - | ^^^^ + | ^^^^ invalid suffix `is` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) @@ -10,7 +10,7 @@ error: invalid suffix `us` for numeric literal --> $DIR/old-suffixes-are-really-forbidden.rs:3:13 | LL | let b = 2_us; //~ ERROR invalid suffix - | ^^^^ + | ^^^^ invalid suffix `us` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr index 4fd2ab8177bd4..608c5fda2482a 100644 --- a/src/test/ui/parser/bad-lit-suffixes.stderr +++ b/src/test/ui/parser/bad-lit-suffixes.stderr @@ -2,49 +2,49 @@ error: ABI spec with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:5:5 | LL | "C"suffix //~ ERROR ABI spec with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ ABI spec with a suffix is invalid error: ABI spec with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:9:5 | LL | "C"suffix //~ ERROR ABI spec with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ ABI spec with a suffix is invalid error: string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:13:5 | LL | ""suffix; //~ ERROR string literal with a suffix is invalid - | ^^^^^^^^ + | ^^^^^^^^ string literal with a suffix is invalid error: byte string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:14:5 | LL | b""suffix; //~ ERROR byte string literal with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ byte string literal with a suffix is invalid error: string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:15:5 | LL | r#""#suffix; //~ ERROR string literal with a suffix is invalid - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ string literal with a suffix is invalid error: byte string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:16:5 | LL | br#""#suffix; //~ ERROR byte string literal with a suffix is invalid - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ byte string literal with a suffix is invalid error: char literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:17:5 | LL | 'a'suffix; //~ ERROR char literal with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ char literal with a suffix is invalid error: byte literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:18:5 | LL | b'a'suffix; //~ ERROR byte literal with a suffix is invalid - | ^^^^^^^^^^ + | ^^^^^^^^^^ byte literal with a suffix is invalid error: invalid width `1024` for integer literal --> $DIR/bad-lit-suffixes.rs:20:5 @@ -82,7 +82,7 @@ error: invalid suffix `suffix` for numeric literal --> $DIR/bad-lit-suffixes.rs:25:5 | LL | 1234suffix; //~ ERROR invalid suffix `suffix` for numeric literal - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid suffix `suffix` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) @@ -90,7 +90,7 @@ error: invalid suffix `suffix` for numeric literal --> $DIR/bad-lit-suffixes.rs:26:5 | LL | 0b101suffix; //~ ERROR invalid suffix `suffix` for numeric literal - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ invalid suffix `suffix` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) @@ -98,7 +98,7 @@ error: invalid suffix `suffix` for float literal --> $DIR/bad-lit-suffixes.rs:27:5 | LL | 1.0suffix; //~ ERROR invalid suffix `suffix` for float literal - | ^^^^^^^^^ + | ^^^^^^^^^ invalid suffix `suffix` | = help: valid suffixes are `f32` and `f64` @@ -106,7 +106,7 @@ error: invalid suffix `suffix` for float literal --> $DIR/bad-lit-suffixes.rs:28:5 | LL | 1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ invalid suffix `suffix` | = help: valid suffixes are `f32` and `f64` diff --git a/src/test/ui/parser/bad-pointer-type.rs b/src/test/ui/parser/bad-pointer-type.rs index 0e5a01103dc5f..59e5e0c5d31db 100644 --- a/src/test/ui/parser/bad-pointer-type.rs +++ b/src/test/ui/parser/bad-pointer-type.rs @@ -1,5 +1,5 @@ fn foo(_: *()) { - //~^ expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) + //~^ ERROR expected mut or const in raw pointer type } fn main() {} diff --git a/src/test/ui/parser/bad-pointer-type.stderr b/src/test/ui/parser/bad-pointer-type.stderr index 860f9f96bb8f5..e18c220affe6e 100644 --- a/src/test/ui/parser/bad-pointer-type.stderr +++ b/src/test/ui/parser/bad-pointer-type.stderr @@ -1,8 +1,10 @@ -error: expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) +error: expected mut or const in raw pointer type --> $DIR/bad-pointer-type.rs:1:11 | LL | fn foo(_: *()) { - | ^ + | ^ expected mut or const in raw pointer type + | + = help: use `*mut T` or `*const T` as appropriate error: aborting due to previous error diff --git a/src/test/ui/parser/impl-parsing.stderr b/src/test/ui/parser/impl-parsing.stderr index 308f14c60c765..353f5e21ee641 100644 --- a/src/test/ui/parser/impl-parsing.stderr +++ b/src/test/ui/parser/impl-parsing.stderr @@ -2,13 +2,13 @@ error: missing `for` in a trait impl --> $DIR/impl-parsing.rs:6:11 | LL | impl Trait Type {} //~ ERROR missing `for` in a trait impl - | ^ + | ^ help: add `for` here error: missing `for` in a trait impl --> $DIR/impl-parsing.rs:7:11 | LL | impl Trait .. {} //~ ERROR missing `for` in a trait impl - | ^ + | ^ help: add `for` here error: expected a trait, found type --> $DIR/impl-parsing.rs:8:6 diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs index f5894349e1576..17b9b766b2181 100644 --- a/src/test/ui/parser/issue-14303-fncall.rs +++ b/src/test/ui/parser/issue-14303-fncall.rs @@ -1,6 +1,17 @@ -fn main() { - (0..4) - .map(|x| x * 2) - .collect::>() - //~^ ERROR lifetime parameters must be declared prior to type parameters +// can't run rustfix because it doesn't handle multipart suggestions correctly +// compile-flags: -Zborrowck=mir +// we need the above to avoid ast borrowck failure in recovered code + +struct S<'a, T> { + a: &'a T, + b: &'a T, } + +fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { + let _x = (*start..*end) + .map(|x| S { a: start, b: end }) + .collect::>>(); + //~^ ERROR lifetime parameters must be declared prior to type parameters +} + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.stderr index 1cc82f523c4ba..2a7364915949e 100644 --- a/src/test/ui/parser/issue-14303-fncall.stderr +++ b/src/test/ui/parser/issue-14303-fncall.stderr @@ -1,8 +1,12 @@ error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-fncall.rs:4:31 + --> $DIR/issue-14303-fncall.rs:13:29 | -LL | .collect::>() - | ^^ +LL | .collect::>>(); + | ^^ must be declared prior to type parameters +help: move the lifetime parameter prior to the first type parameter + | +LL | .collect::>>(); + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-path.rs b/src/test/ui/parser/issue-14303-path.rs index f61cb6b8dd6eb..a08c89f3437b4 100644 --- a/src/test/ui/parser/issue-14303-path.rs +++ b/src/test/ui/parser/issue-14303-path.rs @@ -1,4 +1,13 @@ -fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {} +mod foo { + pub struct X<'a, 'b, 'c, T> { + a: &'a str, + b: &'b str, + c: &'c str, + t: T, + } +} + +fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} //~^ ERROR lifetime parameters must be declared prior to type parameters fn main() {} diff --git a/src/test/ui/parser/issue-14303-path.stderr b/src/test/ui/parser/issue-14303-path.stderr index 3de8a169c6922..fb4fb32e11e50 100644 --- a/src/test/ui/parser/issue-14303-path.stderr +++ b/src/test/ui/parser/issue-14303-path.stderr @@ -1,8 +1,14 @@ error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-path.rs:1:37 + --> $DIR/issue-14303-path.rs:10:40 | -LL | fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {} - | ^^ +LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} + | ^^ ^^ must be declared prior to type parameters + | | + | must be declared prior to type parameters +help: move the lifetime parameters prior to the first type parameter + | +LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, 'b, 'c, T>) {} + | ^^^ ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-17383.rs b/src/test/ui/parser/issue-17383.rs index 9c00289287cde..04cd43d0b1071 100644 --- a/src/test/ui/parser/issue-17383.rs +++ b/src/test/ui/parser/issue-17383.rs @@ -1,8 +1,7 @@ enum X { - A = - b'a' //~ ERROR discriminator values can only be used with a field-less enum - , - B(isize) + A = 3, + //~^ ERROR discriminator values can only be used with a field-less enum + B(usize) } fn main() {} diff --git a/src/test/ui/parser/issue-17383.stderr b/src/test/ui/parser/issue-17383.stderr index b225e11066dbc..57caa3372a629 100644 --- a/src/test/ui/parser/issue-17383.stderr +++ b/src/test/ui/parser/issue-17383.stderr @@ -1,8 +1,8 @@ error: discriminator values can only be used with a field-less enum - --> $DIR/issue-17383.rs:3:9 + --> $DIR/issue-17383.rs:2:9 | -LL | b'a' //~ ERROR discriminator values can only be used with a field-less enum - | ^^^^ +LL | A = 3, + | ^ only valid in field-less enums error: aborting due to previous error diff --git a/src/test/ui/parser/issue-1802-1.rs b/src/test/ui/parser/issue-1802-1.rs index 050e9a258d1ed..3c34b0d8febbc 100644 --- a/src/test/ui/parser/issue-1802-1.rs +++ b/src/test/ui/parser/issue-1802-1.rs @@ -1,4 +1,7 @@ -// error-pattern:no valid digits found for number +fn log(a: i32, b: i32) {} + fn main() { + let error = 42; log(error, 0b); + //~^ ERROR no valid digits found for number } diff --git a/src/test/ui/parser/issue-1802-1.stderr b/src/test/ui/parser/issue-1802-1.stderr index 5cd6a4f7c6860..b7d003df56b71 100644 --- a/src/test/ui/parser/issue-1802-1.stderr +++ b/src/test/ui/parser/issue-1802-1.stderr @@ -1,5 +1,5 @@ error: no valid digits found for number - --> $DIR/issue-1802-1.rs:3:16 + --> $DIR/issue-1802-1.rs:5:16 | LL | log(error, 0b); | ^^ diff --git a/src/test/ui/parser/issue-1802-2.rs b/src/test/ui/parser/issue-1802-2.rs index 796db66d22e9a..3c34b0d8febbc 100644 --- a/src/test/ui/parser/issue-1802-2.rs +++ b/src/test/ui/parser/issue-1802-2.rs @@ -1,4 +1,7 @@ -// error-pattern:no valid digits found for number +fn log(a: i32, b: i32) {} + fn main() { - log(error, 0b_usize); + let error = 42; + log(error, 0b); + //~^ ERROR no valid digits found for number } diff --git a/src/test/ui/parser/issue-1802-2.stderr b/src/test/ui/parser/issue-1802-2.stderr index c6c04279666a0..8491dd07cb788 100644 --- a/src/test/ui/parser/issue-1802-2.stderr +++ b/src/test/ui/parser/issue-1802-2.stderr @@ -1,8 +1,8 @@ error: no valid digits found for number - --> $DIR/issue-1802-2.rs:3:16 + --> $DIR/issue-1802-2.rs:5:16 | -LL | log(error, 0b_usize); - | ^^^ +LL | log(error, 0b); + | ^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-27255.rs b/src/test/ui/parser/issue-27255.rs index c0ff331b8bae0..d619688e10183 100644 --- a/src/test/ui/parser/issue-27255.rs +++ b/src/test/ui/parser/issue-27255.rs @@ -1,3 +1,10 @@ -impl A .. {} //~ ERROR +trait A {} + +impl A .. {} +//~^ ERROR missing `for` in a trait impl +//~| ERROR `impl Trait for .. {}` is an obsolete syntax + +impl A usize {} +//~^ ERROR missing `for` in a trait impl fn main() {} diff --git a/src/test/ui/parser/issue-27255.stderr b/src/test/ui/parser/issue-27255.stderr index 6d09d82e34f33..391a23556c4e0 100644 --- a/src/test/ui/parser/issue-27255.stderr +++ b/src/test/ui/parser/issue-27255.stderr @@ -1,8 +1,22 @@ error: missing `for` in a trait impl - --> $DIR/issue-27255.rs:1:7 + --> $DIR/issue-27255.rs:3:7 | -LL | impl A .. {} //~ ERROR - | ^ +LL | impl A .. {} + | ^ help: add `for` here -error: aborting due to previous error +error: missing `for` in a trait impl + --> $DIR/issue-27255.rs:7:7 + | +LL | impl A usize {} + | ^^^^^^ help: add `for` here + +error: `impl Trait for .. {}` is an obsolete syntax + --> $DIR/issue-27255.rs:3:1 + | +LL | impl A .. {} + | ^^^^^^^^^^^^ + | + = help: use `auto trait Trait {}` instead + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr index a01517d016d07..a889513eaee52 100644 --- a/src/test/ui/parser/issue-32214.stderr +++ b/src/test/ui/parser/issue-32214.stderr @@ -2,7 +2,7 @@ error: type parameters must be declared prior to associated type bindings --> $DIR/issue-32214.rs:5:34 | LL | pub fn test >() {} - | ^ + | ^ must be declared prior to associated type bindings error: aborting due to previous error diff --git a/src/test/ui/parser/lex-bad-numeric-literals.stderr b/src/test/ui/parser/lex-bad-numeric-literals.stderr index b1a91705533a0..1fa23b8b73c9e 100644 --- a/src/test/ui/parser/lex-bad-numeric-literals.stderr +++ b/src/test/ui/parser/lex-bad-numeric-literals.stderr @@ -110,7 +110,7 @@ error: octal float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:5:5 | LL | 0o2f32; //~ ERROR: octal float literal is not supported - | ^^^^^^ + | ^^^^^^ not supported error: int literal is too large --> $DIR/lex-bad-numeric-literals.rs:16:5 @@ -128,13 +128,13 @@ error: octal float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:23:5 | LL | 0o123f64; //~ ERROR: octal float literal is not supported - | ^^^^^^^^ + | ^^^^^^^^ not supported error: binary float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:25:5 | LL | 0b101f64; //~ ERROR: binary float literal is not supported - | ^^^^^^^^ + | ^^^^^^^^ not supported error: aborting due to 23 previous errors diff --git a/src/test/ui/parser/no-binary-float-literal.rs b/src/test/ui/parser/no-binary-float-literal.rs index c078bf5f63ef9..a42d2cbc442f0 100644 --- a/src/test/ui/parser/no-binary-float-literal.rs +++ b/src/test/ui/parser/no-binary-float-literal.rs @@ -1,7 +1,8 @@ -// error-pattern:binary float literal is not supported - fn main() { 0b101010f64; + //~^ ERROR binary float literal is not supported 0b101.010; + //~^ ERROR binary float literal is not supported 0b101p4f64; + //~^ ERROR invalid suffix `p4f64` for numeric literal } diff --git a/src/test/ui/parser/no-binary-float-literal.stderr b/src/test/ui/parser/no-binary-float-literal.stderr index 7ff3e28ccb688..21f415bcfb000 100644 --- a/src/test/ui/parser/no-binary-float-literal.stderr +++ b/src/test/ui/parser/no-binary-float-literal.stderr @@ -1,8 +1,22 @@ error: binary float literal is not supported - --> $DIR/no-binary-float-literal.rs:5:5 + --> $DIR/no-binary-float-literal.rs:4:5 | LL | 0b101.010; | ^^^^^^^^^ -error: aborting due to previous error +error: binary float literal is not supported + --> $DIR/no-binary-float-literal.rs:2:5 + | +LL | 0b101010f64; + | ^^^^^^^^^^^ not supported + +error: invalid suffix `p4f64` for numeric literal + --> $DIR/no-binary-float-literal.rs:6:5 + | +LL | 0b101p4f64; + | ^^^^^^^^^^ invalid suffix `p4f64` + | + = help: the suffix must be one of the integral types (`u32`, `isize`, etc) + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/no-hex-float-literal.rs b/src/test/ui/parser/no-hex-float-literal.rs index d830c96fc2f98..bf11dee08338e 100644 --- a/src/test/ui/parser/no-hex-float-literal.rs +++ b/src/test/ui/parser/no-hex-float-literal.rs @@ -1,7 +1,9 @@ -// error-pattern:hexadecimal float literal is not supported - fn main() { 0xABC.Df; + //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields 0x567.89; + //~^ ERROR hexadecimal float literal is not supported 0xDEAD.BEEFp-2f; + //~^ ERROR invalid suffix `f` for float literal + //~| ERROR `{integer}` is a primitive type and therefore doesn't have fields } diff --git a/src/test/ui/parser/no-hex-float-literal.stderr b/src/test/ui/parser/no-hex-float-literal.stderr index 1668cfe5a33ed..258ab06d5ee2f 100644 --- a/src/test/ui/parser/no-hex-float-literal.stderr +++ b/src/test/ui/parser/no-hex-float-literal.stderr @@ -1,8 +1,29 @@ error: hexadecimal float literal is not supported - --> $DIR/no-hex-float-literal.rs:5:5 + --> $DIR/no-hex-float-literal.rs:4:5 | LL | 0x567.89; | ^^^^^^^^ -error: aborting due to previous error +error: invalid suffix `f` for float literal + --> $DIR/no-hex-float-literal.rs:6:18 + | +LL | 0xDEAD.BEEFp-2f; + | ^^ invalid suffix `f` + | + = help: valid suffixes are `f32` and `f64` + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/no-hex-float-literal.rs:2:11 + | +LL | 0xABC.Df; + | ^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/no-hex-float-literal.rs:6:12 + | +LL | 0xDEAD.BEEFp-2f; + | ^^^^^ + +error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/parser/no-unsafe-self.stderr b/src/test/ui/parser/no-unsafe-self.stderr index 364c22a962226..84779b09dc7c6 100644 --- a/src/test/ui/parser/no-unsafe-self.stderr +++ b/src/test/ui/parser/no-unsafe-self.stderr @@ -2,37 +2,37 @@ error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:4:17 | LL | fn foo(*mut self); //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:5:19 | LL | fn baz(*const self); //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:6:13 | LL | fn bar(*self); //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:11:17 | LL | fn foo(*mut self) { } //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:12:19 | LL | fn baz(*const self) { } //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:13:13 | LL | fn bar(*self) { } //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: aborting due to 6 previous errors diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs index 108278fa58e94..fd25499381a28 100644 --- a/src/test/ui/parser/pat-tuple-2.rs +++ b/src/test/ui/parser/pat-tuple-2.rs @@ -1,5 +1,6 @@ fn main() { - match 0 { - (pat, ..,) => {} //~ ERROR trailing comma is not permitted after `..` + match (0, 1, 2) { + (pat, ..,) => {} + //~^ ERROR trailing comma is not permitted after `..` } } diff --git a/src/test/ui/parser/pat-tuple-2.stderr b/src/test/ui/parser/pat-tuple-2.stderr index ec12336356619..c3a5c39a8e32a 100644 --- a/src/test/ui/parser/pat-tuple-2.stderr +++ b/src/test/ui/parser/pat-tuple-2.stderr @@ -1,8 +1,8 @@ error: trailing comma is not permitted after `..` --> $DIR/pat-tuple-2.rs:3:17 | -LL | (pat, ..,) => {} //~ ERROR trailing comma is not permitted after `..` - | ^ +LL | (pat, ..,) => {} + | ^ trailing comma is not permitted after `..` error: aborting due to previous error diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs index 63dcde45bfb5e..e1e975d3c3ea0 100644 --- a/src/test/ui/parser/pat-tuple-3.rs +++ b/src/test/ui/parser/pat-tuple-3.rs @@ -1,5 +1,6 @@ fn main() { - match 0 { - (.., pat, ..) => {} //~ ERROR `..` can only be used once per tuple or tuple struct pattern + match (0, 1, 2) { + (.., pat, ..) => {} + //~^ ERROR `..` can only be used once per tuple or tuple struct pattern } } diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr index 90940eb1723b8..0ad7d27b94e54 100644 --- a/src/test/ui/parser/pat-tuple-3.stderr +++ b/src/test/ui/parser/pat-tuple-3.stderr @@ -1,8 +1,8 @@ error: `..` can only be used once per tuple or tuple struct pattern --> $DIR/pat-tuple-3.rs:3:19 | -LL | (.., pat, ..) => {} //~ ERROR `..` can only be used once per tuple or tuple struct pattern - | ^^ +LL | (.., pat, ..) => {} + | ^^ can only be used once per pattern error: aborting due to previous error diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.rs b/src/test/ui/parser/tag-variant-disr-non-nullary.rs index 35a36cbbf91c6..83a3b727982b5 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.rs +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.rs @@ -1,12 +1,11 @@ -//error-pattern: discriminator values can only be used with a field-less enum - -enum color { - red = 0xff0000, - green = 0x00ff00, - blue = 0x0000ff, - black = 0x000000, - white = 0xffffff, - other (str), +enum Color { + Red = 0xff0000, + //~^ ERROR discriminator values can only be used with a field-less enum + Green = 0x00ff00, + Blue = 0x0000ff, + Black = 0x000000, + White = 0xffffff, + Other(usize), } fn main() {} diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr index aa45ea4ac26e9..cc6312b454551 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr @@ -1,8 +1,17 @@ error: discriminator values can only be used with a field-less enum - --> $DIR/tag-variant-disr-non-nullary.rs:8:13 + --> $DIR/tag-variant-disr-non-nullary.rs:2:11 | -LL | white = 0xffffff, - | ^^^^^^^^ +LL | Red = 0xff0000, + | ^^^^^^^^ only valid in field-less enums +LL | //~^ ERROR discriminator values can only be used with a field-less enum +LL | Green = 0x00ff00, + | ^^^^^^^^ only valid in field-less enums +LL | Blue = 0x0000ff, + | ^^^^^^^^ only valid in field-less enums +LL | Black = 0x000000, + | ^^^^^^^^ only valid in field-less enums +LL | White = 0xffffff, + | ^^^^^^^^ only valid in field-less enums error: aborting due to previous error diff --git a/src/test/ui/parser/where_with_bound.rs b/src/test/ui/parser/where_with_bound.rs index 3a1edb9ffc911..3ca45f1889c9c 100644 --- a/src/test/ui/parser/where_with_bound.rs +++ b/src/test/ui/parser/where_with_bound.rs @@ -1,4 +1,5 @@ fn foo() where ::Item: ToString, T: Iterator { } //~^ ERROR generic parameters on `where` clauses are reserved for future use +//~| ERROR cannot find type `Item` in the crate root fn main() {} diff --git a/src/test/ui/parser/where_with_bound.stderr b/src/test/ui/parser/where_with_bound.stderr index e68f744555809..ff98b3f5fed61 100644 --- a/src/test/ui/parser/where_with_bound.stderr +++ b/src/test/ui/parser/where_with_bound.stderr @@ -2,7 +2,14 @@ error: generic parameters on `where` clauses are reserved for future use --> $DIR/where_with_bound.rs:1:19 | LL | fn foo() where ::Item: ToString, T: Iterator { } - | ^^^ + | ^^^ currently unsupported -error: aborting due to previous error +error[E0412]: cannot find type `Item` in the crate root + --> $DIR/where_with_bound.rs:1:24 + | +LL | fn foo() where ::Item: ToString, T: Iterator { } + | ^^^^ not found in the crate root + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/rfc-2126-extern-in-paths/auxiliary/xcrate.rs b/src/test/ui/rfc-2126-extern-in-paths/auxiliary/xcrate.rs deleted file mode 100644 index c4d4447644577..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/auxiliary/xcrate.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[derive(Debug)] -pub struct S; - -#[derive(Debug)] -pub struct Z; diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.rs b/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.rs deleted file mode 100644 index 5e5e6c6eebfad..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(extern_in_paths)] - -use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate` - -fn main() {} diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr b/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr deleted file mode 100644 index 5b7528c2ed9aa..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0432]: unresolved import `extern::xcrate` - --> $DIR/non-existent-1.rs:3:13 - | -LL | use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate` - | ^^^^^^ could not find `xcrate` in `extern` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs b/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs deleted file mode 100644 index 0f26eef5d7e1b..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(extern_in_paths)] - -fn main() { - let s = extern::xcrate::S; - //~^ ERROR failed to resolve: could not find `xcrate` in `extern` -} diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr b/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr deleted file mode 100644 index 21c2a0c14d601..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0433]: failed to resolve: could not find `xcrate` in `extern` - --> $DIR/non-existent-2.rs:4:21 - | -LL | let s = extern::xcrate::S; - | ^^^^^^ could not find `xcrate` in `extern` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-3.rs b/src/test/ui/rfc-2126-extern-in-paths/non-existent-3.rs deleted file mode 100644 index 1875fb99fe893..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-3.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(extern_in_paths)] - -use extern::ycrate; //~ ERROR unresolved import `extern::ycrate` - -fn main() {} diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-3.stderr b/src/test/ui/rfc-2126-extern-in-paths/non-existent-3.stderr deleted file mode 100644 index e2e7df648c62c..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-3.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0432]: unresolved import `extern::ycrate` - --> $DIR/non-existent-3.rs:3:5 - | -LL | use extern::ycrate; //~ ERROR unresolved import `extern::ycrate` - | ^^^^^^^^^^^^^^ no `ycrate` external crate - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/rfc-2126-extern-in-paths/single-segment.rs b/src/test/ui/rfc-2126-extern-in-paths/single-segment.rs deleted file mode 100644 index 1d5af1e9d8636..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/single-segment.rs +++ /dev/null @@ -1,13 +0,0 @@ -// aux-build:xcrate.rs -// compile-flags:--extern xcrate - -#![feature(extern_in_paths)] - -use extern; //~ ERROR unresolved import `extern` - //~^ NOTE no `extern` in the root -use extern::*; //~ ERROR cannot glob-import all possible crates - -fn main() { - let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate` - //~^ NOTE not a value -} diff --git a/src/test/ui/rfc-2126-extern-in-paths/single-segment.stderr b/src/test/ui/rfc-2126-extern-in-paths/single-segment.stderr deleted file mode 100644 index 2d8ecd48d4825..0000000000000 --- a/src/test/ui/rfc-2126-extern-in-paths/single-segment.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: cannot glob-import all possible crates - --> $DIR/single-segment.rs:8:5 - | -LL | use extern::*; //~ ERROR cannot glob-import all possible crates - | ^^^^^^^^^ - -error[E0432]: unresolved import `extern` - --> $DIR/single-segment.rs:6:5 - | -LL | use extern; //~ ERROR unresolved import `extern` - | ^^^^^^ no `extern` in the root - -error[E0423]: expected value, found module `extern::xcrate` - --> $DIR/single-segment.rs:11:13 - | -LL | let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate` - | ^^^^^^^^^^^^^^ not a value - -error: aborting due to 3 previous errors - -Some errors occurred: E0423, E0432. -For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs new file mode 100644 index 0000000000000..82935af0a81d2 --- /dev/null +++ b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs @@ -0,0 +1,16 @@ +// verify that after encountering a semicolon after an item the parser recovers +mod M {}; +//~^ ERROR expected item, found `;` +struct S {}; +//~^ ERROR expected item, found `;` +fn foo(a: usize) {}; +//~^ ERROR expected item, found `;` +fn main() { + struct X {}; // ok + let _: usize = S {}; + //~^ ERROR mismatched types + let _: usize = X {}; + //~^ ERROR mismatched types + foo(""); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr new file mode 100644 index 0000000000000..9a47a1efb752a --- /dev/null +++ b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr @@ -0,0 +1,50 @@ +error: expected item, found `;` + --> $DIR/recover-from-semicolon-trailing-item.rs:2:9 + | +LL | mod M {}; + | ^ help: remove this semicolon + +error: expected item, found `;` + --> $DIR/recover-from-semicolon-trailing-item.rs:4:12 + | +LL | struct S {}; + | ^ help: remove this semicolon + | + = help: braced struct declarations are not followed by a semicolon + +error: expected item, found `;` + --> $DIR/recover-from-semicolon-trailing-item.rs:6:20 + | +LL | fn foo(a: usize) {}; + | ^ help: remove this semicolon + +error[E0308]: mismatched types + --> $DIR/recover-from-semicolon-trailing-item.rs:10:20 + | +LL | let _: usize = S {}; + | ^^^^ expected usize, found struct `S` + | + = note: expected type `usize` + found type `S` + +error[E0308]: mismatched types + --> $DIR/recover-from-semicolon-trailing-item.rs:12:20 + | +LL | let _: usize = X {}; + | ^^^^ expected usize, found struct `main::X` + | + = note: expected type `usize` + found type `main::X` + +error[E0308]: mismatched types + --> $DIR/recover-from-semicolon-trailing-item.rs:14:9 + | +LL | foo(""); + | ^^ expected usize, found reference + | + = note: expected type `usize` + found type `&'static str` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/traits/trait-object-vs-lifetime.rs b/src/test/ui/traits/trait-object-vs-lifetime.rs index 57d9b2df9f5d7..a12429c868ed0 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.rs +++ b/src/test/ui/traits/trait-object-vs-lifetime.rs @@ -1,8 +1,6 @@ // A few contrived examples where lifetime should (or should not) be parsed as an object type. // Lifetimes parsed as types are still rejected later by semantic checks. -// compile-flags: -Z continue-parse-after-error - struct S<'a, T>(&'a u8, T); fn main() { diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr index 20218c19e452b..4cc96bae5cd17 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr @@ -1,29 +1,33 @@ error: lifetime parameters must be declared prior to type parameters - --> $DIR/trait-object-vs-lifetime.rs:16:25 + --> $DIR/trait-object-vs-lifetime.rs:14:25 | LL | let _: S<'static +, 'static>; - | ^^^^^^^ + | ^^^^^^^ must be declared prior to type parameters +help: move the lifetime parameter prior to the first type parameter + | +LL | let _: S<'static, 'static +>; + | ^^^^^^^^ -- error[E0224]: at least one non-builtin trait is required for an object type - --> $DIR/trait-object-vs-lifetime.rs:11:23 + --> $DIR/trait-object-vs-lifetime.rs:9:23 | LL | let _: S<'static, 'static +>; | ^^^^^^^^^ error[E0107]: wrong number of lifetime arguments: expected 1, found 2 - --> $DIR/trait-object-vs-lifetime.rs:13:23 + --> $DIR/trait-object-vs-lifetime.rs:11:23 | LL | let _: S<'static, 'static>; | ^^^^^^^ unexpected lifetime argument error[E0107]: wrong number of type arguments: expected 1, found 0 - --> $DIR/trait-object-vs-lifetime.rs:13:12 + --> $DIR/trait-object-vs-lifetime.rs:11:12 | LL | let _: S<'static, 'static>; | ^^^^^^^^^^^^^^^^^^^ expected 1 type argument error[E0224]: at least one non-builtin trait is required for an object type - --> $DIR/trait-object-vs-lifetime.rs:16:14 + --> $DIR/trait-object-vs-lifetime.rs:14:14 | LL | let _: S<'static +, 'static>; | ^^^^^^^^^