Auto merge of #65399 - Centril:rollup-6lzj0w5, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #65215 (Add long error explanation for E0697)
 - #65292 (Print lifetimes with backticks)
 - #65362 (syntax: consolidate function parsing in item.rs)
 - #65363 (Remove implicit dependencies on syntax::pprust)
 - #65379 (refactor session::config::build_session_options_and_crate_config)
 - #65392 (Move `Nonterminal::to_tokenstream` to parser & don't rely directly on parser in lowering)
 - #65395 (Add some tests for fixed ICEs)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-10-14 10:00:51 +00:00
commit 446e5e57b6
152 changed files with 1454 additions and 1175 deletions

View file

@ -2005,6 +2005,24 @@ a (non-transparent) struct containing a single float, while `Grams` is a
transparent wrapper around a float. This can make a difference for the ABI.
"##,
E0697: r##"
A closure has been used as `static`.
Erroneous code example:
```compile_fail,E0697
fn main() {
static || {}; // used as `static`
}
```
Closures cannot be used as `static`. They "save" the environment,
and as such a static closure would save only a static environment
which would consist only of variables with a static lifetime. Given
this it would be better to use a proper function. The easiest fix
is to remove the `static` keyword.
"##,
E0698: r##"
When using generators (or async) all type variables must be bound so a
generator can be constructed.
@ -2191,7 +2209,6 @@ See [RFC 2091] for details on this and other limitations.
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
E0697, // closures cannot be static
// E0707, // multiple elided lifetimes used in arguments of `async fn`
E0708, // `async` non-`move` closures with parameters are not currently
// supported

View file

