diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index c4fbd9dbadaea..aa50e7cdf578d 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -304,7 +304,7 @@ impl super::Hasher for Hasher { if self.ntail != 0 { needed = 8 - self.ntail; - self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail; + self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail); if length < needed { self.ntail += length; return; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9b94f92acd476..3086f9b04df67 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2046,6 +2046,15 @@ impl<'tcx> Operand<'tcx> { Operand::Move(place) => Operand::Copy(place), } } + + /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a + /// constant. + pub fn place(&self) -> Option<&Place<'tcx>> { + match self { + Operand::Copy(place) | Operand::Move(place) => Some(place), + Operand::Constant(_) => None, + } + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 02c51a2ebb0e9..3a6961660fd69 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -308,6 +308,9 @@ rustc_queries! { /// Returns `Some(mutability)` if the node pointed to by `def_id` is a static item. query static_mutability(_: DefId) -> Option {} + /// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator. + query generator_kind(_: DefId) -> Option {} + /// Gets a map with the variance of every item; use `item_variance` instead. query crate_variances(_: CrateNum) -> &'tcx ty::CrateVariancesMap<'tcx> { desc { "computing the variances for items in this crate" } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c027d6f61b01f..823cbf0966de9 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -5,7 +5,7 @@ use crate::dep_graph::DepGraph; use crate::dep_graph::{self, DepConstructor}; use crate::hir::exports::Export; use crate::hir::map as hir_map; -use crate::hir::map::DefPathHash; +use crate::hir::map::{DefPathData, DefPathHash}; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::{struct_lint_level, LintSource}; @@ -209,7 +209,7 @@ fn validate_hir_id_for_typeck_tables( ty::tls::with(|tcx| { bug!( "node {} with HirId::owner {:?} cannot be placed in \ - TypeckTables with local_id_root {:?}", + TypeckTables with local_id_root {:?}", tcx.hir().node_to_string(hir_id), DefId::local(hir_id.owner), local_id_root @@ -1512,6 +1512,24 @@ impl<'tcx> TyCtxt<'tcx> { .subst(*self, self.mk_substs([self.lifetimes.re_static.into()].iter())), ) } + + /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`). + pub fn article_and_description(&self, def_id: DefId) -> (&'static str, &'static str) { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::TypeNs(..) | DefPathData::ValueNs(..) | DefPathData::MacroNs(..) => { + let kind = self.def_kind(def_id).unwrap(); + (kind.article(), kind.descr(def_id)) + } + DefPathData::ClosureExpr => match self.generator_kind(def_id) { + None => ("a", "closure"), + Some(rustc_hir::GeneratorKind::Async(..)) => ("an", "async closure"), + Some(rustc_hir::GeneratorKind::Gen) => ("a", "generator"), + }, + DefPathData::LifetimeNs(..) => ("a", "lifetime"), + DefPathData::Impl => ("an", "implementation"), + _ => bug!("article_and_description called on def_id {:?}", def_id), + } + } } impl<'tcx> GlobalCtxt<'tcx> { diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 0ec30bc583cf8..66888cdb55210 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -53,7 +53,10 @@ pub enum InstanceDef<'tcx> { call_once: DefId, }, - /// `drop_in_place::; None` for empty drop glue. + /// `core::ptr::drop_in_place::`. + /// The `DefId` is for `core::ptr::drop_in_place`. + /// The `Option>` is either `Some(T)`, or `None` for empty drop + /// glue. DropGlue(DefId, Option>), ///`::clone` shim. @@ -176,11 +179,25 @@ impl<'tcx> InstanceDef<'tcx> { if self.requires_inline(tcx) { return true; } - if let ty::InstanceDef::DropGlue(..) = *self { - // Drop glue wants to be instantiated at every codegen + if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self { + // Drop glue generally wants to be instantiated at every codegen // unit, but without an #[inline] hint. We should make this // available to normal end-users. - return true; + if tcx.sess.opts.incremental.is_none() { + return true; + } + // When compiling with incremental, we can generate a *lot* of + // codegen units. Including drop glue into all of them has a + // considerable compile time cost. + // + // We include enums without destructors to allow, say, optimizing + // drops of `Option::None` before LTO. We also respect the intent of + // `#[inline]` on `Drop::drop` implementations. + return ty.ty_adt_def().map_or(true, |adt_def| { + adt_def.destructor(tcx).map_or(adt_def.is_enum(), |dtor| { + tcx.codegen_fn_attrs(dtor.did).requests_inline() + }) + }); } tcx.codegen_fn_attrs(self.def_id()).requests_inline() } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d17ef3a6c9a8c..dae9f945ce098 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -931,7 +931,17 @@ pub enum GenericParamDefKind { Const, } -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +impl GenericParamDefKind { + pub fn descr(&self) -> &'static str { + match self { + GenericParamDefKind::Lifetime => "lifetime", + GenericParamDefKind::Type { .. } => "type", + GenericParamDefKind::Const => "constant", + } + } +} + +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] pub struct GenericParamDef { pub name: Symbol, pub def_id: DefId, diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 0fb5f66feca9e..f96bf6c110cec 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -997,7 +997,7 @@ impl SpecializedEncoder for opaque::Encoder { fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> { let start_pos = self.position(); for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE { - ((x.0 >> i * 8) as u8).encode(self)?; + ((x.0 >> (i * 8)) as u8).encode(self)?; } let end_pos = self.position(); assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE); diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 59dd41e9d56c9..03ff1b8a3171f 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -17,17 +17,6 @@ use std::fmt; use std::rc::Rc; use std::sync::Arc; -impl fmt::Debug for ty::GenericParamDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_name = match self.kind { - ty::GenericParamDefKind::Lifetime => "Lifetime", - ty::GenericParamDefKind::Type { .. } => "Type", - ty::GenericParamDefKind::Const => "Const", - }; - write!(f, "{}({}, {:?}, {})", type_name, self.name, self.def_id, self.index) - } -} - impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::tls::with(|tcx| { diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 44fed6dee6628..0463ad7fb7b6f 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -8,7 +8,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{error_code, struct_span_err, Applicability, FatalError}; +use rustc_errors::{error_code, struct_span_err, Applicability}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_session::lint::LintBuffer; @@ -596,23 +596,15 @@ impl<'a> AstValidator<'a> { } } -enum GenericPosition { - Param, - Arg, -} - -fn validate_generics_order<'a>( +fn validate_generic_param_order<'a>( sess: &Session, handler: &rustc_errors::Handler, generics: impl Iterator, Span, Option)>, - pos: GenericPosition, span: Span, ) { let mut max_param: Option = None; let mut out_of_order = FxHashMap::default(); let mut param_idents = vec![]; - let mut found_type = false; - let mut found_const = false; for (kind, bounds, span, ident) in generics { if let Some(ident) = ident { @@ -626,11 +618,6 @@ fn validate_generics_order<'a>( } Some(_) | None => *max_param = Some(kind), }; - match kind { - ParamKindOrd::Type => found_type = true, - ParamKindOrd::Const => found_const = true, - _ => {} - } } let mut ordered_params = "<".to_string(); @@ -653,42 +640,26 @@ fn validate_generics_order<'a>( } ordered_params += ">"; - let pos_str = match pos { - GenericPosition::Param => "parameter", - GenericPosition::Arg => "argument", - }; - for (param_ord, (max_param, spans)) in &out_of_order { - let mut err = handler.struct_span_err( - spans.clone(), - &format!( - "{} {pos}s must be declared prior to {} {pos}s", - param_ord, - max_param, - pos = pos_str, - ), - ); - if let GenericPosition::Param = pos { - err.span_suggestion( - span, + let mut err = + handler.struct_span_err( + spans.clone(), &format!( - "reorder the {}s: lifetimes, then types{}", - pos_str, - if sess.features_untracked().const_generics { ", then consts" } else { "" }, + "{} parameters must be declared prior to {} parameters", + param_ord, max_param, ), - ordered_params.clone(), - Applicability::MachineApplicable, ); - } + err.span_suggestion( + span, + &format!( + "reorder the parameters: lifetimes, then types{}", + if sess.features_untracked().const_generics { ", then consts" } else { "" }, + ), + ordered_params.clone(), + Applicability::MachineApplicable, + ); err.emit(); } - - // FIXME(const_generics): we shouldn't have to abort here at all, but we currently get ICEs - // if we don't. Const parameters and type parameters can currently conflict if they - // are out-of-order. - if !out_of_order.is_empty() && found_type && found_const { - FatalError.raise(); - } } impl<'a> Visitor<'a> for AstValidator<'a> { @@ -1016,24 +987,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { match *generic_args { GenericArgs::AngleBracketed(ref data) => { walk_list!(self, visit_generic_arg, &data.args); - validate_generics_order( - self.session, - self.err_handler(), - data.args.iter().map(|arg| { - ( - match arg { - GenericArg::Lifetime(..) => ParamKindOrd::Lifetime, - GenericArg::Type(..) => ParamKindOrd::Type, - GenericArg::Const(..) => ParamKindOrd::Const, - }, - None, - arg.span(), - None, - ) - }), - GenericPosition::Arg, - generic_args.span(), - ); // Type bindings such as `Item = impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. @@ -1070,7 +1023,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } - validate_generics_order( + validate_generic_param_order( self.session, self.err_handler(), generics.params.iter().map(|param| { @@ -1085,7 +1038,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }; (kind, Some(&*param.bounds), param.ident.span, ident) }), - GenericPosition::Param, generics.span, ); diff --git a/src/librustc_data_structures/sip128.rs b/src/librustc_data_structures/sip128.rs index af0e9f79fe120..beb28dd072058 100644 --- a/src/librustc_data_structures/sip128.rs +++ b/src/librustc_data_structures/sip128.rs @@ -274,7 +274,7 @@ impl Hasher for SipHasher128 { if self.ntail != 0 { needed = 8 - self.ntail; - self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail; + self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail); if length < needed { self.ntail += length; return; diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index fa98b4d72dda2..9051b1751b119 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -203,11 +203,7 @@ cfg_if! { t.into_iter() } - pub fn par_for_each_in( - t: T, - for_each: - impl Fn(<::IntoIter as Iterator>::Item) + Sync + Send - ) { + pub fn par_for_each_in(t: T, for_each: impl Fn(T::Item) + Sync + Send) { // We catch panics here ensuring that all the loop iterations execute. // This makes behavior consistent with the parallel compiler. let mut panic = None; @@ -397,9 +393,7 @@ cfg_if! { pub fn par_for_each_in( t: T, - for_each: impl Fn( - <::Iter as ParallelIterator>::Item - ) + Sync + Send + for_each: impl Fn(T::Item) + Sync + Send, ) { t.into_par_iter().for_each(for_each) } diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index ba43b29538d50..91a7b6c895838 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -417,6 +417,7 @@ E0743: include_str!("./error_codes/E0743.md"), E0744: include_str!("./error_codes/E0744.md"), E0745: include_str!("./error_codes/E0745.md"), E0746: include_str!("./error_codes/E0746.md"), +E0747: include_str!("./error_codes/E0747.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0373.md b/src/librustc_error_codes/error_codes/E0373.md index 808363e6eb041..fd96987793115 100644 --- a/src/librustc_error_codes/error_codes/E0373.md +++ b/src/librustc_error_codes/error_codes/E0373.md @@ -1,6 +1,6 @@ -This error occurs when an attempt is made to use data captured by a closure, -when that data may no longer exist. It's most commonly seen when attempting to -return a closure: +A captured variable in a closure may not live long enough. + +Erroneous code example: ```compile_fail,E0373 fn foo() -> Box u32> { @@ -9,6 +9,10 @@ fn foo() -> Box u32> { } ``` +This error occurs when an attempt is made to use data captured by a closure, +when that data may no longer exist. It's most commonly seen when attempting to +return a closure as shown in the previous code example. + Notice that `x` is stack-allocated by `foo()`. By default, Rust captures closed-over data by reference. This means that once `foo()` returns, `x` no longer exists. An attempt to access `x` within the closure would thus be diff --git a/src/librustc_error_codes/error_codes/E0747.md b/src/librustc_error_codes/error_codes/E0747.md new file mode 100644 index 0000000000000..df1afbfef46df --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0747.md @@ -0,0 +1,20 @@ +Generic arguments must be provided in the same order as the corresponding +generic parameters are declared. + +Erroneous code example: + +```compile_fail,E0747 +struct S<'a, T>(&'a T); + +type X = S<(), 'static>; // error: the type argument is provided before the + // lifetime argument +``` + +The argument order should be changed to match the parameter declaration +order, as in the following. + +``` +struct S<'a, T>(&'a T); + +type X = S<'static, ()>; // ok +``` diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 6d2f5ba6baf14..2e99998c627bf 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -298,6 +298,14 @@ impl GenericArg<'_> { _ => false, } } + + pub fn descr(&self) -> &'static str { + match self { + GenericArg::Lifetime(_) => "lifetime", + GenericArg::Type(_) => "type", + GenericArg::Const(_) => "constant", + } + } } #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 3dacd2cbe95c8..ee68697d260b3 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -492,7 +492,7 @@ impl MetadataBlob { } } -impl<'tcx> EntryKind<'tcx> { +impl EntryKind { fn def_kind(&self) -> Option { Some(match *self { EntryKind::Const(..) => DefKind::Const, @@ -606,11 +606,11 @@ impl<'a, 'tcx> CrateMetadata { self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some() } - fn maybe_kind(&self, item_id: DefIndex) -> Option> { + fn maybe_kind(&self, item_id: DefIndex) -> Option { self.root.per_def.kind.get(self, item_id).map(|k| k.decode(self)) } - fn kind(&self, item_id: DefIndex) -> EntryKind<'tcx> { + fn kind(&self, item_id: DefIndex) -> EntryKind { assert!(!self.is_proc_macro(item_id)); self.maybe_kind(item_id).unwrap_or_else(|| { bug!( @@ -715,7 +715,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_variant( &self, tcx: TyCtxt<'tcx>, - kind: &EntryKind<'_>, + kind: &EntryKind, index: DefIndex, parent_did: DefId, ) -> ty::VariantDef { @@ -1382,6 +1382,13 @@ impl<'a, 'tcx> CrateMetadata { } } + fn generator_kind(&self, id: DefIndex) -> Option { + match self.kind(id) { + EntryKind::Generator(data) => Some(data), + _ => None, + } + } + fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx)) } @@ -1491,8 +1498,8 @@ impl<'a, 'tcx> CrateMetadata { ); debug!( "CrateMetaData::imported_source_files alloc \ - source_file {:?} original (start_pos {:?} end_pos {:?}) \ - translated (start_pos {:?} end_pos {:?})", + source_file {:?} original (start_pos {:?} end_pos {:?}) \ + translated (start_pos {:?} end_pos {:?})", local_version.name, start_pos, end_pos, diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index fb7e5541e266e..e6270e903295c 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -134,6 +134,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, asyncness => { cdata.asyncness(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } static_mutability => { cdata.static_mutability(def_id.index) } + generator_kind => { cdata.generator_kind(def_id.index) } def_kind => { cdata.def_kind(def_id.index) } def_span => { cdata.get_span(def_id.index, &tcx.sess) } lookup_stability => { diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 41fc5ed843fd3..ee54f40ece5c8 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -306,7 +306,7 @@ impl<'tcx> EncodeContext<'tcx> { assert!( last_min_end <= lazy.position, "make sure that the calls to `lazy*` \ - are in the same order as the metadata fields", + are in the same order as the metadata fields", ); lazy.position.get() - last_min_end.get() } @@ -1248,12 +1248,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); } - fn encode_info_for_generic_param( - &mut self, - def_id: DefId, - kind: EntryKind<'tcx>, - encode_type: bool, - ) { + fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) { record!(self.per_def.kind[def_id] <- kind); record!(self.per_def.visibility[def_id] <- ty::Visibility::Public); record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); @@ -1271,12 +1266,9 @@ impl EncodeContext<'tcx> { let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id); record!(self.per_def.kind[def_id] <- match ty.kind { - ty::Generator(def_id, ..) => { - let layout = self.tcx.generator_layout(def_id); - let data = GeneratorData { - layout: layout.clone(), - }; - EntryKind::Generator(self.lazy(data)) + ty::Generator(..) => { + let data = self.tcx.generator_kind(def_id).unwrap(); + EntryKind::Generator(data) } ty::Closure(..) => EntryKind::Closure, diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 77ec3eb4555e3..01a3f6c560f1b 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -252,7 +252,7 @@ macro_rules! define_per_def_tables { } define_per_def_tables! { - kind: Table)>, + kind: Table>, visibility: Table>, span: Table>, attributes: Table>, @@ -279,7 +279,7 @@ define_per_def_tables! { } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -enum EntryKind<'tcx> { +enum EntryKind { Const(mir::ConstQualifs, Lazy), ImmStatic, MutStatic, @@ -302,7 +302,7 @@ enum EntryKind<'tcx> { Mod(Lazy), MacroDef(Lazy), Closure, - Generator(Lazy!(GeneratorData<'tcx>)), + Generator(hir::GeneratorKind), Trait(Lazy), Impl(Lazy), Method(Lazy), diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 0ed7dd03f3ab7..ca51d16f9f269 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1257,7 +1257,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } _ => bug!( "report_escaping_closure_capture called with unexpected constraint \ - category: `{:?}`", + category: `{:?}`", category ), }; @@ -1275,17 +1275,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> DiagnosticBuilder<'cx> { let tcx = self.infcx.tcx; - let escapes_from = if tcx.is_closure(self.mir_def_id) { - let tables = tcx.typeck_tables_of(self.mir_def_id); - let mir_hir_id = tcx.hir().def_index_to_hir_id(self.mir_def_id.index); - match tables.node_type(mir_hir_id).kind { - ty::Closure(..) => "closure", - ty::Generator(..) => "generator", - _ => bug!("Closure body doesn't have a closure or generator type"), - } - } else { - "function" - }; + let (_, escapes_from) = tcx.article_and_description(self.mir_def_id); let mut err = borrowck_errors::borrowed_data_escapes_closure(tcx, escape_span, escapes_from); @@ -1350,7 +1340,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // there. let mut mpis = vec![mpi]; let move_paths = &self.move_data.move_paths; - mpis.extend(move_paths[mpi].parents(move_paths)); + mpis.extend(move_paths[mpi].parents(move_paths).map(|(mpi, _)| mpi)); for moi in &self.move_data.loc_map[location] { debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi); diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index a3e0e51c5b64d..8d991927d5437 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -427,18 +427,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let escapes_from = match self.regioncx.universal_regions().defining_ty { - DefiningTy::Closure(..) => "closure", - DefiningTy::Generator(..) => "generator", - DefiningTy::FnDef(..) => "function", - DefiningTy::Const(..) => "const", - }; + let (_, escapes_from) = self + .infcx + .tcx + .article_and_description(self.regioncx.universal_regions().defining_ty.def_id()); // Revert to the normal error in these cases. // Assignments aren't "escapes" in function items. if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none()) - || (*category == ConstraintCategory::Assignment && escapes_from == "function") - || escapes_from == "const" + || (*category == ConstraintCategory::Assignment + && self.regioncx.universal_regions().defining_ty.is_fn_def()) + || self.regioncx.universal_regions().defining_ty.is_const() { return self.report_general_error(&ErrorConstraintInfo { fr_is_local: true, @@ -504,8 +503,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mut diag = self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); - let mir_def_name = - if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" }; + let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id); let fr_name = self.give_region_a_name(*fr).unwrap(); fr_name.highlight_region_name(&mut diag); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index a3edfb662c50e..c4d6023e06b3b 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1599,9 +1599,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) { if let Some(mpi) = self.move_path_for_place(place_span.0) { let move_paths = &self.move_data.move_paths; - let mut child = move_paths[mpi].first_child; - while let Some(child_mpi) = child { - let child_move_path = &move_paths[child_mpi]; + + let root_path = &move_paths[mpi]; + for (child_mpi, child_move_path) in root_path.children(move_paths) { let last_proj = child_move_path.place.projection.last().unwrap(); if let ProjectionElem::ConstantIndex { offset, from_end, .. } = last_proj { debug_assert!(!from_end, "Array constant indexing shouldn't be `from_end`."); @@ -1623,7 +1623,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } } - child = child_move_path.next_sibling; } } } diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index ba0f2e8a7ad76..2201abe4b92f9 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -92,7 +92,7 @@ fn populate_polonius_move_facts( for (child, move_path) in move_data.move_paths.iter_enumerated() { all_facts .child - .extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (child, parent))); + .extend(move_path.parents(&move_data.move_paths).map(|(parent, _)| (child, parent))); } // initialized_at diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs index 0913de63e8ef1..af4ea759f4f8b 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/src/librustc_mir/borrow_check/universal_regions.rs @@ -131,6 +131,29 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::FnDef(..) | DefiningTy::Const(..) => 0, } } + + pub fn is_fn_def(&self) -> bool { + match *self { + DefiningTy::FnDef(..) => true, + _ => false, + } + } + + pub fn is_const(&self) -> bool { + match *self { + DefiningTy::Const(..) => true, + _ => false, + } + } + + pub fn def_id(&self) -> DefId { + match *self { + DefiningTy::Closure(def_id, ..) + | DefiningTy::Generator(def_id, ..) + | DefiningTy::FnDef(def_id, ..) + | DefiningTy::Const(def_id, ..) => def_id, + } + } } #[derive(Debug)] diff --git a/src/librustc_mir/dataflow/generic/engine.rs b/src/librustc_mir/dataflow/generic/engine.rs index 0eb567da10356..371bfa9a6fdb4 100644 --- a/src/librustc_mir/dataflow/generic/engine.rs +++ b/src/librustc_mir/dataflow/generic/engine.rs @@ -5,7 +5,7 @@ use std::fs; use std::path::PathBuf; use rustc::mir::{self, traversal, BasicBlock, Location}; -use rustc::ty::TyCtxt; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::work_queue::WorkQueue; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet; @@ -238,10 +238,15 @@ where } } - SwitchInt { ref targets, .. } => { - for target in targets { - self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list); - } + SwitchInt { ref targets, ref values, ref discr, .. } => { + self.propagate_bits_into_switch_int_successors( + in_out, + (bb, bb_data), + dirty_list, + discr, + &*values, + &*targets, + ); } Call { cleanup, ref destination, ref func, ref args, .. } => { @@ -287,6 +292,66 @@ where dirty_queue.insert(bb); } } + + fn propagate_bits_into_switch_int_successors( + &mut self, + in_out: &mut BitSet, + (bb, bb_data): (BasicBlock, &mir::BasicBlockData<'tcx>), + dirty_list: &mut WorkQueue, + switch_on: &mir::Operand<'tcx>, + values: &[u128], + targets: &[BasicBlock], + ) { + match bb_data.statements.last().map(|stmt| &stmt.kind) { + // Look at the last statement to see if it is an assignment of an enum discriminant to + // the local that determines the target of a `SwitchInt` like so: + // _42 = discriminant(..) + // SwitchInt(_42, ..) + Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(enum_)))) + if Some(lhs) == switch_on.place() => + { + let adt = match enum_.ty(self.body, self.tcx).ty.kind { + ty::Adt(def, _) => def, + _ => bug!("Switch on discriminant of non-ADT"), + }; + + // MIR building adds discriminants to the `values` array in the same order as they + // are yielded by `AdtDef::discriminants`. We rely on this to match each + // discriminant in `values` to its corresponding variant in linear time. + let mut tmp = BitSet::new_empty(in_out.domain_size()); + let mut discriminants = adt.discriminants(self.tcx); + for (value, target) in values.iter().zip(targets.iter().copied()) { + let (variant_idx, _) = + discriminants.find(|&(_, discr)| discr.val == *value).expect( + "Order of `AdtDef::discriminants` differed \ + from that of `SwitchInt::values`", + ); + + tmp.overwrite(in_out); + self.analysis.apply_discriminant_switch_effect( + &mut tmp, + bb, + enum_, + adt, + variant_idx, + ); + self.propagate_bits_into_entry_set_for(&tmp, target, dirty_list); + } + + std::mem::drop(tmp); + + // Propagate dataflow state along the "otherwise" edge. + let otherwise = targets.last().copied().unwrap(); + self.propagate_bits_into_entry_set_for(&in_out, otherwise, dirty_list); + } + + _ => { + for target in targets.iter().copied() { + self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list); + } + } + } + } } // Graphviz diff --git a/src/librustc_mir/dataflow/generic/mod.rs b/src/librustc_mir/dataflow/generic/mod.rs index 23b22550a3b0e..c61b7bed3538b 100644 --- a/src/librustc_mir/dataflow/generic/mod.rs +++ b/src/librustc_mir/dataflow/generic/mod.rs @@ -35,7 +35,8 @@ use std::io; use rustc::mir::{self, BasicBlock, Location}; -use rustc::ty::TyCtxt; +use rustc::ty::layout::VariantIdx; +use rustc::ty::{self, TyCtxt}; use rustc_hir::def_id::DefId; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_index::vec::{Idx, IndexVec}; @@ -172,7 +173,22 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { return_place: &mir::Place<'tcx>, ); - /// Calls the appropriate `Engine` constructor to find the fixpoint for this dataflow problem. + /// Updates the current dataflow state with the effect of taking a particular branch in a + /// `SwitchInt` terminator. + /// + /// Much like `apply_call_return_effect`, this effect is only propagated along a single + /// outgoing edge from this basic block. + fn apply_discriminant_switch_effect( + &self, + _state: &mut BitSet, + _block: BasicBlock, + _enum_place: &mir::Place<'tcx>, + _adt: &ty::AdtDef, + _variant: VariantIdx, + ) { + } + + /// Creates an `Engine` to find the fixpoint for this dataflow problem. /// /// You shouldn't need to override this outside this module, since the combination of the /// default impl and the one for all `A: GenKillAnalysis` will do the right thing. @@ -249,6 +265,17 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { args: &[mir::Operand<'tcx>], return_place: &mir::Place<'tcx>, ); + + /// See `Analysis::apply_discriminant_switch_effect`. + fn discriminant_switch_effect( + &self, + _state: &mut impl GenKill, + _block: BasicBlock, + _enum_place: &mir::Place<'tcx>, + _adt: &ty::AdtDef, + _variant: VariantIdx, + ) { + } } impl Analysis<'tcx> for A @@ -302,6 +329,17 @@ where self.call_return_effect(state, block, func, args, return_place); } + fn apply_discriminant_switch_effect( + &self, + state: &mut BitSet, + block: BasicBlock, + enum_place: &mir::Place<'tcx>, + adt: &ty::AdtDef, + variant: VariantIdx, + ) { + self.discriminant_switch_effect(state, block, enum_place, adt, variant); + } + fn into_engine( self, tcx: TyCtxt<'tcx>, diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index acea31857818b..59aa91ab82499 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -3,7 +3,8 @@ //! zero-sized structure. use rustc::mir::{self, Body, Location}; -use rustc::ty::TyCtxt; +use rustc::ty::layout::VariantIdx; +use rustc::ty::{self, TyCtxt}; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; @@ -12,12 +13,13 @@ use super::MoveDataParamEnv; use crate::util::elaborate_drops::DropFlagState; use super::generic::{AnalysisDomain, GenKill, GenKillAnalysis}; -use super::move_paths::{HasMoveData, InitIndex, InitKind, MoveData, MovePathIndex}; +use super::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex}; use super::{BottomValue, GenKillSet}; use super::drop_flag_effects_for_function_entry; use super::drop_flag_effects_for_location; use super::on_lookup_result_bits; +use crate::dataflow::drop_flag_effects; mod borrowed_locals; mod storage_liveness; @@ -336,6 +338,37 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { }, ); } + + fn discriminant_switch_effect( + &self, + trans: &mut impl GenKill, + _block: mir::BasicBlock, + enum_place: &mir::Place<'tcx>, + _adt: &ty::AdtDef, + variant: VariantIdx, + ) { + let enum_mpi = match self.move_data().rev_lookup.find(enum_place.as_ref()) { + LookupResult::Exact(mpi) => mpi, + LookupResult::Parent(_) => return, + }; + + // Kill all move paths that correspond to variants other than this one + let move_paths = &self.move_data().move_paths; + let enum_path = &move_paths[enum_mpi]; + for (mpi, variant_path) in enum_path.children(move_paths) { + trans.kill(mpi); + match variant_path.place.projection.last().unwrap() { + mir::ProjectionElem::Downcast(_, idx) if *idx == variant => continue, + _ => drop_flag_effects::on_all_children_bits( + self.tcx, + self.body, + self.move_data(), + mpi, + |mpi| trans.kill(mpi), + ), + } + } + } } impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 614a276164334..6f6ba7dc27128 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -58,19 +58,32 @@ pub struct MovePath<'tcx> { } impl<'tcx> MovePath<'tcx> { - pub fn parents( + /// Returns an iterator over the parents of `self`. + pub fn parents<'a>( &self, - move_paths: &IndexVec>, - ) -> Vec { - let mut parents = Vec::new(); - - let mut curr_parent = self.parent; - while let Some(parent_mpi) = curr_parent { - parents.push(parent_mpi); - curr_parent = move_paths[parent_mpi].parent; + move_paths: &'a IndexVec>, + ) -> impl 'a + Iterator)> { + let first = self.parent.map(|mpi| (mpi, &move_paths[mpi])); + MovePathLinearIter { + next: first, + fetch_next: move |_, parent: &MovePath<'_>| { + parent.parent.map(|mpi| (mpi, &move_paths[mpi])) + }, } + } - parents + /// Returns an iterator over the immediate children of `self`. + pub fn children<'a>( + &self, + move_paths: &'a IndexVec>, + ) -> impl 'a + Iterator)> { + let first = self.first_child.map(|mpi| (mpi, &move_paths[mpi])); + MovePathLinearIter { + next: first, + fetch_next: move |_, child: &MovePath<'_>| { + child.next_sibling.map(|mpi| (mpi, &move_paths[mpi])) + }, + } } /// Finds the closest descendant of `self` for which `f` returns `true` using a breadth-first @@ -131,6 +144,25 @@ impl<'tcx> fmt::Display for MovePath<'tcx> { } } +#[allow(unused)] +struct MovePathLinearIter<'a, 'tcx, F> { + next: Option<(MovePathIndex, &'a MovePath<'tcx>)>, + fetch_next: F, +} + +impl<'a, 'tcx, F> Iterator for MovePathLinearIter<'a, 'tcx, F> +where + F: FnMut(MovePathIndex, &'a MovePath<'tcx>) -> Option<(MovePathIndex, &'a MovePath<'tcx>)>, +{ + type Item = (MovePathIndex, &'a MovePath<'tcx>); + + fn next(&mut self) -> Option { + let ret = self.next.take()?; + self.next = (self.fetch_next)(ret.0, ret.1); + Some(ret) + } +} + #[derive(Debug)] pub struct MoveData<'tcx> { pub move_paths: IndexVec>, diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index de45808a4816c..9b81d69ce694c 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -680,13 +680,20 @@ fn characteristic_def_id_of_mono_item<'tcx>( if tcx.trait_of_item(def_id).is_some() { let self_ty = instance.substs.type_at(0); - // This is an implementation of a trait method. + // This is a default implementation of a trait method. return characteristic_def_id_of_type(self_ty).or(Some(def_id)); } if let Some(impl_def_id) = tcx.impl_of_method(def_id) { - // This is a method within an inherent impl, find out what the - // self-type is: + if tcx.sess.opts.incremental.is_some() + && tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait() + { + // Put `Drop::drop` into the same cgu as `drop_in_place` + // since `drop_in_place` is the only thing that can + // call it. + return None; + } + // This is a method within an impl, find out what the self-type is: let impl_self_ty = tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 7c48ccfaddd3a..bf9eeb0b6c5ff 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -6,9 +6,8 @@ use rustc::session::Session; use rustc::ty::{self, DefIdTree}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; -use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -20,7 +19,6 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::lifetimes::{ElisionFailureInfo, LifetimeContext}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -49,40 +47,6 @@ crate struct ImportSuggestion { pub path: Path, } -crate enum MissingLifetimeSpot<'tcx> { - Generics(&'tcx hir::Generics<'tcx>), - HigherRanked { span: Span, span_type: ForLifetimeSpanType }, -} - -crate enum ForLifetimeSpanType { - BoundEmpty, - BoundTail, - TypeEmpty, - TypeTail, -} - -impl ForLifetimeSpanType { - crate fn descr(&self) -> &'static str { - match self { - Self::BoundEmpty | Self::BoundTail => "bound", - Self::TypeEmpty | Self::TypeTail => "type", - } - } - - crate fn suggestion(&self, sugg: &str) -> String { - match self { - Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg), - Self::BoundTail | Self::TypeTail => format!(", {}", sugg), - } - } -} - -impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { - fn into(self) -> MissingLifetimeSpot<'tcx> { - MissingLifetimeSpot::Generics(self) - } -} - /// Adjust the impl span so that just the `impl` keyword is taken by removing /// everything after `<` (`"impl Iterator for A {}" -> "impl"`) and /// everything after the first whitespace (`"impl Iterator for A" -> "impl"`). @@ -1491,208 +1455,3 @@ crate fn show_candidates( err.note(&msg); } } - -impl<'tcx> LifetimeContext<'_, 'tcx> { - crate fn report_missing_lifetime_specifiers( - &self, - span: Span, - count: usize, - ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( - self.tcx.sess, - span, - E0106, - "missing lifetime specifier{}", - pluralize!(count) - ) - } - - crate fn emit_undeclared_lifetime_error(&self, lifetime_ref: &hir::Lifetime) { - let mut err = struct_span_err!( - self.tcx.sess, - lifetime_ref.span, - E0261, - "use of undeclared lifetime name `{}`", - lifetime_ref - ); - err.span_label(lifetime_ref.span, "undeclared lifetime"); - for missing in &self.missing_named_lifetime_spots { - match missing { - MissingLifetimeSpot::Generics(generics) => { - let (span, sugg) = if let Some(param) = generics - .params - .iter() - .filter(|p| match p.kind { - hir::GenericParamKind::Type { - synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), - .. - } => false, - _ => true, - }) - .next() - { - (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) - } else { - (generics.span, format!("<{}>", lifetime_ref)) - }; - err.span_suggestion( - span, - &format!("consider introducing lifetime `{}` here", lifetime_ref), - sugg, - Applicability::MaybeIncorrect, - ); - } - MissingLifetimeSpot::HigherRanked { span, span_type } => { - err.span_suggestion( - *span, - &format!( - "consider making the {} lifetime-generic with a new `{}` lifetime", - span_type.descr(), - lifetime_ref - ), - span_type.suggestion(&lifetime_ref.to_string()), - Applicability::MaybeIncorrect, - ); - err.note( - "for more information on higher-ranked polymorphism, visit \ - https://doc.rust-lang.org/nomicon/hrtb.html", - ); - } - } - } - err.emit(); - } - - crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { - if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { - if [ - self.tcx.lang_items().fn_once_trait(), - self.tcx.lang_items().fn_trait(), - self.tcx.lang_items().fn_mut_trait(), - ] - .contains(&Some(did)) - { - let (span, span_type) = match &trait_ref.bound_generic_params { - [] => (trait_ref.span.shrink_to_lo(), ForLifetimeSpanType::BoundEmpty), - [.., bound] => (bound.span.shrink_to_hi(), ForLifetimeSpanType::BoundTail), - }; - self.missing_named_lifetime_spots - .push(MissingLifetimeSpot::HigherRanked { span, span_type }); - return true; - } - }; - false - } - - crate fn add_missing_lifetime_specifiers_label( - &self, - err: &mut DiagnosticBuilder<'_>, - span: Span, - count: usize, - lifetime_names: &FxHashSet, - params: &[ElisionFailureInfo], - ) { - if count > 1 { - err.span_label(span, format!("expected {} lifetime parameters", count)); - } else { - let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok(); - let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { - err.span_suggestion( - span, - "consider using the named lifetime", - sugg, - Applicability::MaybeIncorrect, - ); - }; - let suggest_new = - |err: &mut DiagnosticBuilder<'_>, sugg: &str| { - err.span_label(span, "expected named lifetime parameter"); - - for missing in self.missing_named_lifetime_spots.iter().rev() { - let mut introduce_suggestion = vec![]; - let msg; - let should_break; - introduce_suggestion.push(match missing { - MissingLifetimeSpot::Generics(generics) => { - msg = "consider introducing a named lifetime parameter".to_string(); - should_break = true; - if let Some(param) = generics.params.iter().filter(|p| match p.kind { - hir::GenericParamKind::Type { - synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), - .. - } => false, - _ => true, - }).next() { - (param.span.shrink_to_lo(), "'a, ".to_string()) - } else { - (generics.span, "<'a>".to_string()) - } - } - MissingLifetimeSpot::HigherRanked { span, span_type } => { - msg = format!( - "consider making the {} lifetime-generic with a new `'a` lifetime", - span_type.descr(), - ); - should_break = false; - err.note( - "for more information on higher-ranked polymorphism, visit \ - https://doc.rust-lang.org/nomicon/hrtb.html", - ); - (*span, span_type.suggestion("'a")) - } - }); - for param in params { - if let Ok(snippet) = - self.tcx.sess.source_map().span_to_snippet(param.span) - { - if snippet.starts_with("&") && !snippet.starts_with("&'") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[1..]))); - } else if snippet.starts_with("&'_ ") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[4..]))); - } - } - } - introduce_suggestion.push((span, sugg.to_string())); - err.multipart_suggestion( - &msg, - introduce_suggestion, - Applicability::MaybeIncorrect, - ); - if should_break { - break; - } - } - }; - - match ( - lifetime_names.len(), - lifetime_names.iter().next(), - snippet.as_ref().map(|s| s.as_str()), - ) { - (1, Some(name), Some("&")) => { - suggest_existing(err, format!("&{} ", name)); - } - (1, Some(name), Some("'_")) => { - suggest_existing(err, name.to_string()); - } - (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { - suggest_existing(err, format!("{}<{}>", snippet, name)); - } - (0, _, Some("&")) => { - suggest_new(err, "&'a "); - } - (0, _, Some("'_")) => { - suggest_new(err, "'a"); - } - (0, _, Some(snippet)) if !snippet.ends_with(">") => { - suggest_new(err, &format!("{}<'a>", snippet)); - } - _ => { - err.span_label(span, "expected lifetime parameter"); - } - } - } - } -} diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 5b5180a7e1a44..c924fef4dc9d2 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -32,6 +32,7 @@ use std::collections::BTreeSet; use std::mem::replace; mod diagnostics; +crate mod lifetimes; type Res = def::Res; diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index fa1dc3f450a4b..957574cced79b 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -1,4 +1,5 @@ use crate::diagnostics::{ImportSuggestion, TypoSuggestion}; +use crate::late::lifetimes::{ElisionFailureInfo, LifetimeContext}; use crate::late::{LateResolutionVisitor, RibKind}; use crate::path_names_to_string; use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot}; @@ -6,7 +7,8 @@ use crate::{PathResult, PathSource, Segment}; use rustc::session::config::nightly_options; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; @@ -28,6 +30,40 @@ enum AssocSuggestion { AssocItem, } +crate enum MissingLifetimeSpot<'tcx> { + Generics(&'tcx hir::Generics<'tcx>), + HigherRanked { span: Span, span_type: ForLifetimeSpanType }, +} + +crate enum ForLifetimeSpanType { + BoundEmpty, + BoundTail, + TypeEmpty, + TypeTail, +} + +impl ForLifetimeSpanType { + crate fn descr(&self) -> &'static str { + match self { + Self::BoundEmpty | Self::BoundTail => "bound", + Self::TypeEmpty | Self::TypeTail => "type", + } + } + + crate fn suggestion(&self, sugg: &str) -> String { + match self { + Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg), + Self::BoundTail | Self::TypeTail => format!(", {}", sugg), + } + } +} + +impl<'tcx> Into> for &'tcx hir::Generics<'tcx> { + fn into(self) -> MissingLifetimeSpot<'tcx> { + MissingLifetimeSpot::Generics(self) + } +} + fn is_self_type(path: &[Segment], namespace: Namespace) -> bool { namespace == TypeNS && path.len() == 1 && path[0].ident.name == kw::SelfUpper } @@ -904,3 +940,208 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { None } } + +impl<'tcx> LifetimeContext<'_, 'tcx> { + crate fn report_missing_lifetime_specifiers( + &self, + span: Span, + count: usize, + ) -> DiagnosticBuilder<'tcx> { + struct_span_err!( + self.tcx.sess, + span, + E0106, + "missing lifetime specifier{}", + pluralize!(count) + ) + } + + crate fn emit_undeclared_lifetime_error(&self, lifetime_ref: &hir::Lifetime) { + let mut err = struct_span_err!( + self.tcx.sess, + lifetime_ref.span, + E0261, + "use of undeclared lifetime name `{}`", + lifetime_ref + ); + err.span_label(lifetime_ref.span, "undeclared lifetime"); + for missing in &self.missing_named_lifetime_spots { + match missing { + MissingLifetimeSpot::Generics(generics) => { + let (span, sugg) = if let Some(param) = generics + .params + .iter() + .filter(|p| match p.kind { + hir::GenericParamKind::Type { + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + .. + } => false, + _ => true, + }) + .next() + { + (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) + } else { + (generics.span, format!("<{}>", lifetime_ref)) + }; + err.span_suggestion( + span, + &format!("consider introducing lifetime `{}` here", lifetime_ref), + sugg, + Applicability::MaybeIncorrect, + ); + } + MissingLifetimeSpot::HigherRanked { span, span_type } => { + err.span_suggestion( + *span, + &format!( + "consider making the {} lifetime-generic with a new `{}` lifetime", + span_type.descr(), + lifetime_ref + ), + span_type.suggestion(&lifetime_ref.to_string()), + Applicability::MaybeIncorrect, + ); + err.note( + "for more information on higher-ranked polymorphism, visit \ + https://doc.rust-lang.org/nomicon/hrtb.html", + ); + } + } + } + err.emit(); + } + + crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { + if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { + if [ + self.tcx.lang_items().fn_once_trait(), + self.tcx.lang_items().fn_trait(), + self.tcx.lang_items().fn_mut_trait(), + ] + .contains(&Some(did)) + { + let (span, span_type) = match &trait_ref.bound_generic_params { + [] => (trait_ref.span.shrink_to_lo(), ForLifetimeSpanType::BoundEmpty), + [.., bound] => (bound.span.shrink_to_hi(), ForLifetimeSpanType::BoundTail), + }; + self.missing_named_lifetime_spots + .push(MissingLifetimeSpot::HigherRanked { span, span_type }); + return true; + } + }; + false + } + + crate fn add_missing_lifetime_specifiers_label( + &self, + err: &mut DiagnosticBuilder<'_>, + span: Span, + count: usize, + lifetime_names: &FxHashSet, + params: &[ElisionFailureInfo], + ) { + if count > 1 { + err.span_label(span, format!("expected {} lifetime parameters", count)); + } else { + let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok(); + let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_suggestion( + span, + "consider using the named lifetime", + sugg, + Applicability::MaybeIncorrect, + ); + }; + let suggest_new = + |err: &mut DiagnosticBuilder<'_>, sugg: &str| { + err.span_label(span, "expected named lifetime parameter"); + + for missing in self.missing_named_lifetime_spots.iter().rev() { + let mut introduce_suggestion = vec![]; + let msg; + let should_break; + introduce_suggestion.push(match missing { + MissingLifetimeSpot::Generics(generics) => { + msg = "consider introducing a named lifetime parameter".to_string(); + should_break = true; + if let Some(param) = generics.params.iter().filter(|p| match p.kind { + hir::GenericParamKind::Type { + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + .. + } => false, + _ => true, + }).next() { + (param.span.shrink_to_lo(), "'a, ".to_string()) + } else { + (generics.span, "<'a>".to_string()) + } + } + MissingLifetimeSpot::HigherRanked { span, span_type } => { + msg = format!( + "consider making the {} lifetime-generic with a new `'a` lifetime", + span_type.descr(), + ); + should_break = false; + err.note( + "for more information on higher-ranked polymorphism, visit \ + https://doc.rust-lang.org/nomicon/hrtb.html", + ); + (*span, span_type.suggestion("'a")) + } + }); + for param in params { + if let Ok(snippet) = + self.tcx.sess.source_map().span_to_snippet(param.span) + { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[1..]))); + } else if snippet.starts_with("&'_ ") { + introduce_suggestion + .push((param.span, format!("&'a {}", &snippet[4..]))); + } + } + } + introduce_suggestion.push((span, sugg.to_string())); + err.multipart_suggestion( + &msg, + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + if should_break { + break; + } + } + }; + + match ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet.as_ref().map(|s| s.as_str()), + ) { + (1, Some(name), Some("&")) => { + suggest_existing(err, format!("&{} ", name)); + } + (1, Some(name), Some("'_")) => { + suggest_existing(err, name.to_string()); + } + (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { + suggest_existing(err, format!("{}<{}>", snippet, name)); + } + (0, _, Some("&")) => { + suggest_new(err, "&'a "); + } + (0, _, Some("'_")) => { + suggest_new(err, "'a"); + } + (0, _, Some(snippet)) if !snippet.ends_with(">") => { + suggest_new(err, &format!("{}<'a>", snippet)); + } + _ => { + err.span_label(span, "expected lifetime parameter"); + } + } + } + } +} diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs similarity index 99% rename from src/librustc_resolve/lifetimes.rs rename to src/librustc_resolve/late/lifetimes.rs index b9c5f4992f6ed..478757f0db737 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -5,7 +5,7 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. -use crate::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot}; +use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot}; use rustc::hir::map::Map; use rustc::lint; use rustc::middle::resolve_lifetime::*; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 4278bf867f305..ebd3f8b832bf1 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -68,7 +68,6 @@ mod def_collector; mod diagnostics; mod imports; mod late; -mod lifetimes; mod macros; enum Weak { @@ -2959,5 +2958,5 @@ impl CrateLint { } pub fn provide(providers: &mut Providers<'_>) { - lifetimes::provide(providers); + late::lifetimes::provide(providers); } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 78c05a51e4fbd..49f38d86d9161 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -12,7 +12,7 @@ use crate::middle::resolve_lifetime as rl; use crate::require_c_abi_if_c_variadic; use crate::util::common::ErrorReported; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; -use rustc::session::parse::feature_err; +use rustc::session::{parse::feature_err, Session}; use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; @@ -132,6 +132,15 @@ enum GenericArgPosition { MethodCall, } +/// A marker denoting that the generic arguments that were +/// provided did not match the respective generic parameters. +pub struct GenericArgCountMismatch { + /// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`). + pub reported: Option, + /// A list of spans of arguments provided that were not valid. + pub invalid_args: Vec, +} + impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { pub fn ast_region_to_region( &self, @@ -262,7 +271,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { def: &ty::Generics, seg: &hir::PathSegment<'_>, is_method_call: bool, - ) -> bool { + ) -> Result<(), GenericArgCountMismatch> { let empty_args = hir::GenericArgs::none(); let suppress_mismatch = Self::check_impl_trait(tcx, seg, &def); Self::check_generic_arg_count( @@ -274,7 +283,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { def.parent.is_none() && def.has_self, // `has_self` seg.infer_args || suppress_mismatch, // `infer_args` ) - .0 } /// Checks that the correct number of generic arguments have been provided. @@ -287,7 +295,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { position: GenericArgPosition, has_self: bool, infer_args: bool, - ) -> (bool, Option>) { + ) -> Result<(), GenericArgCountMismatch> { // At this stage we are guaranteed that the generic arguments are in the correct order, e.g. // that lifetimes will proceed types. So it suffices to check the number of each generic // arguments in order to validate them with respect to the generic parameters. @@ -313,7 +321,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // Prohibit explicit lifetime arguments if late-bound lifetime parameters are present. - let mut reported_late_bound_region_err = None; + let mut explicit_lifetimes = Ok(()); if !infer_lifetimes { if let Some(span_late) = def.has_late_bound_regions { let msg = "cannot specify lifetime arguments explicitly \ @@ -323,11 +331,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if position == GenericArgPosition::Value && arg_counts.lifetimes != param_counts.lifetimes { + explicit_lifetimes = Err(true); let mut err = tcx.sess.struct_span_err(span, msg); err.span_note(span_late, note); err.emit(); - reported_late_bound_region_err = Some(true); } else { + explicit_lifetimes = Err(false); let mut multispan = MultiSpan::from_span(span); multispan.push_span_label(span_late, note.to_string()); tcx.struct_span_lint_hir( @@ -336,112 +345,136 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { multispan, |lint| lint.build(msg).emit(), ); - reported_late_bound_region_err = Some(false); } } } - let check_kind_count = |kind, required, permitted, provided, offset| { - debug!( - "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}", - kind, required, permitted, provided, offset - ); - // We enforce the following: `required` <= `provided` <= `permitted`. - // For kinds without defaults (e.g.., lifetimes), `required == permitted`. - // For other kinds (i.e., types), `permitted` may be greater than `required`. - if required <= provided && provided <= permitted { - return (reported_late_bound_region_err.unwrap_or(false), None); - } - - // Unfortunately lifetime and type parameter mismatches are typically styled - // differently in diagnostics, which means we have a few cases to consider here. - let (bound, quantifier) = if required != permitted { - if provided < required { - (required, "at least ") - } else { - // provided > permitted - (permitted, "at most ") + let check_kind_count = + |kind, required, permitted, provided, offset, unexpected_spans: &mut Vec| { + debug!( + "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}", + kind, required, permitted, provided, offset + ); + // We enforce the following: `required` <= `provided` <= `permitted`. + // For kinds without defaults (e.g.., lifetimes), `required == permitted`. + // For other kinds (i.e., types), `permitted` may be greater than `required`. + if required <= provided && provided <= permitted { + return Ok(()); } - } else { - (required, "") - }; - let mut potential_assoc_types: Option> = None; - let (spans, label) = if required == permitted && provided > permitted { - // In the case when the user has provided too many arguments, - // we want to point to the unexpected arguments. - let spans: Vec = args.args[offset + permitted..offset + provided] - .iter() - .map(|arg| arg.span()) - .collect(); - potential_assoc_types = Some(spans.clone()); - (spans, format!("unexpected {} argument", kind)) - } else { - ( - vec![span], - format!( - "expected {}{} {} argument{}", - quantifier, - bound, - kind, - pluralize!(bound), + // Unfortunately lifetime and type parameter mismatches are typically styled + // differently in diagnostics, which means we have a few cases to consider here. + let (bound, quantifier) = if required != permitted { + if provided < required { + (required, "at least ") + } else { + // provided > permitted + (permitted, "at most ") + } + } else { + (required, "") + }; + + let (spans, label) = if required == permitted && provided > permitted { + // In the case when the user has provided too many arguments, + // we want to point to the unexpected arguments. + let spans: Vec = args.args[offset + permitted..offset + provided] + .iter() + .map(|arg| arg.span()) + .collect(); + unexpected_spans.extend(spans.clone()); + (spans, format!("unexpected {} argument", kind)) + } else { + ( + vec![span], + format!( + "expected {}{} {} argument{}", + quantifier, + bound, + kind, + pluralize!(bound), + ), + ) + }; + + let mut err = tcx.sess.struct_span_err_with_code( + spans.clone(), + &format!( + "wrong number of {} arguments: expected {}{}, found {}", + kind, quantifier, bound, provided, ), - ) - }; + DiagnosticId::Error("E0107".into()), + ); + for span in spans { + err.span_label(span, label.as_str()); + } + err.emit(); - let mut err = tcx.sess.struct_span_err_with_code( - spans.clone(), - &format!( - "wrong number of {} arguments: expected {}{}, found {}", - kind, quantifier, bound, provided, - ), - DiagnosticId::Error("E0107".into()), - ); - for span in spans { - err.span_label(span, label.as_str()); - } - err.emit(); + Err(true) + }; - ( - provided > required, // `suppress_error` - potential_assoc_types, - ) - }; + let mut arg_count_correct = explicit_lifetimes; + let mut unexpected_spans = vec![]; - if reported_late_bound_region_err.is_none() + if arg_count_correct.is_ok() && (!infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes) { - check_kind_count( + arg_count_correct = check_kind_count( "lifetime", param_counts.lifetimes, param_counts.lifetimes, arg_counts.lifetimes, 0, - ); + &mut unexpected_spans, + ) + .and(arg_count_correct); } // FIXME(const_generics:defaults) if !infer_args || arg_counts.consts > param_counts.consts { - check_kind_count( + arg_count_correct = check_kind_count( "const", param_counts.consts, param_counts.consts, arg_counts.consts, arg_counts.lifetimes + arg_counts.types, - ); + &mut unexpected_spans, + ) + .and(arg_count_correct); } // Note that type errors are currently be emitted *after* const errors. if !infer_args || arg_counts.types > param_counts.types - defaults.types - has_self as usize { - check_kind_count( + arg_count_correct = check_kind_count( "type", param_counts.types - defaults.types - has_self as usize, param_counts.types - has_self as usize, arg_counts.types, arg_counts.lifetimes, + &mut unexpected_spans, ) - } else { - (reported_late_bound_region_err.unwrap_or(false), None) + .and(arg_count_correct); } + + arg_count_correct.map_err(|reported_err| GenericArgCountMismatch { + reported: if reported_err { Some(ErrorReported) } else { None }, + invalid_args: unexpected_spans, + }) + } + + /// Report an error that a generic argument did not match the generic parameter that was + /// expected. + fn generic_arg_mismatch_err(sess: &Session, arg: &GenericArg<'_>, kind: &'static str) { + let mut err = struct_span_err!( + sess, + arg.span(), + E0747, + "{} provided when a {} was expected", + arg.descr(), + kind, + ); + // This note will be true as long as generic parameters are strictly ordered by their kind. + err.note(&format!("{} arguments must be provided before {} arguments", kind, arg.descr())); + err.emit(); } /// Creates the relevant generic argument substitutions @@ -479,6 +512,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { parent_substs: &[subst::GenericArg<'tcx>], has_self: bool, self_ty: Option>, + arg_count_correct: bool, args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs<'b>>, bool), provided_kind: impl Fn(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>, mut inferred_kind: impl FnMut( @@ -502,7 +536,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // methods in `subst.rs`, so that we can iterate over the arguments and // parameters in lock-step linearly, instead of trying to match each pair. let mut substs: SmallVec<[subst::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count); - // Iterate over each segment of the path. while let Some((def_id, defs)) = stack.pop() { let mut params = defs.params.iter().peekable(); @@ -539,6 +572,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut args = generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable(); + // If we encounter a type or const when we expect a lifetime, we infer the lifetimes. + // If we later encounter a lifetime, we know that the arguments were provided in the + // wrong order. `force_infer_lt` records the type or const that forced lifetimes to be + // inferred, so we can use it for diagnostics later. + let mut force_infer_lt = None; + loop { // We're going to iterate through the generic arguments that the user // provided, matching them with the generic parameters we expect. @@ -559,30 +598,58 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // We expected a lifetime argument, but got a type or const // argument. That means we're inferring the lifetimes. substs.push(inferred_kind(None, param, infer_args)); + force_infer_lt = Some(arg); params.next(); } - (_, _) => { + (_, kind) => { // We expected one kind of parameter, but the user provided - // another. This is an error, but we need to handle it - // gracefully so we can report sensible errors. - // In this case, we're simply going to infer this argument. - args.next(); + // another. This is an error. However, if we already know that + // the arguments don't match up with the parameters, we won't issue + // an additional error, as the user already knows what's wrong. + if arg_count_correct { + Self::generic_arg_mismatch_err(tcx.sess, arg, kind.descr()); + } + + // We've reported the error, but we want to make sure that this + // problem doesn't bubble down and create additional, irrelevant + // errors. In this case, we're simply going to ignore the argument + // and any following arguments. The rest of the parameters will be + // inferred. + while args.next().is_some() {} } } } - (Some(_), None) => { + + (Some(&arg), None) => { // We should never be able to reach this point with well-formed input. - // Getting to this point means the user supplied more arguments than - // there are parameters. - args.next(); + // There are two situations in which we can encounter this issue. + // + // 1. The number of arguments is incorrect. In this case, an error + // will already have been emitted, and we can ignore it. This case + // also occurs when late-bound lifetime parameters are present, yet + // the lifetime arguments have also been explicitly specified by the + // user. + // 2. We've inferred some lifetimes, which have been provided later (i.e. + // after a type or const). We want to throw an error in this case. + + if arg_count_correct { + let kind = arg.descr(); + assert_eq!(kind, "lifetime"); + let provided = + force_infer_lt.expect("lifetimes ought to have been inferred"); + Self::generic_arg_mismatch_err(tcx.sess, provided, kind); + } + + break; } + (None, Some(¶m)) => { // If there are fewer arguments than parameters, it means // we're inferring the remaining arguments. substs.push(inferred_kind(Some(&substs), param, infer_args)); - args.next(); params.next(); } + (None, None) => break, } } @@ -630,7 +697,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option>, - ) -> (SubstsRef<'tcx>, Vec>, Option>) { + ) -> (SubstsRef<'tcx>, Vec>, Result<(), GenericArgCountMismatch>) + { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, // whatever & would get replaced with). @@ -656,7 +724,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert!(self_ty.is_none() && parent_substs.is_empty()); } - let (_, potential_assoc_types) = Self::check_generic_arg_count( + let arg_count_correct = Self::check_generic_arg_count( tcx, span, &generic_params, @@ -689,8 +757,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { parent_substs, self_ty.is_some(), self_ty, + arg_count_correct.is_ok(), // Provide the generic args, and whether types should be inferred. - |_| (Some(generic_args), infer_args), + |did| { + if did == def_id { + (Some(generic_args), infer_args) + } else { + // The last component of this tuple is unimportant. + (None, false) + } + }, // Provide substitutions for parameters for which (valid) arguments have been provided. |param, arg| match (¶m.kind, arg) { (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { @@ -794,7 +870,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_params, self_ty, substs ); - (substs, assoc_bindings, potential_assoc_types) + (substs, assoc_bindings, arg_count_correct) } crate fn create_substs_for_associated_item( @@ -925,7 +1001,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, - ) -> Option> { + ) -> Result<(), GenericArgCountMismatch> { let trait_def_id = trait_ref.trait_def_id(); debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); @@ -942,7 +1018,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { trait_ref.path.span }; - let (substs, assoc_bindings, potential_assoc_types) = self.create_substs_for_ast_trait_ref( + let (substs, assoc_bindings, arg_count_correct) = self.create_substs_for_ast_trait_ref( path_span, trait_def_id, self_ty, @@ -971,7 +1047,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}", trait_ref, bounds, poly_trait_ref ); - potential_assoc_types + + arg_count_correct } /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct @@ -999,7 +1076,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { constness: Constness, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, - ) -> Option> { + ) -> Result<(), GenericArgCountMismatch> { self.instantiate_poly_trait_ref_inner( &poly_trait_ref.trait_ref, poly_trait_ref.span, @@ -1088,7 +1165,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_def_id: DefId, self_ty: Ty<'tcx>, trait_segment: &'a hir::PathSegment<'a>, - ) -> (SubstsRef<'tcx>, Vec>, Option>) { + ) -> (SubstsRef<'tcx>, Vec>, Result<(), GenericArgCountMismatch>) + { debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment); self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment); @@ -1433,13 +1511,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut potential_assoc_types = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; for trait_bound in trait_bounds.iter().rev() { - let cur_potential_assoc_types = self.instantiate_poly_trait_ref( + if let Err(GenericArgCountMismatch { + invalid_args: cur_potential_assoc_types, .. + }) = self.instantiate_poly_trait_ref( trait_bound, Constness::NotConst, dummy_self, &mut bounds, - ); - potential_assoc_types.extend(cur_potential_assoc_types.into_iter().flatten()); + ) { + potential_assoc_types.extend(cur_potential_assoc_types.into_iter()); + } } // Expand trait aliases recursively and check that only one regular (non-auto) trait diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 17842be9a4392..108affe5a86c0 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -299,7 +299,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // If they were not explicitly supplied, just construct fresh // variables. let generics = self.tcx.generics_of(pick.item.def_id); - AstConv::check_generic_arg_count_for_call( + let arg_count_correct = AstConv::check_generic_arg_count_for_call( self.tcx, self.span, &generics, &seg, true, // `is_method_call` ); @@ -313,10 +313,16 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { parent_substs, false, None, + arg_count_correct.is_ok(), // Provide the generic args, and whether types should be inferred. - |_| { - // The last argument of the returned tuple here is unimportant. - if let Some(ref data) = seg.args { (Some(data), false) } else { (None, false) } + |def_id| { + // The last component of the returned tuple here is unimportant. + if def_id == pick.item.def_id { + if let Some(ref data) = seg.args { + return (Some(data), false); + } + } + (None, false) }, // Provide substitutions for parameters for which (valid) arguments have been provided. |param, arg| match (¶m.kind, arg) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4ab5d8f9ad3f6..3c71e8bf6b8fa 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -87,7 +87,7 @@ mod upvar; mod wfcheck; pub mod writeback; -use crate::astconv::{AstConv, PathSeg}; +use crate::astconv::{AstConv, GenericArgCountMismatch, PathSeg}; use crate::middle::lang_items; use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::map::Map; @@ -5431,10 +5431,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // parameter internally, but we don't allow users to specify the // parameter's value explicitly, so we have to do some error- // checking here. - let suppress_errors = AstConv::check_generic_arg_count_for_call( - tcx, span, &generics, &seg, false, // `is_method_call` - ); - if suppress_errors { + if let Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }) = + AstConv::check_generic_arg_count_for_call( + tcx, span, &generics, &seg, false, // `is_method_call` + ) + { infer_args_for_err.insert(index); self.set_tainted_by_errors(); // See issue #53251. } @@ -5499,6 +5500,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &[][..], has_self, self_ty, + infer_args_for_err.is_empty(), // Provide the generic args, and whether types should be inferred. |def_id| { if let Some(&PathSeg(_, index)) = diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 70586be0d0433..1fade1b5ca65e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -76,6 +76,7 @@ pub fn provide(providers: &mut Providers<'_>) { impl_polarity, is_foreign_item, static_mutability, + generator_kind, codegen_fn_attrs, collect_mod_item_types, ..*providers @@ -319,7 +320,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { - self.tcx().sess.delay_span_bug(span, "bad placeholder type"); + placeholder_type_error(self.tcx(), span, &[], vec![span], false); self.tcx().types.err } @@ -1006,7 +1007,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef { .struct_span_err( item.span, "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \ - which traits can use parenthetical notation", + which traits can use parenthetical notation", ) .help("add `#![feature(unboxed_closures)]` to the crate attributes to use it") .emit(); @@ -1269,7 +1270,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id); - // Now create the real type parameters. + // Now create the real type and const parameters. let type_start = own_start - has_self as u32 + params.len() as u32; let mut i = 0; params.extend(ast_generics.params.iter().filter_map(|param| { @@ -2106,7 +2107,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( ast_ty.span, &format!( "use of SIMD type `{}` in FFI is highly experimental and \ - may result in invalid code", + may result in invalid code", tcx.hir().hir_to_pretty_string(ast_ty.hir_id) ), ) @@ -2145,6 +2146,17 @@ fn static_mutability(tcx: TyCtxt<'_>, def_id: DefId) -> Option } } +fn generator_kind(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + match tcx.hir().get_if_local(def_id) { + Some(Node::Expr(&rustc_hir::Expr { + kind: rustc_hir::ExprKind::Closure(_, _, body_id, _, _), + .. + })) => tcx.hir().body(body_id).generator_kind(), + Some(_) => None, + _ => bug!("generator_kind applied to non-local def-id {:?}", def_id), + } +} + fn from_target_feature( tcx: TyCtxt<'_>, id: DefId, diff --git a/src/llvm-project b/src/llvm-project index 73cf98d865673..9f65ad057357b 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 73cf98d8656736781e3ea667011d2aefc21f521e +Subproject commit 9f65ad057357b307180955831968f79e74090a90 diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index f85ae0c077486..662519067d78e 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -2,23 +2,23 @@ // We specify -Z incremental here because we want to test the partitioning for // incremental compilation +// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing // compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/extern-drop-glue -// compile-flags:-Zinline-in-all-cgus +// compile-flags:-Zinline-in-all-cgus -Copt-level=0 #![allow(dead_code)] -#![crate_type="rlib"] +#![crate_type = "rlib"] // aux-build:cgu_extern_drop_glue.rs extern crate cgu_extern_drop_glue; -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue-fallback.cgu[External] struct LocalStruct(cgu_extern_drop_glue::Struct); //~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External] -pub fn user() -{ - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue[Internal] +pub fn user() { + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue-fallback.cgu[External] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } @@ -28,9 +28,8 @@ pub mod mod1 { struct LocalStruct(cgu_extern_drop_glue::Struct); //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External] - pub fn user() - { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue-mod1[Internal] + pub fn user() { + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue-fallback.cgu[External] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } } diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index 366af4d4c386b..14a50bf579806 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -1,54 +1,45 @@ // ignore-tidy-linelength // We specify -Z incremental here because we want to test the partitioning for // incremental compilation +// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing // compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/local-drop-glue -// compile-flags:-Zinline-in-all-cgus +// compile-flags:-Zinline-in-all-cgus -Copt-level=0 #![allow(dead_code)] -#![crate_type="rlib"] +#![crate_type = "rlib"] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue-fallback.cgu[External] struct Struct { - _a: u32 + _a: u32, } impl Drop for Struct { - //~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[External] + //~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue-fallback.cgu[External] fn drop(&mut self) {} } -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue-fallback.cgu[External] struct Outer { - _a: Struct + _a: Struct, } //~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External] -pub fn user() -{ - let _ = Outer { - _a: Struct { - _a: 0 - } - }; +pub fn user() { + let _ = Outer { _a: Struct { _a: 0 } }; } -pub mod mod1 -{ +pub mod mod1 { use super::Struct; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue-fallback.cgu[External] struct Struct2 { _a: Struct, - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-fallback.cgu[Internal] _b: (u32, Struct), } //~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External] - pub fn user() - { - let _ = Struct2 { - _a: Struct { _a: 0 }, - _b: (0, Struct { _a: 0 }), - }; + pub fn user() { + let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) }; } } diff --git a/src/test/ui/async-await/issues/issue-62097.nll.stderr b/src/test/ui/async-await/issues/issue-62097.nll.stderr index 0c64f90cb9fae..f72c645bf8dbf 100644 --- a/src/test/ui/async-await/issues/issue-62097.nll.stderr +++ b/src/test/ui/async-await/issues/issue-62097.nll.stderr @@ -16,13 +16,13 @@ help: to force the closure to take ownership of `self` (and any other referenced LL | foo(move || self.bar()).await; | ^^^^^^^ -error[E0521]: borrowed data escapes outside of function +error[E0521]: borrowed data escapes outside of method --> $DIR/issue-62097.rs:13:9 | LL | pub async fn run_dummy_fn(&self) { - | ----- `self` is a reference that is only valid in the function body + | ----- `self` is a reference that is only valid in the method body LL | foo(|| self.bar()).await; - | ^^^^^^^^^^^^^^^^^^ `self` escapes the function body here + | ^^^^^^^^^^^^^^^^^^ `self` escapes the method body here error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr index 8e0e1ce3dc34d..696f79ec40f36 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr @@ -9,7 +9,7 @@ LL | ) -> &dyn Foo LL | / { LL | | foo LL | | } - | |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + | |_____^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs new file mode 100644 index 0000000000000..f024eb6a957e3 --- /dev/null +++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs @@ -0,0 +1,10 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +type Array = [T; N]; + +fn foo() -> Array { //~ ERROR constant provided when a type was expected + unimplemented!() +} + +fn main() {} diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr new file mode 100644 index 0000000000000..150a6011c2c13 --- /dev/null +++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr @@ -0,0 +1,19 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-arg-type-arg-misordered.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0747]: constant provided when a type was expected + --> $DIR/const-arg-type-arg-misordered.rs:6:35 + | +LL | fn foo() -> Array { + | ^ + | + = note: type arguments must be provided before constant arguments + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/const-generics/const-param-after-const-literal-arg.rs b/src/test/ui/const-generics/const-param-after-const-literal-arg.rs new file mode 100644 index 0000000000000..19c4120eb2f14 --- /dev/null +++ b/src/test/ui/const-generics/const-param-after-const-literal-arg.rs @@ -0,0 +1,10 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(const_generics)] + +struct Foo; + +impl Foo<1, A> {} // ok + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs index 5bdbfd8ff1f39..756e961ce914f 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.rs +++ b/src/test/ui/const-generics/const-param-before-other-params.rs @@ -1,3 +1,4 @@ +#![allow(incomplete_features)] #![feature(const_generics)] fn bar(_: &'a ()) { diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr index 87622f7e50010..9b18b8c79edda 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.stderr +++ b/src/test/ui/const-generics/const-param-before-other-params.stderr @@ -1,11 +1,11 @@ error: lifetime parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:3:21 + --> $DIR/const-param-before-other-params.rs:4:21 | LL | fn bar(_: &'a ()) { | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` error: type parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:7:21 + --> $DIR/const-param-before-other-params.rs:8:21 | LL | fn foo(_: &T) { | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.rs b/src/test/ui/did_you_mean/bad-assoc-ty.rs index fccfb7911cecf..f02931eeb6fc3 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.rs +++ b/src/test/ui/did_you_mean/bad-assoc-ty.rs @@ -17,6 +17,7 @@ type D = (u8, u8)::AssocTy; type E = _::AssocTy; //~^ ERROR missing angle brackets in associated item path //~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures type F = &'static (u8)::AssocTy; //~^ ERROR missing angle brackets in associated item path diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 64e49934d8762..d5b2abf2f8b50 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -29,25 +29,25 @@ LL | type E = _::AssocTy; | ^^^^^^^^^^ help: try: `<_>::AssocTy` error: missing angle brackets in associated item path - --> $DIR/bad-assoc-ty.rs:21:19 + --> $DIR/bad-assoc-ty.rs:22:19 | LL | type F = &'static (u8)::AssocTy; | ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy` error: missing angle brackets in associated item path - --> $DIR/bad-assoc-ty.rs:27:10 + --> $DIR/bad-assoc-ty.rs:28:10 | LL | type G = dyn 'static + (Send)::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `::AssocTy` error: missing angle brackets in associated item path - --> $DIR/bad-assoc-ty.rs:44:10 + --> $DIR/bad-assoc-ty.rs:45:10 | LL | type I = ty!()::AssocTy; | ^^^^^^^^^^^^^^ help: try: `::AssocTy` error: missing angle brackets in associated item path - --> $DIR/bad-assoc-ty.rs:37:19 + --> $DIR/bad-assoc-ty.rs:38:19 | LL | ($ty: ty) => ($ty::AssocTy); | ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy` @@ -87,26 +87,32 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa LL | type E = _::AssocTy; | ^ not allowed in type signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/bad-assoc-ty.rs:17:10 + | +LL | type E = _::AssocTy; + | ^ not allowed in type signatures + error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:21:19 + --> $DIR/bad-assoc-ty.rs:22:19 | LL | type F = &'static (u8)::AssocTy; | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:27:10 + --> $DIR/bad-assoc-ty.rs:28:10 | LL | type G = dyn 'static + (Send)::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn std::marker::Send + 'static) as Trait>::AssocTy` error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:33:10 + --> $DIR/bad-assoc-ty.rs:34:10 | LL | type H = Fn(u8) -> (u8)::Output; | ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output` error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:37:19 + --> $DIR/bad-assoc-ty.rs:38:19 | LL | ($ty: ty) => ($ty::AssocTy); | ^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` @@ -117,12 +123,12 @@ LL | type J = ty!(u8); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:44:10 + --> $DIR/bad-assoc-ty.rs:45:10 | LL | type I = ty!()::AssocTy; | ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0121, E0223. For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/generic/generic-arg-mismatch-recover.rs b/src/test/ui/generic/generic-arg-mismatch-recover.rs index f4e15fbebcebb..3e5e2e601f5c4 100644 --- a/src/test/ui/generic/generic-arg-mismatch-recover.rs +++ b/src/test/ui/generic/generic-arg-mismatch-recover.rs @@ -4,7 +4,6 @@ struct Bar<'a>(&'a ()); fn main() { Foo::<'static, 'static, ()>(&0); //~ ERROR wrong number of lifetime arguments - //~^ ERROR mismatched types Bar::<'static, 'static, ()>(&()); //~ ERROR wrong number of lifetime arguments //~^ ERROR wrong number of type arguments diff --git a/src/test/ui/generic/generic-arg-mismatch-recover.stderr b/src/test/ui/generic/generic-arg-mismatch-recover.stderr index 4b86212e4862b..99adb35268527 100644 --- a/src/test/ui/generic/generic-arg-mismatch-recover.stderr +++ b/src/test/ui/generic/generic-arg-mismatch-recover.stderr @@ -4,28 +4,18 @@ error[E0107]: wrong number of lifetime arguments: expected 1, found 2 LL | Foo::<'static, 'static, ()>(&0); | ^^^^^^^ unexpected lifetime argument -error[E0308]: mismatched types - --> $DIR/generic-arg-mismatch-recover.rs:6:33 - | -LL | Foo::<'static, 'static, ()>(&0); - | ^^ expected `()`, found integer - | - = note: expected reference `&'static ()` - found reference `&{integer}` - error[E0107]: wrong number of lifetime arguments: expected 1, found 2 - --> $DIR/generic-arg-mismatch-recover.rs:9:20 + --> $DIR/generic-arg-mismatch-recover.rs:8:20 | LL | Bar::<'static, 'static, ()>(&()); | ^^^^^^^ unexpected lifetime argument error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/generic-arg-mismatch-recover.rs:9:29 + --> $DIR/generic-arg-mismatch-recover.rs:8:29 | LL | Bar::<'static, 'static, ()>(&()); | ^^ unexpected type argument -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0308. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/issues/issue-16683.nll.stderr b/src/test/ui/issues/issue-16683.nll.stderr index ea6b69d1a76c6..f76e7a4e44fd7 100644 --- a/src/test/ui/issues/issue-16683.nll.stderr +++ b/src/test/ui/issues/issue-16683.nll.stderr @@ -1,10 +1,10 @@ -error[E0521]: borrowed data escapes outside of function +error[E0521]: borrowed data escapes outside of method --> $DIR/issue-16683.rs:4:9 | LL | fn b(&self) { - | ----- `self` is a reference that is only valid in the function body + | ----- `self` is a reference that is only valid in the method body LL | self.a(); - | ^^^^^^^^ `self` escapes the function body here + | ^^^^^^^^ `self` escapes the method body here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17758.nll.stderr b/src/test/ui/issues/issue-17758.nll.stderr index b9dc9da3683d6..92e21f4dc1769 100644 --- a/src/test/ui/issues/issue-17758.nll.stderr +++ b/src/test/ui/issues/issue-17758.nll.stderr @@ -1,10 +1,10 @@ -error[E0521]: borrowed data escapes outside of function +error[E0521]: borrowed data escapes outside of method --> $DIR/issue-17758.rs:7:9 | LL | fn bar(&self) { - | ----- `self` is a reference that is only valid in the function body + | ----- `self` is a reference that is only valid in the method body LL | self.foo(); - | ^^^^^^^^^^ `self` escapes the function body here + | ^^^^^^^^^^ `self` escapes the method body here error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr index fc9093bb2e4b8..291edc505cd1e 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { | lifetime `'a` defined here LL | LL | if x > y { x } else { y } - | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr index 3384c24da8fbe..15ee58574ecaa 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo<'a>(&self, x: &'a i32) -> &i32 { | lifetime `'a` defined here LL | LL | x - | ^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | ^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr index 5ef29076e07bf..a27a91e38f1e4 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | lifetime `'a` defined here LL | LL | if true { x } else { self } - | ^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + | ^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr index 1c258ad98ba10..5f922d8560b2a 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr @@ -6,7 +6,7 @@ LL | fn foo<'a>(&self, x: &i32) -> &i32 { | | | let's call the lifetime of this reference `'2` LL | x - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr index ffe39fdd8c9f5..91d7597c87fea 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr @@ -6,7 +6,7 @@ LL | fn foo<'a>(&self, x: &Foo) -> &Foo { | | | let's call the lifetime of this reference `'2` LL | if true { x } else { self } - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/nll/outlives-suggestion-simple.rs b/src/test/ui/nll/outlives-suggestion-simple.rs index 91a7a1d71e80c..ee5a80ae6483f 100644 --- a/src/test/ui/nll/outlives-suggestion-simple.rs +++ b/src/test/ui/nll/outlives-suggestion-simple.rs @@ -70,7 +70,7 @@ pub struct Foo2<'a> { impl<'a> Foo2<'a> { // should not produce outlives suggestions to name 'self fn get_bar(&self) -> Bar2 { - Bar2::new(&self) //~ERROR borrowed data escapes outside of function + Bar2::new(&self) //~ERROR borrowed data escapes outside of method } } diff --git a/src/test/ui/nll/outlives-suggestion-simple.stderr b/src/test/ui/nll/outlives-suggestion-simple.stderr index db7f57ceccf13..cf55603cd71f5 100644 --- a/src/test/ui/nll/outlives-suggestion-simple.stderr +++ b/src/test/ui/nll/outlives-suggestion-simple.stderr @@ -93,16 +93,16 @@ LL | self.x | = help: consider adding the following bound: `'b: 'a` -error[E0521]: borrowed data escapes outside of function +error[E0521]: borrowed data escapes outside of method --> $DIR/outlives-suggestion-simple.rs:73:9 | LL | fn get_bar(&self) -> Bar2 { | ----- | | - | `self` declared here, outside of the function body - | `self` is a reference that is only valid in the function body + | `self` declared here, outside of the method body + | `self` is a reference that is only valid in the method body LL | Bar2::new(&self) - | ^^^^^^^^^^^^^^^^ `self` escapes the function body here + | ^^^^^^^^^^^^^^^^ `self` escapes the method body here error: aborting due to 9 previous errors diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs index 39694198cdb4d..46ece84d69e45 100644 --- a/src/test/ui/parser/issue-14303-fncall.rs +++ b/src/test/ui/parser/issue-14303-fncall.rs @@ -11,7 +11,7 @@ fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { let _x = (*start..*end) .map(|x| S { a: start, b: end }) .collect::>>(); - //~^ ERROR lifetime arguments must be declared prior to type arguments + //~^ ERROR type provided when a lifetime was expected } fn main() {} diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.stderr index 8ef9f1a1a6c79..109542237130a 100644 --- a/src/test/ui/parser/issue-14303-fncall.stderr +++ b/src/test/ui/parser/issue-14303-fncall.stderr @@ -1,8 +1,11 @@ -error: lifetime arguments must be declared prior to type arguments - --> $DIR/issue-14303-fncall.rs:13:29 +error[E0747]: type provided when a lifetime was expected + --> $DIR/issue-14303-fncall.rs:13:26 | LL | .collect::>>(); - | ^^ + | ^ + | + = note: lifetime arguments must be provided before type arguments error: aborting due to previous error +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/parser/issue-14303-path.rs b/src/test/ui/parser/issue-14303-path.rs index 386d19859e4a8..89ef914aba238 100644 --- a/src/test/ui/parser/issue-14303-path.rs +++ b/src/test/ui/parser/issue-14303-path.rs @@ -8,6 +8,6 @@ mod foo { } fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} -//~^ ERROR lifetime arguments must be declared prior to type arguments +//~^ ERROR type provided when a lifetime was expected fn main() {} diff --git a/src/test/ui/parser/issue-14303-path.stderr b/src/test/ui/parser/issue-14303-path.stderr index 19f2995ebee53..c1ad2332b5bfa 100644 --- a/src/test/ui/parser/issue-14303-path.stderr +++ b/src/test/ui/parser/issue-14303-path.stderr @@ -1,8 +1,11 @@ -error: lifetime arguments must be declared prior to type arguments - --> $DIR/issue-14303-path.rs:10:40 +error[E0747]: type provided when a lifetime was expected + --> $DIR/issue-14303-path.rs:10:37 | LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} - | ^^ ^^ + | ^ + | + = note: lifetime arguments must be provided before type arguments error: aborting due to previous error +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr index 61f6680d5a423..6afcf24cd3e1e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -11,7 +11,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -20,7 +20,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | -- - ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | -- - ^^^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` | | | | | let's call the lifetime of this reference `'1` | lifetime `'a` defined here diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr index 1a0904fcbba6e..a659e4487856c 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46 | LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -11,7 +11,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:69 | LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -20,7 +20,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58 | LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | -- ---- has type `std::pin::Pin<&'1 Foo>` ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | -- ---- has type `std::pin::Pin<&'1 Foo>` ^^^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` | | | lifetime `'a` defined here diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr index e66711076e893..57d0929c50a79 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr @@ -6,7 +6,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:19:9 @@ -16,7 +16,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:23:9 @@ -26,7 +26,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:27:9 @@ -36,7 +36,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:31:9 @@ -46,7 +46,7 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:35:9 @@ -56,7 +56,7 @@ LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr index a0c56f2221850..b51b5a0ba38f2 100644 --- a/src/test/ui/self/elision/lt-ref-self.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr @@ -6,7 +6,7 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:17:9 @@ -16,7 +16,7 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:21:9 @@ -26,7 +26,7 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:25:9 @@ -36,7 +36,7 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:29:9 @@ -46,7 +46,7 @@ LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:33:9 @@ -56,7 +56,7 @@ LL | fn box_pin_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr index 82098cd4f077e..46e828390b0fc 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr @@ -6,7 +6,7 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:19:9 @@ -16,7 +16,7 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:23:9 @@ -26,7 +26,7 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:27:9 @@ -36,7 +36,7 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:31:9 @@ -46,7 +46,7 @@ LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:35:9 @@ -56,7 +56,7 @@ LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr index 4e7d7f521d256..6c8c030e5fffa 100644 --- a/src/test/ui/self/elision/ref-mut-self.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr @@ -6,7 +6,7 @@ LL | fn ref_self(&mut self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:17:9 @@ -16,7 +16,7 @@ LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:21:9 @@ -26,7 +26,7 @@ LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:25:9 @@ -36,7 +36,7 @@ LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:29:9 @@ -46,7 +46,7 @@ LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:33:9 @@ -56,7 +56,7 @@ LL | fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr index 736cebae4bccf..99340800790ec 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr @@ -6,7 +6,7 @@ LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:17:9 @@ -16,7 +16,7 @@ LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:21:9 @@ -26,7 +26,7 @@ LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:25:9 @@ -36,7 +36,7 @@ LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:29:9 @@ -46,7 +46,7 @@ LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr index cec7034cd9f9d..e3886444db2ad 100644 --- a/src/test/ui/self/elision/ref-mut-struct.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr @@ -6,7 +6,7 @@ LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:15:9 @@ -16,7 +16,7 @@ LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:19:9 @@ -26,7 +26,7 @@ LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:23:9 @@ -36,7 +36,7 @@ LL | fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:27:9 @@ -46,7 +46,7 @@ LL | fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr index 20045be0527a4..ecac1ce3378d6 100644 --- a/src/test/ui/self/elision/ref-self.nll.stderr +++ b/src/test/ui/self/elision/ref-self.nll.stderr @@ -6,7 +6,7 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-self.rs:27:9 @@ -16,7 +16,7 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-self.rs:31:9 @@ -26,7 +26,7 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-self.rs:35:9 @@ -36,7 +36,7 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-self.rs:39:9 @@ -46,7 +46,7 @@ LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-self.rs:43:9 @@ -56,7 +56,7 @@ LL | fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-self.rs:47:9 @@ -66,7 +66,7 @@ LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr index 5d7dd76827a96..bcbf79bc039fd 100644 --- a/src/test/ui/self/elision/ref-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr @@ -6,7 +6,7 @@ LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:17:9 @@ -16,7 +16,7 @@ LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:21:9 @@ -26,7 +26,7 @@ LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:25:9 @@ -36,7 +36,7 @@ LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:29:9 @@ -46,7 +46,7 @@ LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr index 31bb9f49a6c4d..39e7631f31e7b 100644 --- a/src/test/ui/self/elision/ref-struct.nll.stderr +++ b/src/test/ui/self/elision/ref-struct.nll.stderr @@ -6,7 +6,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct.rs:15:9 @@ -16,7 +16,7 @@ LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct.rs:19:9 @@ -26,7 +26,7 @@ LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct.rs:23:9 @@ -36,7 +36,7 @@ LL | fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/ref-struct.rs:27:9 @@ -46,7 +46,7 @@ LL | fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 5 previous errors diff --git a/src/test/ui/self/self-infer.rs b/src/test/ui/self/self-infer.rs index 0956f2a56918c..77c80521236a0 100644 --- a/src/test/ui/self/self-infer.rs +++ b/src/test/ui/self/self-infer.rs @@ -2,7 +2,9 @@ struct S; impl S { fn f(self: _) {} //~ERROR the type placeholder `_` is not allowed within types on item sig + //~^ ERROR the type placeholder `_` is not allowed within types on item sig fn g(self: &_) {} //~ERROR the type placeholder `_` is not allowed within types on item sig + //~^ ERROR the type placeholder `_` is not allowed within types on item sig } fn main() {} diff --git a/src/test/ui/self/self-infer.stderr b/src/test/ui/self/self-infer.stderr index 1475b212b56a6..d6bf8b44d6099 100644 --- a/src/test/ui/self/self-infer.stderr +++ b/src/test/ui/self/self-infer.stderr @@ -1,3 +1,9 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/self-infer.rs:4:16 + | +LL | fn f(self: _) {} + | ^ not allowed in type signatures + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/self-infer.rs:4:16 | @@ -10,7 +16,13 @@ LL | fn f(self: T) {} | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/self-infer.rs:5:17 + --> $DIR/self-infer.rs:6:17 + | +LL | fn g(self: &_) {} + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/self-infer.rs:6:17 | LL | fn g(self: &_) {} | ^ not allowed in type signatures @@ -20,6 +32,6 @@ help: use type parameters instead LL | fn g(self: &T) {} | ^^^ ^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/suggestions/suggest-move-types.rs b/src/test/ui/suggestions/suggest-move-types.rs index 890950ea08c5d..6505a97de6e4b 100644 --- a/src/test/ui/suggestions/suggest-move-types.rs +++ b/src/test/ui/suggestions/suggest-move-types.rs @@ -33,7 +33,7 @@ struct A> { //~ ERROR associated type bindings must be declar struct Al<'a, T, M: OneWithLifetime> { //~^ ERROR associated type bindings must be declared after generic parameters -//~^^ ERROR lifetime arguments must be declared prior to type arguments +//~^^ ERROR type provided when a lifetime was expected m: M, t: &'a T, } @@ -47,7 +47,7 @@ struct B> { //~ ERROR associated ty struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { //~^ ERROR associated type bindings must be declared after generic parameters -//~^^ ERROR lifetime arguments must be declared prior to type arguments +//~^^ ERROR type provided when a lifetime was expected m: M, t: &'a T, u: &'b U, @@ -63,7 +63,7 @@ struct C> { //~ ERROR associated ty struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { //~^ ERROR associated type bindings must be declared after generic parameters -//~^^ ERROR lifetime arguments must be declared prior to type arguments +//~^^ ERROR lifetime provided when a type was expected m: M, t: &'a T, u: &'b U, @@ -79,7 +79,7 @@ struct D> { //~ ERROR associated ty struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { //~^ ERROR associated type bindings must be declared after generic parameters -//~^^ ERROR lifetime arguments must be declared prior to type arguments +//~^^ ERROR lifetime provided when a type was expected m: M, t: &'a T, u: &'b U, diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr index 552fb78cd3fdd..ac91813f92839 100644 --- a/src/test/ui/suggestions/suggest-move-types.stderr +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -74,29 +74,38 @@ LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime $DIR/suggest-move-types.rs:34:46 +error[E0747]: type provided when a lifetime was expected + --> $DIR/suggest-move-types.rs:34:43 | LL | struct Al<'a, T, M: OneWithLifetime> { - | ^^ + | ^ + | + = note: lifetime arguments must be provided before type arguments -error: lifetime arguments must be declared prior to type arguments - --> $DIR/suggest-move-types.rs:48:80 +error[E0747]: type provided when a lifetime was expected + --> $DIR/suggest-move-types.rs:48:71 | LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^^ ^^ + | ^ + | + = note: lifetime arguments must be provided before type arguments -error: lifetime arguments must be declared prior to type arguments +error[E0747]: lifetime provided when a type was expected --> $DIR/suggest-move-types.rs:64:56 | LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^^ ^^ + | ^^ + | + = note: type arguments must be provided before lifetime arguments -error: lifetime arguments must be declared prior to type arguments +error[E0747]: lifetime provided when a type was expected --> $DIR/suggest-move-types.rs:80:56 | LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^^ ^^ + | ^^ + | + = note: type arguments must be provided before lifetime arguments error: aborting due to 12 previous errors +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/traits/trait-object-vs-lifetime.rs b/src/test/ui/traits/trait-object-vs-lifetime.rs index e0ff734948376..e885cd2f68ac5 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.rs +++ b/src/test/ui/traits/trait-object-vs-lifetime.rs @@ -12,6 +12,6 @@ fn main() { //~^ ERROR wrong number of lifetime arguments: expected 1, found 2 //~| ERROR wrong number of type arguments: expected 1, found 0 let _: S; - //~^ ERROR lifetime arguments must be declared prior to type arguments + //~^ ERROR type provided when a lifetime was expected //~| ERROR at least one trait is required for an object type } diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr index be1958770a426..04529fb8cfab3 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr @@ -1,9 +1,3 @@ -error: lifetime arguments must be declared prior to type arguments - --> $DIR/trait-object-vs-lifetime.rs:14:29 - | -LL | let _: S; - | ^^^^^^^ - error[E0224]: at least one trait is required for an object type --> $DIR/trait-object-vs-lifetime.rs:9:23 | @@ -28,6 +22,15 @@ error[E0224]: at least one trait is required for an object type LL | let _: S; | ^^^^^^^^^^^^^ +error[E0747]: type provided when a lifetime was expected + --> $DIR/trait-object-vs-lifetime.rs:14:14 + | +LL | let _: S; + | ^^^^^^^^^^^^^ + | + = note: lifetime arguments must be provided before type arguments + error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0107, E0747. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 86c7c52b27166..eb6cc832fb417 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -19,19 +19,24 @@ static TEST5: (_, _) = (1, 2); fn test6(_: _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures fn test6_b(_: _, _: T) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures fn test6_c(_: _, _: (T, K, L, A, B)) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures fn test7(x: _) { let _x: usize = x; } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures fn test8(_f: fn() -> _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures //~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures struct Test9; @@ -41,6 +46,7 @@ impl Test9 { fn test10(&self, _x : _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } fn test11(x: &usize) -> &_ { @@ -59,12 +65,16 @@ impl Clone for Test9 { fn clone_from(&mut self, other: _) { *self = Test9; } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } struct Test10 { a: _, //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures b: (_, _), + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } pub fn main() { @@ -92,13 +102,16 @@ pub fn main() { fn fn_test6(_: _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn fn_test7(x: _) { let _x: usize = x; } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn fn_test8(_f: fn() -> _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures //~| ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures struct FnTest9; @@ -108,6 +121,7 @@ pub fn main() { fn fn_test10(&self, _x : _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } impl Clone for FnTest9 { @@ -116,12 +130,16 @@ pub fn main() { fn clone_from(&mut self, other: _) { *self = FnTest9; } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } struct FnTest10 { a: _, //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures b: (_, _), + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } fn fn_test11(_: _) -> (_, _) { panic!() } @@ -138,28 +156,40 @@ pub fn main() { trait T { fn method_test1(&self, x: _); //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn method_test2(&self, x: _) -> _; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn method_test3(&self) -> _; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn assoc_fn_test1(x: _); //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn assoc_fn_test2(x: _) -> _; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures fn assoc_fn_test3() -> _; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR the type placeholder `_` is not allowed within types on item signatures } struct BadStruct<_>(_); //~^ ERROR expected identifier, found reserved identifier `_` //~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures trait BadTrait<_> {} //~^ ERROR expected identifier, found reserved identifier `_` impl BadTrait<_> for BadStruct<_> {} //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures fn impl_trait() -> impl BadTrait<_> { //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures unimplemented!() } @@ -168,18 +198,22 @@ struct BadStruct1<_, _>(_); //~| ERROR expected identifier, found reserved identifier `_` //~| ERROR the name `_` is already used //~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures struct BadStruct2<_, T>(_, T); //~^ ERROR expected identifier, found reserved identifier `_` //~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures type X = Box<_>; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures struct Struct; trait Trait {} impl Trait for Struct {} type Y = impl Trait<_>; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures fn foo() -> Y { Struct } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 95e8f94c6f3e7..a8fdd66ee3753 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:153:18 + --> $DIR/typeck_type_placeholder_item.rs:179:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:156:16 + --> $DIR/typeck_type_placeholder_item.rs:183:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:166:19 + --> $DIR/typeck_type_placeholder_item.rs:196:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:166:22 + --> $DIR/typeck_type_placeholder_item.rs:196:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:171:19 + --> $DIR/typeck_type_placeholder_item.rs:202:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:166:22 + --> $DIR/typeck_type_placeholder_item.rs:196:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -79,6 +79,12 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa LL | static TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:20:13 + | +LL | fn test6(_: _) { } + | ^ not allowed in type signatures + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:20:13 | @@ -91,7 +97,13 @@ LL | fn test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:23:18 + --> $DIR/typeck_type_placeholder_item.rs:24:18 + | +LL | fn test6_b(_: _, _: T) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:24:18 | LL | fn test6_b(_: _, _: T) { } | ^ not allowed in type signatures @@ -102,7 +114,13 @@ LL | fn test6_b(_: K, _: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:26:30 + --> $DIR/typeck_type_placeholder_item.rs:28:30 + | +LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:28:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } | ^ not allowed in type signatures @@ -113,7 +131,13 @@ LL | fn test6_c(_: C, _: (T, K, L, A, B)) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:29:13 + --> $DIR/typeck_type_placeholder_item.rs:32:13 + | +LL | fn test7(x: _) { let _x: usize = x; } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:32:13 | LL | fn test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -124,13 +148,19 @@ LL | fn test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:32:22 + --> $DIR/typeck_type_placeholder_item.rs:36:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:32:22 + --> $DIR/typeck_type_placeholder_item.rs:36:22 + | +LL | fn test8(_f: fn() -> _) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:36:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -141,7 +171,61 @@ LL | fn test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:46:26 + --> $DIR/typeck_type_placeholder_item.rs:72:8 + | +LL | a: _, + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:75:9 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:75:12 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:137:12 + | +LL | a: _, + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:140:13 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:140:16 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:179:21 + | +LL | struct BadStruct<_>(_); + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:196:25 + | +LL | struct BadStruct1<_, _>(_); + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:202:25 + | +LL | struct BadStruct2<_, T>(_, T); + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:52:26 | LL | fn test11(x: &usize) -> &_ { | -^ @@ -150,7 +234,7 @@ LL | fn test11(x: &usize) -> &_ { | help: replace with the correct return type: `&&usize` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:51:52 + --> $DIR/typeck_type_placeholder_item.rs:57:52 | LL | unsafe fn test12(x: *const usize) -> *const *const _ { | --------------^ @@ -159,11 +243,11 @@ LL | unsafe fn test12(x: *const usize) -> *const *const _ { | help: replace with the correct return type: `*const *const usize` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:65:8 + --> $DIR/typeck_type_placeholder_item.rs:72:8 | LL | a: _, | ^ not allowed in type signatures -LL | +... LL | b: (_, _), | ^ ^ not allowed in type signatures | | @@ -174,17 +258,18 @@ help: use type parameters instead LL | struct Test10 { LL | a: T, LL | +LL | LL | b: (T, T), | error: missing type for `static` item - --> $DIR/typeck_type_placeholder_item.rs:71:12 + --> $DIR/typeck_type_placeholder_item.rs:81:12 | LL | static A = 42; | ^ help: provide a type for the item: `A: i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:73:15 + --> $DIR/typeck_type_placeholder_item.rs:83:15 | LL | static B: _ = 42; | ^ @@ -193,13 +278,13 @@ LL | static B: _ = 42; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:75:15 + --> $DIR/typeck_type_placeholder_item.rs:85:15 | LL | static C: Option<_> = Some(42); | ^^^^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:78:21 + --> $DIR/typeck_type_placeholder_item.rs:88:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -208,7 +293,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:81:23 + --> $DIR/typeck_type_placeholder_item.rs:91:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -218,7 +303,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:84:22 + --> $DIR/typeck_type_placeholder_item.rs:94:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -227,7 +312,7 @@ LL | static FN_TEST3: _ = "test"; | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:87:22 + --> $DIR/typeck_type_placeholder_item.rs:97:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -236,13 +321,19 @@ LL | static FN_TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:90:22 + --> $DIR/typeck_type_placeholder_item.rs:100:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:93:20 + --> $DIR/typeck_type_placeholder_item.rs:103:20 + | +LL | fn fn_test6(_: _) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:103:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -253,7 +344,13 @@ LL | fn fn_test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:96:20 + --> $DIR/typeck_type_placeholder_item.rs:107:20 + | +LL | fn fn_test7(x: _) { let _x: usize = x; } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:107:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -264,13 +361,19 @@ LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:99:29 + --> $DIR/typeck_type_placeholder_item.rs:111:29 + | +LL | fn fn_test8(_f: fn() -> _) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:111:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:99:29 + --> $DIR/typeck_type_placeholder_item.rs:111:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -281,11 +384,11 @@ LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:122:12 + --> $DIR/typeck_type_placeholder_item.rs:137:12 | LL | a: _, | ^ not allowed in type signatures -LL | +... LL | b: (_, _), | ^ ^ not allowed in type signatures | | @@ -296,17 +399,18 @@ help: use type parameters instead LL | struct FnTest10 { LL | a: T, LL | +LL | LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:127:18 + --> $DIR/typeck_type_placeholder_item.rs:145:18 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:127:28 + --> $DIR/typeck_type_placeholder_item.rs:145:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures @@ -314,7 +418,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:131:30 + --> $DIR/typeck_type_placeholder_item.rs:149:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -324,7 +428,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:134:33 + --> $DIR/typeck_type_placeholder_item.rs:152:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -333,7 +437,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:153:21 + --> $DIR/typeck_type_placeholder_item.rs:179:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -344,7 +448,19 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:158:15 + --> $DIR/typeck_type_placeholder_item.rs:185:32 + | +LL | impl BadTrait<_> for BadStruct<_> {} + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:185:15 + | +LL | impl BadTrait<_> for BadStruct<_> {} + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:185:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -357,13 +473,13 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:161:34 + --> $DIR/typeck_type_placeholder_item.rs:190:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:166:25 + --> $DIR/typeck_type_placeholder_item.rs:196:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -374,7 +490,7 @@ LL | struct BadStruct1(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:171:25 + --> $DIR/typeck_type_placeholder_item.rs:202:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -385,13 +501,25 @@ LL | struct BadStruct2(K, T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:175:14 + --> $DIR/typeck_type_placeholder_item.rs:207:14 | LL | type X = Box<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:42:27 + --> $DIR/typeck_type_placeholder_item.rs:207:14 + | +LL | type X = Box<_>; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:47:27 + | +LL | fn test10(&self, _x : _) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:47:27 | LL | fn test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -402,7 +530,13 @@ LL | fn test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:139:31 + --> $DIR/typeck_type_placeholder_item.rs:157:31 + | +LL | fn method_test1(&self, x: _); + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:157:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -413,7 +547,19 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:141:31 + --> $DIR/typeck_type_placeholder_item.rs:160:37 + | +LL | fn method_test2(&self, x: _) -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:160:31 + | +LL | fn method_test2(&self, x: _) -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:160:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -426,7 +572,13 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:143:31 + --> $DIR/typeck_type_placeholder_item.rs:164:31 + | +LL | fn method_test3(&self) -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:164:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -437,7 +589,13 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:145:26 + --> $DIR/typeck_type_placeholder_item.rs:167:26 + | +LL | fn assoc_fn_test1(x: _); + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:167:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -448,7 +606,19 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:147:26 + --> $DIR/typeck_type_placeholder_item.rs:170:32 + | +LL | fn assoc_fn_test2(x: _) -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:170:26 + | +LL | fn assoc_fn_test2(x: _) -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:170:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -461,7 +631,13 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:149:28 + --> $DIR/typeck_type_placeholder_item.rs:174:28 + | +LL | fn assoc_fn_test3() -> _; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:174:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -472,7 +648,13 @@ LL | fn assoc_fn_test3() -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:60:37 + --> $DIR/typeck_type_placeholder_item.rs:66:37 + | +LL | fn clone_from(&mut self, other: _) { *self = Test9; } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:66:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures @@ -483,7 +665,13 @@ LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:109:34 + --> $DIR/typeck_type_placeholder_item.rs:122:34 + | +LL | fn fn_test10(&self, _x : _) { } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:122:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -494,7 +682,13 @@ LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:117:41 + --> $DIR/typeck_type_placeholder_item.rs:131:41 + | +LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:131:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -505,13 +699,25 @@ LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:181:21 + --> $DIR/typeck_type_placeholder_item.rs:190:34 + | +LL | fn impl_trait() -> impl BadTrait<_> { + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:214:21 + | +LL | type Y = impl Trait<_>; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:214:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:39:24 + --> $DIR/typeck_type_placeholder_item.rs:44:24 | LL | fn test9(&self) -> _ { () } | ^ @@ -520,7 +726,7 @@ LL | fn test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:57:24 + --> $DIR/typeck_type_placeholder_item.rs:63:24 | LL | fn clone(&self) -> _ { Test9 } | ^ @@ -529,7 +735,7 @@ LL | fn clone(&self) -> _ { Test9 } | help: replace with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:106:31 + --> $DIR/typeck_type_placeholder_item.rs:119:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -538,7 +744,7 @@ LL | fn fn_test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:114:28 + --> $DIR/typeck_type_placeholder_item.rs:128:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -546,7 +752,7 @@ LL | fn clone(&self) -> _ { FnTest9 } | not allowed in type signatures | help: replace with the correct return type: `main::FnTest9` -error: aborting due to 58 previous errors +error: aborting due to 92 previous errors Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. diff --git a/triagebot.toml b/triagebot.toml index 7ece7f977ce2a..a174dd1e7f3fe 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1,6 +1,7 @@ [relabel] allow-unauthenticated = [ "C-*", "A-*", "E-*", "NLL-*", "O-*", "S-*", "T-*", "WG-*", "F-*", + "D-*", "requires-nightly", # I-* without I-nominated "I-*", "!I-nominated",