1
Fork 0

Auto merge of #57607 - Centril:rollup, r=Centril

Rollup of 8 pull requests

Successful merges:

 - #57043 (Fix poor worst case performance of set intersection)
 - #57480 (Clean up and fix a bug in query plumbing)
 - #57481 (provide suggestion for invalid boolean cast)
 - #57540 (Modify some parser diagnostics to continue evaluating beyond the parser)
 - #57570 (Querify local `plugin_registrar_fn` and `proc_macro_decls_static`)
 - #57572 (Unaccept `extern_in_paths`)
 - #57585 (Recover from item trailing semicolon)
 - #57589 (Add a debug_assert to Vec::set_len)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-01-14 23:00:50 +00:00
commit aea9f0aa97
94 changed files with 716 additions and 497 deletions

View file

@ -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");
}
```

View file

@ -819,6 +819,8 @@ impl<T> Vec<T> {
#[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;
}

View file

@ -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,
}

View file

@ -69,8 +69,6 @@ pub struct Session {
pub parse_sess: ParseSess,
/// For a library crate, this is always none
pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
pub plugin_registrar_fn: Once<Option<ast::NodeId>>,
pub proc_macro_decls_static: Once<Option<ast::NodeId>>,
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,

View file

@ -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::<Q>(key, job, null_dep_node).map(|(v, _)| v);
return Ok(self.force_query_with_job::<Q>(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::<Q>(key,
job,
dep_node_index,
&dep_node)
return Ok(self.load_from_disk_and_cache_in_memory::<Q>(
key,
job,
dep_node_index,
&dep_node
))
}
}
match self.force_query_with_job::<Q>(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::<Q>(key, job, dep_node);
self.dep_graph.read_index(dep_node_index);
Ok(result)
}
fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'gcx>>(
@ -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, Box<CycleError<'gcx>>>
) -> 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<CycleError<'gcx>>> {
-> (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::<Q>(key, job, dep_node) {
self.report_cycle(e).emit();
}
self.force_query_with_job::<Q>(key, job, dep_node);
}
pub(super) fn try_get_query<Q: QueryDescription<'gcx>>(

View file

@ -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)

View file

@ -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);
}

View file

@ -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", || {

View file

@ -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<ast::NodeId> {
let krate = hir_map.krate();
pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option<DefId> {
tcx.proc_macro_decls_static(LOCAL_CRATE)
}
fn proc_macro_decls_static<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
cnum: CrateNum,
) -> Option<DefId> {
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
};
}

View file

@ -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;
}

View file

@ -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
},

View file

@ -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<ast::NodeId> {
let krate = hir_map.krate();
pub fn find_plugin_registrar<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option<DefId> {
tcx.plugin_registrar_fn(LOCAL_CRATE)
}
fn plugin_registrar_fn<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
cnum: CrateNum,
) -> Option<DefId> {
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
};
}

View file

@ -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
}

View file

@ -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,

View file

@ -410,9 +410,16 @@ impl<T, S> HashSet<T, S>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> 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<T, S> HashSet<T, S>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> 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<T, S> HashSet<T, S>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_disjoint(&self, other: &HashSet<T, S>) -> 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]

View file

@ -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,

View file

@ -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();
}

View file

@ -520,6 +520,7 @@ fn filtered_float_lit(data: Symbol, suffix: Option<Symbol>, 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<Symbol>, 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<Symbol>, 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();

View file

@ -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<GenericArg>, Vec<TypeBinding>)> {
fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> {
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<Span> = 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<Item>]) -> 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<Mac>>
{
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)?;

View file

@ -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()

View file

@ -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) $<

View file

@ -1,7 +0,0 @@
#![feature(extern_in_paths)]
use extern::krate2;
fn main() {
extern::krate2::hello();
}

View file

@ -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 {});
}

View file

@ -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

View file

@ -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

View file

@ -5,12 +5,8 @@
struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
fn hof_lt<Q>(_: 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() {}

View file

@ -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

View file

@ -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`
}

View file

@ -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
|
= help: compare with zero instead
LL | let u = 5 as bool; //~ ERROR cannot cast as `bool`
| ^^^^^^^^^ help: compare with zero instead: `5 != 0`
error: aborting due to previous error
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
|
LL | let v = "hello" as bool; //~ ERROR cannot cast as `bool`
| ^^^^^^^^^^^^^^^ unsupported cast
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0054`.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,5 +0,0 @@
struct S;
fn main() {
let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
}

View file

@ -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`.

View file

@ -1,5 +1,6 @@
struct Struct {
a: usize,
}; //~ ERROR expected item, found `;`
};
//~^ ERROR expected item, found `;`
fn main() {}

View file

@ -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

View file

@ -1,2 +1,2 @@
#![allow(unused_variables)]; //~ ERROR expected item, found `;`
fn main() {}
fn foo() {}

View file

@ -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`.

View file

@ -0,0 +1,3 @@
fn main() {
let s = extern::foo::Bar; //~ ERROR expected expression, found keyword `extern`
}

View file

@ -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

View file

@ -0,0 +1,3 @@
fn main() {
let extern = 0; //~ ERROR expected pattern, found keyword `extern`
}

View file

@ -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

View file

@ -0,0 +1,3 @@
type A = extern::foo::bar; //~ ERROR expected `fn`, found `::`
fn main() {}

View file

@ -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

View file

@ -0,0 +1,3 @@
use extern::foo; //~ ERROR expected identifier, found keyword `extern`
fn main() {}

View file

@ -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

View file

@ -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
}

View file

@ -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`.

View file

@ -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

View file

@ -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)

View file

@ -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`

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -1,6 +1,17 @@
fn main() {
(0..4)
.map(|x| x * 2)
.collect::<Vec<'a, usize, 'b>>()
//~^ 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::<Vec<S<_, 'a>>>();
//~^ ERROR lifetime parameters must be declared prior to type parameters
}
fn main() {}

View file

@ -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::<Vec<'a, usize, 'b>>()
| ^^
LL | .collect::<Vec<S<_, 'a>>>();
| ^^ must be declared prior to type parameters
help: move the lifetime parameter prior to the first type parameter
|
LL | .collect::<Vec<S<'a, _>>>();
| ^^^ --
error: aborting due to previous error

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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
}

View file

@ -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);
| ^^

View file

@ -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
}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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<W, I: Trait<Item=(), W> >() {}
| ^
| ^ must be declared prior to associated type bindings
error: aborting due to previous error

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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`.

View file

@ -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

View file

@ -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 `..`
}
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -1,4 +1,5 @@
fn foo<T>() where <T>::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() {}

View file

@ -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<T>() where <T>::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<T>() where <T>::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`.

View file

@ -1,5 +0,0 @@
#[derive(Debug)]
pub struct S;
#[derive(Debug)]
pub struct Z;

View file

@ -1,5 +0,0 @@
#![feature(extern_in_paths)]
use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate`
fn main() {}

View file

@ -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`.

View file

@ -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`
}

View file

@ -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`.

View file

@ -1,5 +0,0 @@
#![feature(extern_in_paths)]
use extern::ycrate; //~ ERROR unresolved import `extern::ycrate`
fn main() {}

View file

@ -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`.

View file

@ -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
}

View file

@ -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`.

View file

@ -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
}

View file

@ -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`.

View file

@ -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() {

View file

@ -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>;
| ^^^^^^^^^