@ -70,7 +70,8 @@ use syntax::print::pprust;
use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
use syntax::symbol::{kw, sym, Symbol};
use syntax::tokenstream::{TokenStream, TokenTree};
use syntax::parse::token::{self, Token};
use syntax::parse::token::{self, Nonterminal, Token};
use syntax::parse::ParseSess;
use syntax::visit::{self, Visitor};
use syntax_pos::Span;
@ -86,6 +87,11 @@ pub struct LoweringContext<'a> {
resolver: &'a mut dyn Resolver,
/// HACK(Centril): there is a cyclic dependency between the parser and lowering
/// if we don't have this function pointer. To avoid that dependency so that
/// librustc is independent of the parser, we use dynamic dispatch here.
nt_to_tokenstream: NtToTokenstream,
/// The items being lowered are collected here.
items: BTreeMap<hir::HirId, hir::Item>,
@ -180,6 +186,8 @@ pub trait Resolver {
fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool;
}
type NtToTokenstream = fn(&Nonterminal, &ParseSess, Span) -> TokenStream;
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
/// and if so, what meaning it has.
#[derive(Debug)]
@ -236,6 +244,7 @@ pub fn lower_crate(
dep_graph: &DepGraph,
krate: &Crate,
resolver: &mut dyn Resolver,
nt_to_tokenstream: NtToTokenstream,
) -> hir::Crate {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
@ -249,6 +258,7 @@ pub fn lower_crate(
sess,
cstore,
resolver,
nt_to_tokenstream,
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
@ -1022,7 +1032,7 @@ impl<'a> LoweringContext<'a> {
fn lower_token(&mut self, token: Token) -> TokenStream {
match token.kind {
token::Interpolated(nt) => {
let tts = nt.to_tokenstream(&self.sess.parse_sess, token.span);
let tts = (self.nt_to_tokenstream)(&nt, &self.sess.parse_sess, token.span);
self.lower_token_stream(tts)
}
_ => TokenTree::Token(token).into(),

View file

@ -200,7 +200,7 @@ impl<'tcx> TyCtxt<'tcx> {
{
sp = param.span;
}
(format!("the lifetime {} as defined on", br.name), sp)
(format!("the lifetime `{}` as defined on", br.name), sp)
}
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegion::BrNamed(_, name),
@ -213,7 +213,7 @@ impl<'tcx> TyCtxt<'tcx> {
{
sp = param.span;
}
(format!("the lifetime {} as defined on", name), sp)
(format!("the lifetime `{}` as defined on", name), sp)
}
ty::ReFree(ref fr) => match fr.bound_region {
ty::BrAnon(idx) => (
@ -221,7 +221,7 @@ impl<'tcx> TyCtxt<'tcx> {
self.hir().span(node),
),
_ => (
format!("the lifetime {} as defined on", region),
format!("the lifetime `{}` as defined on", region),
cm.def_span(self.hir().span(node)),
),
},

View file

@ -12,6 +12,7 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHa
use syntax::ast;
use syntax::attr;
use syntax::feature_gate;
use syntax::print::pprust;
use syntax::source_map::MultiSpan;
use syntax::symbol::{Symbol, sym};
@ -285,7 +286,7 @@ impl<'a> LintLevelsBuilder<'a> {
tool_ident.span,
E0710,
"an unknown tool name found in scoped lint: `{}`",
meta_item.path
pprust::path_to_string(&meta_item.path),
);
continue;
}

View file

@ -2038,11 +2038,7 @@ pub fn parse_error_format(
return error_format;
}
pub fn build_session_options_and_crate_config(
matches: &getopts::Matches,
) -> (Options, FxHashSet<(String, Option<String>)>) {
let color = parse_color(matches);
fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
let edition = match matches.opt_str("edition") {
Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_|
early_error(
@ -2069,19 +2065,14 @@ pub fn build_session_options_and_crate_config(
)
}
let (json_rendered, json_artifact_notifications) = parse_json(matches);
let error_format = parse_error_format(matches, color, json_rendered);
let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(error_format, &e[..]));
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
let mut debugging_opts = build_debugging_options(matches, error_format);
edition
}
fn check_debug_option_stability(
debugging_opts: &DebuggingOptions,
error_format: ErrorOutputType,
json_rendered: HumanReadableErrorType,
) {
if !debugging_opts.unstable_options {
if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
early_error(
@ -2097,7 +2088,13 @@ pub fn build_session_options_and_crate_config(
);
}
}
}
fn parse_output_types(
debugging_opts: &DebuggingOptions,
matches: &getopts::Matches,
error_format: ErrorOutputType,
) -> OutputTypes {
let mut output_types = BTreeMap::new();
if !debugging_opts.parse_only {
for list in matches.opt_strs("emit") {
@ -2122,14 +2119,19 @@ pub fn build_session_options_and_crate_config(
if output_types.is_empty() {
output_types.insert(OutputType::Exe, None);
}
OutputTypes(output_types)
}
let mut cg = build_codegen_options(matches, error_format);
let mut codegen_units = cg.codegen_units;
fn should_override_cgus_and_disable_thinlto(
output_types: &OutputTypes,
matches: &getopts::Matches,
error_format: ErrorOutputType,
mut codegen_units: Option<usize>,
) -> (bool, Option<usize>) {
let mut disable_thinlto = false;
// Issue #30063: if user requests LLVM-related output to one
// particular path, disable codegen-units.
let incompatible: Vec<_> = output_types
let incompatible: Vec<_> = output_types.0
.iter()
.map(|ot_path| ot_path.0)
.filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
@ -2161,6 +2163,17 @@ pub fn build_session_options_and_crate_config(
}
}
if codegen_units == Some(0) {
early_error(
error_format,
"value for codegen units must be a positive non-zero integer",
);
}
(disable_thinlto, codegen_units)
}
fn check_thread_count(debugging_opts: &DebuggingOptions, error_format: ErrorOutputType) {
if debugging_opts.threads == 0 {
early_error(
error_format,
@ -2174,16 +2187,15 @@ pub fn build_session_options_and_crate_config(
"optimization fuel is incompatible with multiple threads",
);
}
}
if codegen_units == Some(0) {
early_error(
error_format,
"value for codegen units must be a positive non-zero integer",
);
}
let incremental = match (&debugging_opts.incremental, &cg.incremental) {
(&Some(ref path1), &Some(ref path2)) => {
fn select_incremental_path(
debugging_opts: &DebuggingOptions,
cg: &CodegenOptions,
error_format: ErrorOutputType,
) -> Option<PathBuf> {
match (&debugging_opts.incremental, &cg.incremental) {
(Some(path1), Some(path2)) => {
if path1 != path2 {
early_error(
error_format,
@ -2197,25 +2209,19 @@ pub fn build_session_options_and_crate_config(
Some(path1)
}
}
(&Some(ref path), &None) => Some(path),
(&None, &Some(ref path)) => Some(path),
(&None, &None) => None,
}.map(|m| PathBuf::from(m));
if debugging_opts.profile && incremental.is_some() {
early_error(
error_format,
"can't instrument with gcov profiling when compiling incrementally",
);
}
if cg.profile_generate.enabled() && cg.profile_use.is_some() {
early_error(
error_format,
"options `-C profile-generate` and `-C profile-use` are exclusive",
);
}
(Some(path), None) => Some(path),
(None, Some(path)) => Some(path),
(None, None) => None,
}.map(|m| PathBuf::from(m))
}
fn collect_print_requests(
cg: &mut CodegenOptions,
dopts: &mut DebuggingOptions,
matches: &getopts::Matches,
is_unstable_enabled: bool,
error_format: ErrorOutputType,
) -> Vec<PrintRequest> {
let mut prints = Vec::<PrintRequest>::new();
if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
prints.push(PrintRequest::TargetCPUs);
@ -2233,30 +2239,61 @@ pub fn build_session_options_and_crate_config(
prints.push(PrintRequest::CodeModels);
cg.code_model = None;
}
if debugging_opts
if dopts
.tls_model
.as_ref()
.map_or(false, |s| s == "help")
{
prints.push(PrintRequest::TlsModels);
debugging_opts.tls_model = None;
dopts.tls_model = None;
}
let cg = cg;
prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
"crate-name" => PrintRequest::CrateName,
"file-names" => PrintRequest::FileNames,
"sysroot" => PrintRequest::Sysroot,
"cfg" => PrintRequest::Cfg,
"target-list" => PrintRequest::TargetList,
"target-cpus" => PrintRequest::TargetCPUs,
"target-features" => PrintRequest::TargetFeatures,
"relocation-models" => PrintRequest::RelocationModels,
"code-models" => PrintRequest::CodeModels,
"tls-models" => PrintRequest::TlsModels,
"native-static-libs" => PrintRequest::NativeStaticLibs,
"target-spec-json" => {
if is_unstable_enabled {
PrintRequest::TargetSpec
} else {
early_error(
error_format,
"the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option",
);
}
}
req => early_error(error_format, &format!("unknown print request `{}`", req)),
}));
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let target_triple = if let Some(target) = matches.opt_str("target") {
if target.ends_with(".json") {
prints
}
fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType) -> TargetTriple {
match matches.opt_str("target") {
Some(target) if target.ends_with(".json") => {
let path = Path::new(&target);
TargetTriple::from_path(&path).unwrap_or_else(|_|
early_error(error_format, &format!("target file {:?} does not exist", path)))
} else {
TargetTriple::TargetTriple(target)
}
} else {
TargetTriple::from_triple(host_triple())
};
let opt_level = {
Some(target) => TargetTriple::TargetTriple(target),
_ => TargetTriple::from_triple(host_triple()),
}
}
fn parse_opt_level(
matches: &getopts::Matches,
cg: &CodegenOptions,
error_format: ErrorOutputType,
) -> OptLevel {
// The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
// to use them interchangeably. However, because they're technically different flags,
// we need to work out manually which should take precedence if both are supplied (i.e.
@ -2294,11 +2331,13 @@ pub fn build_session_options_and_crate_config(
}
}
}
};
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
// for more details.
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
}
fn select_debuginfo(
matches: &getopts::Matches,
cg: &CodegenOptions,
error_format: ErrorOutputType,
) -> DebugInfo {
let max_g = matches.opt_positions("g").into_iter().max();
let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
if let Some("debuginfo") = s.splitn(2, '=').next() {
@ -2307,7 +2346,7 @@ pub fn build_session_options_and_crate_config(
None
}
}).max();
let debuginfo = if max_g > max_c {
if max_g > max_c {
DebugInfo::Full
} else {
match cg.debuginfo {
@ -2325,14 +2364,14 @@ pub fn build_session_options_and_crate_config(
);
}
}
};
let mut search_paths = vec![];
for s in &matches.opt_strs("L") {
search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
}
}
let libs = matches
fn parse_libs(
matches: &getopts::Matches,
error_format: ErrorOutputType,
) -> Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> {
matches
.opt_strs("l")
.into_iter()
.map(|s| {
@ -2371,52 +2410,23 @@ pub fn build_session_options_and_crate_config(
let new_name = name_parts.next();
(name.to_owned(), new_name.map(|n| n.to_owned()), kind)
})
.collect();
.collect()
}
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
let test = matches.opt_present("test");
let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
"crate-name" => PrintRequest::CrateName,
"file-names" => PrintRequest::FileNames,
"sysroot" => PrintRequest::Sysroot,
"cfg" => PrintRequest::Cfg,
"target-list" => PrintRequest::TargetList,
"target-cpus" => PrintRequest::TargetCPUs,
"target-features" => PrintRequest::TargetFeatures,
"relocation-models" => PrintRequest::RelocationModels,
"code-models" => PrintRequest::CodeModels,
"tls-models" => PrintRequest::TlsModels,
"native-static-libs" => PrintRequest::NativeStaticLibs,
"target-spec-json" => {
if is_unstable_enabled {
PrintRequest::TargetSpec
} else {
early_error(
error_format,
"the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option",
);
}
}
req => early_error(error_format, &format!("unknown print request `{}`", req)),
}));
let borrowck_mode = match debugging_opts.borrowck.as_ref().map(|s| &s[..]) {
fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType) -> BorrowckMode {
match dopts.borrowck.as_ref().map(|s| &s[..]) {
None | Some("migrate") => BorrowckMode::Migrate,
Some("mir") => BorrowckMode::Mir,
Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
};
if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
early_warn(
error_format,
"-C remark requires \"-C debuginfo=n\" to show source locations",
);
}
}
fn parse_externs(
matches: &getopts::Matches,
debugging_opts: &DebuggingOptions,
error_format: ErrorOutputType,
is_unstable_enabled: bool,
) -> Externs {
if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
early_error(
ErrorOutputType::default(),
@ -2457,10 +2467,14 @@ pub fn build_session_options_and_crate_config(
// flag
entry.is_private_dep |= private;
}
Externs(externs)
}
let crate_name = matches.opt_str("crate-name");
let remap_path_prefix = matches
fn parse_remap_path_prefix(
matches: &getopts::Matches,
error_format: ErrorOutputType
) -> Vec<(PathBuf, PathBuf)> {
matches
.opt_strs("remap-path-prefix")
.into_iter()
.map(|remap| {
@ -2475,9 +2489,99 @@ pub fn build_session_options_and_crate_config(
),
}
})
.collect();
.collect()
}
pub fn build_session_options(matches: &getopts::Matches) -> Options {
let color = parse_color(matches);
let edition = parse_crate_edition(matches);
let (json_rendered, json_artifact_notifications) = parse_json(matches);
let error_format = parse_error_format(matches, color, json_rendered);
let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(error_format, &e[..]));
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
let mut debugging_opts = build_debugging_options(matches, error_format);
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
let output_types = parse_output_types(&debugging_opts, matches, error_format);
let mut cg = build_codegen_options(matches, error_format);
let (disable_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
&output_types,
matches,
error_format,
cg.codegen_units,
);
check_thread_count(&debugging_opts, error_format);
let incremental = select_incremental_path(&debugging_opts, &cg, error_format);
if debugging_opts.profile && incremental.is_some() {
early_error(
error_format,
"can't instrument with gcov profiling when compiling incrementally",
);
}
if cg.profile_generate.enabled() && cg.profile_use.is_some() {
early_error(
error_format,
"options `-C profile-generate` and `-C profile-use` are exclusive",
);
}
let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
let prints = collect_print_requests(
&mut cg,
&mut debugging_opts,
matches,
is_unstable_enabled,
error_format,
);
let cg = cg;
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let target_triple = parse_target_triple(matches, error_format);
let opt_level = parse_opt_level(matches, &cg, error_format);
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
// for more details.
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
let debuginfo = select_debuginfo(matches, &cg, error_format);
let mut search_paths = vec![];
for s in &matches.opt_strs("L") {
search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
}
let libs = parse_libs(matches, error_format);
let test = matches.opt_present("test");
let borrowck_mode = parse_borrowck_mode(&debugging_opts, error_format);
if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
early_warn(
error_format,
"-C remark requires \"-C debuginfo=n\" to show source locations",
);
}
let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled);
let crate_name = matches.opt_str("crate-name");
let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
(
Options {
crate_types,
optimize: opt_level,
@ -2485,7 +2589,7 @@ pub fn build_session_options_and_crate_config(
lint_opts,
lint_cap,
describe_lints,
output_types: OutputTypes(output_types),
output_types,
search_paths,
maybe_sysroot: sysroot_opt,
target_triple,
@ -2496,7 +2600,7 @@ pub fn build_session_options_and_crate_config(
borrowck_mode,
cg,
error_format,
externs: Externs(externs),
externs,
crate_name,
alt_std_name: None,
libs,
@ -2508,9 +2612,7 @@ pub fn build_session_options_and_crate_config(
remap_path_prefix,
edition,
json_artifact_notifications,
},
cfg,
)
}
}
pub fn make_crate_type_option() -> RustcOptGroup {

View file

@ -3,8 +3,9 @@ use crate::lint;
use crate::middle::cstore;
use crate::session::config::{
build_configuration,
build_session_options_and_crate_config,
to_crate_config
build_session_options,
to_crate_config,
parse_cfgspecs,
};
use crate::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
use crate::session::build_session;
@ -18,6 +19,16 @@ use syntax::symbol::sym;
use syntax::edition::{Edition, DEFAULT_EDITION};
use syntax;
use super::Options;
use rustc_data_structures::fx::FxHashSet;
pub fn build_session_options_and_crate_config(
matches: &getopts::Matches,
) -> (Options, FxHashSet<(String, Option<String>)>) {
(
build_session_options(matches),
parse_cfgspecs(matches.opt_strs("cfg")),
)
}
impl ExternEntry {
fn new_public<S: Into<String>,

View file

@ -166,7 +166,8 @@ pub fn run_compiler(
None => return Ok(()),
};
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
let sopts = config::build_session_options(&matches);
let cfg = config::parse_cfgspecs(matches.opt_strs("cfg"));
let mut dummy_config = |sopts, cfg, diagnostic_output| {
let mut config = interface::Config {

View file

@ -541,7 +541,8 @@ pub fn lower_to_hir(
) -> Result<hir::map::Forest> {
// Lower AST to HIR.
let hir_forest = time(sess, "lowering AST -> HIR", || {
let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver);
let nt_to_tokenstream = syntax::parse::nt_to_tokenstream;
let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver, nt_to_tokenstream);
if sess.opts.debugging_opts.hir_stats {
hir_stats::print_hir_stats(&hir_crate);

View file

@ -45,7 +45,7 @@ use syntax::feature_gate::{Stability, deprecated_attributes};
use syntax_pos::{BytePos, Span};
use syntax::symbol::{Symbol, kw, sym};
use syntax::errors::{Applicability, DiagnosticBuilder};
use syntax::print::pprust::expr_to_string;
use syntax::print::pprust::{self, expr_to_string};
use syntax::visit::FnKind;
use rustc::hir::{self, GenericParamKind, PatKind};
@ -701,7 +701,8 @@ impl EarlyLintPass for DeprecatedAttr {
}
}
if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) {
let msg = format!("use of deprecated attribute `{}`: no longer used.", attr.path);
let path_str = pprust::path_to_string(&attr.path);
let msg = format!("use of deprecated attribute `{}`: no longer used.", path_str);
lint_deprecated_attr(cx, attr, &msg, None);
}
}

View file

@ -1,4 +1,5 @@
use syntax::ast::{self, MetaItem};
use syntax::print::pprust;
use syntax::symbol::{Symbol, sym};
use rustc_index::bit_set::{BitSet, HybridBitSet};
@ -159,9 +160,8 @@ where
if let Some(s) = item.value_str() {
return Some(s.to_string())
} else {
sess.span_err(
item.span,
&format!("{} attribute requires a path", item.path));
let path = pprust::path_to_string(&item.path);
sess.span_err(item.span, &format!("{} attribute requires a path", path));
return None;
}
}

View file

@ -263,7 +263,8 @@ impl<'a> AstValidator<'a> {
let mut err = self.err_handler().struct_span_err(poly.span,
&format!("`?Trait` is not permitted in {}", where_));
if is_trait {
err.note(&format!("traits are `?{}` by default", poly.trait_ref.path));
let path_str = pprust::path_to_string(&poly.trait_ref.path);
err.note(&format!("traits are `?{}` by default", path_str));
}
err.emit();
}

View file

@ -37,6 +37,7 @@ use syntax::ext::expand::AstFragment;
use syntax::ext::hygiene::ExpnId;
use syntax::feature_gate::is_builtin_attr;
use syntax::parse::token::{self, Token};
use syntax::print::pprust;
use syntax::{span_err, struct_span_err};
use syntax::source_map::{respan, Spanned};
use syntax::symbol::{kw, sym};
@ -228,7 +229,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
.span_suggestion(
path.span,
"try",
format!("crate::{}", path),
format!("crate::{}", pprust::path_to_string(&path)),
Applicability::MaybeIncorrect,
)
.emit();

View file

@ -38,6 +38,7 @@ use rustc_metadata::cstore::CStore;
use syntax::ext::hygiene::{ExpnId, Transparency, SyntaxContext};
use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
use syntax::ext::base::{SyntaxExtension, MacroKind, SpecialDerives};
use syntax::print::pprust;
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
@ -2011,13 +2012,13 @@ impl<'a> Resolver<'a> {
let mut candidates =
self.lookup_import_candidates(ident, TypeNS, is_mod);
candidates.sort_by_cached_key(|c| {
(c.path.segments.len(), c.path.to_string())
(c.path.segments.len(), pprust::path_to_string(&c.path))
});
if let Some(candidate) = candidates.get(0) {
(
String::from("unresolved import"),
Some((
vec![(ident.span, candidate.path.to_string())],
vec![(ident.span, pprust::path_to_string(&candidate.path))],
String::from("a similar path exists"),
Applicability::MaybeIncorrect,
)),

View file

@ -21,6 +21,7 @@ use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
use syntax::ext::compile_declarative_macro;
use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
use syntax::feature_gate::GateIssue;
use syntax::print::pprust;
use syntax::symbol::{Symbol, kw, sym};
use syntax_pos::{Span, DUMMY_SP};
@ -324,7 +325,8 @@ impl<'a> Resolver<'a> {
Ok(if ext.macro_kind() != kind {
let expected = kind.descr_expected();
let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path);
let path_str = pprust::path_to_string(path);
let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path_str);
self.session.struct_span_err(path.span, &msg)
.span_label(path.span, format!("not {} {}", kind.article(), expected))
.emit();
@ -805,14 +807,16 @@ impl<'a> Resolver<'a> {
}
}
if let Some(depr) = &stability.rustc_depr {
let (message, lint) = stability::rustc_deprecation_message(depr, &path.to_string());
let path = pprust::path_to_string(path);
let (message, lint) = stability::rustc_deprecation_message(depr, &path);
stability::early_report_deprecation(
self.session, &message, depr.suggestion, lint, span
);
}
}
if let Some(depr) = &ext.deprecation {
let (message, lint) = stability::deprecation_message(depr, &path.to_string());
let path = pprust::path_to_string(&path);
let (message, lint) = stability::deprecation_message(depr, &path);
stability::early_report_deprecation(self.session, &message, None, lint, span);
}
}

View file

@ -46,6 +46,7 @@ use serialize::json::{ToJson, Json, as_json};
use syntax::ast;
use syntax::edition::Edition;
use syntax::ext::base::MacroKind;
use syntax::print::pprust;
use syntax::source_map::FileName;
use syntax::feature_gate::UnstableFeatures;
use syntax::symbol::{Symbol, sym};
@ -2957,7 +2958,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
}
fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
let path = attr.path.to_string();
let path = pprust::path_to_string(&attr.path);
if attr.is_word() {
Some(path)

View file

@ -7,7 +7,6 @@ pub use crate::util::parser::ExprPrecedence;
use crate::ext::hygiene::ExpnId;
use crate::parse::token::{self, DelimToken};
use crate::print::pprust;
use crate::ptr::P;
use crate::source_map::{dummy_spanned, respan, Spanned};
use crate::symbol::{kw, sym, Symbol};
@ -70,7 +69,7 @@ impl fmt::Display for Lifetime {
/// along with a bunch of supporting information.
///
/// E.g., `std::cmp::PartialEq`.
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Path {
pub span: Span,
/// The segments in the path: the things separated by `::`.
@ -86,18 +85,6 @@ impl PartialEq<Symbol> for Path {
}
}
impl fmt::Debug for Path {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "path({})", pprust::path_to_string(self))
}
}
impl fmt::Display for Path {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", pprust::path_to_string(self))
}
}
impl Path {
// Convert a span and an identifier to the corresponding
// one-segment path.
@ -507,19 +494,13 @@ pub struct Block {
pub span: Span,
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Pat {
pub id: NodeId,
pub kind: PatKind,
pub span: Span,
}
impl fmt::Debug for Pat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
}
}
impl Pat {
/// Attempt reparsing the pattern as a type.
/// This is intended for use by diagnostics.
@ -831,7 +812,7 @@ impl UnOp {
}
/// A statement
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Stmt {
pub id: NodeId,
pub kind: StmtKind,
@ -865,18 +846,7 @@ impl Stmt {
}
}
impl fmt::Debug for Stmt {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"stmt({}: {})",
self.id.to_string(),
pprust::stmt_to_string(self)
)
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum StmtKind {
/// A local (let) binding.
Local(P<Local>),
@ -973,7 +943,7 @@ pub struct AnonConst {
}
/// An expression.
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Expr {
pub id: NodeId,
pub kind: ExprKind,
@ -1100,12 +1070,6 @@ impl Expr {
}
}
impl fmt::Debug for Expr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
}
}
/// Limit types of a range (inclusive or exclusive)
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
pub enum RangeLimits {
@ -1660,19 +1624,13 @@ pub enum AssocTyConstraintKind {
},
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Ty {
pub id: NodeId,
pub kind: TyKind,
pub span: Span,
}
impl fmt::Debug for Ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "type({})", pprust::ty_to_string(self))
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct BareFnTy {
pub unsafety: Unsafety,

View file

@ -5,6 +5,7 @@ use crate::early_buffered_lints::BufferedEarlyLintId;
use crate::ext::base::ExtCtxt;
use crate::feature_gate::{Features, GatedCfg};
use crate::parse::ParseSess;
use crate::print::pprust;
use errors::{Applicability, Handler};
use syntax_pos::hygiene::Transparency;
@ -243,7 +244,11 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
let meta = meta.as_ref().unwrap();
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(sess, meta.span, AttrError::MultipleItem(meta.path.to_string()));
handle_errors(
sess,
meta.span,
AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
return false
}
if let Some(v) = meta.value_str() {
@ -271,7 +276,10 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
handle_errors(
sess,
mi.span,
AttrError::UnknownMetaItem(mi.path.to_string(), expected),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
expected,
),
);
continue 'outer
}
@ -362,7 +370,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
sess,
meta.span(),
AttrError::UnknownMetaItem(
mi.path.to_string(),
pprust::path_to_string(&mi.path),
&["feature", "reason", "issue", "soft"]
),
);
@ -434,7 +442,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
sess,
meta.span(),
AttrError::UnknownMetaItem(
mi.path.to_string(), &["since", "note"],
pprust::path_to_string(&mi.path),
&["since", "note"],
),
);
continue 'outer
@ -597,8 +606,11 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
!eval_condition(mis[0].meta_item().unwrap(), sess, eval)
},
_ => {
span_err!(sess.span_diagnostic, cfg.span, E0537,
"invalid predicate `{}`", cfg.path);
span_err!(
sess.span_diagnostic, cfg.span, E0537,
"invalid predicate `{}`",
pprust::path_to_string(&cfg.path)
);
false
}
}
@ -653,7 +665,9 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(
sess, meta.span, AttrError::MultipleItem(meta.path.to_string())
sess,
meta.span,
AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
return false
}
@ -691,8 +705,10 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
handle_errors(
sess,
meta.span(),
AttrError::UnknownMetaItem(mi.path.to_string(),
&["since", "note"]),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
&["since", "note"],
),
);
continue 'outer
}

View file

@ -13,6 +13,7 @@ use crate::mut_visit::*;
use crate::parse::{DirectoryOwnership, PResult, ParseSess};
use crate::parse::token;
use crate::parse::parser::Parser;
use crate::print::pprust;
use crate::ptr::P;
use crate::symbol::{sym, Symbol};
use crate::tokenstream::{TokenStream, TokenTree};
@ -388,7 +389,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
"`derive` may only be applied to structs, enums and unions");
if let ast::AttrStyle::Inner = attr.style {
let trait_list = derives.iter()
.map(|t| t.to_string()).collect::<Vec<_>>();
.map(|t| pprust::path_to_string(t))
.collect::<Vec<_>>();
let suggestion = format!("#[derive({})]", trait_list.join(", "));
err.span_suggestion(
span, "try an outer attribute", suggestion,
@ -587,8 +589,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let result = if let Some(result) = fragment_kind.make_from(tok_result) {
result
} else {
let msg = format!("non-{kind} macro in {kind} position: {path}",
kind = fragment_kind.name(), path = mac.path);
let msg = format!(
"non-{kind} macro in {kind} position: {path}",
kind = fragment_kind.name(),
path = pprust::path_to_string(&mac.path),
);
self.cx.span_err(span, &msg);
self.cx.trace_macros_diag();
fragment_kind.dummy(span)
@ -878,7 +883,7 @@ impl<'a> Parser<'a> {
err.span_label(span, "caused by the macro expansion here");
let msg = format!(
"the usage of `{}!` is likely invalid in {} context",
macro_path,
pprust::path_to_string(&macro_path),
kind_name,
);
err.note(&msg);

View file

@ -174,7 +174,8 @@ fn generic_extension<'cx>(
rhses: &[mbe::TokenTree],
) -> Box<dyn MacResult + 'cx> {
if cx.trace_macros() {
trace_macros_note(cx, sp, format!("expanding `{}! {{ {} }}`", name, arg));
let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone()));
trace_macros_note(cx, sp, msg);
}
// Which arm's failure should we report? (the one furthest along)
@ -212,7 +213,8 @@ fn generic_extension<'cx>(
}
if cx.trace_macros() {
trace_macros_note(cx, sp, format!("to `{}`", tts));
let msg = format!("to `{}`", pprust::tts_to_string(tts.clone()));
trace_macros_note(cx, sp, msg);
}
let directory = Directory {

View file

@ -2,6 +2,7 @@ use crate::ast;
use crate::ext::base::ExtCtxt;
use crate::parse::{self, token, ParseSess};
use crate::parse::lexer::comments;
use crate::print::pprust;
use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
use errors::Diagnostic;
@ -174,7 +175,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
}
Interpolated(nt) => {
let stream = nt.to_tokenstream(sess, span);
let stream = parse::nt_to_tokenstream(&nt, sess, span);
TokenTree::Group(Group {
delimiter: Delimiter::None,
stream,
@ -407,7 +408,7 @@ impl server::TokenStream for Rustc<'_> {
)
}
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
stream.to_string()
pprust::tts_to_string(stream.clone())
}
fn from_token_tree(
&mut self,

View file

@ -856,7 +856,7 @@ impl<'a> Parser<'a> {
// This is a best-effort recovery.
path.span,
"try",
format!("<{}>::{}", ty_str, path),
format!("<{}>::{}", ty_str, pprust::path_to_string(&path)),
Applicability::MaybeIncorrect,
)
.emit();

View file

@ -4,10 +4,9 @@ use crate::ast::{self, CrateConfig, NodeId};
use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
use crate::source_map::{SourceMap, FilePathMapping};
use crate::feature_gate::UnstableFeatures;
use crate::parse::parser::Parser;
use crate::parse::parser::emit_unclosed_delims;
use crate::parse::token::TokenKind;
use crate::tokenstream::{TokenStream, TokenTree};
use crate::parse::parser::{Parser, emit_unclosed_delims};
use crate::parse::token::{Nonterminal, TokenKind};
use crate::tokenstream::{self, TokenStream, TokenTree};
use crate::print::pprust;
use crate::symbol::Symbol;
@ -24,6 +23,8 @@ use std::borrow::Cow;
use std::path::{Path, PathBuf};
use std::str;
use log::info;
#[cfg(test)]
mod tests;
@ -407,3 +408,132 @@ impl SeqSep {
}
}
}
// NOTE(Centril): The following probably shouldn't be here but it acknowledges the
// fact that architecturally, we are using parsing (read on below to understand why).
pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> TokenStream {
// A `Nonterminal` is often a parsed AST item. At this point we now
// need to convert the parsed AST to an actual token stream, e.g.
// un-parse it basically.
//
// Unfortunately there's not really a great way to do that in a
// guaranteed lossless fashion right now. The fallback here is to just
// stringify the AST node and reparse it, but this loses all span
// information.
//
// As a result, some AST nodes are annotated with the token stream they
// came from. Here we attempt to extract these lossless token streams
// before we fall back to the stringification.
let tokens = match *nt {
Nonterminal::NtItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtTraitItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtImplItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtIdent(ident, is_raw) => {
Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into())
}
Nonterminal::NtLifetime(ident) => {
Some(tokenstream::TokenTree::token(token::Lifetime(ident.name), ident.span).into())
}
Nonterminal::NtTT(ref tt) => {
Some(tt.clone().into())
}
_ => None,
};
// FIXME(#43081): Avoid this pretty-print + reparse hack
let source = pprust::nonterminal_to_string(nt);
let filename = FileName::macro_expansion_source_code(&source);
let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
// During early phases of the compiler the AST could get modified
// directly (e.g., attributes added or removed) and the internal cache
// of tokens my not be invalidated or updated. Consequently if the
// "lossless" token stream disagrees with our actual stringification
// (which has historically been much more battle-tested) then we go
// with the lossy stream anyway (losing span information).
//
// Note that the comparison isn't `==` here to avoid comparing spans,
// but it *also* is a "probable" equality which is a pretty weird
// definition. We mostly want to catch actual changes to the AST
// like a `#[cfg]` being processed or some weird `macro_rules!`
// expansion.
//
// What we *don't* want to catch is the fact that a user-defined
// literal like `0xf` is stringified as `15`, causing the cached token
// stream to not be literal `==` token-wise (ignoring spans) to the
// token stream we got from stringification.
//
// Instead the "probably equal" check here is "does each token
// recursively have the same discriminant?" We basically don't look at
// the token values here and assume that such fine grained token stream
// modifications, including adding/removing typically non-semantic
// tokens such as extra braces and commas, don't happen.
if let Some(tokens) = tokens {
if tokens.probably_equal_for_proc_macro(&tokens_for_real) {
return tokens
}
info!("cached tokens found, but they're not \"probably equal\", \
going with stringified version");
}
return tokens_for_real
}
fn prepend_attrs(
sess: &ParseSess,
attrs: &[ast::Attribute],
tokens: Option<&tokenstream::TokenStream>,
span: syntax_pos::Span
) -> Option<tokenstream::TokenStream> {
let tokens = tokens?;
if attrs.len() == 0 {
return Some(tokens.clone())
}
let mut builder = tokenstream::TokenStreamBuilder::new();
for attr in attrs {
assert_eq!(attr.style, ast::AttrStyle::Outer,
"inner attributes should prevent cached tokens from existing");
let source = pprust::attribute_to_string(attr);
let macro_filename = FileName::macro_expansion_source_code(&source);
if attr.is_sugared_doc {
let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
builder.push(stream);
continue
}
// synthesize # [ $path $tokens ] manually here
let mut brackets = tokenstream::TokenStreamBuilder::new();
// For simple paths, push the identifier directly
if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() {
let ident = attr.path.segments[0].ident;
let token = token::Ident(ident.name, ident.as_str().starts_with("r#"));
brackets.push(tokenstream::TokenTree::token(token, ident.span));
// ... and for more complicated paths, fall back to a reparse hack that
// should eventually be removed.
} else {
let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
brackets.push(stream);
}
brackets.push(attr.tokens.clone());
// The span we list here for `#` and for `[ ... ]` are both wrong in
// that it encompasses more than each token, but it hopefully is "good
// enough" for now at least.
builder.push(tokenstream::TokenTree::token(token::Pound, attr.span));
let delim_span = tokenstream::DelimSpan::from_single(attr.span);
builder.push(tokenstream::TokenTree::Delimited(
delim_span, token::DelimToken::Bracket, brackets.build().into()));
}
builder.push(tokens.clone());
Some(builder.build())
}

View file

@ -9,20 +9,19 @@ mod path;
pub use path::PathStyle;
mod stmt;
mod generics;
use super::diagnostics::Error;
use crate::ast::{
self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, Ident,
IsAsync, MacDelimiter, Mutability, Param, StrStyle, SelfKind, TyKind, Visibility,
VisibilityKind, Unsafety,
self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
};
use crate::parse::{ParseSess, PResult, Directory, DirectoryOwnership, SeqSep, literal, token};
use crate::parse::diagnostics::{Error, dummy_arg};
use crate::parse::lexer::UnmatchedBrace;
use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use crate::parse::token::{Token, TokenKind, DelimToken};
use crate::print::pprust;
use crate::ptr::P;
use crate::source_map::{self, respan};
use crate::source_map::respan;
use crate::symbol::{kw, sym, Symbol};
use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
use crate::ThinVec;
@ -56,17 +55,6 @@ crate enum BlockMode {
Ignore,
}
/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
struct ParamCfg {
/// Is `self` is allowed as the first parameter?
is_self_allowed: bool,
/// Is `...` allowed as the tail of the parameter list?
allow_c_variadic: bool,
/// `is_name_required` decides if, per-parameter,
/// the parameter must have a pattern or just a type.
is_name_required: fn(&token::Token) -> bool,
}
/// Like `maybe_whole_expr`, but for things other than expressions.
#[macro_export]
macro_rules! maybe_whole {
@ -1105,271 +1093,6 @@ impl<'a> Parser<'a> {
res
}
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
let sp = self.token.span;
let is_trait_item = cfg.is_self_allowed;
let mut c_variadic = false;
// Parse the arguments, starting out with `self` being possibly allowed...
let (params, _) = self.parse_paren_comma_seq(|p| {
let param = p.parse_param_general(&cfg, is_trait_item);
// ...now that we've parsed the first argument, `self` is no longer allowed.
cfg.is_self_allowed = false;
match param {
Ok(param) => Ok(
if let TyKind::CVarArgs = param.ty.kind {
c_variadic = true;
if p.token != token::CloseDelim(token::Paren) {
p.span_err(
p.token.span,
"`...` must be the last argument of a C-variadic function",
);
// FIXME(eddyb) this should probably still push `CVarArgs`.
// Maybe AST validation/HIR lowering should emit the above error?
None
} else {
Some(param)
}
} else {
Some(param)
}
),
Err(mut e) => {
e.emit();
let lo = p.prev_span;
// Skip every token until next possible arg or end.
p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
// Create a placeholder argument for proper arg count (issue #34264).
let span = lo.to(p.prev_span);
Ok(Some(dummy_arg(Ident::new(kw::Invalid, span))))
}
}
})?;
let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
self.deduplicate_recovered_params_names(&mut params);
if c_variadic && params.len() <= 1 {
self.span_err(
sp,
"C-variadic function must be declared with at least one named argument",
);
}
Ok(params)
}
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
/// error.
/// This version of parse param doesn't necessarily require identifier names.
fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
let lo = self.token.span;
let attrs = self.parse_outer_attributes()?;
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
if let Some(mut param) = self.parse_self_param()? {
param.attrs = attrs.into();
return if cfg.is_self_allowed {
Ok(param)
} else {
self.recover_bad_self_param(param, is_trait_item)
};
}
let is_name_required = match self.token.kind {
token::DotDotDot => false,
_ => (cfg.is_name_required)(&self.token),
};
let (pat, ty) = if is_name_required || self.is_named_param() {
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
let pat = self.parse_fn_param_pat()?;
if let Err(mut err) = self.expect(&token::Colon) {
return if let Some(ident) = self.parameter_without_type(
&mut err,
pat,
is_name_required,
cfg.is_self_allowed,
is_trait_item,
) {
err.emit();
Ok(dummy_arg(ident))
} else {
Err(err)
};
}
self.eat_incorrect_doc_comment_for_param_type();
(pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?)
} else {
debug!("parse_param_general ident_to_pat");
let parser_snapshot_before_ty = self.clone();
self.eat_incorrect_doc_comment_for_param_type();
let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic);
if ty.is_ok() && self.token != token::Comma &&
self.token != token::CloseDelim(token::Paren) {
// This wasn't actually a type, but a pattern looking like a type,
// so we are going to rollback and re-parse for recovery.
ty = self.unexpected();
}
match ty {
Ok(ty) => {
let ident = Ident::new(kw::Invalid, self.prev_span);
let bm = BindingMode::ByValue(Mutability::Immutable);
let pat = self.mk_pat_ident(ty.span, bm, ident);
(pat, ty)
}
// If this is a C-variadic argument and we hit an error, return the error.
Err(err) if self.token == token::DotDotDot => return Err(err),
// Recover from attempting to parse the argument as a type without pattern.
Err(mut err) => {
err.cancel();
mem::replace(self, parser_snapshot_before_ty);
self.recover_arg_parse()?
}
}
};
let span = lo.to(self.token.span);
Ok(Param {
attrs: attrs.into(),
id: ast::DUMMY_NODE_ID,
is_placeholder: false,
pat,
span,
ty,
})
}
/// Returns the parsed optional self parameter and whether a self shortcut was used.
///
/// See `parse_self_param_with_attrs` to collect attributes.
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
// Extract an identifier *after* having confirmed that the token is one.
let expect_self_ident = |this: &mut Self| {
match this.token.kind {
// Preserve hygienic context.
token::Ident(name, _) => {
let span = this.token.span;
this.bump();
Ident::new(name, span)
}
_ => unreachable!(),
}
};
// Is `self` `n` tokens ahead?
let is_isolated_self = |this: &Self, n| {
this.is_keyword_ahead(n, &[kw::SelfLower])
&& this.look_ahead(n + 1, |t| t != &token::ModSep)
};
// Is `mut self` `n` tokens ahead?
let is_isolated_mut_self = |this: &Self, n| {
this.is_keyword_ahead(n, &[kw::Mut])
&& is_isolated_self(this, n + 1)
};
// Parse `self` or `self: TYPE`. We already know the current token is `self`.
let parse_self_possibly_typed = |this: &mut Self, m| {
let eself_ident = expect_self_ident(this);
let eself_hi = this.prev_span;
let eself = if this.eat(&token::Colon) {
SelfKind::Explicit(this.parse_ty()?, m)
} else {
SelfKind::Value(m)
};
Ok((eself, eself_ident, eself_hi))
};
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
let recover_self_ptr = |this: &mut Self| {
let msg = "cannot pass `self` by raw pointer";
let span = this.token.span;
this.struct_span_err(span, msg)
.span_label(span, msg)
.emit();
Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span))
};
// Parse optional `self` parameter of a method.
// Only a limited set of initial token sequences is considered `self` parameters; anything
// else is parsed as a normal function parameter list, so some lookahead is required.
let eself_lo = self.token.span;
let (eself, eself_ident, eself_hi) = match self.token.kind {
token::BinOp(token::And) => {
let eself = if is_isolated_self(self, 1) {
// `&self`
self.bump();
SelfKind::Region(None, Mutability::Immutable)
} else if is_isolated_mut_self(self, 1) {
// `&mut self`
self.bump();
self.bump();
SelfKind::Region(None, Mutability::Mutable)
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
// `&'lt self`
self.bump();
let lt = self.expect_lifetime();
SelfKind::Region(Some(lt), Mutability::Immutable)
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
// `&'lt mut self`
self.bump();
let lt = self.expect_lifetime();
self.bump();
SelfKind::Region(Some(lt), Mutability::Mutable)
} else {
// `&not_self`
return Ok(None);
};
(eself, expect_self_ident(self), self.prev_span)
}
// `*self`
token::BinOp(token::Star) if is_isolated_self(self, 1) => {
self.bump();
recover_self_ptr(self)?
}
// `*mut self` and `*const self`
token::BinOp(token::Star) if
self.look_ahead(1, |t| t.is_mutability())
&& is_isolated_self(self, 2) =>
{
self.bump();
self.bump();
recover_self_ptr(self)?
}
// `self` and `self: TYPE`
token::Ident(..) if is_isolated_self(self, 0) => {
parse_self_possibly_typed(self, Mutability::Immutable)?
}
// `mut self` and `mut self: TYPE`
token::Ident(..) if is_isolated_mut_self(self, 0) => {
self.bump();
parse_self_possibly_typed(self, Mutability::Mutable)?
}
_ => return Ok(None),
};
let eself = source_map::respan(eself_lo.to(eself_hi), eself);
Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
}
fn is_named_param(&self) -> bool {
let offset = match self.token.kind {
token::Interpolated(ref nt) => match **nt {
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
_ => 0,
}
token::BinOp(token::And) | token::AndAnd => 1,
_ if self.token.is_keyword(kw::Mut) => 1,
_ => 0,
};
self.look_ahead(offset, |t| t.is_ident()) &&
self.look_ahead(offset + 1, |t| t == &token::Colon)
}
fn is_crate_vis(&self) -> bool {
self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
}
@ -1454,12 +1177,14 @@ impl<'a> Parser<'a> {
`pub(super)`: visible only in the current module's parent
`pub(in path::to::module)`: visible only on the specified path"##;
let path_str = pprust::path_to_string(&path);
struct_span_err!(self.sess.span_diagnostic, path.span, E0704, "{}", msg)
.help(suggestion)
.span_suggestion(
path.span,
&format!("make this visible only to module `{}` with `in`", path),
format!("in {}", path),
&format!("make this visible only to module `{}` with `in`", path_str),
format!("in {}", path_str),
Applicability::MachineApplicable,
)
.emit();

View file

@ -552,8 +552,11 @@ impl<'a> Parser<'a> {
// Report non-fatal diagnostics, keep `x as usize` as an expression
// in AST and continue parsing.
let msg = format!("`<` is interpreted as a start of generic \
arguments for `{}`, not a {}", path, op_noun);
let msg = format!(
"`<` is interpreted as a start of generic arguments for `{}`, not a {}",
pprust::path_to_string(&path),
op_noun,
);
let span_after_type = parser_snapshot_after_type.token.span;
let expr = mk_expr(self, P(Ty {
span: path.span,

View file

@ -1,28 +1,23 @@
use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode, ParamCfg};
use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode};
use crate::maybe_whole;
use crate::ptr::P;
use crate::ast::{
self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle,
Item, ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind,
UseTree, UseTreeKind, PathSegment,
IsAuto, Constness, IsAsync, Unsafety, Defaultness,
Visibility, VisibilityKind, Mutability, FnDecl, FnHeader, MethodSig, Block,
ForeignItem, ForeignItemKind,
Ty, TyKind, Generics, GenericBounds, TraitRef,
EnumDef, VariantData, StructField, AnonConst,
Mac, MacDelimiter,
};
use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle, AnonConst, Item, ItemKind};
use crate::ast::{ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, MethodSig, SelfKind, Param};
use crate::ext::base::DummyResult;
use crate::parse::token;
use crate::parse::parser::maybe_append;
use crate::parse::diagnostics::Error;
use crate::parse::diagnostics::{Error, dummy_arg};
use crate::tokenstream::{TokenTree, TokenStream};
use crate::source_map::{respan, Span};
use crate::symbol::{kw, sym};
use crate::source_map::{self, respan, Span};
use crate::ThinVec;
use std::mem;
use log::debug;
use std::mem;
use rustc_target::spec::abi::Abi;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
@ -412,7 +407,7 @@ impl<'a> Parser<'a> {
self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, vis)
}
fn mk_item_with_info(
pub(super) fn mk_item_with_info(
&self,
attrs: Vec<Attribute>,
lo: Span,
@ -425,16 +420,6 @@ impl<'a> Parser<'a> {
Ok(Some(self.mk_item(span, ident, item, vis, attrs)))
}
fn recover_first_param(&mut self) -> &'static str {
match self.parse_outer_attributes()
.and_then(|_| self.parse_self_param())
.map_err(|mut e| e.cancel())
{
Ok(Some(_)) => "method",
_ => "function",
}
}
/// This is the fall-through for parsing items.
fn parse_macro_use_or_failure(
&mut self,
@ -707,9 +692,11 @@ impl<'a> Parser<'a> {
Ok(item)
}
fn parse_impl_item_(&mut self,
fn parse_impl_item_(
&mut self,
at_end: &mut bool,
mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
mut attrs: Vec<Attribute>,
) -> PResult<'a, ImplItem> {
let lo = self.token.span;
let vis = self.parse_visibility(false)?;
let defaultness = self.parse_defaultness();
@ -722,8 +709,11 @@ impl<'a> Parser<'a> {
(name, kind, generics)
} else if self.is_const_item() {
self.parse_impl_const()?
} else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
// FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
(Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
} else {
let (name, inner_attrs, generics, kind) = self.parse_impl_method(&vis, at_end)?;
let (name, inner_attrs, generics, kind) = self.parse_impl_method(at_end)?;
attrs.extend(inner_attrs);
(name, kind, generics)
};
@ -783,71 +773,6 @@ impl<'a> Parser<'a> {
Ok((name, ImplItemKind::Const(typ, expr), Generics::default()))
}
/// Parses a method or a macro invocation in a trait impl.
fn parse_impl_method(
&mut self,
vis: &Visibility,
at_end: &mut bool
) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> {
// FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
// method macro
Ok((Ident::invalid(), vec![], Generics::default(), ast::ImplItemKind::Macro(mac)))
} else {
let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body)))
}
}
/// Parse the "signature", including the identifier, parameters, and generics
/// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
fn parse_method_sig(
&mut self,
is_name_required: fn(&token::Token) -> bool,
) -> PResult<'a, (Ident, MethodSig, Generics)> {
let header = self.parse_fn_front_matter()?;
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: true,
allow_c_variadic: false,
is_name_required,
})?;
Ok((ident, MethodSig { header, decl }, generics))
}
/// Parses all the "front matter" for a `fn` declaration, up to
/// and including the `fn` keyword:
///
/// - `const fn`
/// - `unsafe fn`
/// - `const unsafe fn`
/// - `extern fn`
/// - etc.
fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
let is_const_fn = self.eat_keyword(kw::Const);
let const_span = self.prev_span;
let asyncness = self.parse_asyncness();
if let IsAsync::Async { .. } = asyncness {
self.ban_async_in_2015(self.prev_span);
}
let asyncness = respan(self.prev_span, asyncness);
let unsafety = self.parse_unsafety();
let (constness, unsafety, abi) = if is_const_fn {
(respan(const_span, Constness::Const), unsafety, Abi::Rust)
} else {
let abi = self.parse_extern_abi()?;
(respan(self.prev_span, Constness::NotConst), unsafety, abi)
};
if !self.eat_keyword(kw::Fn) {
// It is possible for `expect_one_of` to recover given the contents of
// `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
// account for this.
if !self.expect_one_of(&[], &[])? { unreachable!() }
}
Ok(FnHeader { constness, unsafety, asyncness, abi })
}
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
// Parse optional `auto` prefix.
@ -957,13 +882,7 @@ impl<'a> Parser<'a> {
// trait item macro.
(Ident::invalid(), TraitItemKind::Macro(mac), Generics::default())
} else {
// This is somewhat dubious; We don't want to allow
// argument names to be left off if there is a definition...
//
// We don't allow argument names to be left off in edition 2018.
let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?;
let body = self.parse_trait_method_body(at_end, &mut attrs)?;
(ident, TraitItemKind::Method(sig, body), generics)
self.parse_trait_item_method(at_end, &mut attrs)?
};
Ok(TraitItem {
@ -991,43 +910,6 @@ impl<'a> Parser<'a> {
Ok((ident, TraitItemKind::Const(ty, default), Generics::default()))
}
/// Parse the "body" of a method in a trait item definition.
/// This can either be `;` when there's no body,
/// or e.g. a block when the method is a provided one.
fn parse_trait_method_body(
&mut self,
at_end: &mut bool,
attrs: &mut Vec<Attribute>,
) -> PResult<'a, Option<P<Block>>> {
Ok(match self.token.kind {
token::Semi => {
debug!("parse_trait_method_body(): parsing required method");
self.bump();
*at_end = true;
None
}
token::OpenDelim(token::Brace) => {
debug!("parse_trait_method_body(): parsing provided method");
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
attrs.extend(inner_attrs.iter().cloned());
Some(body)
}
token::Interpolated(ref nt) => {
match **nt {
token::NtBlock(..) => {
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
attrs.extend(inner_attrs.iter().cloned());
Some(body)
}
_ => return self.expected_semi_or_open_brace(),
}
}
_ => return self.expected_semi_or_open_brace(),
})
}
/// Parses the following grammar:
///
/// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
@ -1194,45 +1076,6 @@ impl<'a> Parser<'a> {
Ok(ident)
}
/// Parses an item-position function declaration.
fn parse_item_fn(
&mut self,
lo: Span,
vis: Visibility,
attrs: Vec<Attribute>,
header: FnHeader,
) -> PResult<'a, Option<P<Item>>> {
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: false,
allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe,
is_name_required: |_| true,
})?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
let kind = ItemKind::Fn(decl, header, generics, body);
self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
}
/// Parse the "signature", including the identifier, parameters, and generics of a function.
fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
let decl = self.parse_fn_decl(cfg, true)?;
generics.where_clause = self.parse_where_clause()?;
Ok((ident, decl, generics))
}
/// Parses the parameter list and result type of a function declaration.
pub(super) fn parse_fn_decl(
&mut self,
cfg: ParamCfg,
ret_allow_plus: bool,
) -> PResult<'a, P<FnDecl>> {
Ok(P(FnDecl {
inputs: self.parse_fn_params(cfg)?,
output: self.parse_ret_ty(ret_allow_plus)?,
}))
}
/// Parses `extern` for foreign ABIs modules.
///
/// `extern` is expected to have been
@ -1344,32 +1187,6 @@ impl<'a> Parser<'a> {
}
}
/// Parses a function declaration from a foreign module.
fn parse_item_foreign_fn(
&mut self,
vis: ast::Visibility,
lo: Span,
attrs: Vec<Attribute>,
extern_sp: Span,
) -> PResult<'a, ForeignItem> {
self.expect_keyword(kw::Fn)?;
let (ident, decl, generics) = self.parse_fn_sig(super::ParamCfg {
is_self_allowed: false,
allow_c_variadic: true,
is_name_required: |_| true,
})?;
let span = lo.to(self.token.span);
self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
Ok(ast::ForeignItem {
ident,
attrs,
kind: ForeignItemKind::Fn(decl, generics),
id: DUMMY_NODE_ID,
span,
vis,
})
}
/// Parses a static item from a foreign module.
/// Assumes that the `static` keyword is already parsed.
fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
@ -1910,3 +1727,466 @@ impl<'a> Parser<'a> {
})
}
}
/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
pub(super) struct ParamCfg {
/// Is `self` is allowed as the first parameter?
pub is_self_allowed: bool,
/// Is `...` allowed as the tail of the parameter list?
pub allow_c_variadic: bool,
/// `is_name_required` decides if, per-parameter,
/// the parameter must have a pattern or just a type.
pub is_name_required: fn(&token::Token) -> bool,
}
/// Parsing of functions and methods.
impl<'a> Parser<'a> {
/// Parses an item-position function declaration.
fn parse_item_fn(
&mut self,
lo: Span,
vis: Visibility,
attrs: Vec<Attribute>,
header: FnHeader,
) -> PResult<'a, Option<P<Item>>> {
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: false,
allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe,
is_name_required: |_| true,
})?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
let kind = ItemKind::Fn(decl, header, generics, body);
self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
}
/// Parses a function declaration from a foreign module.
fn parse_item_foreign_fn(
&mut self,
vis: ast::Visibility,
lo: Span,
attrs: Vec<Attribute>,
extern_sp: Span,
) -> PResult<'a, ForeignItem> {
self.expect_keyword(kw::Fn)?;
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: false,
allow_c_variadic: true,
is_name_required: |_| true,
})?;
let span = lo.to(self.token.span);
self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
Ok(ast::ForeignItem {
ident,
attrs,
kind: ForeignItemKind::Fn(decl, generics),
id: DUMMY_NODE_ID,
span,
vis,
})
}
/// Parses a method or a macro invocation in a trait impl.
fn parse_impl_method(
&mut self,
at_end: &mut bool,
) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> {
let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body)))
}
fn parse_trait_item_method(
&mut self,
at_end: &mut bool,
attrs: &mut Vec<Attribute>,
) -> PResult<'a, (Ident, TraitItemKind, Generics)> {
// This is somewhat dubious; We don't want to allow
// argument names to be left off if there is a definition...
//
// We don't allow argument names to be left off in edition 2018.
let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?;
let body = self.parse_trait_method_body(at_end, attrs)?;
Ok((ident, TraitItemKind::Method(sig, body), generics))
}
/// Parse the "body" of a method in a trait item definition.
/// This can either be `;` when there's no body,
/// or e.g. a block when the method is a provided one.
fn parse_trait_method_body(
&mut self,
at_end: &mut bool,
attrs: &mut Vec<Attribute>,
) -> PResult<'a, Option<P<Block>>> {
Ok(match self.token.kind {
token::Semi => {
debug!("parse_trait_method_body(): parsing required method");
self.bump();
*at_end = true;
None
}
token::OpenDelim(token::Brace) => {
debug!("parse_trait_method_body(): parsing provided method");
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
attrs.extend(inner_attrs.iter().cloned());
Some(body)
}
token::Interpolated(ref nt) => {
match **nt {
token::NtBlock(..) => {
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
attrs.extend(inner_attrs.iter().cloned());
Some(body)
}
_ => return self.expected_semi_or_open_brace(),
}
}
_ => return self.expected_semi_or_open_brace(),
})
}
/// Parse the "signature", including the identifier, parameters, and generics
/// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
fn parse_method_sig(
&mut self,
is_name_required: fn(&token::Token) -> bool,
) -> PResult<'a, (Ident, MethodSig, Generics)> {
let header = self.parse_fn_front_matter()?;
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: true,
allow_c_variadic: false,
is_name_required,
})?;
Ok((ident, MethodSig { header, decl }, generics))
}
/// Parses all the "front matter" for a `fn` declaration, up to
/// and including the `fn` keyword:
///
/// - `const fn`
/// - `unsafe fn`
/// - `const unsafe fn`
/// - `extern fn`
/// - etc.
fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
let is_const_fn = self.eat_keyword(kw::Const);
let const_span = self.prev_span;
let asyncness = self.parse_asyncness();
if let IsAsync::Async { .. } = asyncness {
self.ban_async_in_2015(self.prev_span);
}
let asyncness = respan(self.prev_span, asyncness);
let unsafety = self.parse_unsafety();
let (constness, unsafety, abi) = if is_const_fn {
(respan(const_span, Constness::Const), unsafety, Abi::Rust)
} else {
let abi = self.parse_extern_abi()?;
(respan(self.prev_span, Constness::NotConst), unsafety, abi)
};
if !self.eat_keyword(kw::Fn) {
// It is possible for `expect_one_of` to recover given the contents of
// `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
// account for this.
if !self.expect_one_of(&[], &[])? { unreachable!() }
}
Ok(FnHeader { constness, unsafety, asyncness, abi })
}
/// Parse the "signature", including the identifier, parameters, and generics of a function.
fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
let decl = self.parse_fn_decl(cfg, true)?;
generics.where_clause = self.parse_where_clause()?;
Ok((ident, decl, generics))
}
/// Parses the parameter list and result type of a function declaration.
pub(super) fn parse_fn_decl(
&mut self,
cfg: ParamCfg,
ret_allow_plus: bool,
) -> PResult<'a, P<FnDecl>> {
Ok(P(FnDecl {
inputs: self.parse_fn_params(cfg)?,
output: self.parse_ret_ty(ret_allow_plus)?,
}))
}
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
let sp = self.token.span;
let is_trait_item = cfg.is_self_allowed;
let mut c_variadic = false;
// Parse the arguments, starting out with `self` being possibly allowed...
let (params, _) = self.parse_paren_comma_seq(|p| {
let param = p.parse_param_general(&cfg, is_trait_item);
// ...now that we've parsed the first argument, `self` is no longer allowed.
cfg.is_self_allowed = false;
match param {
Ok(param) => Ok(
if let TyKind::CVarArgs = param.ty.kind {
c_variadic = true;
if p.token != token::CloseDelim(token::Paren) {
p.span_err(
p.token.span,
"`...` must be the last argument of a C-variadic function",
);
// FIXME(eddyb) this should probably still push `CVarArgs`.
// Maybe AST validation/HIR lowering should emit the above error?
None
} else {
Some(param)
}
} else {
Some(param)
}
),
Err(mut e) => {
e.emit();
let lo = p.prev_span;
// Skip every token until next possible arg or end.
p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
// Create a placeholder argument for proper arg count (issue #34264).
let span = lo.to(p.prev_span);
Ok(Some(dummy_arg(Ident::new(kw::Invalid, span))))
}
}
})?;
let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
self.deduplicate_recovered_params_names(&mut params);
if c_variadic && params.len() <= 1 {
self.span_err(
sp,
"C-variadic function must be declared with at least one named argument",
);
}
Ok(params)
}
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
/// error.
/// This version of parse param doesn't necessarily require identifier names.
fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
let lo = self.token.span;
let attrs = self.parse_outer_attributes()?;
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
if let Some(mut param) = self.parse_self_param()? {
param.attrs = attrs.into();
return if cfg.is_self_allowed {
Ok(param)
} else {
self.recover_bad_self_param(param, is_trait_item)
};
}
let is_name_required = match self.token.kind {
token::DotDotDot => false,
_ => (cfg.is_name_required)(&self.token),
};
let (pat, ty) = if is_name_required || self.is_named_param() {
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
let pat = self.parse_fn_param_pat()?;
if let Err(mut err) = self.expect(&token::Colon) {
return if let Some(ident) = self.parameter_without_type(
&mut err,
pat,
is_name_required,
cfg.is_self_allowed,
is_trait_item,
) {
err.emit();
Ok(dummy_arg(ident))
} else {
Err(err)
};
}
self.eat_incorrect_doc_comment_for_param_type();
(pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?)
} else {
debug!("parse_param_general ident_to_pat");
let parser_snapshot_before_ty = self.clone();
self.eat_incorrect_doc_comment_for_param_type();
let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic);
if ty.is_ok() && self.token != token::Comma &&
self.token != token::CloseDelim(token::Paren) {
// This wasn't actually a type, but a pattern looking like a type,
// so we are going to rollback and re-parse for recovery.
ty = self.unexpected();
}
match ty {
Ok(ty) => {
let ident = Ident::new(kw::Invalid, self.prev_span);
let bm = BindingMode::ByValue(Mutability::Immutable);
let pat = self.mk_pat_ident(ty.span, bm, ident);
(pat, ty)
}
// If this is a C-variadic argument and we hit an error, return the error.
Err(err) if self.token == token::DotDotDot => return Err(err),
// Recover from attempting to parse the argument as a type without pattern.
Err(mut err) => {
err.cancel();
mem::replace(self, parser_snapshot_before_ty);
self.recover_arg_parse()?
}
}
};
let span = lo.to(self.token.span);
Ok(Param {
attrs: attrs.into(),
id: ast::DUMMY_NODE_ID,
is_placeholder: false,
pat,
span,
ty,
})
}
/// Returns the parsed optional self parameter and whether a self shortcut was used.
///
/// See `parse_self_param_with_attrs` to collect attributes.
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
// Extract an identifier *after* having confirmed that the token is one.
let expect_self_ident = |this: &mut Self| {
match this.token.kind {
// Preserve hygienic context.
token::Ident(name, _) => {
let span = this.token.span;
this.bump();
Ident::new(name, span)
}
_ => unreachable!(),
}
};
// Is `self` `n` tokens ahead?
let is_isolated_self = |this: &Self, n| {
this.is_keyword_ahead(n, &[kw::SelfLower])
&& this.look_ahead(n + 1, |t| t != &token::ModSep)
};
// Is `mut self` `n` tokens ahead?
let is_isolated_mut_self = |this: &Self, n| {
this.is_keyword_ahead(n, &[kw::Mut])
&& is_isolated_self(this, n + 1)
};
// Parse `self` or `self: TYPE`. We already know the current token is `self`.
let parse_self_possibly_typed = |this: &mut Self, m| {
let eself_ident = expect_self_ident(this);
let eself_hi = this.prev_span;
let eself = if this.eat(&token::Colon) {
SelfKind::Explicit(this.parse_ty()?, m)
} else {
SelfKind::Value(m)
};
Ok((eself, eself_ident, eself_hi))
};
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
let recover_self_ptr = |this: &mut Self| {
let msg = "cannot pass `self` by raw pointer";
let span = this.token.span;
this.struct_span_err(span, msg)
.span_label(span, msg)
.emit();
Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span))
};
// Parse optional `self` parameter of a method.
// Only a limited set of initial token sequences is considered `self` parameters; anything
// else is parsed as a normal function parameter list, so some lookahead is required.
let eself_lo = self.token.span;
let (eself, eself_ident, eself_hi) = match self.token.kind {
token::BinOp(token::And) => {
let eself = if is_isolated_self(self, 1) {
// `&self`
self.bump();
SelfKind::Region(None, Mutability::Immutable)
} else if is_isolated_mut_self(self, 1) {
// `&mut self`
self.bump();
self.bump();
SelfKind::Region(None, Mutability::Mutable)
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
// `&'lt self`
self.bump();
let lt = self.expect_lifetime();
SelfKind::Region(Some(lt), Mutability::Immutable)
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
// `&'lt mut self`
self.bump();
let lt = self.expect_lifetime();
self.bump();
SelfKind::Region(Some(lt), Mutability::Mutable)
} else {
// `&not_self`
return Ok(None);
};
(eself, expect_self_ident(self), self.prev_span)
}
// `*self`
token::BinOp(token::Star) if is_isolated_self(self, 1) => {
self.bump();
recover_self_ptr(self)?
}
// `*mut self` and `*const self`
token::BinOp(token::Star) if
self.look_ahead(1, |t| t.is_mutability())
&& is_isolated_self(self, 2) =>
{
self.bump();
self.bump();
recover_self_ptr(self)?
}
// `self` and `self: TYPE`
token::Ident(..) if is_isolated_self(self, 0) => {
parse_self_possibly_typed(self, Mutability::Immutable)?
}
// `mut self` and `mut self: TYPE`
token::Ident(..) if is_isolated_mut_self(self, 0) => {
self.bump();
parse_self_possibly_typed(self, Mutability::Mutable)?
}
_ => return Ok(None),
};
let eself = source_map::respan(eself_lo.to(eself_hi), eself);
Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
}
fn is_named_param(&self) -> bool {
let offset = match self.token.kind {
token::Interpolated(ref nt) => match **nt {
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
_ => 0,
}
token::BinOp(token::And) | token::AndAnd => 1,
_ if self.token.is_keyword(kw::Mut) => 1,
_ => 0,
};
self.look_ahead(offset, |t| t.is_ident()) &&
self.look_ahead(offset + 1, |t| t == &token::Colon)
}
fn recover_first_param(&mut self) -> &'static str {
match self.parse_outer_attributes()
.and_then(|_| self.parse_self_param())
.map_err(|mut e| e.cancel())
{
Ok(Some(_)) => "method",
_ => "function",
}
}
}

View file

@ -1,4 +1,5 @@
use super::{Parser, PResult, PathStyle, PrevTokenKind, TokenType};
use super::item::ParamCfg;
use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath};
use crate::ptr::P;
@ -281,7 +282,7 @@ impl<'a> Parser<'a> {
let unsafety = self.parse_unsafety();
let abi = self.parse_extern_abi()?;
self.expect_keyword(kw::Fn)?;
let cfg = super::ParamCfg {
let cfg = ParamCfg {
is_self_allowed: false,
allow_c_variadic: true,
is_name_required: |_| false,

View file

@ -4,16 +4,13 @@ pub use DelimToken::*;
pub use LitKind::*;
pub use TokenKind::*;
use crate::ast::{self};
use crate::parse::{parse_stream_from_source_str, ParseSess};
use crate::print::pprust;
use crate::ast;
use crate::ptr::P;
use crate::symbol::kw;
use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
use crate::tokenstream::TokenTree;
use syntax_pos::symbol::Symbol;
use syntax_pos::{self, Span, FileName, DUMMY_SP};
use log::info;
use syntax_pos::{self, Span, DUMMY_SP};
use std::fmt;
use std::mem;
@ -737,131 +734,3 @@ impl fmt::Debug for Nonterminal {
}
}
}
impl Nonterminal {
pub fn to_tokenstream(&self, sess: &ParseSess, span: Span) -> TokenStream {
// A `Nonterminal` is often a parsed AST item. At this point we now
// need to convert the parsed AST to an actual token stream, e.g.
// un-parse it basically.
//
// Unfortunately there's not really a great way to do that in a
// guaranteed lossless fashion right now. The fallback here is to just
// stringify the AST node and reparse it, but this loses all span
// information.
//
// As a result, some AST nodes are annotated with the token stream they
// came from. Here we attempt to extract these lossless token streams
// before we fall back to the stringification.
let tokens = match *self {
Nonterminal::NtItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtTraitItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtImplItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtIdent(ident, is_raw) => {
Some(TokenTree::token(Ident(ident.name, is_raw), ident.span).into())
}
Nonterminal::NtLifetime(ident) => {
Some(TokenTree::token(Lifetime(ident.name), ident.span).into())
}
Nonterminal::NtTT(ref tt) => {
Some(tt.clone().into())
}
_ => None,
};
// FIXME(#43081): Avoid this pretty-print + reparse hack
let source = pprust::nonterminal_to_string(self);
let filename = FileName::macro_expansion_source_code(&source);
let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
// During early phases of the compiler the AST could get modified
// directly (e.g., attributes added or removed) and the internal cache
// of tokens my not be invalidated or updated. Consequently if the
// "lossless" token stream disagrees with our actual stringification
// (which has historically been much more battle-tested) then we go
// with the lossy stream anyway (losing span information).
//
// Note that the comparison isn't `==` here to avoid comparing spans,
// but it *also* is a "probable" equality which is a pretty weird
// definition. We mostly want to catch actual changes to the AST
// like a `#[cfg]` being processed or some weird `macro_rules!`
// expansion.
//
// What we *don't* want to catch is the fact that a user-defined
// literal like `0xf` is stringified as `15`, causing the cached token
// stream to not be literal `==` token-wise (ignoring spans) to the
// token stream we got from stringification.
//
// Instead the "probably equal" check here is "does each token
// recursively have the same discriminant?" We basically don't look at
// the token values here and assume that such fine grained token stream
// modifications, including adding/removing typically non-semantic
// tokens such as extra braces and commas, don't happen.
if let Some(tokens) = tokens {
if tokens.probably_equal_for_proc_macro(&tokens_for_real) {
return tokens
}
info!("cached tokens found, but they're not \"probably equal\", \
going with stringified version");
}
return tokens_for_real
}
}
fn prepend_attrs(sess: &ParseSess,
attrs: &[ast::Attribute],
tokens: Option<&tokenstream::TokenStream>,
span: syntax_pos::Span)
-> Option<tokenstream::TokenStream>
{
let tokens = tokens?;
if attrs.len() == 0 {
return Some(tokens.clone())
}
let mut builder = tokenstream::TokenStreamBuilder::new();
for attr in attrs {
assert_eq!(attr.style, ast::AttrStyle::Outer,
"inner attributes should prevent cached tokens from existing");
let source = pprust::attribute_to_string(attr);
let macro_filename = FileName::macro_expansion_source_code(&source);
if attr.is_sugared_doc {
let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
builder.push(stream);
continue
}
// synthesize # [ $path $tokens ] manually here
let mut brackets = tokenstream::TokenStreamBuilder::new();
// For simple paths, push the identifier directly
if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() {
let ident = attr.path.segments[0].ident;
let token = Ident(ident.name, ident.as_str().starts_with("r#"));
brackets.push(tokenstream::TokenTree::token(token, ident.span));
// ... and for more complicated paths, fall back to a reparse hack that
// should eventually be removed.
} else {
let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
brackets.push(stream);
}
brackets.push(attr.tokens.clone());
// The span we list here for `#` and for `[ ... ]` are both wrong in
// that it encompasses more than each token, but it hopefully is "good
// enough" for now at least.
builder.push(tokenstream::TokenTree::token(Pound, attr.span));
let delim_span = DelimSpan::from_single(attr.span);
builder.push(tokenstream::TokenTree::Delimited(
delim_span, DelimToken::Bracket, brackets.build().into()));
}
builder.push(tokens.clone());
Some(builder.build())
}

View file

@ -14,7 +14,6 @@
//! ownership of the original.
use crate::parse::token::{self, DelimToken, Token, TokenKind};
use crate::print::pprust;
use syntax_pos::{BytePos, Span, DUMMY_SP};
#[cfg(target_arch = "x86_64")]
@ -23,7 +22,7 @@ use rustc_data_structures::sync::Lrc;
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
use smallvec::{SmallVec, smallvec};
use std::{fmt, iter, mem};
use std::{iter, mem};
#[cfg(test)]
mod tests;
@ -507,12 +506,6 @@ impl Cursor {
}
}
impl fmt::Display for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&pprust::tts_to_string(self.clone()))
}
}
impl Encodable for TokenStream {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
self.trees().collect::<Vec<_>>().encode(encoder)

View file

@ -7,6 +7,7 @@ use syntax::ext::base::ExtCtxt;
use syntax::ext::expand::{AstFragment, ExpansionConfig};
use syntax::ext::proc_macro::is_proc_macro_attr;
use syntax::parse::ParseSess;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
@ -248,13 +249,20 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
for attr in &item.attrs {
if is_proc_macro_attr(&attr) {
if let Some(prev_attr) = found_attr {
let path_str = pprust::path_to_string(&attr.path);
let msg = if attr.path.segments[0].ident.name ==
prev_attr.path.segments[0].ident.name {
format!("only one `#[{}]` attribute is allowed on any given function",
attr.path)
format!(
"only one `#[{}]` attribute is allowed on any given function",
path_str,
)
} else {
format!("`#[{}]` and `#[{}]` attributes cannot both be applied \
to the same function", attr.path, prev_attr.path)
format!(
"`#[{}]` and `#[{}]` attributes cannot both be applied
to the same function",
path_str,
pprust::path_to_string(&prev_attr.path),
)
};
self.handler.struct_span_err(attr.span, &msg)
@ -280,8 +288,10 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
};
if !is_fn {
let msg = format!("the `#[{}]` attribute may only be used on bare functions",
attr.path);
let msg = format!(
"the `#[{}]` attribute may only be used on bare functions",
pprust::path_to_string(&attr.path),
);
self.handler.span_err(attr.span, &msg);
return;
@ -292,8 +302,10 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
}
if !self.is_proc_macro_crate {
let msg = format!("the `#[{}]` attribute is only usable with crates of the \
`proc-macro` crate type", attr.path);
let msg = format!(
"the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type",
pprust::path_to_string(&attr.path),
);
self.handler.span_err(attr.span, &msg);
return;

View file

@ -6,7 +6,7 @@ LL | const NAME: &'a str = "unit";
|
= note: expected type `&'static str`
found type `&'a str`
note: the lifetime 'a as defined on the impl at 6:6...
note: the lifetime `'a` as defined on the impl at 6:6...
--> $DIR/associated-const-impl-wrong-lifetime.rs:6:6
|
LL | impl<'a> Foo for &'a () {

View file

@ -0,0 +1,8 @@
trait Bar {
const X: usize;
fn return_n(&self) -> [u8; Bar::X]; //~ ERROR: type annotations needed
}
impl dyn Bar {} //~ ERROR: the trait `Bar` cannot be made into an object
fn main() {}

View file

@ -0,0 +1,21 @@
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-48027.rs:6:6
|
LL | const X: usize;
| - the trait cannot contain associated consts like `X`
...
LL | impl dyn Bar {}
| ^^^^^^^ the trait `Bar` cannot be made into an object
error[E0283]: type annotations needed: cannot resolve `_: Bar`
--> $DIR/issue-48027.rs:3:32
|
LL | const X: usize;
| --------------- required by `Bar::X`
LL | fn return_n(&self) -> [u8; Bar::X];
| ^^^^^^
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0283.
For more information about an error, try `rustc --explain E0038`.

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | bar(foo, x)
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 37:8...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 37:8...
--> $DIR/project-fn-ret-contravariant.rs:37:8
|
LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | bar(foo, x)
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 44:8...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8...
--> $DIR/project-fn-ret-invariant.rs:44:8
|
LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {

View file

@ -0,0 +1,19 @@
pub trait Array {
type Element;
}
pub trait Visit {
fn visit() {}
}
impl Array for () {
type Element = ();
}
impl<'a> Visit for () where
(): Array<Element=&'a ()>,
{}
fn main() {
<() as Visit>::visit(); //~ ERROR: type mismatch resolving
}

View file

@ -0,0 +1,16 @@
error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
--> $DIR/issue-44153.rs:18:5
|
LL | fn visit() {}
| ---------- required by `Visit::visit`
...
LL | <() as Visit>::visit();
| ^^^^^^^^^^^^^^^^^^^^ expected (), found &()
|
= note: expected type `()`
found type `&()`
= note: required because of the requirements on the impl of `Visit` for `()`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.

View file

@ -0,0 +1,23 @@
// check-pass
#![crate_type = "lib"]
pub struct Foo;
pub struct Path<T: Bar> {
_inner: T::Slice,
}
pub trait Bar: Sized {
type Slice: ?Sized;
fn open(_: &Path<Self>);
}
impl Bar for Foo {
type Slice = [u8];
fn open(_: &Path<Self>) {
unimplemented!()
}
}

View file

@ -15,12 +15,12 @@ LL | foo: &dyn Foo, bar: &'a dyn Foo
LL | foo
| --- this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime '_ as defined on the method body at 11:14
note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14
--> $DIR/issue-63388-2.rs:11:14
|
LL | foo: &dyn Foo, bar: &'a dyn Foo
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 11:14
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'_` as defined on the method body at 11:14
|
LL | foo + '_
|

View file

@ -24,12 +24,12 @@ LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d
|
= note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
note: the lifetime 'c as defined on the method body at 27:24...
note: the lifetime `'c` as defined on the method body at 27:24...
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
| ^^
note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 27:24
note: ...does not necessarily outlive the lifetime `'c` as defined on the method body at 27:24
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {

View file

@ -14,7 +14,7 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<
LL | | ap
LL | | }
| |_^
note: ...does not necessarily outlive the lifetime 'f as defined on the function body at 7:37
note: ...does not necessarily outlive the lifetime `'f` as defined on the function body at 7:37
--> $DIR/variadic-ffi-4.rs:7:37
|
LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {

View file

@ -11,7 +11,7 @@ note: the anonymous lifetime #2 defined on the body at 14:48...
|
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
| ^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 11:36
note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 11:36
--> $DIR/expect-fn-supply-fn.rs:11:36
|
LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
@ -25,7 +25,7 @@ LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
|
= note: expected type `fn(&u32)`
found type `fn(&'x u32)`
note: the lifetime 'x as defined on the function body at 11:36...
note: the lifetime `'x` as defined on the function body at 11:36...
--> $DIR/expect-fn-supply-fn.rs:11:36
|
LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {

View file

@ -38,7 +38,7 @@ LL | |
LL | |
LL | | });
| |_____^
note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 32:30
note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 32:30
--> $DIR/expect-region-supply-region.rs:32:30
|
LL | fn expect_bound_supply_named<'x>() {
@ -52,7 +52,7 @@ LL | closure_expecting_bound(|x: &'x u32| {
|
= note: expected type `&u32`
found type `&'x u32`
note: the lifetime 'x as defined on the function body at 32:30...
note: the lifetime `'x` as defined on the function body at 32:30...
--> $DIR/expect-region-supply-region.rs:32:30
|
LL | fn expect_bound_supply_named<'x>() {

View file

@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied
LL | child: Box<dyn Wedding<'kiss> + 'SnowWhite>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime 'SnowWhite as defined on the struct at 3:22
note: lifetime parameter instantiated with the lifetime `'SnowWhite` as defined on the struct at 3:22
--> $DIR/E0478.rs:3:22
|
LL | struct Prince<'kiss, 'SnowWhite> {
| ^^^^^^^^^^
note: but lifetime parameter must outlive the lifetime 'kiss as defined on the struct at 3:15
note: but lifetime parameter must outlive the lifetime `'kiss` as defined on the struct at 3:15
--> $DIR/E0478.rs:3:15
|
LL | struct Prince<'kiss, 'SnowWhite> {

View file

@ -6,12 +6,12 @@ LL | Foo<'b,'a>
|
= note: expected type `Foo<'a, 'b>`
found type `Foo<'b, 'a>`
note: the lifetime 'b as defined on the impl at 6:9...
note: the lifetime `'b` as defined on the impl at 6:9...
--> $DIR/explicit-self-lifetime-mismatch.rs:6:9
|
LL | impl<'a,'b> Foo<'a,'b> {
| ^^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 6:6
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 6:6
--> $DIR/explicit-self-lifetime-mismatch.rs:6:6
|
LL | impl<'a,'b> Foo<'a,'b> {
@ -25,12 +25,12 @@ LL | Foo<'b,'a>
|
= note: expected type `Foo<'a, 'b>`
found type `Foo<'b, 'a>`
note: the lifetime 'a as defined on the impl at 6:6...
note: the lifetime `'a` as defined on the impl at 6:6...
--> $DIR/explicit-self-lifetime-mismatch.rs:6:6
|
LL | impl<'a,'b> Foo<'a,'b> {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 6:9
note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 6:9
--> $DIR/explicit-self-lifetime-mismatch.rs:6:9
|
LL | impl<'a,'b> Foo<'a,'b> {

View file

@ -10,7 +10,7 @@ LL | | fn(Inv<'y>)) }
|
= note: expected type `std::option::Option<fn(Inv<'y>)>`
found type `std::option::Option<fn(Inv<'x>)>`
note: the lifetime 'x as defined on the function body at 32:20...
note: the lifetime `'x` as defined on the function body at 32:20...
--> $DIR/hr-subtype.rs:32:20
|
LL | fn subtype<'x,'y:'x,'z:'y>() {
@ -19,7 +19,7 @@ LL | fn subtype<'x,'y:'x,'z:'y>() {
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
LL | | fn(Inv<'y>)) }
| |__________________________________________________- in this macro invocation
note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 32:23
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 32:23
--> $DIR/hr-subtype.rs:32:23
|
LL | fn subtype<'x,'y:'x,'z:'y>() {
@ -41,7 +41,7 @@ LL | | fn(Inv<'y>)) }
|
= note: expected type `std::option::Option<fn(Inv<'x>)>`
found type `std::option::Option<fn(Inv<'y>)>`
note: the lifetime 'x as defined on the function body at 38:22...
note: the lifetime `'x` as defined on the function body at 38:22...
--> $DIR/hr-subtype.rs:38:22
|
LL | fn supertype<'x,'y:'x,'z:'y>() {
@ -50,7 +50,7 @@ LL | fn supertype<'x,'y:'x,'z:'y>() {
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
LL | | fn(Inv<'y>)) }
| |__________________________________________________- in this macro invocation
note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 38:25
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25
--> $DIR/hr-subtype.rs:38:25
|
LL | fn supertype<'x,'y:'x,'z:'y>() {

View file

@ -10,7 +10,7 @@ LL | | fn(&'y u32)) }
|
= note: expected type `std::option::Option<fn(&'x u32)>`
found type `std::option::Option<fn(&'y u32)>`
note: the lifetime 'x as defined on the function body at 38:22...
note: the lifetime `'x` as defined on the function body at 38:22...
--> $DIR/hr-subtype.rs:38:22
|
LL | fn supertype<'x,'y:'x,'z:'y>() {
@ -19,7 +19,7 @@ LL | fn supertype<'x,'y:'x,'z:'y>() {
LL | / check! { free_x_vs_free_y: (fn(&'x u32),
LL | | fn(&'y u32)) }
| |__________________________________________- in this macro invocation
note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 38:25
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25
--> $DIR/hr-subtype.rs:38:25
|
LL | fn supertype<'x,'y:'x,'z:'y>() {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | static_val(x);
| ^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 19:26...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 19:26...
--> $DIR/dyn-trait.rs:19:26
|
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {

View file

@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
| ^^^^^^^^^^^^^^
|
note: hidden type `&'a mut &'b T` captures the lifetime 'b as defined on the function body at 28:17
note: hidden type `&'a mut &'b T` captures the lifetime `'b` as defined on the function body at 28:17
--> $DIR/hidden-lifetimes.rs:28:17
|
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
@ -16,7 +16,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
| ^^^^^^^^^^^^^^
|
note: hidden type `std::rc::Rc<std::cell::RefCell<&'b T>>` captures the lifetime 'b as defined on the function body at 45:24
note: hidden type `std::rc::Rc<std::cell::RefCell<&'b T>>` captures the lifetime `'b` as defined on the function body at 45:24
--> $DIR/hidden-lifetimes.rs:45:24
|
LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {

View file

@ -24,12 +24,12 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| |
| this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime 'a as defined on the function body at 6:13
note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13
--> $DIR/must_outlive_least_region_or_bound.rs:6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| ^^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 6:13
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^^^^^^^^^^^
@ -42,12 +42,12 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| |
| this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime 'a as defined on the function body at 12:15
note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15
--> $DIR/must_outlive_least_region_or_bound.rs:12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ^^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 12:15
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
| ^^^^^^^^^^^^^^
|
note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 17:7
note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime `'x` as defined on the function body at 17:7
--> $DIR/region-escape-via-bound.rs:17:7
|
LL | where 'x: 'y

View file

@ -30,12 +30,12 @@ LL | self.x.iter().map(|a| a.0)
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime 'a as defined on the method body at 10:20
note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20
--> $DIR/static-return-lifetime-infered.rs:10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ^^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the method body at 10:20
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -11,7 +11,7 @@ LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
LL | | x
LL | | }
| |_____^
note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32...
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32...
--> $DIR/mismatched_trait_impl.rs:9:32
|
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {

View file

@ -11,7 +11,7 @@ LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
LL | | x
LL | | }
| |_____^
note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32...
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32...
--> $DIR/mismatched_trait_impl.rs:9:32
|
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {

View file

@ -12,7 +12,7 @@ LL | drop::<Box<dyn for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
LL | | x
LL | | }));
| |_____^
note: ...but the borrowed content is only valid for the lifetime 'x as defined on the function body at 1:9
note: ...but the borrowed content is only valid for the lifetime `'x` as defined on the function body at 1:9
--> $DIR/issue-10291.rs:1:9
|
LL | fn test<'x>(x: &'x isize) {

View file

@ -16,7 +16,7 @@ note: ...so that reference does not outlive borrowed content
|
LL | self.a();
| ^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the trait at 1:9...
note: but, the lifetime must be valid for the lifetime `'a` as defined on the trait at 1:9...
--> $DIR/issue-16683.rs:1:9
|
LL | trait T<'a> {

View file

@ -17,7 +17,7 @@ LL | |
LL | |
LL | | }
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 5:7
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 5:7
--> $DIR/issue-17740.rs:5:7
|
LL | impl <'a> Foo<'a>{
@ -31,7 +31,7 @@ LL | fn bar(self: &mut Foo) {
|
= note: expected type `Foo<'a>`
found type `Foo<'_>`
note: the lifetime 'a as defined on the impl at 5:7...
note: the lifetime `'a` as defined on the impl at 5:7...
--> $DIR/issue-17740.rs:5:7
|
LL | impl <'a> Foo<'a>{

View file

@ -17,7 +17,7 @@ note: ...so that reference does not outlive borrowed content
|
LL | self.foo();
| ^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the trait at 4:11...
note: but, the lifetime must be valid for the lifetime `'a` as defined on the trait at 4:11...
--> $DIR/issue-17758.rs:4:11
|
LL | trait Foo<'a> {

View file

@ -15,7 +15,7 @@ LL | |
LL | | println!("{:?}", self);
LL | | }
| |_____^
note: ...does not necessarily outlive the lifetime '_ as defined on the impl at 5:5
note: ...does not necessarily outlive the lifetime `'_` as defined on the impl at 5:5
--> $DIR/issue-17905-2.rs:5:5
|
LL | &str,
@ -29,7 +29,7 @@ LL | fn say(self: &Pair<&str, isize>) {
|
= note: expected type `Pair<&str, _>`
found type `Pair<&str, _>`
note: the lifetime '_ as defined on the impl at 5:5...
note: the lifetime `'_` as defined on the impl at 5:5...
--> $DIR/issue-17905-2.rs:5:5
|
LL | &str,

View file

@ -23,7 +23,7 @@ LL | |
LL | | self.sub = t;
LL | | }
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 26:6
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 26:6
--> $DIR/issue-20831-debruijn.rs:26:6
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
@ -43,7 +43,7 @@ LL | | }
|
= note: expected type `'a`
found type `'_`
note: the lifetime 'a as defined on the impl at 26:6...
note: the lifetime `'a` as defined on the impl at 26:6...
--> $DIR/issue-20831-debruijn.rs:26:6
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
@ -83,7 +83,7 @@ LL | |
LL | | self.sub = t;
LL | | }
| |_____^
note: ...but the lifetime must also be valid for the lifetime 'a as defined on the impl at 26:6...
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 26:6...
--> $DIR/issue-20831-debruijn.rs:26:6
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {

View file

@ -11,7 +11,7 @@ note: the anonymous lifetime #1 defined on the method body at 5:5...
|
LL | fn select(&self) -> BufferViewHandle<R>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 3:18
note: ...does not necessarily outlive the lifetime `'a` as defined on the trait at 3:18
--> $DIR/issue-27942.rs:3:18
|
LL | pub trait Buffer<'a, R: Resources<'a>> {
@ -25,7 +25,7 @@ LL | fn select(&self) -> BufferViewHandle<R>;
|
= note: expected type `Resources<'_>`
found type `Resources<'a>`
note: the lifetime 'a as defined on the trait at 3:18...
note: the lifetime `'a` as defined on the trait at 3:18...
--> $DIR/issue-27942.rs:3:18
|
LL | pub trait Buffer<'a, R: Resources<'a>> {

View file

@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied
LL | Foo::<'a, 'b>::xmute(u)
| ^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime 'b as defined on the function body at 9:16
note: lifetime parameter instantiated with the lifetime `'b` as defined on the function body at 9:16
--> $DIR/issue-28848.rs:9:16
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
| ^^
note: but lifetime parameter must outlive the lifetime 'a as defined on the function body at 9:12
note: but lifetime parameter must outlive the lifetime `'a` as defined on the function body at 9:12
--> $DIR/issue-28848.rs:9:12
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {

View file

@ -21,7 +21,7 @@ LL | | {
LL | | Some(&mut self.0)
LL | | }
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 3:6
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 3:6
--> $DIR/issue-37884.rs:3:6
|
LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {

View file

@ -0,0 +1,4 @@
fn main() {
() < std::mem::size_of::<_>(); //~ ERROR: mismatched types
[0u8; std::mem::size_of::<_>()]; //~ ERROR: type annotations needed
}

View file

@ -0,0 +1,19 @@
error[E0308]: mismatched types
--> $DIR/issue-47486.rs:2:10
|
LL | () < std::mem::size_of::<_>();
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found usize
|
= note: expected type `()`
found type `usize`
error[E0282]: type annotations needed
--> $DIR/issue-47486.rs:3:11
|
LL | [0u8; std::mem::size_of::<_>()];
| ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | match (&t,) {
| ^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 1:23...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 1:23...
--> $DIR/issue-52213.rs:1:23
|
LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
@ -12,7 +12,7 @@ LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
= note: ...so that the types are compatible:
expected (&&(T,),)
found (&&'a (T,),)
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 1:27...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 1:27...
--> $DIR/issue-52213.rs:1:27
|
LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | Box::new(self.out_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the trait at 5:17...
--> $DIR/issue-55796.rs:5:17
|
LL | pub trait Graph<'a> {
@ -25,7 +25,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | Box::new(self.in_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the trait at 5:17...
--> $DIR/issue-55796.rs:5:17
|
LL | pub trait Graph<'a> {

View file

@ -6,7 +6,7 @@ LL | ref_obj(x)
|
= note: expected type `&std::boxed::Box<(dyn std::ops::Fn() + 'static)>`
found type `&std::boxed::Box<(dyn std::ops::Fn() + 'a)>`
note: the lifetime 'a as defined on the function body at 32:10...
note: the lifetime `'a` as defined on the function body at 32:10...
--> $DIR/lifetime-bound-will-change-warning.rs:32:10
|
LL | fn test2<'a>(x: &'a Box<dyn Fn() + 'a>) {
@ -21,7 +21,7 @@ LL | lib::ref_obj(x)
|
= note: expected type `&std::boxed::Box<(dyn std::ops::Fn() + 'static)>`
found type `&std::boxed::Box<(dyn std::ops::Fn() + 'a)>`
note: the lifetime 'a as defined on the function body at 37:12...
note: the lifetime `'a` as defined on the function body at 37:12...
--> $DIR/lifetime-bound-will-change-warning.rs:37:12
|
LL | fn test2cc<'a>(x: &'a Box<dyn Fn() + 'a>) {

View file

@ -5,7 +5,7 @@ LL | s
| ^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 23:17
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 23:17
--> $DIR/lub-if.rs:23:17
|
LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
@ -18,7 +18,7 @@ LL | s
| ^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 32:17
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 32:17
--> $DIR/lub-if.rs:32:17
|
LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {

View file

@ -5,7 +5,7 @@ LL | s
| ^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 25:17
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 25:17
--> $DIR/lub-match.rs:25:17
|
LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
@ -18,7 +18,7 @@ LL | s
| ^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 35:17
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 35:17
--> $DIR/lub-match.rs:35:17
|
LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {

View file

@ -6,12 +6,12 @@ LL | match self.0 { ref mut x => x }
|
= note: expected type `&'a mut &'a i32`
found type `&'a mut &'b i32`
note: the lifetime 'a as defined on the method body at 9:12...
note: the lifetime `'a` as defined on the method body at 9:12...
--> $DIR/match-ref-mut-invariance.rs:9:12
|
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 8:6
note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 8:6
--> $DIR/match-ref-mut-invariance.rs:8:6
|
LL | impl<'b> S<'b> {

View file

@ -6,12 +6,12 @@ LL | x
|
= note: expected type `&'a mut &'a i32`
found type `&'a mut &'b i32`
note: the lifetime 'a as defined on the method body at 9:12...
note: the lifetime `'a` as defined on the method body at 9:12...
--> $DIR/match-ref-mut-let-invariance.rs:9:12
|
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 8:6
note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 8:6
--> $DIR/match-ref-mut-let-invariance.rs:8:6
|
LL | impl<'b> S<'b> {

View file

@ -6,7 +6,7 @@ LL | let _x = *s;
|
= note: expected type `std::marker::Sized`
found type `std::marker::Sized`
note: the lifetime 'a as defined on the function body at 9:8...
note: the lifetime `'a` as defined on the function body at 9:8...
--> $DIR/issue-50716.rs:9:8
|
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)

View file

@ -4,7 +4,7 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content...
LL | self.y = b.z
| ^^^
|
note: ...the reference is valid for the lifetime '_ as defined on the impl at 12:10...
note: ...the reference is valid for the lifetime `'_` as defined on the impl at 12:10...
--> $DIR/issue-52742.rs:12:10
|
LL | impl Foo<'_, '_> {

View file

@ -16,7 +16,7 @@ note: ...so that reference does not outlive borrowed content
|
LL | Foo { bar }
| ^^^
note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 7:10...
note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 7:10...
--> $DIR/issue-55394.rs:7:10
|
LL | impl Foo<'_> {

View file

@ -5,7 +5,7 @@ LL | *y
| ^^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 1:47
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 1:47
--> $DIR/issue-55401.rs:1:47
|
LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 {

View file

@ -4,12 +4,12 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` d
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 12:14...
note: first, the lifetime cannot outlive the lifetime `'d` as defined on the function body at 12:14...
--> $DIR/normalization-bounds-error.rs:12:14
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^
note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 12:18...
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the function body at 12:18...
--> $DIR/normalization-bounds-error.rs:12:18
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}

View file

@ -6,12 +6,12 @@ LL | const AC: Option<&'c str> = None;
|
= note: expected type `std::option::Option<&'b str>`
found type `std::option::Option<&'c str>`
note: the lifetime 'c as defined on the impl at 20:18...
note: the lifetime `'c` as defined on the impl at 20:18...
--> $DIR/trait-associated-constant.rs:20:18
|
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 20:14
note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 20:14
--> $DIR/trait-associated-constant.rs:20:14
|
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {

View file

@ -14,7 +14,7 @@ LL | | }
= note: ...so that the expression is assignable:
expected std::boxed::Box<std::boxed::Box<&isize>>
found std::boxed::Box<std::boxed::Box<&isize>>
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 15:6...
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 15:6...
--> $DIR/type-alias-free-regions.rs:15:6
|
LL | impl<'a> FromBox<'a> for C<'a> {
@ -39,7 +39,7 @@ LL | | }
= note: ...so that the expression is assignable:
expected std::boxed::Box<&isize>
found std::boxed::Box<&isize>
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 25:6...
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 25:6...
--> $DIR/type-alias-free-regions.rs:25:6
|
LL | impl<'a> FromTuple<'a> for C<'a> {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | <Foo<'a>>::C
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 7:8...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 7:8...
--> $DIR/constant-in-expr-inherent-1.rs:7:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {

View file

@ -5,7 +5,7 @@ LL | <() as Foo<'a>>::C
| ^^^^^^^^^^^^^^^^^^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 17:8
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 17:8
--> $DIR/constant-in-expr-normalize.rs:17:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {

View file

@ -5,7 +5,7 @@ LL | <() as Foo<'a>>::C
| ^^^^^^^^^^^^^^^^^^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 9:8
--> $DIR/constant-in-expr-trait-item-1.rs:9:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {

View file

@ -5,7 +5,7 @@ LL | <T as Foo<'a>>::C
| ^^^^^^^^^^^^^^^^^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8
note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 9:8
--> $DIR/constant-in-expr-trait-item-2.rs:9:8
|
LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | T::C
| ^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:8...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:8...
--> $DIR/constant-in-expr-trait-item-3.rs:9:8
|
LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for automatic coercion due to
LL | ss
| ^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 54:10...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 54:10...
--> $DIR/object-lifetime-default-elision.rs:54:10
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content
|
LL | ss
| ^^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 54:13...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 54:13...
--> $DIR/object-lifetime-default-elision.rs:54:13
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
@ -29,7 +29,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | ss
| ^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 54:10...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 54:10...
--> $DIR/object-lifetime-default-elision.rs:54:10
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
@ -39,7 +39,7 @@ note: ...so that the declared lifetime parameter bounds are satisfied
|
LL | ss
| ^^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 54:13...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 54:13...
--> $DIR/object-lifetime-default-elision.rs:54:13
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {

View file

@ -6,7 +6,7 @@ LL | ss.t = t;
|
= note: expected type `&'a std::boxed::Box<(dyn Test + 'static)>`
found type `&'a std::boxed::Box<(dyn Test + 'a)>`
note: the lifetime 'a as defined on the function body at 14:6...
note: the lifetime `'a` as defined on the function body at 14:6...
--> $DIR/object-lifetime-default-from-rptr-box-error.rs:14:6
|
LL | fn c<'a>(t: &'a Box<dyn Test+'a>, mut ss: SomeStruct<'a>) {

View file

@ -6,7 +6,7 @@ LL | ss.t = t;
|
= note: expected type `&'a MyBox<(dyn Test + 'static)>`
found type `&'a MyBox<(dyn Test + 'a)>`
note: the lifetime 'a as defined on the function body at 20:6...
note: the lifetime `'a` as defined on the function body at 20:6...
--> $DIR/object-lifetime-default-from-rptr-struct-error.rs:20:6
|
LL | fn c<'a>(t: &'a MyBox<dyn Test+'a>, mut ss: SomeStruct<'a>) {

View file

@ -18,7 +18,7 @@ LL | load0(ss)
|
= note: expected type `&MyBox<(dyn SomeTrait + 'static)>`
found type `&MyBox<(dyn SomeTrait + 'a)>`
note: the lifetime 'a as defined on the function body at 30:10...
note: the lifetime `'a` as defined on the function body at 30:10...
--> $DIR/object-lifetime-default-mybox.rs:30:10
|
LL | fn load2<'a>(ss: &MyBox<dyn SomeTrait + 'a>) -> MyBox<dyn SomeTrait + 'a> {

View file

@ -10,12 +10,12 @@ error[E0478]: lifetime bound not satisfied
LL | z: Box<dyn Is<'a>+'b+'c>,
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime 'b as defined on the struct at 11:15
note: lifetime parameter instantiated with the lifetime `'b` as defined on the struct at 11:15
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:15
|
LL | struct Foo<'a,'b,'c> {
| ^^
note: but lifetime parameter must outlive the lifetime 'a as defined on the struct at 11:12
note: but lifetime parameter must outlive the lifetime `'a` as defined on the struct at 11:12
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:12
|
LL | struct Foo<'a,'b,'c> {

View file

@ -3,7 +3,7 @@
// over time, but this test used to exhibit some pretty bogus messages
// that were not remotely helpful.
// error-pattern:the lifetime 'a
// error-pattern:the lifetime `'a`
// error-pattern:the static lifetime
struct Invariant<'a>(Option<&'a mut &'a mut ()>);

View file

@ -13,7 +13,7 @@ LL | | };
|
= note: expected type `Invariant<'a>`
found type `Invariant<'static>`
note: the lifetime 'a as defined on the function body at 13:10...
note: the lifetime `'a` as defined on the function body at 13:10...
--> $DIR/region-invariant-static-error-reporting.rs:13:10
|
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin
LL | x.borrowed()
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:42...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:42...
--> $DIR/region-object-lifetime-2.rs:9:42
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content
|
LL | x.borrowed()
| ^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 9:45...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 9:45...
--> $DIR/region-object-lifetime-2.rs:9:45
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin
LL | x.borrowed()
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 11:41...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 11:41...
--> $DIR/region-object-lifetime-4.rs:11:41
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content
|
LL | x.borrowed()
| ^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 11:44...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 11:44...
--> $DIR/region-object-lifetime-4.rs:11:44
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {

View file

@ -29,7 +29,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | Box::new(v)
| ^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 25:6...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 25:6...
--> $DIR/region-object-lifetime-in-coercion.rs:25:6
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
@ -37,7 +37,7 @@ LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
= note: ...so that the expression is assignable:
expected &[u8]
found &'a [u8]
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 25:9...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9...
--> $DIR/region-object-lifetime-in-coercion.rs:25:9
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to
LL | let p: &'static mut usize = &mut self.food;
| ^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18...
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 9:18...
--> $DIR/regions-addr-of-upvar-self.rs:9:18
|
LL | let _f = || {

View file

@ -4,12 +4,12 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifet
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime 'a as defined on the function body at 33:15
note: the pointer is valid for the lifetime `'a` as defined on the function body at 33:15
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 33:18
note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 33:18
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:18
|
LL | fn with_assoc<'a,'b>() {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | impl<'a> Foo<'static> for &'a i32 {
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 14:6...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 14:6...
--> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:14:6
|
LL | impl<'a> Foo<'static> for &'a i32 {
@ -25,7 +25,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | impl<'a,'b> Foo<'b> for &'a i64 {
| ^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 19:6...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 19:6...
--> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:6
|
LL | impl<'a,'b> Foo<'b> for &'a i64 {
@ -33,7 +33,7 @@ LL | impl<'a,'b> Foo<'b> for &'a i64 {
= note: ...so that the types are compatible:
expected Foo<'b>
found Foo<'_>
note: but, the lifetime must be valid for the lifetime 'b as defined on the impl at 19:9...
note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 19:9...
--> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:9
|
LL | impl<'a,'b> Foo<'b> for &'a i64 {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | impl<'a> Foo for &'a i32 {
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 9:6...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 9:6...
--> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:9:6
|
LL | impl<'a> Foo for &'a i32 {

View file

@ -6,12 +6,12 @@ LL | return e;
|
= note: expected type `TupleStruct<'b>`
found type `TupleStruct<'a>`
note: the lifetime 'a as defined on the function body at 8:10...
note: the lifetime `'a` as defined on the function body at 8:10...
--> $DIR/regions-bounds.rs:8:10
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 8:13
note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 8:13
--> $DIR/regions-bounds.rs:8:13
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
@ -25,12 +25,12 @@ LL | return e;
|
= note: expected type `Struct<'b>`
found type `Struct<'a>`
note: the lifetime 'a as defined on the function body at 12:10...
note: the lifetime `'a` as defined on the function body at 12:10...
--> $DIR/regions-bounds.rs:12:10
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 12:13
note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 12:13
--> $DIR/regions-bounds.rs:12:13
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to
LL | box B(&*v) as Box<dyn X>
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:6...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
--> $DIR/regions-close-object-into-object-2.rs:9:6
|
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {

View file

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to
LL | box B(&*v) as Box<dyn X>
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:6...
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
--> $DIR/regions-close-object-into-object-4.rs:9:6
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {

Some files were not shown because too many files have changed in this diff Show more