From b90edfcc9e1c4ff547b012c41ba2d55974794a7e Mon Sep 17 00:00:00 2001 From: Arkadiusz Piekarz Date: Fri, 6 Mar 2020 22:22:18 +0100 Subject: [PATCH 01/38] Fix sequence of Type and Trait in optin-builtin-traits in Unstable Book --- .../unstable-book/src/language-features/optin-builtin-traits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md index 5c8124c9c6b7d..1ec8b8bf8ddbd 100644 --- a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md +++ b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md @@ -16,7 +16,7 @@ has explicitly opted out via a negative impl. [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html ```rust,ignore -impl !Type for Trait +impl !Trait for Type ``` Example: From c54ce496635e0e013e14aa4be5d86c1247f9319a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Mar 2020 17:00:41 +1100 Subject: [PATCH 02/38] Remove unused `ModuleConfig::emit_lto_bc` field. --- src/librustc_codegen_ssa/back/write.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index dbc2ef6f2b05e..87764593fda50 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -74,7 +74,6 @@ pub struct ModuleConfig { pub emit_no_opt_bc: bool, pub emit_bc: bool, pub emit_bc_compressed: bool, - pub emit_lto_bc: bool, pub emit_ir: bool, pub emit_asm: bool, pub emit_obj: bool, @@ -116,7 +115,6 @@ impl ModuleConfig { emit_pre_lto_bc: false, emit_bc: false, emit_bc_compressed: false, - emit_lto_bc: false, emit_ir: false, emit_asm: false, emit_obj: false, @@ -381,7 +379,6 @@ pub fn start_async_codegen( modules_config.emit_no_opt_bc = true; modules_config.emit_pre_lto_bc = true; modules_config.emit_bc = true; - modules_config.emit_lto_bc = true; metadata_config.emit_bc = true; allocator_config.emit_bc = true; } From d8448d2291d39cf5d0b0e814ada1b6e407fa0533 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 21 Mar 2020 08:40:23 +0200 Subject: [PATCH 03/38] infer: export methods on `InferCtxt` instead of `ShallowResolver`. --- src/librustc_infer/infer/mod.rs | 61 ++++++++----------- .../traits/fulfill.rs | 6 +- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs index 391fce946bf43..bb39858122a86 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/src/librustc_infer/infer/mod.rs @@ -1347,8 +1347,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { where T: TypeFoldable<'tcx>, { - let mut r = ShallowResolver::new(self); - value.fold_with(&mut r) + value.fold_with(&mut ShallowResolver { infcx: self }) } pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { @@ -1565,22 +1564,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // variables, thus we don't need to substitute back the original values. self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span) } -} - -pub struct ShallowResolver<'a, 'tcx> { - infcx: &'a InferCtxt<'a, 'tcx>, -} - -impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { - #[inline(always)] - pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self { - ShallowResolver { infcx } - } /// If `typ` is a type variable of some kind, resolve it one level /// (but do not resolve types found in the result). If `typ` is /// not a type variable, just return it unmodified. - pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> { + // FIXME(eddyb) inline into `ShallowResolver::visit_ty`. + fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> { match typ.kind { ty::Infer(ty::TyVar(v)) => { // Not entirely obvious: if `typ` is a type variable, @@ -1594,64 +1583,62 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { // depth. // // Note: if these two lines are combined into one we get - // dynamic borrow errors on `self.infcx.inner`. - let known = self.infcx.inner.borrow_mut().type_variables.probe(v).known(); - known.map(|t| self.fold_ty(t)).unwrap_or(typ) + // dynamic borrow errors on `self.inner`. + let known = self.inner.borrow_mut().type_variables.probe(v).known(); + known.map(|t| self.shallow_resolve_ty(t)).unwrap_or(typ) } ty::Infer(ty::IntVar(v)) => self - .infcx .inner .borrow_mut() .int_unification_table .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)) + .map(|v| v.to_type(self.tcx)) .unwrap_or(typ), ty::Infer(ty::FloatVar(v)) => self - .infcx .inner .borrow_mut() .float_unification_table .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)) + .map(|v| v.to_type(self.tcx)) .unwrap_or(typ), _ => typ, } } - // `resolver.shallow_resolve_changed(ty)` is equivalent to - // `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always - // inlined, despite being large, because it has only two call sites that - // are extremely hot. + /// `infer_ty_changed(infer_ty)` is equivalent to `shallow_resolve(ty) != ty` + /// (where `ty.kind = ty::Infer(infer_ty)`), but more efficient. It's always + /// inlined, despite being large, because it has only two call sites that + /// are extremely hot. #[inline(always)] - pub fn shallow_resolve_changed(&self, infer: ty::InferTy) -> bool { - match infer { + pub fn infer_ty_changed(&self, infer_ty: ty::InferTy) -> bool { + match infer_ty { ty::TyVar(v) => { use self::type_variable::TypeVariableValue; - // If `inlined_probe` returns a `Known` value its `kind` never - // matches `infer`. - match self.infcx.inner.borrow_mut().type_variables.inlined_probe(v) { + // If `inlined_probe` returns a `Known` value, it never equals + // `ty::Infer(ty::TyVar(v))`. + match self.inner.borrow_mut().type_variables.inlined_probe(v) { TypeVariableValue::Unknown { .. } => false, TypeVariableValue::Known { .. } => true, } } ty::IntVar(v) => { - // If inlined_probe_value returns a value it's always a + // If `inlined_probe_value` returns a value it's always a // `ty::Int(_)` or `ty::UInt(_)`, which never matches a // `ty::Infer(_)`. - self.infcx.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some() + self.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some() } ty::FloatVar(v) => { - // If inlined_probe_value returns a value it's always a + // If `inlined_probe_value` returns a value it's always a // `ty::Float(_)`, which never matches a `ty::Infer(_)`. // // Not `inlined_probe_value(v)` because this call site is colder. - self.infcx.inner.borrow_mut().float_unification_table.probe_value(v).is_some() + self.inner.borrow_mut().float_unification_table.probe_value(v).is_some() } _ => unreachable!(), @@ -1659,13 +1646,17 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { } } +struct ShallowResolver<'a, 'tcx> { + infcx: &'a InferCtxt<'a, 'tcx>, +} + impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.shallow_resolve(ty) + self.infcx.shallow_resolve_ty(ty) } fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 5def77ce7324c..710f01475842f 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -1,4 +1,4 @@ -use crate::infer::{InferCtxt, ShallowResolver}; +use crate::infer::InferCtxt; use rustc::ty::error::ExpectedFound; use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable}; use rustc_data_structures::obligation_forest::ProcessResult; @@ -267,7 +267,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { // code is so hot. 1 and 0 dominate; 2+ is fairly rare. 1 => { let infer = pending_obligation.stalled_on[0]; - ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) + self.selcx.infcx().infer_ty_changed(infer) } 0 => { // In this case we haven't changed, but wish to make a change. @@ -278,7 +278,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { // form was a perf win. See #64545 for details. (|| { for &infer in &pending_obligation.stalled_on { - if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) { + if self.selcx.infcx().infer_ty_changed(infer) { return true; } } From 40f73e74d3d84a1f0ae89a933fa31078850a1b20 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 21 Mar 2020 09:27:08 +0200 Subject: [PATCH 04/38] traits/fulfill: allow `stalled_on` to track `ty::Const::Infer(_)` (unused yet). --- src/librustc_infer/infer/mod.rs | 85 ++++++++++++++++--- .../traits/fulfill.rs | 49 +++++------ 2 files changed, 96 insertions(+), 38 deletions(-) diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs index bb39858122a86..5ada9ce5df722 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/src/librustc_infer/infer/mod.rs @@ -19,7 +19,7 @@ use rustc::traits::select; use rustc::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use rustc::ty::fold::{TypeFoldable, TypeFolder}; use rustc::ty::relate::RelateResult; -use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; +use rustc::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; pub use rustc::ty::IntVarValue; use rustc::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; use rustc::ty::{ConstVid, FloatVid, IntVid, TyVid}; @@ -501,6 +501,7 @@ impl NLLRegionVariableOrigin { } } +// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`. #[derive(Copy, Clone, Debug)] pub enum FixupError<'tcx> { UnresolvedIntTy(IntVid), @@ -1608,14 +1609,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - /// `infer_ty_changed(infer_ty)` is equivalent to `shallow_resolve(ty) != ty` - /// (where `ty.kind = ty::Infer(infer_ty)`), but more efficient. It's always + /// `ty_or_const_infer_var_changed` is equivalent to one of these two: + /// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`) + /// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`) + /// + /// However, `ty_or_const_infer_var_changed` is more efficient. It's always /// inlined, despite being large, because it has only two call sites that - /// are extremely hot. + /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on` + /// inference variables), and it handles both `Ty` and `ty::Const` without + /// having to resort to storing full `GenericArg`s in `stalled_on`. #[inline(always)] - pub fn infer_ty_changed(&self, infer_ty: ty::InferTy) -> bool { - match infer_ty { - ty::TyVar(v) => { + pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool { + match infer_var { + TyOrConstInferVar::Ty(v) => { use self::type_variable::TypeVariableValue; // If `inlined_probe` returns a `Known` value, it never equals @@ -1626,22 +1632,79 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - ty::IntVar(v) => { + TyOrConstInferVar::TyInt(v) => { // If `inlined_probe_value` returns a value it's always a // `ty::Int(_)` or `ty::UInt(_)`, which never matches a // `ty::Infer(_)`. self.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some() } - ty::FloatVar(v) => { - // If `inlined_probe_value` returns a value it's always a + TyOrConstInferVar::TyFloat(v) => { + // If `probe_value` returns a value it's always a // `ty::Float(_)`, which never matches a `ty::Infer(_)`. // // Not `inlined_probe_value(v)` because this call site is colder. self.inner.borrow_mut().float_unification_table.probe_value(v).is_some() } - _ => unreachable!(), + TyOrConstInferVar::Const(v) => { + // If `probe_value` returns a `Known` value, it never equals + // `ty::ConstKind::Infer(ty::InferConst::Var(v))`. + // + // Not `inlined_probe_value(v)` because this call site is colder. + match self.inner.borrow_mut().const_unification_table.probe_value(v).val { + ConstVariableValue::Unknown { .. } => false, + ConstVariableValue::Known { .. } => true, + } + } + } + } +} + +/// Helper for `ty_or_const_infer_var_changed` (see comment on that), currently +/// used only for `traits::fulfill`'s list of `stalled_on` inference variables. +#[derive(Copy, Clone, Debug)] +pub enum TyOrConstInferVar<'tcx> { + /// Equivalent to `ty::Infer(ty::TyVar(_))`. + Ty(TyVid), + /// Equivalent to `ty::Infer(ty::IntVar(_))`. + TyInt(IntVid), + /// Equivalent to `ty::Infer(ty::FloatVar(_))`. + TyFloat(FloatVid), + + /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`. + Const(ConstVid<'tcx>), +} + +impl TyOrConstInferVar<'tcx> { + /// Tries to extract an inference variable from a type or a constant, returns `None` + /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and + /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). + pub fn maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option { + match arg.unpack() { + GenericArgKind::Type(ty) => Self::maybe_from_ty(ty), + GenericArgKind::Const(ct) => Self::maybe_from_const(ct), + GenericArgKind::Lifetime(_) => None, + } + } + + /// Tries to extract an inference variable from a type, returns `None` + /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`). + pub fn maybe_from_ty(ty: Ty<'tcx>) -> Option { + match ty.kind { + ty::Infer(ty::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)), + ty::Infer(ty::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)), + ty::Infer(ty::FloatVar(v)) => Some(TyOrConstInferVar::TyFloat(v)), + _ => None, + } + } + + /// Tries to extract an inference variable from a constant, returns `None` + /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). + pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option { + match ct.val { + ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)), + _ => None, } } } diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 710f01475842f..559718fca546d 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -1,4 +1,4 @@ -use crate::infer::InferCtxt; +use crate::infer::{InferCtxt, TyOrConstInferVar}; use rustc::ty::error::ExpectedFound; use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable}; use rustc_data_structures::obligation_forest::ProcessResult; @@ -73,7 +73,7 @@ pub struct FulfillmentContext<'tcx> { #[derive(Clone, Debug)] pub struct PendingPredicateObligation<'tcx> { pub obligation: PredicateObligation<'tcx>, - pub stalled_on: Vec, + pub stalled_on: Vec>, } // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. @@ -266,8 +266,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { // Match arms are in order of frequency, which matters because this // code is so hot. 1 and 0 dominate; 2+ is fairly rare. 1 => { - let infer = pending_obligation.stalled_on[0]; - self.selcx.infcx().infer_ty_changed(infer) + let infer_var = pending_obligation.stalled_on[0]; + self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) } 0 => { // In this case we haven't changed, but wish to make a change. @@ -277,8 +277,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { // This `for` loop was once a call to `all()`, but this lower-level // form was a perf win. See #64545 for details. (|| { - for &infer in &pending_obligation.stalled_on { - if self.selcx.infcx().infer_ty_changed(infer) { + for &infer_var in &pending_obligation.stalled_on { + if self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) { return true; } } @@ -309,13 +309,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { debug!("process_obligation: obligation = {:?} cause = {:?}", obligation, obligation.cause); - fn infer_ty(ty: Ty<'tcx>) -> ty::InferTy { - match ty.kind { - ty::Infer(infer) => infer, - _ => panic!(), - } - } - match obligation.predicate { ty::Predicate::Trait(ref data, _) => { let trait_obligation = obligation.with(data.clone()); @@ -467,7 +460,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { obligation.cause.span, ) { None => { - pending_obligation.stalled_on = vec![infer_ty(ty)]; + pending_obligation.stalled_on = + vec![TyOrConstInferVar::maybe_from_ty(ty).unwrap()]; ProcessResult::Unchanged } Some(os) => ProcessResult::Changed(mk_pending(os)), @@ -483,8 +477,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { None => { // None means that both are unresolved. pending_obligation.stalled_on = vec![ - infer_ty(subtype.skip_binder().a), - infer_ty(subtype.skip_binder().b), + TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().a).unwrap(), + TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().b).unwrap(), ]; ProcessResult::Unchanged } @@ -534,20 +528,21 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } } -/// Returns the set of type variables contained in a trait ref +/// Returns the set of type inference variables contained in a trait ref. fn trait_ref_type_vars<'a, 'tcx>( selcx: &mut SelectionContext<'a, 'tcx>, - t: ty::PolyTraitRef<'tcx>, -) -> Vec { - t.skip_binder() // ok b/c this check doesn't care about regions + trait_ref: ty::PolyTraitRef<'tcx>, +) -> Vec> { + trait_ref + .skip_binder() // ok b/c this check doesn't care about regions + // FIXME(eddyb) walk over `GenericArg` to support const infer vars. .input_types() - .map(|t| selcx.infcx().resolve_vars_if_possible(&t)) - .filter(|t| t.has_infer_types()) - .flat_map(|t| t.walk()) - .filter_map(|t| match t.kind { - ty::Infer(infer) => Some(infer), - _ => None, - }) + .map(|ty| selcx.infcx().resolve_vars_if_possible(&ty)) + // FIXME(eddyb) use `has_infer_types_or_const`. + .filter(|ty| ty.has_infer_types()) + .flat_map(|ty| ty.walk()) + // FIXME(eddyb) use `TyOrConstInferVar::maybe_from_generic_arg`. + .filter_map(TyOrConstInferVar::maybe_from_ty) .collect() } From 78c178bcda3589affb0f4ffa248398cfca08c98f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 21 Mar 2020 09:57:30 +0200 Subject: [PATCH 05/38] traits/fulfill: add a couple FIXME comments about potential optimizations. --- src/librustc_trait_selection/traits/fulfill.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 559718fca546d..9eddeba50c1ad 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -73,6 +73,9 @@ pub struct FulfillmentContext<'tcx> { #[derive(Clone, Debug)] pub struct PendingPredicateObligation<'tcx> { pub obligation: PredicateObligation<'tcx>, + // FIXME(eddyb) look into whether this could be a `SmallVec`. + // Judging by the comment in `process_obligation`, the 1-element case + // is common so this could be a `SmallVec<[TyOrConstInferVar<'tcx>; 1]>`. pub stalled_on: Vec>, } @@ -538,6 +541,8 @@ fn trait_ref_type_vars<'a, 'tcx>( // FIXME(eddyb) walk over `GenericArg` to support const infer vars. .input_types() .map(|ty| selcx.infcx().resolve_vars_if_possible(&ty)) + // FIXME(eddyb) try using `maybe_walk` to skip *all* subtrees that + // don't contain inference variables, not just the outermost level. // FIXME(eddyb) use `has_infer_types_or_const`. .filter(|ty| ty.has_infer_types()) .flat_map(|ty| ty.walk()) From 4f405119e8305b26d0ee9e857887d2720b5c5c2a Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 21 Mar 2020 22:37:51 -0400 Subject: [PATCH 06/38] Resolve worsened debug build codegen --- src/librustc_mir/transform/const_prop.rs | 9 +-- .../const_prop/control-flow-simplification.rs | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 src/test/mir-opt/const_prop/control-flow-simplification.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 8d7cafc34b356..1c6ae0918c7a1 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -324,14 +324,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) -> ConstPropagator<'mir, 'tcx> { let def_id = source.def_id(); let substs = &InternalSubsts::identity_for_item(tcx, def_id); - let mut param_env = tcx.param_env(def_id); - - // If we're evaluating inside a monomorphic function, then use `Reveal::All` because - // we want to see the same instances that codegen will see. This allows us to `resolve()` - // specializations. - if !substs.needs_subst() { - param_env = param_env.with_reveal_all(); - } + let param_env = tcx.param_env(def_id).with_reveal_all(); let span = tcx.def_span(def_id); let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ()); diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs new file mode 100644 index 0000000000000..0e9f33b15e2cc --- /dev/null +++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs @@ -0,0 +1,64 @@ +// compile-flags: -Zmir-opt-level=1 + +trait NeedsDrop:Sized{ + const NEEDS:bool=std::mem::needs_drop::(); +} + +impl NeedsDrop for This{} + +fn hello(){ + if ::NEEDS { + panic!() + } +} + +pub fn main() { + hello::<()>(); + hello::>(); +} + +// END RUST SOURCE +// START rustc.hello.ConstProp.before.mir +// let mut _0: (); +// let mut _1: bool; +// let mut _2: !; +// bb0: { +// StorageLive(_1); +// _1 = const ::NEEDS; +// switchInt(_1) -> [false: bb1, otherwise: bb2]; +// } +// bb1: { +// _0 = (); +// StorageDead(_1); +// return; +// } +// bb2: { +// StorageLive(_2); +// const std::rt::begin_panic::<&str>(const "explicit panic"); +// } +// END rustc.hello.ConstProp.before.mir +// START rustc.hello.ConstProp.after.mir +// let mut _0: (); +// let mut _1: bool; +// let mut _2: !; +// bb0: { +// StorageLive(_1); +// _1 = const false; +// switchInt(const false) -> [false: bb1, otherwise: bb2]; +// } +// bb1: { +// _0 = (); +// StorageDead(_1); +// return; +// } +// bb2: { +// StorageLive(_2); +// const std::rt::begin_panic::<&str>(const "explicit panic"); +// } +// END rustc.hello.ConstProp.after.mir +// START rustc.hello.PreCodegen.before.mir +// let mut _0: (); +// bb0: { +// return; +// } +// END rustc.hello.PreCodegen.before.mir From 61d3be8de784e7ec2642c06daa5ff95f226d65d3 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 21 Mar 2020 23:08:32 -0400 Subject: [PATCH 07/38] Use Reveal::All in MIR inliner --- src/librustc_mir/transform/inline.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 52c7225a850fb..16c32e138fdf0 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -3,8 +3,8 @@ use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::mir::visit::*; use rustc::mir::*; -use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::subst::{Subst, SubstsRef}; +use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_attr as attr; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet; @@ -66,14 +66,7 @@ impl Inliner<'tcx> { let mut callsites = VecDeque::new(); - let mut param_env = self.tcx.param_env(self.source.def_id()); - - let substs = &InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); - - // For monomorphic functions, we can use `Reveal::All` to resolve specialized instances. - if !substs.needs_subst() { - param_env = param_env.with_reveal_all(); - } + let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all(); // Only do inlining into fn bodies. let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap(); From 645fedd183a341b5ab5553d4d35ce9140276371f Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 22 Mar 2020 22:29:54 +0100 Subject: [PATCH 08/38] correctly handle const params in type_of --- src/librustc_hir/def.rs | 1 + src/librustc_typeck/collect/type_of.rs | 32 ++++++++++--------- src/librustc_typeck/lib.rs | 1 + .../issues/issue70273-assoc-fn.rs | 17 ++++++++++ .../issues/issue70273-assoc-fn.stderr | 8 +++++ .../ui/const-generics/type_of_anon_const.rs | 21 ++++++++++++ .../const-generics/type_of_anon_const.stderr | 8 +++++ 7 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue70273-assoc-fn.rs create mode 100644 src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr create mode 100644 src/test/ui/const-generics/type_of_anon_const.rs create mode 100644 src/test/ui/const-generics/type_of_anon_const.stderr diff --git a/src/librustc_hir/def.rs b/src/librustc_hir/def.rs index 696aa5c6f7dfe..3334cc32a52f7 100644 --- a/src/librustc_hir/def.rs +++ b/src/librustc_hir/def.rs @@ -159,6 +159,7 @@ impl DefKind { } } +/// The resolution of a path or export. #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(HashStable_Generic)] pub enum Res { diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 55642dfb4557b..eec87f3e3b08b 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -235,29 +235,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { }; if let Some(path) = path { - let arg_index = path + // We've encountered an `AnonConst` in some path, so we need to + // figure out which generic parameter it corresponds to and return + // the relevant type. + + let (arg_index, segment) = path .segments .iter() - .filter_map(|seg| seg.args.as_ref()) - .map(|generic_args| generic_args.args) - .find_map(|args| { + .filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg))) + .find_map(|(args, seg)| { args.iter() .filter(|arg| arg.is_const()) .enumerate() .filter(|(_, arg)| arg.id() == hir_id) - .map(|(index, _)| index) + .map(|(index, _)| (index, seg)) .next() }) .unwrap_or_else(|| { bug!("no arg matching AnonConst in path"); }); - // We've encountered an `AnonConst` in some path, so we need to - // figure out which generic parameter it corresponds to and return - // the relevant type. - let generics = match path.res { - Res::Def(DefKind::Ctor(..), def_id) - | Res::Def(DefKind::AssocTy, def_id) => { + // try to use the segment resolution if it is valid, otherwise we + // default to the path resolution. + let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); + let generics = match res { + Res::Def(DefKind::Ctor(..) | DefKind::AssocTy, def_id) => { tcx.generics_of(tcx.parent(def_id).unwrap()) } Res::Def(_, def_id) => tcx.generics_of(def_id), @@ -265,8 +267,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { tcx.sess.delay_span_bug( DUMMY_SP, &format!( - "unexpected const parent path def, parent: {:?}, def: {:?}", - parent_node, res + "unexpected anon const res {:?} in path: {:?}", + res, path, ), ); return tcx.types.err; @@ -291,8 +293,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { tcx.sess.delay_span_bug( DUMMY_SP, &format!( - "missing generic parameter for `AnonConst`, parent {:?}", - parent_node + "missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}", + parent_node, res ), ); tcx.types.err diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index e487e0d265c3e..fd854c750184e 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -62,6 +62,7 @@ This API is completely unstable and subject to change. #![feature(crate_visibility_modifier)] #![feature(in_band_lifetimes)] #![feature(nll)] +#![feature(or_patterns)] #![feature(try_blocks)] #![feature(never_type)] #![feature(slice_partition_dedup)] diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs new file mode 100644 index 0000000000000..a192ddea9c6ab --- /dev/null +++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs @@ -0,0 +1,17 @@ +// check-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +trait T { + fn f(); +} +struct S; + +impl T<0usize> for S { + fn f() {} +} + +fn main() { + let _err = >::f(); +} diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr b/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr new file mode 100644 index 0000000000000..64007ade0f2ed --- /dev/null +++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue70273-assoc-fn.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + diff --git a/src/test/ui/const-generics/type_of_anon_const.rs b/src/test/ui/const-generics/type_of_anon_const.rs new file mode 100644 index 0000000000000..776084b77a577 --- /dev/null +++ b/src/test/ui/const-generics/type_of_anon_const.rs @@ -0,0 +1,21 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +trait T { + fn l() -> usize; + fn r() -> bool; +} + +struct S; + +impl T for S { + fn l() -> usize { N } + fn r() -> bool { M } +} + +fn main() { + assert_eq!(>::l::(), 123); + assert!(>::r::()); +} diff --git a/src/test/ui/const-generics/type_of_anon_const.stderr b/src/test/ui/const-generics/type_of_anon_const.stderr new file mode 100644 index 0000000000000..495d34ce09b81 --- /dev/null +++ b/src/test/ui/const-generics/type_of_anon_const.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/type_of_anon_const.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From d156bf658fd2478ee83d8e86e8c7c46093b74ec8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Mar 2020 12:09:24 +1100 Subject: [PATCH 09/38] Remove some local variables. I find the code easier to read if the values in `config` are all used directly, rather than a mix of `config` values and local variables. It will also faciliate some of the following commits. Also, use `config.bitcode_needed()` in one place. --- src/librustc_codegen_llvm/back/write.rs | 32 ++++++++++--------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 0c243128104e7..9ffccad4b932d 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -634,30 +634,24 @@ pub(crate) unsafe fn codegen( f(cpm) } - // If we don't have the integrated assembler, then we need to emit asm - // from LLVM and use `gcc` to create the object file. - let asm_to_obj = config.emit_obj && config.no_integrated_as; - - // Change what we write and cleanup based on whether obj files are - // just llvm bitcode. In that case write bitcode, and possibly - // delete the bitcode if it wasn't requested. Don't generate the - // machine code, instead copy the .o file from the .bc - let write_bc = config.emit_bc || config.obj_is_bitcode; - let rm_bc = !config.emit_bc && config.obj_is_bitcode; - let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm_to_obj; - let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode; + // Two things to note: + // - If object files are just LLVM bitcode we write bitcode, copy it to + // the .o file, and delete the bitcode if it wasn't otherwise + // requested. + // - If we don't have the integrated assembler then we need to emit + // asm from LLVM and use `gcc` to create the object file. let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); - if write_bc || config.emit_bc_compressed || config.embed_bitcode { + if config.bitcode_needed() { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]); let thin = ThinBuffer::new(llmod); let data = thin.data(); - if write_bc { + if config.emit_bc || config.obj_is_bitcode { let _timer = cgcx.prof.generic_activity_with_arg( "LLVM_module_codegen_emit_bitcode", &module.name[..], @@ -740,7 +734,7 @@ pub(crate) unsafe fn codegen( })?; } - if config.emit_asm || asm_to_obj { + if config.emit_asm || (config.emit_obj && config.no_integrated_as) { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); @@ -762,7 +756,7 @@ pub(crate) unsafe fn codegen( })?; } - if write_obj { + if config.emit_obj && !config.obj_is_bitcode && !config.no_integrated_as { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); @@ -776,7 +770,7 @@ pub(crate) unsafe fn codegen( llvm::FileType::ObjectFile, ) })?; - } else if asm_to_obj { + } else if config.emit_obj && config.no_integrated_as { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); @@ -789,14 +783,14 @@ pub(crate) unsafe fn codegen( } } - if copy_bc_to_obj { + if config.emit_obj && config.obj_is_bitcode { debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); if let Err(e) = link_or_copy(&bc_out, &obj_out) { diag_handler.err(&format!("failed to copy bitcode to object file: {}", e)); } } - if rm_bc { + if !config.emit_bc && config.obj_is_bitcode { debug!("removing_bitcode {:?}", bc_out); if let Err(e) = fs::remove_file(&bc_out) { diag_handler.err(&format!("failed to remove bitcode: {}", e)); From 47c8f3f56babf7830c481cb679f81466c351db7b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Mar 2020 12:34:39 +1100 Subject: [PATCH 10/38] Combine `ModuleConfig::embed_bitcode{,_marker}`. Because the `(true, true)` combination isn't valid. --- src/librustc_codegen_llvm/back/write.rs | 6 ++--- src/librustc_codegen_ssa/back/write.rs | 36 +++++++++++++++---------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 9ffccad4b932d..828c4a4bdf4ee 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -18,7 +18,7 @@ use rustc::bug; use rustc::session::config::{self, Lto, OutputType, Passes, Sanitizer, SwitchWithOptPath}; use rustc::session::Session; use rustc::ty::TyCtxt; -use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, ModuleConfig}; +use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION}; use rustc_data_structures::small_c_str::SmallCStr; @@ -662,7 +662,7 @@ pub(crate) unsafe fn codegen( } } - if config.embed_bitcode { + if config.embed_bitcode == EmbedBitcode::Full { let _timer = cgcx.prof.generic_activity_with_arg( "LLVM_module_codegen_embed_bitcode", &module.name[..], @@ -682,7 +682,7 @@ pub(crate) unsafe fn codegen( diag_handler.err(&msg); } } - } else if config.embed_bitcode_marker { + } else if config.embed_bitcode == EmbedBitcode::Marker { embed_bitcode(cgcx, llcx, llmod, None); } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 87764593fda50..54d30487c79b1 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -51,6 +51,14 @@ use std::thread; const PRE_LTO_BC_EXT: &str = "pre-lto.bc"; +/// The kind of bitcode to embed in object files. +#[derive(PartialEq)] +pub enum EmbedBitcode { + None, + Marker, + Full, +} + /// Module-specific configuration for `optimize_and_codegen`. pub struct ModuleConfig { /// Names of additional optimization passes to run. @@ -93,8 +101,7 @@ pub struct ModuleConfig { // emscripten's ecc compiler, when used as the linker. pub obj_is_bitcode: bool, pub no_integrated_as: bool, - pub embed_bitcode: bool, - pub embed_bitcode_marker: bool, + pub embed_bitcode: EmbedBitcode, } impl ModuleConfig { @@ -119,8 +126,7 @@ impl ModuleConfig { emit_asm: false, emit_obj: false, obj_is_bitcode: false, - embed_bitcode: false, - embed_bitcode_marker: false, + embed_bitcode: EmbedBitcode::None, no_integrated_as: false, verify_llvm_ir: false, @@ -143,16 +149,15 @@ impl ModuleConfig { self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager; self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled(); - let embed_bitcode = - sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode; - if embed_bitcode { - match sess.opts.optimize { - config::OptLevel::No | config::OptLevel::Less => { - self.embed_bitcode_marker = embed_bitcode; + self.embed_bitcode = + if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode { + match sess.opts.optimize { + config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker, + _ => EmbedBitcode::Full, } - _ => self.embed_bitcode = embed_bitcode, - } - } + } else { + EmbedBitcode::None + }; // Copy what clang does by turning on loop vectorization at O2 and // slp vectorization at O3. Otherwise configure other optimization aspects @@ -188,7 +193,10 @@ impl ModuleConfig { } pub fn bitcode_needed(&self) -> bool { - self.emit_bc || self.obj_is_bitcode || self.emit_bc_compressed || self.embed_bitcode + self.emit_bc + || self.obj_is_bitcode + || self.emit_bc_compressed + || self.embed_bitcode == EmbedBitcode::Full } } From e4b36baf54f0799c744b3f30f5be425ef050ce8c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Mar 2020 12:46:27 +1100 Subject: [PATCH 11/38] Remove an unnecessary block scope. --- src/librustc_codegen_llvm/back/write.rs | 168 +++++++++++------------- 1 file changed, 79 insertions(+), 89 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 828c4a4bdf4ee..2826de1e490d2 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -686,100 +686,90 @@ pub(crate) unsafe fn codegen( embed_bitcode(cgcx, llcx, llmod, None); } - { - if config.emit_ir { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]); - let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); - let out_c = path_to_c_string(&out); - - extern "C" fn demangle_callback( - input_ptr: *const c_char, - input_len: size_t, - output_ptr: *mut c_char, - output_len: size_t, - ) -> size_t { - let input = unsafe { - slice::from_raw_parts(input_ptr as *const u8, input_len as usize) - }; - - let input = match str::from_utf8(input) { - Ok(s) => s, - Err(_) => return 0, - }; - - let output = unsafe { - slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize) - }; - let mut cursor = io::Cursor::new(output); - - let demangled = match rustc_demangle::try_demangle(input) { - Ok(d) => d, - Err(_) => return 0, - }; - - if write!(cursor, "{:#}", demangled).is_err() { - // Possible only if provided buffer is not big enough - return 0; - } - - cursor.position() as size_t + if config.emit_ir { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]); + let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); + let out_c = path_to_c_string(&out); + + extern "C" fn demangle_callback( + input_ptr: *const c_char, + input_len: size_t, + output_ptr: *mut c_char, + output_len: size_t, + ) -> size_t { + let input = + unsafe { slice::from_raw_parts(input_ptr as *const u8, input_len as usize) }; + + let input = match str::from_utf8(input) { + Ok(s) => s, + Err(_) => return 0, + }; + + let output = unsafe { + slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize) + }; + let mut cursor = io::Cursor::new(output); + + let demangled = match rustc_demangle::try_demangle(input) { + Ok(d) => d, + Err(_) => return 0, + }; + + if write!(cursor, "{:#}", demangled).is_err() { + // Possible only if provided buffer is not big enough + return 0; } - let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback); - result.into_result().map_err(|()| { - let msg = format!("failed to write LLVM IR to {}", out.display()); - llvm_err(diag_handler, &msg) - })?; + cursor.position() as size_t } - if config.emit_asm || (config.emit_obj && config.no_integrated_as) { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); - let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - - // We can't use the same module for asm and binary output, because that triggers - // various errors like invalid IR or broken binaries, so we might have to clone the - // module to produce the asm output - let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod }; - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file( - diag_handler, - tm, - cpm, - llmod, - &path, - llvm::FileType::AssemblyFile, - ) - })?; - } + let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback); + result.into_result().map_err(|()| { + let msg = format!("failed to write LLVM IR to {}", out.display()); + llvm_err(diag_handler, &msg) + })?; + } - if config.emit_obj && !config.obj_is_bitcode && !config.no_integrated_as { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file( - diag_handler, - tm, - cpm, - llmod, - &obj_out, - llvm::FileType::ObjectFile, - ) - })?; - } else if config.emit_obj && config.no_integrated_as { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); - let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - run_assembler(cgcx, diag_handler, &assembly, &obj_out); - - if !config.emit_asm && !cgcx.save_temps { - drop(fs::remove_file(&assembly)); - } + if config.emit_asm || (config.emit_obj && config.no_integrated_as) { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); + let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); + + // We can't use the same module for asm and binary output, because that triggers + // various errors like invalid IR or broken binaries, so we might have to clone the + // module to produce the asm output + let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod }; + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) + })?; + } + + if config.emit_obj && !config.obj_is_bitcode && !config.no_integrated_as { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file( + diag_handler, + tm, + cpm, + llmod, + &obj_out, + llvm::FileType::ObjectFile, + ) + })?; + } else if config.emit_obj && config.no_integrated_as { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); + let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); + run_assembler(cgcx, diag_handler, &assembly, &obj_out); + + if !config.emit_asm && !cgcx.save_temps { + drop(fs::remove_file(&assembly)); } } From f8261b496d5c94bd8d6ad5dcce0cb5cc2e0e3fe5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 21 Mar 2020 09:15:07 +1100 Subject: [PATCH 12/38] Factor out a repeated `config.obj_is_bitcode` test. --- src/librustc_codegen_llvm/back/write.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 2826de1e490d2..1df8ee6746d89 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -773,17 +773,19 @@ pub(crate) unsafe fn codegen( } } - if config.emit_obj && config.obj_is_bitcode { - debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); - if let Err(e) = link_or_copy(&bc_out, &obj_out) { - diag_handler.err(&format!("failed to copy bitcode to object file: {}", e)); + if config.obj_is_bitcode { + if config.emit_obj { + debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); + if let Err(e) = link_or_copy(&bc_out, &obj_out) { + diag_handler.err(&format!("failed to copy bitcode to object file: {}", e)); + } } - } - if !config.emit_bc && config.obj_is_bitcode { - debug!("removing_bitcode {:?}", bc_out); - if let Err(e) = fs::remove_file(&bc_out) { - diag_handler.err(&format!("failed to remove bitcode: {}", e)); + if !config.emit_bc { + debug!("removing_bitcode {:?}", bc_out); + if let Err(e) = fs::remove_file(&bc_out) { + diag_handler.err(&format!("failed to remove bitcode: {}", e)); + } } } From a147cd070e4b8824aafc7fa9f20d6fdf34eb3bf9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 21 Mar 2020 09:19:21 +1100 Subject: [PATCH 13/38] Introduce a local variable `config_emit_normal_obj`. This adds a missing `!config.obj_is_bitcode` condition to two places that should have it. As a result, when `obj_is_bitcode` and `no_integrated_as` are both true, the compiler will no longer unnecessarily emit asm, convert it to an object file, and then overwrite that object file with bitcode. --- src/librustc_codegen_llvm/back/write.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 1df8ee6746d89..d2d3eb597966c 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -732,7 +732,9 @@ pub(crate) unsafe fn codegen( })?; } - if config.emit_asm || (config.emit_obj && config.no_integrated_as) { + let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode; + + if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); @@ -747,7 +749,7 @@ pub(crate) unsafe fn codegen( })?; } - if config.emit_obj && !config.obj_is_bitcode && !config.no_integrated_as { + if config_emit_normal_obj && !config.no_integrated_as { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); @@ -761,7 +763,7 @@ pub(crate) unsafe fn codegen( llvm::FileType::ObjectFile, ) })?; - } else if config.emit_obj && config.no_integrated_as { + } else if config_emit_normal_obj && config.no_integrated_as { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); From ca0f9975199b5fbe177dc61d493d411f67c66880 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 21 Mar 2020 09:25:20 +1100 Subject: [PATCH 14/38] Factor out a repeated `config.no_integrated_as` test. --- src/librustc_codegen_llvm/back/write.rs | 48 +++++++++++++------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index d2d3eb597966c..62ac2381e8cd8 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -749,29 +749,31 @@ pub(crate) unsafe fn codegen( })?; } - if config_emit_normal_obj && !config.no_integrated_as { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file( - diag_handler, - tm, - cpm, - llmod, - &obj_out, - llvm::FileType::ObjectFile, - ) - })?; - } else if config_emit_normal_obj && config.no_integrated_as { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); - let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - run_assembler(cgcx, diag_handler, &assembly, &obj_out); - - if !config.emit_asm && !cgcx.save_temps { - drop(fs::remove_file(&assembly)); + if config_emit_normal_obj { + if !config.no_integrated_as { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file( + diag_handler, + tm, + cpm, + llmod, + &obj_out, + llvm::FileType::ObjectFile, + ) + })?; + } else { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); + let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); + run_assembler(cgcx, diag_handler, &assembly, &obj_out); + + if !config.emit_asm && !cgcx.save_temps { + drop(fs::remove_file(&assembly)); + } } } From 96e2d03d4b527b3870bb8cc4fd6dd41e57be109d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 17 Mar 2020 11:45:02 -0400 Subject: [PATCH 15/38] Store idents for `DefPathData` into crate metadata Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for #68686, since throwing away a `Span` means that we lose hygiene information. --- src/librustc_metadata/rmeta/decoder.rs | 56 ++++++++++--------- .../rmeta/decoder/cstore_impl.rs | 6 +- src/librustc_metadata/rmeta/encoder.rs | 23 +++++--- src/librustc_metadata/rmeta/mod.rs | 1 + src/librustc_resolve/build_reduced_graph.rs | 5 +- src/test/ui/copy-a-resource.stderr | 8 +++ .../derives/derive-assoc-type-not-impl.stderr | 8 +++ src/test/ui/error-codes/E0004-2.stderr | 8 +++ src/test/ui/error-codes/E0005.stderr | 5 ++ src/test/ui/error-codes/E0297.stderr | 5 ++ .../feature-gate-exhaustive-patterns.stderr | 5 ++ .../generic-associated-types/iterable.stderr | 10 ++++ .../no-method-suggested-traits.stderr | 10 ++++ src/test/ui/issues/issue-2823.stderr | 8 +++ src/test/ui/issues/issue-69725.stderr | 8 +++ src/test/ui/non-copyable-void.stderr | 8 +++ src/test/ui/noncopyable-class.stderr | 8 +++ .../usefulness/match-arm-statics-2.stderr | 8 +++ .../usefulness/match-privately-empty.stderr | 5 ++ .../usefulness/non-exhaustive-match.stderr | 5 ++ ...recursive-types-are-not-uninhabited.stderr | 5 ++ src/test/ui/resolve/issue-3907-2.stderr | 5 +- .../uninhabited/match.stderr | 7 +++ .../match_with_exhaustive_patterns.stderr | 7 +++ .../uninhabited-matches-feature-gated.stderr | 15 +++++ src/test/ui/union/union-derive-clone.stderr | 8 +++ src/test/ui/unique-object-noncopyable.stderr | 8 +++ src/test/ui/unique-pinned-nocopy.stderr | 8 +++ 28 files changed, 224 insertions(+), 39 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 2bf74fe272ec9..754bae0ddb813 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -509,14 +509,6 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { } } -impl SpecializedDecoder for DecodeContext<'_, '_> { - fn specialized_decode(&mut self) -> Result { - // FIXME(jseyfried): intercrate hygiene - - Ok(Ident::with_dummy_span(Symbol::decode(self)?)) - } -} - impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result { Fingerprint::decode_opaque(&mut self.opaque) @@ -663,15 +655,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { &self.raw_proc_macros.unwrap()[pos] } - fn item_name(&self, item_index: DefIndex) -> Symbol { + fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident { if !self.is_proc_macro(item_index) { - self.def_key(item_index) + let name = self + .def_key(item_index) .disambiguated_data .data .get_opt_name() - .expect("no name in item_name") + .expect("no name in item_ident"); + let span = self + .root + .per_def + .ident_span + .get(self, item_index) + .map(|data| data.decode((self, sess))) + .unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index)); + Ident::new(name, span) } else { - Symbol::intern(self.raw_proc_macro(item_index).name()) + Ident::new( + Symbol::intern(self.raw_proc_macro(item_index).name()), + self.get_span(item_index, sess), + ) } } @@ -750,6 +754,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { kind: &EntryKind, index: DefIndex, parent_did: DefId, + sess: &Session, ) -> ty::VariantDef { let data = match kind { EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => { @@ -771,7 +776,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ty::VariantDef::new( tcx, - Ident::with_dummy_span(self.item_name(index)), + self.item_ident(index, sess), variant_did, ctor_did, data.discr, @@ -783,7 +788,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .decode(self) .map(|index| ty::FieldDef { did: self.local_def_id(index), - ident: Ident::with_dummy_span(self.item_name(index)), + ident: self.item_ident(index, sess), vis: self.get_visibility(index), }) .collect(), @@ -812,10 +817,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .get(self, item_id) .unwrap_or(Lazy::empty()) .decode(self) - .map(|index| self.get_variant(tcx, &self.kind(index), index, did)) + .map(|index| self.get_variant(tcx, &self.kind(index), index, did, tcx.sess)) .collect() } else { - std::iter::once(self.get_variant(tcx, &kind, item_id, did)).collect() + std::iter::once(self.get_variant(tcx, &kind, item_id, did, tcx.sess)).collect() }; tcx.alloc_adt_def(did, adt_kind, variants, repr) @@ -1007,7 +1012,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { if let Some(kind) = self.def_kind(child_index) { callback(Export { res: Res::Def(kind, self.local_def_id(child_index)), - ident: Ident::with_dummy_span(self.item_name(child_index)), + ident: self.item_ident(child_index, sess), vis: self.get_visibility(child_index), span: self .root @@ -1028,10 +1033,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let def_key = self.def_key(child_index); let span = self.get_span(child_index, sess); - if let (Some(kind), Some(name)) = - (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) - { - let ident = Ident::with_dummy_span(name); + if let (Some(kind), true) = ( + self.def_kind(child_index), + def_key.disambiguated_data.data.get_opt_name().is_some(), + ) { + let ident = self.item_ident(child_index, sess); let vis = self.get_visibility(child_index); let def_id = self.local_def_id(child_index); let res = Res::Def(kind, def_id); @@ -1138,10 +1144,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem { + fn get_associated_item(&self, id: DefIndex, sess: &Session) -> ty::AssocItem { let def_key = self.def_key(id); let parent = self.local_def_id(def_key.parent.unwrap()); - let name = def_key.disambiguated_data.data.get_opt_name().unwrap(); + let ident = self.item_ident(id, sess); let (kind, container, has_self) = match self.kind(id) { EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false), @@ -1155,7 +1161,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }; ty::AssocItem { - ident: Ident::with_dummy_span(name), + ident, kind, vis: self.get_visibility(id), defaultness: container.defaultness(), @@ -1219,7 +1225,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .get(self, id) .unwrap_or(Lazy::empty()) .decode(self) - .map(|index| respan(self.get_span(index, sess), self.item_name(index))) + .map(|index| respan(self.get_span(index, sess), self.item_ident(index, sess).name)) .collect() } diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index 1b15646ff9b52..c2ea981caa90d 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -110,7 +110,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, |child| result.push(child.res.def_id()), tcx.sess); tcx.arena.alloc_slice(&result) } - associated_item => { cdata.get_associated_item(def_id.index) } + associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } impl_polarity => { cdata.get_impl_polarity(def_id.index) } coerce_unsized_info => { @@ -442,8 +442,8 @@ impl CStore { ) } - pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem { - self.get_crate_data(def.krate).get_associated_item(def.index) + pub fn associated_item_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::AssocItem { + self.get_crate_data(def.krate).get_associated_item(def.index, sess) } pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource { diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 5963047fc760d..af6486fb9cdd1 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -13,7 +13,7 @@ use rustc::traits::specialization_graph; use rustc::ty::codec::{self as ty_codec, TyEncoder}; use rustc::ty::layout::VariantIdx; use rustc::ty::{self, SymbolName, Ty, TyCtxt}; -use rustc_ast::ast; +use rustc_ast::ast::{self, Ident}; use rustc_ast::attr; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -30,7 +30,7 @@ use rustc_index::vec::Idx; use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder}; use rustc_session::config::{self, CrateType}; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{self, ExternalSource, FileName, SourceFile, Span}; use std::hash::Hash; use std::num::NonZeroUsize; @@ -220,13 +220,6 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { } } -impl SpecializedEncoder for EncodeContext<'tcx> { - fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> { - // FIXME(jseyfried): intercrate hygiene - ident.name.encode(self) - } -} - impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { #[inline] fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> { @@ -633,6 +626,7 @@ impl EncodeContext<'tcx> { assert!(f.did.is_local()); f.did.index })); + self.encode_ident_span(def_id, variant.ident); self.encode_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); @@ -735,6 +729,7 @@ impl EncodeContext<'tcx> { record!(self.per_def.visibility[def_id] <- field.vis); record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); record!(self.per_def.attributes[def_id] <- variant_data.fields()[field_index].attrs); + self.encode_ident_span(def_id, field.ident); self.encode_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); @@ -869,6 +864,7 @@ impl EncodeContext<'tcx> { record!(self.per_def.visibility[def_id] <- trait_item.vis); record!(self.per_def.span[def_id] <- ast_item.span); record!(self.per_def.attributes[def_id] <- ast_item.attrs); + self.encode_ident_span(def_id, ast_item.ident); self.encode_stability(def_id); self.encode_const_stability(def_id); self.encode_deprecation(def_id); @@ -952,6 +948,7 @@ impl EncodeContext<'tcx> { record!(self.per_def.visibility[def_id] <- impl_item.vis); record!(self.per_def.span[def_id] <- ast_item.span); record!(self.per_def.attributes[def_id] <- ast_item.attrs); + self.encode_ident_span(def_id, impl_item.ident); self.encode_stability(def_id); self.encode_const_stability(def_id); self.encode_deprecation(def_id); @@ -1058,6 +1055,8 @@ impl EncodeContext<'tcx> { debug!("EncodeContext::encode_info_for_item({:?})", def_id); + self.encode_ident_span(def_id, item.ident); + record!(self.per_def.kind[def_id] <- match item.kind { hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic, hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic, @@ -1284,6 +1283,7 @@ impl EncodeContext<'tcx> { record!(self.per_def.visibility[def_id] <- ty::Visibility::Public); record!(self.per_def.span[def_id] <- macro_def.span); record!(self.per_def.attributes[def_id] <- macro_def.attrs); + self.encode_ident_span(def_id, macro_def.ident); self.encode_stability(def_id); self.encode_deprecation(def_id); } @@ -1528,6 +1528,7 @@ impl EncodeContext<'tcx> { ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx)); record!(self.per_def.span[def_id] <- nitem.span); record!(self.per_def.attributes[def_id] <- nitem.attrs); + self.encode_ident_span(def_id, nitem.ident); self.encode_stability(def_id); self.encode_const_stability(def_id); self.encode_deprecation(def_id); @@ -1622,6 +1623,10 @@ impl EncodeContext<'tcx> { } } + fn encode_ident_span(&mut self, def_id: DefId, ident: Ident) { + record!(self.per_def.ident_span[def_id] <- ident.span); + } + /// In some cases, along with the item itself, we also /// encode some sub-items. Usually we want some info from the item /// so it's easier to do that here then to wait until we would encounter diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 448c1610c1368..3a4214e916acb 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -256,6 +256,7 @@ define_per_def_tables! { kind: Table>, visibility: Table>, span: Table>, + ident_span: Table>, attributes: Table>, children: Table>, stability: Table>, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 77d6e4560ab93..d29ec83bfa09a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -904,7 +904,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { self.insert_field_names(def_id, field_names); } Res::Def(DefKind::AssocFn, def_id) => { - if cstore.associated_item_cloned_untracked(def_id).method_has_self_argument { + if cstore + .associated_item_cloned_untracked(def_id, self.r.session) + .method_has_self_argument + { self.r.has_self.insert(def_id); } } diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr index c95e8d239d2b9..a5c961a061acb 100644 --- a/src/test/ui/copy-a-resource.stderr +++ b/src/test/ui/copy-a-resource.stderr @@ -6,6 +6,14 @@ LL | struct Foo { ... LL | let _y = x.clone(); | ^^^^^ method not found in `Foo` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr index c4c85773fbc1d..be446feb847eb 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr +++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr @@ -12,6 +12,14 @@ LL | struct NotClone; ... LL | Bar:: { x: 1 }.clone(); | ^^^^^ method not found in `Bar` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `NotClone: std::clone::Clone` diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index f5b41cd1cc0bb..8bf245648f84b 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -3,6 +3,14 @@ error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered | LL | match x { } | ^ patterns `None` and `Some(_)` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | None, + | ---- not covered +... +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr index 577c6e886d523..5028405e731a3 100644 --- a/src/test/ui/error-codes/E0005.stderr +++ b/src/test/ui/error-codes/E0005.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in local binding: `None` not covered | LL | let Some(y) = x; | ^^^^^^^ pattern `None` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | None, + | ---- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr index f356a5b954d6d..e25fb09f15757 100644 --- a/src/test/ui/error-codes/E0297.stderr +++ b/src/test/ui/error-codes/E0297.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in `for` loop binding: `None` not covered | LL | for Some(x) in xs {} | ^^^^^^^ pattern `None` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | None, + | ---- not covered error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index 08c36cece4cf9..3334e47019494 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(_x) = foo(); | ^^^^^^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr index ccb1c9bcc7f4e..b5bc0c76c2fc5 100644 --- a/src/test/ui/generic-associated-types/iterable.stderr +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -5,6 +5,11 @@ LL | impl Iterable for Vec { | --------------------------- in this `impl` item LL | type Item<'a> where T: 'a = as Iterator>::Item; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type + | + ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL + | +LL | type Item; + | ---- associated type defined here | = note: expected reference `&T` found associated type ` as Iterable>::Item<'_>` @@ -18,6 +23,11 @@ LL | impl Iterable for [T] { | ------------------------ in this `impl` item LL | type Item<'a> where T: 'a = as Iterator>::Item; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type + | + ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL + | +LL | type Item; + | ---- associated type defined here | = note: expected reference `&T` found associated type `<[T] as Iterable>::Item<'_>` diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index c0ca341385df5..b5135b53e1890 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -83,6 +83,16 @@ error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::b | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); | ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>` + | + ::: $DIR/auxiliary/no_method_suggested_traits.rs:8:12 + | +LL | fn method(&self) {} + | ------ + | | + | the method is available for `std::boxed::Box>>` here + | the method is available for `std::pin::Pin>>` here + | the method is available for `std::sync::Arc>>` here + | the method is available for `std::rc::Rc>>` here | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr index aa720fd45895a..0cdc501d56811 100644 --- a/src/test/ui/issues/issue-2823.stderr +++ b/src/test/ui/issues/issue-2823.stderr @@ -6,6 +6,14 @@ LL | struct C { ... LL | let _d = c.clone(); | ^^^^^ method not found in `C` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr index 667383e072a54..d9d61fe66f78e 100644 --- a/src/test/ui/issues/issue-69725.stderr +++ b/src/test/ui/issues/issue-69725.stderr @@ -8,6 +8,14 @@ LL | let _ = Struct::::new().clone(); | LL | pub struct Struct(A); | ------------------------ doesn't satisfy `issue_69725::Struct: std::clone::Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `A: std::clone::Clone` diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr index 074ed66a26183..78d212f7a7ba7 100644 --- a/src/test/ui/non-copyable-void.stderr +++ b/src/test/ui/non-copyable-void.stderr @@ -3,6 +3,14 @@ error[E0599]: no method named `clone` found for enum `libc::c_void` in the curre | LL | let _z = (*y).clone(); | ^^^^^ method not found in `libc::c_void` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here error: aborting due to previous error diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr index 6c3c4a6ac9888..994eb65ae15bf 100644 --- a/src/test/ui/noncopyable-class.stderr +++ b/src/test/ui/noncopyable-class.stderr @@ -6,6 +6,14 @@ LL | struct Foo { ... LL | let _y = x.clone(); | ^^^^^ method not found in `Foo` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr index 8521e37d3fddc..5bf491144ae45 100644 --- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr +++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr @@ -11,6 +11,14 @@ error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered | LL | match Some(Some(North)) { | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- + | | + | not covered + | not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr index f79d180a1b8b5..ce2ab34f87d69 100644 --- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr +++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr @@ -3,6 +3,11 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not co | LL | match private::DATA { | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index a06ad5788515c..f7c2772584052 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -25,6 +25,11 @@ error[E0004]: non-exhaustive patterns: `Some(_)` not covered | LL | match Some(10) { | ^^^^^^^^ pattern `Some(_)` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index aa23aed4b425a..a91c4dd35e467 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(x) = res; | ^^^^^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index d0c278d12d70a..bd6e9d5950272 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -3,8 +3,11 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object | LL | fn bar(_x: Foo) {} | ^^^ the trait `issue_3907::Foo` cannot be made into an object + | + ::: $DIR/auxiliary/issue-3907.rs:2:8 | - = note: the trait cannot be made into an object because associated function `bar` has no `self` parameter +LL | fn bar(); + | --- the trait cannot be made into an object because associated function `bar` has no `self` parameter error: aborting due to previous error diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr index ccc25a184e946..a214a652a387f 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr @@ -27,6 +27,13 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere | LL | match x {} | ^ patterns `Tuple(_)` and `Struct { .. }` not covered + | + ::: $DIR/auxiliary/uninhabited.rs:17:23 + | +LL | #[non_exhaustive] Tuple(!), + | ----- not covered +LL | #[non_exhaustive] Struct { x: ! } + | ------ not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr index a54885c96e5ee..63564e9c3cc8c 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr @@ -27,6 +27,13 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere | LL | match x {} | ^ patterns `Tuple(_)` and `Struct { .. }` not covered + | + ::: $DIR/auxiliary/uninhabited.rs:17:23 + | +LL | #[non_exhaustive] Tuple(!), + | ----- not covered +LL | #[non_exhaustive] Struct { x: ! } + | ------ not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index a667e1fe2da3a..e4396afb2dbf5 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -3,6 +3,11 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered | LL | let _ = match x { | ^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -46,6 +51,11 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered | LL | let _ = match x { | ^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -54,6 +64,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(x) = x; | ^^^^^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index 01c8e8471aac2..66437611872df 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -21,6 +21,14 @@ LL | struct CloneNoCopy; ... LL | let w = u.clone(); | ^^^^^ method not found in `U5` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `CloneNoCopy: std::marker::Copy` diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr index fb78095224b90..2e81e7cf83200 100644 --- a/src/test/ui/unique-object-noncopyable.stderr +++ b/src/test/ui/unique-object-noncopyable.stderr @@ -14,6 +14,14 @@ LL | let _z = y.clone(); | LL | pub struct Box(Unique); | ------------------------------------- doesn't satisfy `std::boxed::Box: std::clone::Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `dyn Foo: std::marker::Sized` diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr index ea6575d1d85dc..06c4b95baef56 100644 --- a/src/test/ui/unique-pinned-nocopy.stderr +++ b/src/test/ui/unique-pinned-nocopy.stderr @@ -11,6 +11,14 @@ LL | let _j = i.clone(); | LL | pub struct Box(Unique); | ------------------------------------- doesn't satisfy `std::boxed::Box: std::clone::Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `R: std::clone::Clone` From 86b8dea5ecb10dd12f9e352e9f31ced88a16e5e8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 23 Mar 2020 01:45:16 -0400 Subject: [PATCH 16/38] Ignore tests on some platforms due to #53081 --- src/test/ui/copy-a-resource.rs | 5 +++++ src/test/ui/copy-a-resource.stderr | 2 +- .../ui/derives/derive-assoc-type-not-impl.rs | 5 +++++ .../ui/derives/derive-assoc-type-not-impl.stderr | 2 +- src/test/ui/error-codes/E0004-2.rs | 5 +++++ src/test/ui/error-codes/E0004-2.stderr | 2 +- src/test/ui/error-codes/E0005.rs | 5 +++++ src/test/ui/error-codes/E0005.stderr | 2 +- src/test/ui/error-codes/E0297.rs | 5 +++++ src/test/ui/error-codes/E0297.stderr | 2 +- .../feature-gate-exhaustive-patterns.rs | 5 +++++ .../feature-gate-exhaustive-patterns.stderr | 2 +- src/test/ui/generic-associated-types/iterable.rs | 5 +++++ .../ui/generic-associated-types/iterable.stderr | 8 ++++---- src/test/ui/issues/issue-2823.rs | 5 +++++ src/test/ui/issues/issue-2823.stderr | 2 +- src/test/ui/issues/issue-69725.rs | 5 +++++ src/test/ui/issues/issue-69725.stderr | 2 +- src/test/ui/non-copyable-void.rs | 5 +++++ src/test/ui/non-copyable-void.stderr | 2 +- src/test/ui/noncopyable-class.rs | 5 +++++ src/test/ui/noncopyable-class.stderr | 2 +- .../ui/pattern/usefulness/match-arm-statics-2.rs | 5 +++++ .../usefulness/match-arm-statics-2.stderr | 6 +++--- .../pattern/usefulness/match-privately-empty.rs | 5 +++++ .../usefulness/match-privately-empty.stderr | 2 +- .../pattern/usefulness/non-exhaustive-match.rs | 5 +++++ .../usefulness/non-exhaustive-match.stderr | 16 ++++++++-------- .../recursive-types-are-not-uninhabited.rs | 5 +++++ .../recursive-types-are-not-uninhabited.stderr | 2 +- .../uninhabited-matches-feature-gated.rs | 5 +++++ .../uninhabited-matches-feature-gated.stderr | 14 +++++++------- src/test/ui/union/union-derive-clone.rs | 5 +++++ src/test/ui/union/union-derive-clone.stderr | 4 ++-- 34 files changed, 121 insertions(+), 36 deletions(-) diff --git a/src/test/ui/copy-a-resource.rs b/src/test/ui/copy-a-resource.rs index 55f2dd4ee6dde..1a647692018e5 100644 --- a/src/test/ui/copy-a-resource.rs +++ b/src/test/ui/copy-a-resource.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #[derive(Debug)] struct Foo { i: isize, diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr index a5c961a061acb..71d2eead3554c 100644 --- a/src/test/ui/copy-a-resource.stderr +++ b/src/test/ui/copy-a-resource.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `clone` found for struct `Foo` in the current scope - --> $DIR/copy-a-resource.rs:18:16 + --> $DIR/copy-a-resource.rs:23:16 | LL | struct Foo { | ---------- method `clone` not found for this diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.rs b/src/test/ui/derives/derive-assoc-type-not-impl.rs index 0f642d63a1dcb..fa5afd2419261 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.rs +++ b/src/test/ui/derives/derive-assoc-type-not-impl.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + trait Foo { type X; fn method(&self) {} diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr index be446feb847eb..f15aba97ded81 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr +++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `clone` found for struct `Bar` in the current scope - --> $DIR/derive-assoc-type-not-impl.rs:18:30 + --> $DIR/derive-assoc-type-not-impl.rs:23:30 | LL | struct Bar { | ------------------ diff --git a/src/test/ui/error-codes/E0004-2.rs b/src/test/ui/error-codes/E0004-2.rs index c7612fd50a74e..7f1d064cf3f50 100644 --- a/src/test/ui/error-codes/E0004-2.rs +++ b/src/test/ui/error-codes/E0004-2.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let x = Some(1); diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index 8bf245648f84b..e47a4fa755cac 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered - --> $DIR/E0004-2.rs:4:11 + --> $DIR/E0004-2.rs:9:11 | LL | match x { } | ^ patterns `None` and `Some(_)` not covered diff --git a/src/test/ui/error-codes/E0005.rs b/src/test/ui/error-codes/E0005.rs index f4730697e1843..75faad80579c6 100644 --- a/src/test/ui/error-codes/E0005.rs +++ b/src/test/ui/error-codes/E0005.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let x = Some(1); let Some(y) = x; //~ ERROR E0005 diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr index 5028405e731a3..192b994403191 100644 --- a/src/test/ui/error-codes/E0005.stderr +++ b/src/test/ui/error-codes/E0005.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding: `None` not covered - --> $DIR/E0005.rs:3:9 + --> $DIR/E0005.rs:8:9 | LL | let Some(y) = x; | ^^^^^^^ pattern `None` not covered diff --git a/src/test/ui/error-codes/E0297.rs b/src/test/ui/error-codes/E0297.rs index 27c7960d97731..b26ede9c8e219 100644 --- a/src/test/ui/error-codes/E0297.rs +++ b/src/test/ui/error-codes/E0297.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let xs : Vec> = vec![Some(1), None]; diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr index e25fb09f15757..4a75e9d1771f3 100644 --- a/src/test/ui/error-codes/E0297.stderr +++ b/src/test/ui/error-codes/E0297.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in `for` loop binding: `None` not covered - --> $DIR/E0297.rs:4:9 + --> $DIR/E0297.rs:9:9 | LL | for Some(x) in xs {} | ^^^^^^^ pattern `None` not covered diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs index f0cc9ea70550e..d2e52299c0d86 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![feature(never_type)] fn foo() -> Result { diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index 3334e47019494..c2dd90b91e700 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/feature-gate-exhaustive-patterns.rs:8:9 + --> $DIR/feature-gate-exhaustive-patterns.rs:13:9 | LL | let Ok(_x) = foo(); | ^^^^^^ pattern `Err(_)` not covered diff --git a/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs index 105ab4a8adc38..616421112db67 100644 --- a/src/test/ui/generic-associated-types/iterable.rs +++ b/src/test/ui/generic-associated-types/iterable.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![allow(incomplete_features)] #![feature(generic_associated_types)] diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr index b5bc0c76c2fc5..e18c6cec64e71 100644 --- a/src/test/ui/generic-associated-types/iterable.stderr +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` - --> $DIR/iterable.rs:15:5 + --> $DIR/iterable.rs:20:5 | LL | impl Iterable for Vec { | --------------------------- in this `impl` item @@ -17,7 +17,7 @@ LL | type Item; = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` - --> $DIR/iterable.rs:27:5 + --> $DIR/iterable.rs:32:5 | LL | impl Iterable for [T] { | ------------------------ in this `impl` item @@ -35,7 +35,7 @@ LL | type Item; = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` - --> $DIR/iterable.rs:19:30 + --> $DIR/iterable.rs:24:30 | LL | trait Iterable { | -------------- required by `Iterable` @@ -49,7 +49,7 @@ LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` - --> $DIR/iterable.rs:31:30 + --> $DIR/iterable.rs:36:30 | LL | trait Iterable { | -------------- required by `Iterable` diff --git a/src/test/ui/issues/issue-2823.rs b/src/test/ui/issues/issue-2823.rs index 7b443b4152613..f00c2304733ca 100644 --- a/src/test/ui/issues/issue-2823.rs +++ b/src/test/ui/issues/issue-2823.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + struct C { x: isize, } diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr index 0cdc501d56811..6e11dd4028836 100644 --- a/src/test/ui/issues/issue-2823.stderr +++ b/src/test/ui/issues/issue-2823.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `clone` found for struct `C` in the current scope - --> $DIR/issue-2823.rs:13:16 + --> $DIR/issue-2823.rs:18:16 | LL | struct C { | -------- method `clone` not found for this diff --git a/src/test/ui/issues/issue-69725.rs b/src/test/ui/issues/issue-69725.rs index b8130b41f2167..a8e72e9459e33 100644 --- a/src/test/ui/issues/issue-69725.rs +++ b/src/test/ui/issues/issue-69725.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + // aux-build:issue-69725.rs extern crate issue_69725; diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr index d9d61fe66f78e..439fae9511167 100644 --- a/src/test/ui/issues/issue-69725.stderr +++ b/src/test/ui/issues/issue-69725.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `clone` found for struct `issue_69725::Struct` in the current scope - --> $DIR/issue-69725.rs:7:32 + --> $DIR/issue-69725.rs:12:32 | LL | let _ = Struct::::new().clone(); | ^^^^^ method not found in `issue_69725::Struct` diff --git a/src/test/ui/non-copyable-void.rs b/src/test/ui/non-copyable-void.rs index ddaaee436ae23..186731f2e7233 100644 --- a/src/test/ui/non-copyable-void.rs +++ b/src/test/ui/non-copyable-void.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + // ignore-wasm32-bare no libc to test ffi with #![feature(rustc_private)] diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr index 78d212f7a7ba7..dd67a110d2218 100644 --- a/src/test/ui/non-copyable-void.stderr +++ b/src/test/ui/non-copyable-void.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `clone` found for enum `libc::c_void` in the current scope - --> $DIR/non-copyable-void.rs:11:23 + --> $DIR/non-copyable-void.rs:16:23 | LL | let _z = (*y).clone(); | ^^^^^ method not found in `libc::c_void` diff --git a/src/test/ui/noncopyable-class.rs b/src/test/ui/noncopyable-class.rs index 11b6eb736e9db..731f4ab9c784a 100644 --- a/src/test/ui/noncopyable-class.rs +++ b/src/test/ui/noncopyable-class.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + // Test that a class with a non-copyable field can't be // copied diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr index 994eb65ae15bf..472ce34870a0a 100644 --- a/src/test/ui/noncopyable-class.stderr +++ b/src/test/ui/noncopyable-class.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `clone` found for struct `Foo` in the current scope - --> $DIR/noncopyable-class.rs:34:16 + --> $DIR/noncopyable-class.rs:39:16 | LL | struct Foo { | ---------- method `clone` not found for this diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs index 4c5f2d356491b..728d4a64495b1 100644 --- a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs +++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + use self::Direction::{North, East, South, West}; #[derive(PartialEq, Eq)] diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr index 5bf491144ae45..7bb6a700a3717 100644 --- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr +++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered - --> $DIR/match-arm-statics-2.rs:17:11 + --> $DIR/match-arm-statics-2.rs:22:11 | LL | match (true, false) { | ^^^^^^^^^^^^^ pattern `(true, false)` not covered @@ -7,7 +7,7 @@ LL | match (true, false) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered - --> $DIR/match-arm-statics-2.rs:29:11 + --> $DIR/match-arm-statics-2.rs:34:11 | LL | match Some(Some(North)) { | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered @@ -23,7 +23,7 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered - --> $DIR/match-arm-statics-2.rs:48:11 + --> $DIR/match-arm-statics-2.rs:53:11 | LL | / struct Foo { LL | | bar: Option, diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.rs b/src/test/ui/pattern/usefulness/match-privately-empty.rs index 315eb03d16564..c7cde468bb9bf 100644 --- a/src/test/ui/pattern/usefulness/match-privately-empty.rs +++ b/src/test/ui/pattern/usefulness/match-privately-empty.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![feature(never_type)] #![feature(exhaustive_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr index ce2ab34f87d69..4dcbf05ecce2b 100644 --- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr +++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered - --> $DIR/match-privately-empty.rs:13:11 + --> $DIR/match-privately-empty.rs:18:11 | LL | match private::DATA { | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs index 9947989dc1211..59f7bb892c68c 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![allow(illegal_floating_point_literal_pattern)] enum T { A, B } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index f7c2772584052..dff2c8d9424c3 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `A` not covered - --> $DIR/non-exhaustive-match.rs:7:11 + --> $DIR/non-exhaustive-match.rs:12:11 | LL | enum T { A, B } | --------------- @@ -13,7 +13,7 @@ LL | match x { T::B => { } } = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `false` not covered - --> $DIR/non-exhaustive-match.rs:8:11 + --> $DIR/non-exhaustive-match.rs:13:11 | LL | match true { | ^^^^ pattern `false` not covered @@ -21,7 +21,7 @@ LL | match true { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/non-exhaustive-match.rs:11:11 + --> $DIR/non-exhaustive-match.rs:16:11 | LL | match Some(10) { | ^^^^^^^^ pattern `Some(_)` not covered @@ -34,7 +34,7 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered - --> $DIR/non-exhaustive-match.rs:14:11 + --> $DIR/non-exhaustive-match.rs:19:11 | LL | match (2, 3, 4) { | ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered @@ -42,7 +42,7 @@ LL | match (2, 3, 4) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(A, A)` not covered - --> $DIR/non-exhaustive-match.rs:18:11 + --> $DIR/non-exhaustive-match.rs:23:11 | LL | match (T::A, T::A) { | ^^^^^^^^^^^^ pattern `(A, A)` not covered @@ -50,7 +50,7 @@ LL | match (T::A, T::A) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `B` not covered - --> $DIR/non-exhaustive-match.rs:22:11 + --> $DIR/non-exhaustive-match.rs:27:11 | LL | enum T { A, B } | --------------- @@ -64,7 +64,7 @@ LL | match T::A { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/non-exhaustive-match.rs:33:11 + --> $DIR/non-exhaustive-match.rs:38:11 | LL | match *vec { | ^^^^ pattern `[]` not covered @@ -72,7 +72,7 @@ LL | match *vec { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered - --> $DIR/non-exhaustive-match.rs:46:11 + --> $DIR/non-exhaustive-match.rs:51:11 | LL | match *vec { | ^^^^ pattern `[_, _, _, _, ..]` not covered diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs index 4489303638358..5be426eb38278 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + struct R<'a> { r: &'a R<'a>, } diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index a91c4dd35e467..f371d460cf733 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/recursive-types-are-not-uninhabited.rs:6:9 + --> $DIR/recursive-types-are-not-uninhabited.rs:11:9 | LL | let Ok(x) = res; | ^^^^^ pattern `Err(_)` not covered diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs index e804afcf9ed99..a959aaae05568 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + use std::mem::zeroed; enum Void {} diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index e4396afb2dbf5..9245e293caa85 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:6:19 + --> $DIR/uninhabited-matches-feature-gated.rs:11:19 | LL | let _ = match x { | ^ pattern `Err(_)` not covered @@ -12,7 +12,7 @@ LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `&Void` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:15:19 + --> $DIR/uninhabited-matches-feature-gated.rs:20:19 | LL | enum Void {} | ------------ `Void` defined here @@ -23,7 +23,7 @@ LL | let _ = match x {}; = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:18:19 + --> $DIR/uninhabited-matches-feature-gated.rs:23:19 | LL | let _ = match x {}; | ^ @@ -31,7 +31,7 @@ LL | let _ = match x {}; = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:21:19 + --> $DIR/uninhabited-matches-feature-gated.rs:26:19 | LL | let _ = match x {}; | ^ @@ -39,7 +39,7 @@ LL | let _ = match x {}; = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:24:19 + --> $DIR/uninhabited-matches-feature-gated.rs:29:19 | LL | let _ = match x { | ^ pattern `&[_, ..]` not covered @@ -47,7 +47,7 @@ LL | let _ = match x { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:32:19 + --> $DIR/uninhabited-matches-feature-gated.rs:37:19 | LL | let _ = match x { | ^ pattern `Err(_)` not covered @@ -60,7 +60,7 @@ LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:37:9 + --> $DIR/uninhabited-matches-feature-gated.rs:42:9 | LL | let Ok(x) = x; | ^^^^^ pattern `Err(_)` not covered diff --git a/src/test/ui/union/union-derive-clone.rs b/src/test/ui/union/union-derive-clone.rs index 4a106cc940a18..4b92475f1e4cd 100644 --- a/src/test/ui/union/union-derive-clone.rs +++ b/src/test/ui/union/union-derive-clone.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + #![feature(untagged_unions)] use std::mem::ManuallyDrop; diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index 66437611872df..d0a82a96c165c 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `U1: std::marker::Copy` is not satisfied - --> $DIR/union-derive-clone.rs:5:10 + --> $DIR/union-derive-clone.rs:10:10 | LL | #[derive(Clone)] | ^^^^^ the trait `std::marker::Copy` is not implemented for `U1` @@ -8,7 +8,7 @@ LL | #[derive(Clone)] = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no method named `clone` found for union `U5` in the current scope - --> $DIR/union-derive-clone.rs:37:15 + --> $DIR/union-derive-clone.rs:42:15 | LL | union U5 { | ----------- From 6a7106cb328e0e43b2a0e1c07dc5c0cfbd1b31b9 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 23 Mar 2020 10:58:07 +0100 Subject: [PATCH 17/38] type_of AnonConst AssocTy does not require parent --- src/librustc_typeck/collect/type_of.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index eec87f3e3b08b..f085486900d74 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -259,7 +259,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { // default to the path resolution. let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); let generics = match res { - Res::Def(DefKind::Ctor(..) | DefKind::AssocTy, def_id) => { + Res::Def(DefKind::Ctor(..), def_id) => { tcx.generics_of(tcx.parent(def_id).unwrap()) } Res::Def(_, def_id) => tcx.generics_of(def_id), From 0a17c4c1904ec20b6ec975e44282323c83668751 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 23 Mar 2020 17:08:41 +0100 Subject: [PATCH 18/38] fix comment --- src/librustc_typeck/collect/type_of.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index f085486900d74..16c8689ae0cbc 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -255,7 +255,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { bug!("no arg matching AnonConst in path"); }); - // try to use the segment resolution if it is valid, otherwise we + // Try to use the segment resolution if it is valid, otherwise we // default to the path resolution. let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); let generics = match res { From e8f0a64cf1d6e1aa2e552401988e392f00dc8224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 14 Jan 2020 02:54:55 +0100 Subject: [PATCH 19/38] Make the `type_of` return a generic type for generators --- src/librustc_mir_build/build/mod.rs | 3 ++- src/librustc_typeck/collect/type_of.rs | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index d5daf465bb73d..a7ec4f501ae76 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -139,7 +139,8 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { let arguments = implicit_argument.into_iter().chain(explicit_arguments); let (yield_ty, return_ty) = if body.generator_kind.is_some() { - let gen_sig = match ty.kind { + let gen_ty = tcx.body_tables(body_id).node_type(id); + let gen_sig = match gen_ty.kind { ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(), _ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty), }; diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 55642dfb4557b..675d003bff1f2 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -188,12 +188,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::Field(field) => icx.to_ty(&field.ty), Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => { - if gen.is_some() { - return tcx.typeck_tables_of(def_id).node_type(hir_id); - } - let substs = InternalSubsts::identity_for_item(tcx, def_id); - tcx.mk_closure(def_id, substs) + if let Some(movability) = gen { + tcx.mk_generator(def_id, substs, movability) + } else { + tcx.mk_closure(def_id, substs) + } } Node::AnonConst(_) => { From 47a84f2170c8a4bae817eff603172f5faf52ce64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 6 Feb 2020 10:33:05 +0100 Subject: [PATCH 20/38] Update tests --- ...block-control-flow-static-semantics.stderr | 32 ++++---- src/test/ui/async-await/async-error-span.rs | 1 + .../ui/async-await/async-error-span.stderr | 20 ++++- .../incorrect-syntax-suggestions.rs | 1 + .../incorrect-syntax-suggestions.stderr | 49 +++++++----- src/test/ui/async-await/issue-67651.rs | 20 +++++ src/test/ui/async-await/issue-67651.stderr | 12 +++ .../issues/issue-63388-2.nll.stderr | 13 ---- .../ui/async-await/issues/issue-63388-2.rs | 2 +- .../async-await/issues/issue-63388-2.stderr | 17 +--- src/test/ui/async-await/issues/issue-65159.rs | 1 + .../ui/async-await/issues/issue-65159.stderr | 11 ++- .../ret-impl-trait-no-fg.rs | 3 + .../ret-impl-trait-no-fg.stderr | 39 +++++++++- .../ui/self/elision/ref-self-async.nll.stderr | 77 ++++++++++++++++--- src/test/ui/self/elision/ref-self-async.rs | 1 + .../ui/self/elision/ref-self-async.stderr | 14 ++-- 17 files changed, 224 insertions(+), 89 deletions(-) create mode 100644 src/test/ui/async-await/issue-67651.rs create mode 100644 src/test/ui/async-await/issue-67651.stderr delete mode 100644 src/test/ui/async-await/issues/issue-63388-2.nll.stderr diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr index afb8f146192cc..46a132da309bb 100644 --- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -18,22 +18,6 @@ LL | | break 0u8; LL | | }; | |_________- enclosing `async` block -error[E0308]: mismatched types - --> $DIR/async-block-control-flow-static-semantics.rs:13:43 - | -LL | fn return_targets_async_block_not_fn() -> u8 { - | --------------------------------- ^^ expected `u8`, found `()` - | | - | implicitly returns `()` as its body has no tail or `return` expression - -error[E0271]: type mismatch resolving `::Output == ()` - --> $DIR/async-block-control-flow-static-semantics.rs:18:39 - | -LL | let _: &dyn Future = █ - | ^^^^^^ expected `()`, found `u8` - | - = note: required for the cast to the object type `dyn std::future::Future` - error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:22:58 | @@ -55,6 +39,22 @@ LL | let _: &dyn Future = █ | = note: required for the cast to the object type `dyn std::future::Future` +error[E0308]: mismatched types + --> $DIR/async-block-control-flow-static-semantics.rs:13:43 + | +LL | fn return_targets_async_block_not_fn() -> u8 { + | --------------------------------- ^^ expected `u8`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error[E0271]: type mismatch resolving `::Output == ()` + --> $DIR/async-block-control-flow-static-semantics.rs:18:39 + | +LL | let _: &dyn Future = █ + | ^^^^^^ expected `()`, found `u8` + | + = note: required for the cast to the object type `dyn std::future::Future` + error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:48:44 | diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs index 28132c9789c67..cf10ebfeca939 100644 --- a/src/test/ui/async-await/async-error-span.rs +++ b/src/test/ui/async-await/async-error-span.rs @@ -5,6 +5,7 @@ use std::future::Future; fn get_future() -> impl Future { +//~^ ERROR the trait bound `(): std::future::Future` is not satisfied panic!() } diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr index b551b99587dd9..4054e739c483d 100644 --- a/src/test/ui/async-await/async-error-span.stderr +++ b/src/test/ui/async-await/async-error-span.stderr @@ -1,15 +1,27 @@ +error[E0277]: the trait bound `(): std::future::Future` is not satisfied + --> $DIR/async-error-span.rs:7:20 + | +LL | fn get_future() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `()` +LL | +LL | panic!() + | -------- this returned value is of type `!` + | + = note: the return type of a function must have a statically known size + error[E0698]: type inside `async fn` body must be known in this context - --> $DIR/async-error-span.rs:12:9 + --> $DIR/async-error-span.rs:13:9 | LL | let a; | ^ cannot infer type | note: the type is part of the `async fn` body because of this `await` - --> $DIR/async-error-span.rs:13:5 + --> $DIR/async-error-span.rs:14:5 | LL | get_future().await; | ^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0698`. +Some errors have detailed explanations: E0277, E0698. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs index 22bcbb1064dd7..cebff3be6b059 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs @@ -62,6 +62,7 @@ fn foo10() -> Result<(), ()> { fn foo11() -> Result<(), ()> { let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks //~^ ERROR incorrect use of `await` + //~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try` Ok(()) } fn foo12() -> Result<(), ()> { diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr index 92cef80c19360..61f2570b2ff93 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr @@ -71,49 +71,49 @@ LL | let _ = await bar()?; | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:68:14 + --> $DIR/incorrect-syntax-suggestions.rs:69:14 | LL | let _ = (await bar())?; | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:73:24 + --> $DIR/incorrect-syntax-suggestions.rs:74:24 | LL | let _ = bar().await(); | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:78:24 + --> $DIR/incorrect-syntax-suggestions.rs:79:24 | LL | let _ = bar().await()?; | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:106:13 + --> $DIR/incorrect-syntax-suggestions.rs:107:13 | LL | let _ = await!(bar()); | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:110:13 + --> $DIR/incorrect-syntax-suggestions.rs:111:13 | LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:115:17 + --> $DIR/incorrect-syntax-suggestions.rs:116:17 | LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:123:17 + --> $DIR/incorrect-syntax-suggestions.rs:124:17 | LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: expected expression, found `=>` - --> $DIR/incorrect-syntax-suggestions.rs:131:25 + --> $DIR/incorrect-syntax-suggestions.rs:132:25 | LL | match await { await => () } | ----- ^^ expected expression @@ -121,13 +121,13 @@ LL | match await { await => () } | while parsing this incorrect await expression error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:131:11 + --> $DIR/incorrect-syntax-suggestions.rs:132:11 | LL | match await { await => () } | ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await` error: expected one of `.`, `?`, `{`, or an operator, found `}` - --> $DIR/incorrect-syntax-suggestions.rs:134:1 + --> $DIR/incorrect-syntax-suggestions.rs:135:1 | LL | match await { await => () } | ----- - expected one of `.`, `?`, `{`, or an operator @@ -162,7 +162,7 @@ LL | let _ = await bar()?; | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:68:14 + --> $DIR/incorrect-syntax-suggestions.rs:69:14 | LL | fn foo12() -> Result<(), ()> { | ----- this is not `async` @@ -170,7 +170,7 @@ LL | let _ = (await bar())?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:73:13 + --> $DIR/incorrect-syntax-suggestions.rs:74:13 | LL | fn foo13() -> Result<(), ()> { | ----- this is not `async` @@ -178,7 +178,7 @@ LL | let _ = bar().await(); | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:78:13 + --> $DIR/incorrect-syntax-suggestions.rs:79:13 | LL | fn foo14() -> Result<(), ()> { | ----- this is not `async` @@ -186,7 +186,7 @@ LL | let _ = bar().await()?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:83:13 + --> $DIR/incorrect-syntax-suggestions.rs:84:13 | LL | fn foo15() -> Result<(), ()> { | ----- this is not `async` @@ -194,7 +194,7 @@ LL | let _ = bar().await; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:87:13 + --> $DIR/incorrect-syntax-suggestions.rs:88:13 | LL | fn foo16() -> Result<(), ()> { | ----- this is not `async` @@ -202,7 +202,7 @@ LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:92:17 + --> $DIR/incorrect-syntax-suggestions.rs:93:17 | LL | fn foo() -> Result<(), ()> { | --- this is not `async` @@ -210,7 +210,7 @@ LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:99:17 + --> $DIR/incorrect-syntax-suggestions.rs:100:17 | LL | let foo = || { | -- this is not `async` @@ -218,7 +218,7 @@ LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:115:17 + --> $DIR/incorrect-syntax-suggestions.rs:116:17 | LL | fn foo() -> Result<(), ()> { | --- this is not `async` @@ -226,7 +226,7 @@ LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:123:17 + --> $DIR/incorrect-syntax-suggestions.rs:124:17 | LL | let foo = || { | -- this is not `async` @@ -242,7 +242,16 @@ LL | let _ = await bar()?; = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` = note: required by `std::ops::Try::into_result` -error: aborting due to 35 previous errors +error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` + --> $DIR/incorrect-syntax-suggestions.rs:63:19 + | +LL | let _ = await bar()?; + | ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future` + | + = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` + = note: required by `std::ops::Try::into_result` + +error: aborting due to 36 previous errors Some errors have detailed explanations: E0277, E0728. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issue-67651.rs b/src/test/ui/async-await/issue-67651.rs new file mode 100644 index 0000000000000..bd96a3b709bae --- /dev/null +++ b/src/test/ui/async-await/issue-67651.rs @@ -0,0 +1,20 @@ +// edition:2018 + +trait From { + fn from(); +} + +impl From for () { + fn from() {} +} + +impl From for () { +//~^ ERROR conflicting implementations of trait + fn from() {} +} + +fn bar() -> impl core::future::Future { + async move { From::from() } +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-67651.stderr b/src/test/ui/async-await/issue-67651.stderr new file mode 100644 index 0000000000000..99857c215eb8f --- /dev/null +++ b/src/test/ui/async-await/issue-67651.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `From` for type `()`: + --> $DIR/issue-67651.rs:11:1 + | +LL | impl From for () { + | ---------------- first implementation here +... +LL | impl From for () { + | ^^^^^^^^^^^^^^^^ conflicting implementation for `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr deleted file mode 100644 index 6edb9e63d480a..0000000000000 --- a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0106]: missing lifetime specifier - --> $DIR/issue-63388-2.rs:12:10 - | -LL | foo: &dyn Foo, bar: &'a dyn Foo - | -------- ----------- -LL | ) -> &dyn Foo - | ^ help: consider using the named lifetime: `&'a` - | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/async-await/issues/issue-63388-2.rs b/src/test/ui/async-await/issues/issue-63388-2.rs index 73e7f25f97d0d..458bc9faeaf27 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.rs +++ b/src/test/ui/async-await/issues/issue-63388-2.rs @@ -8,7 +8,7 @@ trait Foo {} impl Xyz { async fn do_sth<'a>( - foo: &dyn Foo, bar: &'a dyn Foo //~ ERROR cannot infer + foo: &dyn Foo, bar: &'a dyn Foo ) -> &dyn Foo //~ ERROR missing lifetime specifier { foo diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr index 9f51ced9c3f49..6edb9e63d480a 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -8,21 +8,6 @@ LL | ) -> &dyn Foo | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` -error: cannot infer an appropriate lifetime - --> $DIR/issue-63388-2.rs:11:9 - | -LL | foo: &dyn Foo, bar: &'a dyn Foo - | ^^^ ...but this borrow... -... -LL | foo - | --- this return type evaluates to the `'static` lifetime... - | -note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14 - --> $DIR/issue-63388-2.rs:11:14 - | -LL | foo: &dyn Foo, bar: &'a dyn Foo - | ^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs index b5fee061f277e..2f80435046bdf 100644 --- a/src/test/ui/async-await/issues/issue-65159.rs +++ b/src/test/ui/async-await/issues/issue-65159.rs @@ -5,6 +5,7 @@ async fn copy() -> Result<()> //~ ERROR wrong number of type arguments { Ok(()) + //~^ type annotations needed } fn main() { } diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr index 56d2c38b302e9..04cfa5249982e 100644 --- a/src/test/ui/async-await/issues/issue-65159.stderr +++ b/src/test/ui/async-await/issues/issue-65159.stderr @@ -4,6 +4,13 @@ error[E0107]: wrong number of type arguments: expected 2, found 1 LL | async fn copy() -> Result<()> | ^^^^^^^^^^ expected 2 type arguments -error: aborting due to previous error +error[E0282]: type annotations needed + --> $DIR/issue-65159.rs:7:5 + | +LL | Ok(()) + | ^^ cannot infer type for type parameter `E` declared on the enum `Result` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0107, E0282. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs index b12d7bccecead..05960c0c7f636 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs @@ -9,6 +9,9 @@ impl Trait<'_, '_> for T { } async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { //~^ ERROR ambiguous lifetime bound //~| ERROR ambiguous lifetime bound + //~| ERROR ambiguous lifetime bound + //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds + //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds (a, b) } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr index f9a1b4b3394c1..c69595a3f4d01 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr @@ -14,5 +14,42 @@ LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<' | = help: add #![feature(member_constraints)] to the crate attributes to enable -error: aborting due to 2 previous errors +error: ambiguous lifetime bound in `impl Trait` + --> $DIR/ret-impl-trait-no-fg.rs:9:64 + | +LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another + | + = help: add #![feature(member_constraints)] to the crate attributes to enable + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ret-impl-trait-no-fg.rs:9:1 + | +LL | / async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { +LL | | +LL | | +LL | | +... | +LL | | (a, b) +LL | | } + | |_^ + | + = note: hidden type `(&u8, &u8)` captures lifetime '_#4r + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ret-impl-trait-no-fg.rs:9:1 + | +LL | / async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { +LL | | +LL | | +LL | | +... | +LL | | (a, b) +LL | | } + | |_^ + | + = note: hidden type `(&u8, &u8)` captures lifetime '_#5r + +error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr index 541e49543221e..bd1f80811b542 100644 --- a/src/test/ui/self/elision/ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-self-async.nll.stderr @@ -1,13 +1,72 @@ -error[E0658]: `Wrap<&Struct, Struct>` cannot be used as the type of `self` without the `arbitrary_self_types` feature - --> $DIR/ref-self-async.rs:47:39 +error: lifetime may not live long enough + --> $DIR/ref-self-async.rs:23:9 | -LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { - | ^^^^^^^^^^^^^^^^^ +LL | async fn ref_self(&self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function 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-async.rs:29:9 + | +LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function 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-async.rs:33:9 | - = note: see issue #44874 for more information - = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) +LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function 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-async.rs:37:9 + | +LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function 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-async.rs:41:9 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function 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-async.rs:45:9 + | +LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function 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-async.rs:49:9 + | +LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` -error: aborting due to previous error +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs index 6a98b79cb3bba..0fbbd95c975d6 100644 --- a/src/test/ui/self/elision/ref-self-async.rs +++ b/src/test/ui/self/elision/ref-self-async.rs @@ -1,6 +1,7 @@ // edition:2018 #![allow(non_snake_case)] +#![feature(arbitrary_self_types)] use std::marker::PhantomData; use std::ops::Deref; diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr index b73290b024f8f..bda958241b67b 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:22:9 + --> $DIR/ref-self-async.rs:23:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ----- ---- @@ -9,7 +9,7 @@ LL | f | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:28:9 + --> $DIR/ref-self-async.rs:29:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ----- ---- @@ -19,7 +19,7 @@ LL | f | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:32:9 + --> $DIR/ref-self-async.rs:33:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ----- ---- @@ -29,7 +29,7 @@ LL | f | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:36:9 + --> $DIR/ref-self-async.rs:37:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ----- ---- @@ -39,7 +39,7 @@ LL | f | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:40:9 + --> $DIR/ref-self-async.rs:41:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | ----- ---- @@ -49,7 +49,7 @@ LL | f | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:44:9 + --> $DIR/ref-self-async.rs:45:9 | LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | ----- ---- @@ -59,7 +59,7 @@ LL | f | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:48:9 + --> $DIR/ref-self-async.rs:49:9 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | ----- --- From 0f2d9686ccbb67ce23e6acf587c5d1395288dc00 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 08:29:34 +0100 Subject: [PATCH 21/38] rustc_expand::base: nix panictry! uses --- src/librustc_expand/base.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 0fc477bbd0b4c..e47e0a757866c 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1168,6 +1168,18 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str) } } +/// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`. +fn parse_expr(p: &mut parser::Parser<'_>) -> Option> { + match p.parse_expr() { + Ok(e) => return Some(e), + Err(mut err) => err.emit(), + } + while p.token != token::Eof { + p.bump(); + } + None +} + /// Interpreting `tts` as a comma-separated sequence of expressions, /// expect exactly one string literal, or emit an error and return `None`. pub fn get_single_str_from_tts( @@ -1181,7 +1193,7 @@ pub fn get_single_str_from_tts( cx.span_err(sp, &format!("{} takes 1 argument", name)); return None; } - let ret = panictry!(p.parse_expr()); + let ret = parse_expr(&mut p)?; let _ = p.eat(&token::Comma); if p.token != token::Eof { @@ -1190,8 +1202,8 @@ pub fn get_single_str_from_tts( expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s.to_string()) } -/// Extracts comma-separated expressions from `tts`. If there is a -/// parsing error, emit a non-fatal error and return `None`. +/// Extracts comma-separated expressions from `tts`. +/// On error, emit it, and return `None`. pub fn get_exprs_from_tts( cx: &mut ExtCtxt<'_>, sp: Span, @@ -1200,7 +1212,7 @@ pub fn get_exprs_from_tts( let mut p = cx.new_parser_from_tts(tts); let mut es = Vec::new(); while p.token != token::Eof { - let expr = panictry!(p.parse_expr()); + let expr = parse_expr(&mut p)?; // Perform eager expansion on the expression. // We want to be able to handle e.g., `concat!("foo", "bar")`. From 0a8db690a4cffc687bddcaabc762e3e8746adec6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 08:55:28 +0100 Subject: [PATCH 22/38] nix panictry! in ParserAnyMacro::make --- src/librustc_expand/expand.rs | 2 +- src/librustc_expand/mbe/macro_rules.rs | 77 +++++++++++-------- .../edition-keywords-2018-2015-parsing.rs | 8 +- .../edition-keywords-2018-2015-parsing.stderr | 22 ++++-- .../edition-keywords-2018-2018-parsing.rs | 8 +- .../edition-keywords-2018-2018-parsing.stderr | 22 ++++-- src/test/ui/macros/macro-context.rs | 2 + src/test/ui/macros/macro-context.stderr | 26 ++++++- src/test/ui/type/ascription/issue-47666.rs | 2 + .../ui/type/ascription/issue-47666.stderr | 32 +++++++- 10 files changed, 153 insertions(+), 48 deletions(-) diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 4f568e5456c72..58217d98986bf 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -204,7 +204,7 @@ ast_fragments! { } impl AstFragmentKind { - fn dummy(self, span: Span) -> AstFragment { + crate fn dummy(self, span: Span) -> AstFragment { self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment") } diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index b6b69400bad43..3c619c62c2bf2 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -83,41 +83,56 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa ); } +fn emit_frag_parse_err( + mut e: DiagnosticBuilder<'_>, + parser: &Parser<'_>, + site_span: Span, + macro_ident: ast::Ident, + arm_span: Span, + kind: AstFragmentKind, +) { + if parser.token == token::Eof && e.message().ends_with(", found ``") { + if !e.span.is_dummy() { + // early end of macro arm (#52866) + e.replace_span_with(parser.sess.source_map().next_point(parser.token.span)); + } + let msg = &e.message[0]; + e.message[0] = ( + format!( + "macro expansion ends with an incomplete expression: {}", + msg.0.replace(", found ``", ""), + ), + msg.1, + ); + } + if e.span.is_dummy() { + // Get around lack of span in error (#30128) + e.replace_span_with(site_span); + if !parser.sess.source_map().is_imported(arm_span) { + e.span_label(arm_span, "in this macro arm"); + } + } else if parser.sess.source_map().is_imported(parser.token.span) { + e.span_label(site_span, "in this macro invocation"); + } + match kind { + AstFragmentKind::Pat if macro_ident.name == sym::vec => { + suggest_slice_pat(&mut e, site_span, parser); + } + _ => annotate_err_with_kind(&mut e, kind, site_span), + }; + e.emit(); +} + impl<'a> ParserAnyMacro<'a> { crate fn make(mut self: Box>, kind: AstFragmentKind) -> AstFragment { let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self; - let fragment = panictry!(parse_ast_fragment(parser, kind).map_err(|mut e| { - if parser.token == token::Eof && e.message().ends_with(", found ``") { - if !e.span.is_dummy() { - // early end of macro arm (#52866) - e.replace_span_with(parser.sess.source_map().next_point(parser.token.span)); - } - let msg = &e.message[0]; - e.message[0] = ( - format!( - "macro expansion ends with an incomplete expression: {}", - msg.0.replace(", found ``", ""), - ), - msg.1, - ); + let fragment = match parse_ast_fragment(parser, kind) { + Ok(f) => f, + Err(err) => { + emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind); + return kind.dummy(site_span); } - if e.span.is_dummy() { - // Get around lack of span in error (#30128) - e.replace_span_with(site_span); - if !parser.sess.source_map().is_imported(arm_span) { - e.span_label(arm_span, "in this macro arm"); - } - } else if parser.sess.source_map().is_imported(parser.token.span) { - e.span_label(site_span, "in this macro invocation"); - } - match kind { - AstFragmentKind::Pat if macro_ident.name == sym::vec => { - suggest_slice_pat(&mut e, site_span, parser); - } - _ => annotate_err_with_kind(&mut e, kind, site_span), - }; - e - })); + }; // We allow semicolons at the end of expressions -- e.g., the semicolon in // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`, diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs index dbc0465b08e77..a7a10d0f677af 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -1,9 +1,15 @@ // edition:2018 // aux-build:edition-kw-macro-2015.rs +fn main() {} + #[macro_use] extern crate edition_kw_macro_2015; +mod module { + pub fn r#async() {} +} + pub fn check_async() { let mut async = 1; //~ ERROR expected identifier, found keyword `async` let mut r#async = 1; // OK @@ -13,7 +19,7 @@ pub fn check_async() { r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` r#async = consumes_async_raw!(r#async); // OK - if passes_ident!(async) == 1 {} + if passes_ident!(async) == 1 {} //~ ERROR async closures are unstable if passes_ident!(r#async) == 1 {} // OK module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index e12d1a48463d7..3c3b934b531c8 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:8:13 + --> $DIR/edition-keywords-2018-2015-parsing.rs:14:13 | LL | let mut async = 1; | ^^^^^ expected identifier, found keyword @@ -10,7 +10,7 @@ LL | let mut r#async = 1; | ^^^^^^^ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:18:13 + --> $DIR/edition-keywords-2018-2015-parsing.rs:24:13 | LL | module::async(); | ^^^^^ expected identifier, found keyword @@ -21,13 +21,13 @@ LL | module::r#async(); | ^^^^^^^ error: no rules expected the token `r#async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:12:31 + --> $DIR/edition-keywords-2018-2015-parsing.rs:18:31 | LL | r#async = consumes_async!(r#async); | ^^^^^^^ no rules expected this token in macro call error: no rules expected the token `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:13:35 + --> $DIR/edition-keywords-2018-2015-parsing.rs:19:35 | LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call @@ -38,10 +38,20 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` | - ::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8 + ::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8 | LL | if passes_ident!(async) == 1 {} | -------------------- in this macro invocation -error: aborting due to 5 previous errors +error[E0658]: async closures are unstable + --> $DIR/edition-keywords-2018-2015-parsing.rs:22:22 + | +LL | if passes_ident!(async) == 1 {} + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + +error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs index 5aca0839f0f15..b12ad76a74798 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -1,9 +1,15 @@ // edition:2018 // aux-build:edition-kw-macro-2018.rs +fn main() {} + #[macro_use] extern crate edition_kw_macro_2018; +mod module { + pub fn r#async() {} +} + pub fn check_async() { let mut async = 1; //~ ERROR expected identifier, found keyword `async` let mut r#async = 1; // OK @@ -13,7 +19,7 @@ pub fn check_async() { r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` r#async = consumes_async_raw!(r#async); // OK - if passes_ident!(async) == 1 {} + if passes_ident!(async) == 1 {} //~ ERROR async closures are unstable if passes_ident!(r#async) == 1 {} // OK module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 110165fc077ca..a2b129d17e0be 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:8:13 + --> $DIR/edition-keywords-2018-2018-parsing.rs:14:13 | LL | let mut async = 1; | ^^^^^ expected identifier, found keyword @@ -10,7 +10,7 @@ LL | let mut r#async = 1; | ^^^^^^^ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:18:13 + --> $DIR/edition-keywords-2018-2018-parsing.rs:24:13 | LL | module::async(); | ^^^^^ expected identifier, found keyword @@ -21,13 +21,13 @@ LL | module::r#async(); | ^^^^^^^ error: no rules expected the token `r#async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:12:31 + --> $DIR/edition-keywords-2018-2018-parsing.rs:18:31 | LL | r#async = consumes_async!(r#async); | ^^^^^^^ no rules expected this token in macro call error: no rules expected the token `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:13:35 + --> $DIR/edition-keywords-2018-2018-parsing.rs:19:35 | LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call @@ -38,10 +38,20 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` | - ::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8 + ::: $DIR/edition-keywords-2018-2018-parsing.rs:22:8 | LL | if passes_ident!(async) == 1 {} | -------------------- in this macro invocation -error: aborting due to 5 previous errors +error[E0658]: async closures are unstable + --> $DIR/edition-keywords-2018-2018-parsing.rs:22:22 + | +LL | if passes_ident!(async) == 1 {} + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + +error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/macros/macro-context.rs b/src/test/ui/macros/macro-context.rs index 9130c3d921c52..13e179578ad01 100644 --- a/src/test/ui/macros/macro-context.rs +++ b/src/test/ui/macros/macro-context.rs @@ -4,6 +4,8 @@ macro_rules! m { //~| ERROR macro expansion ignores token `typeof` //~| ERROR macro expansion ignores token `;` //~| ERROR macro expansion ignores token `;` + //~| ERROR cannot find type `i` in this scope + //~| ERROR cannot find value `i` in this scope } fn main() { diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr index 2e712110689f8..17c7389812475 100644 --- a/src/test/ui/macros/macro-context.stderr +++ b/src/test/ui/macros/macro-context.stderr @@ -42,5 +42,29 @@ LL | m!(); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error[E0412]: cannot find type `i` in this scope + --> $DIR/macro-context.rs:3:13 + | +LL | () => ( i ; typeof ); + | ^ help: a builtin type with a similar name exists: `i8` +... +LL | let a: m!(); + | ---- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `i` in this scope + --> $DIR/macro-context.rs:3:13 + | +LL | () => ( i ; typeof ); + | ^ help: a local variable with a similar name exists: `a` +... +LL | let i = m!(); + | ---- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors +Some errors have detailed explanations: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs index ceb1dd89daea9..8035de4a48a92 100644 --- a/src/test/ui/type/ascription/issue-47666.rs +++ b/src/test/ui/type/ascription/issue-47666.rs @@ -1,5 +1,7 @@ fn main() { let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found + //~^ ERROR expected value, found enum `Option` + //~| ERROR expected type, found variant `Some` } // This case isn't currently being handled gracefully due to the macro invocation. diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr index f4c9240ab5372..3cd3be70aa75b 100644 --- a/src/test/ui/type/ascription/issue-47666.stderr +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -13,5 +13,35 @@ LL | let _ = Option:Some(vec![0, 1]); = note: see issue #23416 for more information = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error[E0423]: expected value, found enum `Option` + --> $DIR/issue-47666.rs:2:13 + | +LL | let _ = Option:Some(vec![0, 1]); + | ^^^^^^ + | +help: try using one of the enum's variants + | +LL | let _ = std::option::Option::None:Some(vec![0, 1]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = std::option::Option::Some:Some(vec![0, 1]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0573]: expected type, found variant `Some` + --> $DIR/issue-47666.rs:2:20 + | +LL | let _ = Option:Some(vec![0, 1]); + | ^^^^^^^^^^^^^^^^ not a type + | +help: try using the variant's enum + | +LL | let _ = Option:std::option::Option; + | ^^^^^^^^^^^^^^^^^^^ +help: maybe you meant to write a path separator here + | +LL | let _ = Option::Some(vec![0, 1]); + | ^^ + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0423, E0573. +For more information about an error, try `rustc --explain E0423`. From b7909b22b5ef31a9cc847be58f50cdf268c7b854 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 08:59:56 +0100 Subject: [PATCH 23/38] nix remaining rustc_expand::panictry! uses. --- src/librustc_builtin_macros/cmdline_attrs.rs | 9 ++++++-- src/librustc_builtin_macros/source_util.rs | 24 +++++++++----------- src/librustc_expand/base.rs | 2 +- src/librustc_expand/lib.rs | 19 ---------------- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/librustc_builtin_macros/cmdline_attrs.rs b/src/librustc_builtin_macros/cmdline_attrs.rs index 7ddbf08306b72..093815dbbcd4f 100644 --- a/src/librustc_builtin_macros/cmdline_attrs.rs +++ b/src/librustc_builtin_macros/cmdline_attrs.rs @@ -3,7 +3,6 @@ use rustc_ast::ast::{self, AttrItem, AttrStyle}; use rustc_ast::attr::mk_attr; use rustc_ast::token; -use rustc_expand::panictry; use rustc_session::parse::ParseSess; use rustc_span::FileName; @@ -16,7 +15,13 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) - ); let start_span = parser.token.span; - let AttrItem { path, args } = panictry!(parser.parse_attr_item()); + let AttrItem { path, args } = match parser.parse_attr_item() { + Ok(ai) => ai, + Err(mut err) => { + err.emit(); + continue; + } + }; let end_span = parser.token.span; if parser.token != token::Eof { parse_sess.span_diagnostic.span_err(start_span.to(end_span), "invalid crate attribute"); diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs index 51a15f9df1bc7..67145c6bf433b 100644 --- a/src/librustc_builtin_macros/source_util.rs +++ b/src/librustc_builtin_macros/source_util.rs @@ -5,7 +5,6 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; use rustc_expand::base::{self, *}; use rustc_expand::module::DirectoryOwnership; -use rustc_expand::panictry; use rustc_parse::{self, new_parser_from_file, parser::Parser}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; use rustc_span::symbol::Symbol; @@ -126,7 +125,7 @@ pub fn expand_include<'cx>( } impl<'a> base::MacResult for ExpandResult<'a> { fn make_expr(mut self: Box>) -> Option> { - let r = panictry!(self.p.parse_expr()); + let r = base::parse_expr(&mut self.p)?; if self.p.token != token::Eof { self.p.sess.buffer_lint( &INCOMPLETE_INCLUDE, @@ -141,18 +140,17 @@ pub fn expand_include<'cx>( fn make_items(mut self: Box>) -> Option; 1]>> { let mut ret = SmallVec::new(); while self.p.token != token::Eof { - match panictry!(self.p.parse_item()) { - Some(item) => ret.push(item), - None => { + match self.p.parse_item() { + Err(mut err) => { + err.emit(); + break; + } + Ok(Some(item)) => ret.push(item), + Ok(None) => { let token = pprust::token_to_string(&self.p.token); - self.p - .sess - .span_diagnostic - .span_fatal( - self.p.token.span, - &format!("expected item, found `{}`", token), - ) - .raise(); + let msg = format!("expected item, found `{}`", token); + self.p.struct_span_err(self.p.token.span, &msg).emit(); + break; } } } diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index e47e0a757866c..b615b34634fb2 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1169,7 +1169,7 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str) } /// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`. -fn parse_expr(p: &mut parser::Parser<'_>) -> Option> { +pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option> { match p.parse_expr() { Ok(e) => return Some(e), Err(mut err) => err.emit(), diff --git a/src/librustc_expand/lib.rs b/src/librustc_expand/lib.rs index 0320a275e5d20..876a26de3fb7e 100644 --- a/src/librustc_expand/lib.rs +++ b/src/librustc_expand/lib.rs @@ -9,25 +9,6 @@ extern crate proc_macro as pm; -// A variant of 'try!' that panics on an Err. This is used as a crutch on the -// way towards a non-panic!-prone parser. It should be used for fatal parsing -// errors; eventually we plan to convert all code using panictry to just use -// normal try. -#[macro_export] -macro_rules! panictry { - ($e:expr) => {{ - use rustc_errors::FatalError; - use std::result::Result::{Err, Ok}; - match $e { - Ok(e) => e, - Err(mut e) => { - e.emit(); - FatalError.raise() - } - } - }}; -} - mod placeholders; mod proc_macro_server; From b0537e2081e11ef55c5ab71c3ca5f76fe7158312 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 09:37:59 +0100 Subject: [PATCH 24/38] generic_extension: defatalize Error case --- src/librustc_expand/mbe/macro_rules.rs | 6 +++++- src/test/ui/macros/macro-match-nonterminal.rs | 9 ++++++++- .../ui/macros/macro-match-nonterminal.stderr | 18 ++++++++++++++---- src/test/ui/parser/macro/issue-33569.rs | 2 ++ src/test/ui/parser/macro/issue-33569.stderr | 6 +++--- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 3c619c62c2bf2..9d6f5e75faadb 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -293,7 +293,11 @@ fn generic_extension<'cx>( Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {} _ => best_failure = Some((token, msg)), }, - Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]), + Error(err_sp, ref msg) => { + let span = err_sp.substitute_dummy(sp); + cx.struct_span_err(span, &msg).emit(); + return DummyResult::any(span); + } } // The matcher was not `Success(..)`ful. diff --git a/src/test/ui/macros/macro-match-nonterminal.rs b/src/test/ui/macros/macro-match-nonterminal.rs index 6d4b32c9bc9a0..b23e5c71c03f0 100644 --- a/src/test/ui/macros/macro-match-nonterminal.rs +++ b/src/test/ui/macros/macro-match-nonterminal.rs @@ -1,4 +1,11 @@ -macro_rules! test { ($a, $b) => (()); } //~ ERROR missing fragment +macro_rules! test { + ($a, $b) => { + //~^ ERROR missing fragment + //~| ERROR missing fragment + //~| WARN this was previously accepted + () + }; +} fn main() { test!() diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr index 1de8c5bd4b472..674ce3434aac6 100644 --- a/src/test/ui/macros/macro-match-nonterminal.stderr +++ b/src/test/ui/macros/macro-match-nonterminal.stderr @@ -1,8 +1,18 @@ error: missing fragment specifier - --> $DIR/macro-match-nonterminal.rs:1:24 + --> $DIR/macro-match-nonterminal.rs:2:8 | -LL | macro_rules! test { ($a, $b) => (()); } - | ^ +LL | ($a, $b) => { + | ^ -error: aborting due to previous error +error: missing fragment specifier + --> $DIR/macro-match-nonterminal.rs:2:10 + | +LL | ($a, $b) => { + | ^^ + | + = note: `#[deny(missing_fragment_specifier)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 + +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs index 9ed53519ceb31..e32825ad3e064 100644 --- a/src/test/ui/parser/macro/issue-33569.rs +++ b/src/test/ui/parser/macro/issue-33569.rs @@ -1,3 +1,5 @@ +fn main() {} + macro_rules! foo { { $+ } => { //~ ERROR expected identifier, found `+` //~^ ERROR missing fragment specifier diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr index b4d38d3ce4806..a08d26095f564 100644 --- a/src/test/ui/parser/macro/issue-33569.stderr +++ b/src/test/ui/parser/macro/issue-33569.stderr @@ -1,17 +1,17 @@ error: expected identifier, found `+` - --> $DIR/issue-33569.rs:2:8 + --> $DIR/issue-33569.rs:4:8 | LL | { $+ } => { | ^ error: expected one of: `*`, `+`, or `?` - --> $DIR/issue-33569.rs:4:13 + --> $DIR/issue-33569.rs:6:13 | LL | $(x)(y) | ^^^ error: missing fragment specifier - --> $DIR/issue-33569.rs:2:8 + --> $DIR/issue-33569.rs:4:8 | LL | { $+ } => { | ^ From 35cca7421264371dd8962bf52d0fa5cc479e1279 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 10:09:18 +0100 Subject: [PATCH 25/38] defatalize BangProcMacro::expand --- src/librustc_expand/base.rs | 18 +++++++++++---- src/librustc_expand/expand.rs | 5 +++- src/librustc_expand/proc_macro.rs | 23 ++++++++----------- .../ui/proc-macro/invalid-punct-ident-1.rs | 2 ++ .../ui/proc-macro/invalid-punct-ident-2.rs | 2 ++ .../ui/proc-macro/invalid-punct-ident-3.rs | 2 ++ .../ui/proc-macro/invalid-punct-ident-4.rs | 9 +++++--- .../proc-macro/invalid-punct-ident-4.stderr | 16 ++++++++++--- 8 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index b615b34634fb2..20e1895270a7b 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; -use rustc_errors::{DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_parse::{self, parser, MACRO_ARGUMENTS}; use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; @@ -296,16 +296,26 @@ where } pub trait ProcMacro { - fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt<'_>, span: Span, ts: TokenStream) -> TokenStream; + fn expand<'cx>( + &self, + ecx: &'cx mut ExtCtxt<'_>, + span: Span, + ts: TokenStream, + ) -> Result; } impl ProcMacro for F where F: Fn(TokenStream) -> TokenStream, { - fn expand<'cx>(&self, _ecx: &'cx mut ExtCtxt<'_>, _span: Span, ts: TokenStream) -> TokenStream { + fn expand<'cx>( + &self, + _ecx: &'cx mut ExtCtxt<'_>, + _span: Span, + ts: TokenStream, + ) -> Result { // FIXME setup implicit context in TLS before calling self. - (*self)(ts) + Ok((*self)(ts)) } } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 58217d98986bf..57314824d5a84 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -682,7 +682,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { InvocationKind::Bang { mac, .. } => match ext { SyntaxExtensionKind::Bang(expander) => { self.gate_proc_macro_expansion_kind(span, fragment_kind); - let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens()); + let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) { + Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)), + Ok(ts) => ts, + }; self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span) } SyntaxExtensionKind::LegacyBang(expander) => { diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs index cb9afa4cd4f02..404f29f1fcf03 100644 --- a/src/librustc_expand/proc_macro.rs +++ b/src/librustc_expand/proc_macro.rs @@ -5,7 +5,7 @@ use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem}; use rustc_ast::token; use rustc_ast::tokenstream::{self, TokenStream}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Applicability, FatalError}; +use rustc_errors::{Applicability, ErrorReported, FatalError}; use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; @@ -21,21 +21,16 @@ impl base::ProcMacro for BangProcMacro { ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, - ) -> TokenStream { + ) -> Result { let server = proc_macro_server::Rustc::new(ecx); - match self.client.run(&EXEC_STRATEGY, server, input) { - Ok(stream) => stream, - Err(e) => { - let msg = "proc macro panicked"; - let mut err = ecx.struct_span_fatal(span, msg); - if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); - } - - err.emit(); - FatalError.raise(); + self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| { + let mut err = ecx.struct_span_err(span, "proc macro panicked"); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); } - } + err.emit(); + ErrorReported + }) } } diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs index 9de57da5af434..3f78dea917b19 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs @@ -14,3 +14,5 @@ extern crate invalid_punct_ident; invalid_punct!(); //~ ERROR proc macro panicked + +fn main() {} diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs index 79f72324b1d89..4e89e80ae7c41 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs @@ -14,3 +14,5 @@ extern crate invalid_punct_ident; invalid_ident!(); //~ ERROR proc macro panicked + +fn main() {} diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs index d01e9b699cac5..8d8ce8f932e71 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs @@ -14,3 +14,5 @@ extern crate invalid_punct_ident; invalid_raw_ident!(); //~ ERROR proc macro panicked + +fn main() {} diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.rs b/src/test/ui/proc-macro/invalid-punct-ident-4.rs index e50f24deae343..ab0250f53f699 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.rs @@ -1,7 +1,10 @@ // aux-build:invalid-punct-ident.rs -#[macro_use] +// We use `main` not found below as a witness for error recovery in proc macro expansion. + +#[macro_use] //~ ERROR `main` function not found extern crate invalid_punct_ident; -lexer_failure!(); //~ ERROR proc macro panicked - //~| ERROR unexpected closing delimiter: `)` +lexer_failure!(); +//~^ ERROR proc macro panicked +//~| ERROR unexpected closing delimiter: `)` diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr index fe3e55b31be5d..296e2fb094280 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr @@ -1,5 +1,5 @@ error: unexpected closing delimiter: `)` - --> $DIR/invalid-punct-ident-4.rs:6:1 + --> $DIR/invalid-punct-ident-4.rs:8:1 | LL | lexer_failure!(); | ^^^^^^^^^^^^^^^^^ unexpected closing delimiter @@ -7,10 +7,20 @@ LL | lexer_failure!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: proc macro panicked - --> $DIR/invalid-punct-ident-4.rs:6:1 + --> $DIR/invalid-punct-ident-4.rs:8:1 | LL | lexer_failure!(); | ^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0601]: `main` function not found in crate `invalid_punct_ident_4` + --> $DIR/invalid-punct-ident-4.rs:5:1 + | +LL | / #[macro_use] +LL | | extern crate invalid_punct_ident; +LL | | +LL | | lexer_failure!(); + | |_________________^ consider adding a `main` function to `$DIR/invalid-punct-ident-4.rs` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0601`. From ce8880d1d8b10cfaebc44449a37b6ad9fc628cb9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 10:56:00 +0100 Subject: [PATCH 26/38] defatalize AttrProcMacro::expand --- src/librustc_expand/base.rs | 6 +++--- src/librustc_expand/expand.rs | 7 +++++-- src/librustc_expand/proc_macro.rs | 21 ++++++++------------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 20e1895270a7b..4947730a4aa7b 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -326,7 +326,7 @@ pub trait AttrProcMacro { span: Span, annotation: TokenStream, annotated: TokenStream, - ) -> TokenStream; + ) -> Result; } impl AttrProcMacro for F @@ -339,9 +339,9 @@ where _span: Span, annotation: TokenStream, annotated: TokenStream, - ) -> TokenStream { + ) -> Result { // FIXME setup implicit context in TLS before calling self. - (*self)(annotation, annotated) + Ok((*self)(annotation, annotated)) } } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 57314824d5a84..cbb695a815ac5 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -712,8 +712,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if let MacArgs::Eq(..) = attr_item.args { self.cx.span_err(span, "key-value macro attributes are not supported"); } - let tok_result = - expander.expand(self.cx, span, attr_item.args.inner_tokens(), tokens); + let inner_tokens = attr_item.args.inner_tokens(); + let tok_result = match expander.expand(self.cx, span, inner_tokens, tokens) { + Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)), + Ok(ts) => ts, + }; self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span) } SyntaxExtensionKind::LegacyAttr(expander) => { diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs index 404f29f1fcf03..40b5e63756be7 100644 --- a/src/librustc_expand/proc_macro.rs +++ b/src/librustc_expand/proc_macro.rs @@ -45,21 +45,16 @@ impl base::AttrProcMacro for AttrProcMacro { span: Span, annotation: TokenStream, annotated: TokenStream, - ) -> TokenStream { + ) -> Result { let server = proc_macro_server::Rustc::new(ecx); - match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) { - Ok(stream) => stream, - Err(e) => { - let msg = "custom attribute panicked"; - let mut err = ecx.struct_span_fatal(span, msg); - if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); - } - - err.emit(); - FatalError.raise(); + self.client.run(&EXEC_STRATEGY, server, annotation, annotated).map_err(|e| { + let mut err = ecx.struct_span_err(span, "custom attribute panicked"); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); } - } + err.emit(); + ErrorReported + }) } } From c1ef1b3bca27709a6ddc40f0eab801f144c1b60c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 11:30:53 +0100 Subject: [PATCH 27/38] defatalize ProcMacroDerive::expand Also remove ExtCtxt::struct_span_fatal. --- src/librustc_expand/base.rs | 3 --- src/librustc_expand/proc_macro.rs | 25 +++++++--------------- src/test/ui/proc-macro/derive-bad.rs | 8 +++---- src/test/ui/proc-macro/derive-bad.stderr | 26 +++++++++++++++++------ src/test/ui/proc-macro/issue-36935.rs | 1 + src/test/ui/proc-macro/issue-36935.stderr | 14 +++++++++++- 6 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 4947730a4aa7b..c107a7f2409b8 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1020,9 +1020,6 @@ impl<'a> ExtCtxt<'a> { pub fn struct_span_err>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> { self.parse_sess.span_diagnostic.struct_span_err(sp, msg) } - pub fn struct_span_fatal>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> { - self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg) - } /// Emit `msg` attached to `sp`, and stop compilation immediately. /// diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs index 40b5e63756be7..df7bf9438c3d0 100644 --- a/src/librustc_expand/proc_macro.rs +++ b/src/librustc_expand/proc_macro.rs @@ -5,7 +5,7 @@ use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem}; use rustc_ast::token; use rustc_ast::tokenstream::{self, TokenStream}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Applicability, ErrorReported, FatalError}; +use rustc_errors::{Applicability, ErrorReported}; use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; @@ -86,8 +86,7 @@ impl MultiItemModifier for ProcMacroDerive { | Annotatable::Expr(_) => { ecx.span_err( span, - "proc-macro derives may only be \ - applied to a struct, enum, or union", + "proc-macro derives may only be applied to a struct, enum, or union", ); return ExpandResult::Ready(Vec::new()); } @@ -97,8 +96,7 @@ impl MultiItemModifier for ProcMacroDerive { _ => { ecx.span_err( span, - "proc-macro derives may only be \ - applied to a struct, enum, or union", + "proc-macro derives may only be applied to a struct, enum, or union", ); return ExpandResult::Ready(Vec::new()); } @@ -111,20 +109,16 @@ impl MultiItemModifier for ProcMacroDerive { let stream = match self.client.run(&EXEC_STRATEGY, server, input) { Ok(stream) => stream, Err(e) => { - let msg = "proc-macro derive panicked"; - let mut err = ecx.struct_span_fatal(span, msg); + let mut err = ecx.struct_span_err(span, "proc-macro derive panicked"); if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } - err.emit(); - FatalError.raise(); + return ExpandResult::Ready(vec![]); } }; let error_count_before = ecx.parse_sess.span_diagnostic.err_count(); - let msg = "proc-macro derive produced unparseable tokens"; - let mut parser = rustc_parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive")); let mut items = vec![]; @@ -134,18 +128,15 @@ impl MultiItemModifier for ProcMacroDerive { Ok(None) => break, Ok(Some(item)) => items.push(Annotatable::Item(item)), Err(mut err) => { - // FIXME: handle this better - err.cancel(); - ecx.struct_span_fatal(span, msg).emit(); - FatalError.raise(); + err.emit(); + break; } } } // fail if there have been errors emitted if ecx.parse_sess.span_diagnostic.err_count() > error_count_before { - ecx.struct_span_fatal(span, msg).emit(); - FatalError.raise(); + ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit(); } ExpandResult::Ready(items) diff --git a/src/test/ui/proc-macro/derive-bad.rs b/src/test/ui/proc-macro/derive-bad.rs index 62c0741b6697a..cb5188b5fb43f 100644 --- a/src/test/ui/proc-macro/derive-bad.rs +++ b/src/test/ui/proc-macro/derive-bad.rs @@ -3,11 +3,9 @@ #[macro_use] extern crate derive_bad; -#[derive( - A -)] -//~^^ ERROR proc-macro derive produced unparseable tokens +#[derive(A)] +//~^ ERROR proc-macro derive produced unparseable tokens //~| ERROR expected `:`, found `}` -struct A; +struct A; //~ ERROR the name `A` is defined multiple times fn main() {} diff --git a/src/test/ui/proc-macro/derive-bad.stderr b/src/test/ui/proc-macro/derive-bad.stderr index 8667396c98989..bc5ed9815238a 100644 --- a/src/test/ui/proc-macro/derive-bad.stderr +++ b/src/test/ui/proc-macro/derive-bad.stderr @@ -1,16 +1,28 @@ error: expected `:`, found `}` - --> $DIR/derive-bad.rs:7:5 + --> $DIR/derive-bad.rs:6:10 | -LL | A - | ^ expected `:` +LL | #[derive(A)] + | ^ expected `:` | = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: proc-macro derive produced unparseable tokens - --> $DIR/derive-bad.rs:7:5 + --> $DIR/derive-bad.rs:6:10 | -LL | A - | ^ +LL | #[derive(A)] + | ^ -error: aborting due to 2 previous errors +error[E0428]: the name `A` is defined multiple times + --> $DIR/derive-bad.rs:9:1 + | +LL | #[derive(A)] + | - previous definition of the type `A` here +... +LL | struct A; + | ^^^^^^^^^ `A` redefined here + | + = note: `A` must be defined only once in the type namespace of this module + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/proc-macro/issue-36935.rs b/src/test/ui/proc-macro/issue-36935.rs index f809592d5f449..5c43a564c00c2 100644 --- a/src/test/ui/proc-macro/issue-36935.rs +++ b/src/test/ui/proc-macro/issue-36935.rs @@ -5,6 +5,7 @@ extern crate test_macros; #[derive(Identity, Panic)] //~ ERROR proc-macro derive panicked struct Baz { + //~^ ERROR the name `Baz` is defined multiple times a: i32, b: i32, } diff --git a/src/test/ui/proc-macro/issue-36935.stderr b/src/test/ui/proc-macro/issue-36935.stderr index da4366eb668d6..2b2e28fdb2fda 100644 --- a/src/test/ui/proc-macro/issue-36935.stderr +++ b/src/test/ui/proc-macro/issue-36935.stderr @@ -6,5 +6,17 @@ LL | #[derive(Identity, Panic)] | = help: message: panic-derive -error: aborting due to previous error +error[E0428]: the name `Baz` is defined multiple times + --> $DIR/issue-36935.rs:7:1 + | +LL | struct Baz { + | ^^^^^^^^^^ + | | + | `Baz` redefined here + | previous definition of the type `Baz` here + | + = note: `Baz` must be defined only once in the type namespace of this module + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0428`. From ad26401dc133aa6db6aaa8631aa9bf54d81947f6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 11:35:21 +0100 Subject: [PATCH 28/38] remove ExtCxt::struct_span_warn --- src/librustc_expand/base.rs | 3 --- src/librustc_expand/expand.rs | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index c107a7f2409b8..0ecbd84cb6a0e 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1014,9 +1014,6 @@ impl<'a> ExtCtxt<'a> { self.current_expansion.id.expansion_cause() } - pub fn struct_span_warn>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> { - self.parse_sess.span_diagnostic.struct_span_warn(sp, msg) - } pub fn struct_span_err>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> { self.parse_sess.span_diagnostic.struct_span_err(sp, msg) } diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index cbb695a815ac5..51208906c2f2d 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1145,6 +1145,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { // macros are expanded before any lint passes so this warning has to be hardcoded if attr.has_name(sym::derive) { self.cx + .parse_sess() + .span_diagnostic .struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations") .note("this may become a hard error in a future release") .emit(); From df9cec2df4da27b8a6d1f3ec031392290ff279d1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 12:12:57 +0100 Subject: [PATCH 29/38] mbe::transcribe: defatalize errors. --- src/librustc_expand/base.rs | 16 ------------ src/librustc_expand/mbe/macro_rules.rs | 8 +++++- src/librustc_expand/mbe/transcribe.rs | 27 +++++++++++--------- src/test/ui/macros/issue-61033-1.rs | 3 ++- src/test/ui/macros/issue-61033-1.stderr | 11 +++++++- src/test/ui/macros/issue-61033-2.rs | 8 +++++- src/test/ui/macros/issue-61033-2.stderr | 15 ++++++++++- src/test/ui/parser/macro/macro-repeat.rs | 9 ++++--- src/test/ui/parser/macro/macro-repeat.stderr | 8 +++++- 9 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 0ecbd84cb6a0e..518a214b4a510 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1018,22 +1018,6 @@ impl<'a> ExtCtxt<'a> { self.parse_sess.span_diagnostic.struct_span_err(sp, msg) } - /// Emit `msg` attached to `sp`, and stop compilation immediately. - /// - /// `span_err` should be strongly preferred where-ever possible: - /// this should *only* be used when: - /// - /// - continuing has a high risk of flow-on errors (e.g., errors in - /// declaring a macro would cause all uses of that macro to - /// complain about "undefined macro"), or - /// - there is literally nothing else that can be done (however, - /// in most cases one can construct a dummy expression/item to - /// substitute; we never hit resolve/type-checking so the dummy - /// value doesn't have to match anything) - pub fn span_fatal>(&self, sp: S, msg: &str) -> ! { - self.parse_sess.span_diagnostic.span_fatal(sp, msg).raise(); - } - /// Emit `msg` attached to `sp`, without immediately stopping /// compilation. /// diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 9d6f5e75faadb..d4fe382b84b61 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -255,7 +255,13 @@ fn generic_extension<'cx>( let rhs_spans = rhs.iter().map(|t| t.span()).collect::>(); // rhs has holes ( `$id` and `$(...)` that need filled) - let mut tts = transcribe(cx, &named_matches, rhs, transparency); + let mut tts = match transcribe(cx, &named_matches, rhs, transparency) { + Ok(tts) => tts, + Err(mut err) => { + err.emit(); + return DummyResult::any(arm_span); + } + }; // Replace all the tokens for the corresponding positions in the macro, to maintain // proper positions in error reporting, while maintaining the macro_backtrace. diff --git a/src/librustc_expand/mbe/transcribe.rs b/src/librustc_expand/mbe/transcribe.rs index 1b1093c9529f4..e2d3d5c4d644e 100644 --- a/src/librustc_expand/mbe/transcribe.rs +++ b/src/librustc_expand/mbe/transcribe.rs @@ -8,7 +8,7 @@ use rustc_ast::token::{self, NtTT, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; -use rustc_errors::pluralize; +use rustc_errors::{pluralize, PResult}; use rustc_span::hygiene::{ExpnId, Transparency}; use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::Span; @@ -80,15 +80,15 @@ impl Iterator for Frame { /// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`. /// /// Along the way, we do some additional error checking. -pub(super) fn transcribe( - cx: &ExtCtxt<'_>, +pub(super) fn transcribe<'a>( + cx: &ExtCtxt<'a>, interp: &FxHashMap, src: Vec, transparency: Transparency, -) -> TokenStream { +) -> PResult<'a, TokenStream> { // Nothing for us to transcribe... if src.is_empty() { - return TokenStream::default(); + return Ok(TokenStream::default()); } // We descend into the RHS (`src`), expanding things as we go. This stack contains the things @@ -152,7 +152,7 @@ pub(super) fn transcribe( Frame::Delimited { forest, span, .. } => { if result_stack.is_empty() { // No results left to compute! We are back at the top-level. - return TokenStream::new(result); + return Ok(TokenStream::new(result)); } // Step back into the parent Delimited. @@ -173,11 +173,11 @@ pub(super) fn transcribe( seq @ mbe::TokenTree::Sequence(..) => { match lockstep_iter_size(&seq, interp, &repeats) { LockstepIterSize::Unconstrained => { - cx.span_fatal( + return Err(cx.struct_span_err( seq.span(), /* blame macro writer */ "attempted to repeat an expression containing no syntax variables \ matched as repeating at this depth", - ); + )); } LockstepIterSize::Contradiction(ref msg) => { @@ -185,7 +185,7 @@ pub(super) fn transcribe( // happens when two meta-variables are used in the same repetition in a // sequence, but they come from different sequence matchers and repeat // different amounts. - cx.span_fatal(seq.span(), &msg[..]); + return Err(cx.struct_span_err(seq.span(), &msg[..])); } LockstepIterSize::Constraint(len, _) => { @@ -203,7 +203,10 @@ pub(super) fn transcribe( // FIXME: this really ought to be caught at macro definition // time... It happens when the Kleene operator in the matcher and // the body for the same meta-variable do not match. - cx.span_fatal(sp.entire(), "this must repeat at least once"); + return Err(cx.struct_span_err( + sp.entire(), + "this must repeat at least once", + )); } } else { // 0 is the initial counter (we have done 0 repretitions so far). `len` @@ -242,10 +245,10 @@ pub(super) fn transcribe( } } else { // We were unable to descend far enough. This is an error. - cx.span_fatal( + return Err(cx.struct_span_err( sp, /* blame the macro writer */ &format!("variable '{}' is still repeating at this depth", ident), - ); + )); } } else { // If we aren't able to match the meta-var, we push it back into the result but diff --git a/src/test/ui/macros/issue-61033-1.rs b/src/test/ui/macros/issue-61033-1.rs index 8f85dec017f2a..18df3f6ee94c1 100644 --- a/src/test/ui/macros/issue-61033-1.rs +++ b/src/test/ui/macros/issue-61033-1.rs @@ -1,9 +1,10 @@ // Regression test for issue #61033. macro_rules! test1 { - ($x:ident, $($tt:tt)*) => { $($tt)+ } //~ERROR this must repeat at least once + ($x:ident, $($tt:tt)*) => { $($tt)+ } //~ ERROR this must repeat at least once } fn main() { test1!(x,); + let _recovery_witness: () = 0; //~ ERROR mismatched types } diff --git a/src/test/ui/macros/issue-61033-1.stderr b/src/test/ui/macros/issue-61033-1.stderr index f3c68f4928dbb..18205c3436b0b 100644 --- a/src/test/ui/macros/issue-61033-1.stderr +++ b/src/test/ui/macros/issue-61033-1.stderr @@ -4,5 +4,14 @@ error: this must repeat at least once LL | ($x:ident, $($tt:tt)*) => { $($tt)+ } | ^^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-61033-1.rs:9:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/macros/issue-61033-2.rs b/src/test/ui/macros/issue-61033-2.rs index 0799be10b96c7..1760ba1584d0b 100644 --- a/src/test/ui/macros/issue-61033-2.rs +++ b/src/test/ui/macros/issue-61033-2.rs @@ -5,7 +5,9 @@ macro_rules! test2 { $(* $id1:ident)* $(+ $id2:ident)* ) => { - $( //~ERROR meta-variable `id1` repeats 2 times + $( + //~^ ERROR meta-variable `id1` repeats 2 times + //~| ERROR meta-variable `id1` repeats 2 times $id1 + $id2 // $id1 and $id2 may repeat different numbers of times )* } @@ -16,4 +18,8 @@ fn main() { * a * b + a + b + c } + test2! { + * a * b + + a + b + c + d + } } diff --git a/src/test/ui/macros/issue-61033-2.stderr b/src/test/ui/macros/issue-61033-2.stderr index bf502919cf794..cdfe7934a0cac 100644 --- a/src/test/ui/macros/issue-61033-2.stderr +++ b/src/test/ui/macros/issue-61033-2.stderr @@ -3,9 +3,22 @@ error: meta-variable `id1` repeats 2 times, but `id2` repeats 3 times | LL | $( | __________^ +LL | | +LL | | LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times LL | | )* | |_________^ -error: aborting due to previous error +error: meta-variable `id1` repeats 2 times, but `id2` repeats 4 times + --> $DIR/issue-61033-2.rs:8:10 + | +LL | $( + | __________^ +LL | | +LL | | +LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times +LL | | )* + | |_________^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro/macro-repeat.rs b/src/test/ui/parser/macro/macro-repeat.rs index 580a1daacbf31..3ffbea217e79e 100644 --- a/src/test/ui/parser/macro/macro-repeat.rs +++ b/src/test/ui/parser/macro/macro-repeat.rs @@ -1,9 +1,12 @@ macro_rules! mac { - ( $($v:tt)* ) => ( - $v //~ ERROR still repeating at this depth - ) + ( $($v:tt)* ) => { + $v + //~^ ERROR still repeating at this depth + //~| ERROR still repeating at this depth + }; } fn main() { mac!(0); + mac!(1); } diff --git a/src/test/ui/parser/macro/macro-repeat.stderr b/src/test/ui/parser/macro/macro-repeat.stderr index c86684de74432..63554b197b91c 100644 --- a/src/test/ui/parser/macro/macro-repeat.stderr +++ b/src/test/ui/parser/macro/macro-repeat.stderr @@ -4,5 +4,11 @@ error: variable 'v' is still repeating at this depth LL | $v | ^^ -error: aborting due to previous error +error: variable 'v' is still repeating at this depth + --> $DIR/macro-repeat.rs:3:9 + | +LL | $v + | ^^ + +error: aborting due to 2 previous errors From 1bfa2483d587cbb41fb335e18459127394242ec1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 12:54:57 +0100 Subject: [PATCH 30/38] defatalize `compile_declarative_macro` --- src/librustc_expand/mbe/macro_rules.rs | 48 ++++++++++++------- ...ocal-ambiguity-multiple-parsing-options.rs | 8 ++++ ...-ambiguity-multiple-parsing-options.stderr | 14 ++++++ 3 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs create mode 100644 src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index d4fe382b84b61..6377347585c76 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Applicability, DiagnosticBuilder, FatalError}; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_feature::Features; use rustc_parse::parser::Parser; use rustc_session::parse::ParseSess; @@ -180,6 +180,19 @@ impl TTMacroExpander for MacroRulesMacroExpander { } } +struct MacroRulesDummyExpander; + +impl TTMacroExpander for MacroRulesDummyExpander { + fn expand<'cx>( + &self, + _: &'cx mut ExtCtxt<'_>, + sp: Span, + _: TokenStream, + ) -> Box { + DummyResult::any(sp) + } +} + fn trace_macros_note(cx_expansions: &mut FxHashMap>, sp: Span, message: String) { let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); cx_expansions.entry(sp).or_default().push(message); @@ -362,6 +375,18 @@ pub fn compile_declarative_macro( def: &ast::Item, edition: Edition, ) -> SyntaxExtension { + let mk_syn_ext = |expander| { + SyntaxExtension::new( + sess, + SyntaxExtensionKind::LegacyBang(expander), + def.span, + Vec::new(), + edition, + def.ident.name, + &def.attrs, + ) + }; + let diag = &sess.span_diagnostic; let lhs_nm = ast::Ident::new(sym::lhs, def.span); let rhs_nm = ast::Ident::new(sym::rhs, def.span); @@ -416,13 +441,12 @@ pub fn compile_declarative_macro( Failure(token, msg) => { let s = parse_failure_msg(&token); let sp = token.span.substitute_dummy(def.span); - let mut err = sess.span_diagnostic.struct_span_fatal(sp, &s); - err.span_label(sp, msg); - err.emit(); - FatalError.raise(); + sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit(); + return mk_syn_ext(Box::new(MacroRulesDummyExpander)); } - Error(sp, s) => { - sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise(); + Error(sp, msg) => { + sess.span_diagnostic.struct_span_err(sp.substitute_dummy(def.span), &msg).emit(); + return mk_syn_ext(Box::new(MacroRulesDummyExpander)); } }; @@ -494,15 +518,7 @@ pub fn compile_declarative_macro( valid, }); - SyntaxExtension::new( - sess, - SyntaxExtensionKind::LegacyBang(expander), - def.span, - Vec::new(), - edition, - def.ident.name, - &def.attrs, - ) + mk_syn_ext(expander) } fn check_lhs_nt_follows( diff --git a/src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs new file mode 100644 index 0000000000000..3967481098cff --- /dev/null +++ b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs @@ -0,0 +1,8 @@ +fn main() {} + +macro_rules! ambiguity { + ($($i:ident)* $j:ident) => {}; +} + +ambiguity!(error); //~ ERROR local ambiguity +ambiguity!(error); //~ ERROR local ambiguity diff --git a/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr new file mode 100644 index 0000000000000..0ae56c422213c --- /dev/null +++ b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr @@ -0,0 +1,14 @@ +error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j'). + --> $DIR/local-ambiguity-multiple-parsing-options.rs:7:12 + | +LL | ambiguity!(error); + | ^^^^^ + +error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j'). + --> $DIR/local-ambiguity-multiple-parsing-options.rs:8:12 + | +LL | ambiguity!(error); + | ^^^^^ + +error: aborting due to 2 previous errors + From 2868045a28f959e612185022688c4469e0b752cd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 13:06:01 +0100 Subject: [PATCH 31/38] expand: nix unused method --- src/librustc_expand/base.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index 518a214b4a510..59c1a5468f100 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; -use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported}; +use rustc_errors::{DiagnosticBuilder, ErrorReported}; use rustc_parse::{self, parser, MACRO_ARGUMENTS}; use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; @@ -1026,9 +1026,6 @@ impl<'a> ExtCtxt<'a> { pub fn span_err>(&self, sp: S, msg: &str) { self.parse_sess.span_diagnostic.span_err(sp, msg); } - pub fn span_err_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { - self.parse_sess.span_diagnostic.span_err_with_code(sp, msg, code); - } pub fn span_warn>(&self, sp: S, msg: &str) { self.parse_sess.span_diagnostic.span_warn(sp, msg); } From 0e0f9311dacad865c43953a1015ac00a010e19df Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 13:19:06 +0100 Subject: [PATCH 32/38] defatalize get_test_runner --- src/librustc_builtin_macros/test_harness.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index b87767f4a4127..160a5204eaf70 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -345,14 +345,14 @@ fn is_test_case(i: &ast::Item) -> bool { fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option { let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?; - test_attr.meta_item_list().map(|meta_list| { - if meta_list.len() != 1 { - sd.span_fatal(test_attr.span, "`#![test_runner(..)]` accepts exactly 1 argument") - .raise() - } - match meta_list[0].meta_item() { - Some(meta_item) if meta_item.is_word() => meta_item.path.clone(), - _ => sd.span_fatal(test_attr.span, "`test_runner` argument must be a path").raise(), - } - }) + let meta_list = test_attr.meta_item_list()?; + let span = test_attr.span; + match &*meta_list { + [single] => match single.meta_item() { + Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()), + _ => sd.struct_span_err(span, "`test_runner` argument must be a path").emit(), + }, + _ => sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(), + } + None } From 397996420040fb7245f1f5e09a8ec441522183c0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 13:27:56 +0100 Subject: [PATCH 33/38] defatalize expand_test_or_bench --- src/librustc_builtin_macros/test.rs | 16 ++++++++-------- .../test-attr-non-associated-functions.rs | 8 +++++++- .../test-attr-non-associated-functions.stderr | 12 +++++++++++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 39009ca27f102..bdc4ae2fe274b 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -74,16 +74,16 @@ pub fn expand_test_or_bench( return vec![]; } - let item = if let Annotatable::Item(i) = item { - i - } else { - cx.parse_sess - .span_diagnostic - .span_fatal( - item.span(), + let item = match item { + Annotatable::Item(i) => i, + other => { + cx.struct_span_err( + other.span(), "`#[test]` attribute is only allowed on non associated functions", ) - .raise(); + .emit(); + return vec![other]; + } }; if let ast::ItemKind::MacCall(_) = item.kind { diff --git a/src/test/ui/test-attrs/test-attr-non-associated-functions.rs b/src/test/ui/test-attrs/test-attr-non-associated-functions.rs index e475f5b4a75a5..31e567c396067 100644 --- a/src/test/ui/test-attrs/test-attr-non-associated-functions.rs +++ b/src/test/ui/test-attrs/test-attr-non-associated-functions.rs @@ -6,7 +6,13 @@ struct A {} impl A { #[test] - fn new() -> A { //~ ERROR `#[test]` attribute is only allowed on non associated functions + fn new() -> A { + //~^ ERROR `#[test]` attribute is only allowed on non associated functions + A {} + } + #[test] + fn recovery_witness() -> A { + //~^ ERROR `#[test]` attribute is only allowed on non associated functions A {} } } diff --git a/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr b/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr index cb3ae51823e45..a81b8f3980c37 100644 --- a/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr +++ b/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr @@ -2,9 +2,19 @@ error: `#[test]` attribute is only allowed on non associated functions --> $DIR/test-attr-non-associated-functions.rs:9:5 | LL | / fn new() -> A { +LL | | LL | | A {} LL | | } | |_____^ -error: aborting due to previous error +error: `#[test]` attribute is only allowed on non associated functions + --> $DIR/test-attr-non-associated-functions.rs:14:5 + | +LL | / fn recovery_witness() -> A { +LL | | +LL | | A {} +LL | | } + | |_____^ + +error: aborting due to 2 previous errors From 21944b3a108784eda5d27f2ca3b6d3769fe51a57 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 17 Mar 2020 14:13:32 +0100 Subject: [PATCH 34/38] expand: add recovery for parse_nt --- src/librustc_expand/mbe/macro_parser.rs | 29 +++++++++---------- src/librustc_expand/mbe/macro_rules.rs | 6 +++- src/test/ui/parser/issue-62894.stderr | 5 ++++ src/test/ui/parser/nt-parsing-has-recovery.rs | 10 +++++++ .../ui/parser/nt-parsing-has-recovery.stderr | 29 +++++++++++++++++++ 5 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/parser/nt-parsing-has-recovery.rs create mode 100644 src/test/ui/parser/nt-parsing-has-recovery.stderr diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 0d777d88cad3a..e868b7e36aac5 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -84,7 +84,7 @@ use rustc_parse::parser::{FollowedByType, Parser, PathStyle}; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol}; -use rustc_errors::{FatalError, PResult}; +use rustc_errors::PResult; use rustc_span::Span; use smallvec::{smallvec, SmallVec}; @@ -271,6 +271,7 @@ crate enum ParseResult { Failure(Token, &'static str), /// Fatal error (malformed macro?). Abort compilation. Error(rustc_span::Span, String), + ErrorReported, } /// A `ParseResult` where the `Success` variant contains a mapping of @@ -652,6 +653,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na Success(_) => {} Failure(token, msg) => return Failure(token, msg), Error(sp, msg) => return Error(sp, msg), + ErrorReported => return ErrorReported, } // inner parse loop handled all cur_items, so it's empty @@ -735,10 +737,11 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na let mut item = bb_items.pop().unwrap(); if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) { let match_cur = item.match_cur; - item.push_match( - match_cur, - MatchedNonterminal(Lrc::new(parse_nt(parser.to_mut(), span, ident.name))), - ); + let nt = match parse_nt(parser.to_mut(), span, ident.name) { + Err(()) => return ErrorReported, + Ok(nt) => nt, + }; + item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt))); item.idx += 1; item.match_cur += 1; } else { @@ -849,20 +852,16 @@ fn may_begin_with(token: &Token, name: Name) -> bool { /// # Returns /// /// The parsed non-terminal. -fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal { +fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Result { // FIXME(Centril): Consider moving this to `parser.rs` to make // the visibilities of the methods used below `pub(super)` at most. - if name == sym::tt { - return token::NtTT(p.parse_token_tree()); - } - match parse_nt_inner(p, sp, name) { - Ok(nt) => nt, - Err(mut err) => { - err.emit(); - FatalError.raise(); - } + return Ok(token::NtTT(p.parse_token_tree())); } + parse_nt_inner(p, sp, name).map_err(|mut err| { + err.span_label(sp, format!("while parsing argument for this `{}` macro fragment", name)) + .emit() + }) } fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> { diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 6377347585c76..43bc72090bc43 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -4,7 +4,7 @@ use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstF use crate::mbe; use crate::mbe::macro_check; use crate::mbe::macro_parser::parse_tt; -use crate::mbe::macro_parser::{Error, Failure, Success}; +use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success}; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; use crate::mbe::transcribe::transcribe; @@ -317,6 +317,7 @@ fn generic_extension<'cx>( cx.struct_span_err(span, &msg).emit(); return DummyResult::any(span); } + ErrorReported => return DummyResult::any(sp), } // The matcher was not `Success(..)`ful. @@ -448,6 +449,9 @@ pub fn compile_declarative_macro( sess.span_diagnostic.struct_span_err(sp.substitute_dummy(def.span), &msg).emit(); return mk_syn_ext(Box::new(MacroRulesDummyExpander)); } + ErrorReported => { + return mk_syn_ext(Box::new(MacroRulesDummyExpander)); + } }; let mut valid = true; diff --git a/src/test/ui/parser/issue-62894.stderr b/src/test/ui/parser/issue-62894.stderr index 6db380f7a7fe2..73e3552e3ec7a 100644 --- a/src/test/ui/parser/issue-62894.stderr +++ b/src/test/ui/parser/issue-62894.stderr @@ -42,6 +42,11 @@ LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! LL | LL | fn main() {} | ^^ unexpected token + | + ::: $SRC_DIR/libcore/macros/mod.rs:LL:COL + | +LL | ($left:expr, $right:expr) => ({ + | ---------- while parsing argument for this `expr` macro fragment error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/nt-parsing-has-recovery.rs b/src/test/ui/parser/nt-parsing-has-recovery.rs new file mode 100644 index 0000000000000..ccbeb398af5ba --- /dev/null +++ b/src/test/ui/parser/nt-parsing-has-recovery.rs @@ -0,0 +1,10 @@ +macro_rules! foo { + ($e:expr) => {} +} + +foo!(1 + @); //~ ERROR expected expression, found `@` +foo!(1 + @); //~ ERROR expected expression, found `@` + +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/nt-parsing-has-recovery.stderr b/src/test/ui/parser/nt-parsing-has-recovery.stderr new file mode 100644 index 0000000000000..263c4ad53612e --- /dev/null +++ b/src/test/ui/parser/nt-parsing-has-recovery.stderr @@ -0,0 +1,29 @@ +error: expected expression, found `@` + --> $DIR/nt-parsing-has-recovery.rs:5:10 + | +LL | ($e:expr) => {} + | ------- while parsing argument for this `expr` macro fragment +... +LL | foo!(1 + @); + | ^ expected expression + +error: expected expression, found `@` + --> $DIR/nt-parsing-has-recovery.rs:6:10 + | +LL | ($e:expr) => {} + | ------- while parsing argument for this `expr` macro fragment +... +LL | foo!(1 + @); + | ^ expected expression + +error[E0308]: mismatched types + --> $DIR/nt-parsing-has-recovery.rs:9:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From d8080d828c4bbe50f13143b82bac56d19ce79f1d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 18 Mar 2020 13:34:11 +0100 Subject: [PATCH 35/38] expand: address review comments --- src/librustc_expand/mbe/macro_rules.rs | 29 +++++++------------ .../edition-keywords-2018-2015-parsing.rs | 6 +++- .../edition-keywords-2018-2015-parsing.stderr | 25 ++++++++-------- .../edition-keywords-2018-2018-parsing.rs | 6 +++- .../edition-keywords-2018-2018-parsing.stderr | 25 ++++++++-------- src/test/ui/parser/macro/issue-33569.rs | 4 +-- src/test/ui/parser/macro/issue-33569.stderr | 6 ++-- .../ui/proc-macro/invalid-punct-ident-4.rs | 8 +++-- .../proc-macro/invalid-punct-ident-4.stderr | 19 ++++++------ 9 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 43bc72090bc43..859362b5e29d3 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -180,17 +180,12 @@ impl TTMacroExpander for MacroRulesMacroExpander { } } -struct MacroRulesDummyExpander; - -impl TTMacroExpander for MacroRulesDummyExpander { - fn expand<'cx>( - &self, - _: &'cx mut ExtCtxt<'_>, - sp: Span, - _: TokenStream, - ) -> Box { - DummyResult::any(sp) - } +fn macro_rules_dummy_expander<'cx>( + _: &'cx mut ExtCtxt<'_>, + span: Span, + _: TokenStream, +) -> Box { + DummyResult::any(span) } fn trace_macros_note(cx_expansions: &mut FxHashMap>, sp: Span, message: String) { @@ -443,14 +438,14 @@ pub fn compile_declarative_macro( let s = parse_failure_msg(&token); let sp = token.span.substitute_dummy(def.span); sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit(); - return mk_syn_ext(Box::new(MacroRulesDummyExpander)); + return mk_syn_ext(Box::new(macro_rules_dummy_expander)); } Error(sp, msg) => { sess.span_diagnostic.struct_span_err(sp.substitute_dummy(def.span), &msg).emit(); - return mk_syn_ext(Box::new(MacroRulesDummyExpander)); + return mk_syn_ext(Box::new(macro_rules_dummy_expander)); } ErrorReported => { - return mk_syn_ext(Box::new(MacroRulesDummyExpander)); + return mk_syn_ext(Box::new(macro_rules_dummy_expander)); } }; @@ -513,16 +508,14 @@ pub fn compile_declarative_macro( None => {} } - let expander: Box<_> = Box::new(MacroRulesMacroExpander { + mk_syn_ext(Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, transparency, lhses, rhses, valid, - }); - - mk_syn_ext(expander) + })) } fn check_lhs_nt_follows( diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs index a7a10d0f677af..d5ed9fb9a285e 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -1,6 +1,8 @@ // edition:2018 // aux-build:edition-kw-macro-2015.rs +#![feature(async_closure)] + fn main() {} #[macro_use] @@ -19,8 +21,10 @@ pub fn check_async() { r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` r#async = consumes_async_raw!(r#async); // OK - if passes_ident!(async) == 1 {} //~ ERROR async closures are unstable + if passes_ident!(async) == 1 {} if passes_ident!(r#async) == 1 {} // OK module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK + + let _recovery_witness: () = 0; //~ ERROR mismatched types } diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index 3c3b934b531c8..28663563c6ccd 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:14:13 + --> $DIR/edition-keywords-2018-2015-parsing.rs:16:13 | LL | let mut async = 1; | ^^^^^ expected identifier, found keyword @@ -10,7 +10,7 @@ LL | let mut r#async = 1; | ^^^^^^^ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:24:13 + --> $DIR/edition-keywords-2018-2015-parsing.rs:26:13 | LL | module::async(); | ^^^^^ expected identifier, found keyword @@ -21,13 +21,13 @@ LL | module::r#async(); | ^^^^^^^ error: no rules expected the token `r#async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:18:31 + --> $DIR/edition-keywords-2018-2015-parsing.rs:20:31 | LL | r#async = consumes_async!(r#async); | ^^^^^^^ no rules expected this token in macro call error: no rules expected the token `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:19:35 + --> $DIR/edition-keywords-2018-2015-parsing.rs:21:35 | LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call @@ -38,20 +38,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` | - ::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8 + ::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8 | LL | if passes_ident!(async) == 1 {} | -------------------- in this macro invocation -error[E0658]: async closures are unstable - --> $DIR/edition-keywords-2018-2015-parsing.rs:22:22 +error[E0308]: mismatched types + --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33 | -LL | if passes_ident!(async) == 1 {} - | ^^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs index b12ad76a74798..044ab249f2c26 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -1,6 +1,8 @@ // edition:2018 // aux-build:edition-kw-macro-2018.rs +#![feature(async_closure)] + fn main() {} #[macro_use] @@ -19,8 +21,10 @@ pub fn check_async() { r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` r#async = consumes_async_raw!(r#async); // OK - if passes_ident!(async) == 1 {} //~ ERROR async closures are unstable + if passes_ident!(async) == 1 {} if passes_ident!(r#async) == 1 {} // OK module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK + + let _recovery_witness: () = 0; //~ ERROR mismatched types } diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index a2b129d17e0be..cda7e65e437e8 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:14:13 + --> $DIR/edition-keywords-2018-2018-parsing.rs:16:13 | LL | let mut async = 1; | ^^^^^ expected identifier, found keyword @@ -10,7 +10,7 @@ LL | let mut r#async = 1; | ^^^^^^^ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:24:13 + --> $DIR/edition-keywords-2018-2018-parsing.rs:26:13 | LL | module::async(); | ^^^^^ expected identifier, found keyword @@ -21,13 +21,13 @@ LL | module::r#async(); | ^^^^^^^ error: no rules expected the token `r#async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:18:31 + --> $DIR/edition-keywords-2018-2018-parsing.rs:20:31 | LL | r#async = consumes_async!(r#async); | ^^^^^^^ no rules expected this token in macro call error: no rules expected the token `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:19:35 + --> $DIR/edition-keywords-2018-2018-parsing.rs:21:35 | LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call @@ -38,20 +38,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` | - ::: $DIR/edition-keywords-2018-2018-parsing.rs:22:8 + ::: $DIR/edition-keywords-2018-2018-parsing.rs:24:8 | LL | if passes_ident!(async) == 1 {} | -------------------- in this macro invocation -error[E0658]: async closures are unstable - --> $DIR/edition-keywords-2018-2018-parsing.rs:22:22 +error[E0308]: mismatched types + --> $DIR/edition-keywords-2018-2018-parsing.rs:29:33 | -LL | if passes_ident!(async) == 1 {} - | ^^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs index e32825ad3e064..80e2d7c6545ba 100644 --- a/src/test/ui/parser/macro/issue-33569.rs +++ b/src/test/ui/parser/macro/issue-33569.rs @@ -1,5 +1,3 @@ -fn main() {} - macro_rules! foo { { $+ } => { //~ ERROR expected identifier, found `+` //~^ ERROR missing fragment specifier @@ -8,3 +6,5 @@ macro_rules! foo { } foo!(); + +fn main() {} diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr index a08d26095f564..b4d38d3ce4806 100644 --- a/src/test/ui/parser/macro/issue-33569.stderr +++ b/src/test/ui/parser/macro/issue-33569.stderr @@ -1,17 +1,17 @@ error: expected identifier, found `+` - --> $DIR/issue-33569.rs:4:8 + --> $DIR/issue-33569.rs:2:8 | LL | { $+ } => { | ^ error: expected one of: `*`, `+`, or `?` - --> $DIR/issue-33569.rs:6:13 + --> $DIR/issue-33569.rs:4:13 | LL | $(x)(y) | ^^^ error: missing fragment specifier - --> $DIR/issue-33569.rs:4:8 + --> $DIR/issue-33569.rs:2:8 | LL | { $+ } => { | ^ diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.rs b/src/test/ui/proc-macro/invalid-punct-ident-4.rs index ab0250f53f699..59b347dac679c 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.rs @@ -1,10 +1,12 @@ // aux-build:invalid-punct-ident.rs -// We use `main` not found below as a witness for error recovery in proc macro expansion. - -#[macro_use] //~ ERROR `main` function not found +#[macro_use] extern crate invalid_punct_ident; lexer_failure!(); //~^ ERROR proc macro panicked //~| ERROR unexpected closing delimiter: `)` + +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr index 296e2fb094280..3b357aecea864 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr @@ -1,5 +1,5 @@ error: unexpected closing delimiter: `)` - --> $DIR/invalid-punct-ident-4.rs:8:1 + --> $DIR/invalid-punct-ident-4.rs:6:1 | LL | lexer_failure!(); | ^^^^^^^^^^^^^^^^^ unexpected closing delimiter @@ -7,20 +7,19 @@ LL | lexer_failure!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: proc macro panicked - --> $DIR/invalid-punct-ident-4.rs:8:1 + --> $DIR/invalid-punct-ident-4.rs:6:1 | LL | lexer_failure!(); | ^^^^^^^^^^^^^^^^^ -error[E0601]: `main` function not found in crate `invalid_punct_ident_4` - --> $DIR/invalid-punct-ident-4.rs:5:1 +error[E0308]: mismatched types + --> $DIR/invalid-punct-ident-4.rs:11:33 | -LL | / #[macro_use] -LL | | extern crate invalid_punct_ident; -LL | | -LL | | lexer_failure!(); - | |_________________^ consider adding a `main` function to `$DIR/invalid-punct-ident-4.rs` +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0308`. From d07103508af687e1b6277f8310e9a1621033d647 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 20 Mar 2020 17:01:53 +0100 Subject: [PATCH 36/38] fix rebase fallout --- src/test/ui/span/transitive-dep-span.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/span/transitive-dep-span.rs b/src/test/ui/span/transitive-dep-span.rs index b445d389c561a..2d46f74ad9bc9 100644 --- a/src/test/ui/span/transitive-dep-span.rs +++ b/src/test/ui/span/transitive-dep-span.rs @@ -11,3 +11,5 @@ extern crate transitive_dep_two; transitive_dep_two::parse_error!(); //~ ERROR expected one of + +fn main() {} From c415f12582b6b5ef75adaf24ba4b219653b79811 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 21 Mar 2020 22:12:24 +0100 Subject: [PATCH 37/38] fix rebase fallout due to #69497. --- src/test/ui/macros/trace_faulty_macros.rs | 12 ++++------ src/test/ui/macros/trace_faulty_macros.stderr | 23 ++++++++++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/test/ui/macros/trace_faulty_macros.rs b/src/test/ui/macros/trace_faulty_macros.rs index a55f05414b206..5a8e2f50ce33d 100644 --- a/src/test/ui/macros/trace_faulty_macros.rs +++ b/src/test/ui/macros/trace_faulty_macros.rs @@ -1,6 +1,6 @@ // compile-flags: -Z trace-macros -#![recursion_limit="4"] +#![recursion_limit = "4"] macro_rules! my_faulty_macro { () => { @@ -24,9 +24,7 @@ macro_rules! my_recursive_macro { } macro_rules! my_macro { - () => { - - }; + () => {}; } fn main() { @@ -39,7 +37,7 @@ fn main() { } #[my_macro] -fn use_bang_macro_as_attr(){} +fn use_bang_macro_as_attr() {} -#[derive(Debug)] -fn use_derive_macro_as_attr(){} +#[derive(Debug)] //~ ERROR `derive` may only be applied to structs +fn use_derive_macro_as_attr() {} diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 109b493b43717..aec9d1ab191af 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -13,7 +13,7 @@ LL | my_faulty_macro!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) note: trace_macro - --> $DIR/trace_faulty_macros.rs:33:5 + --> $DIR/trace_faulty_macros.rs:31:5 | LL | my_faulty_macro!(); | ^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | my_recursive_macro!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) note: trace_macro - --> $DIR/trace_faulty_macros.rs:34:5 + --> $DIR/trace_faulty_macros.rs:32:5 | LL | my_recursive_macro!(); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -60,5 +60,22 @@ LL | let a = pat_macro!(); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: `derive` may only be applied to structs, enums and unions + --> $DIR/trace_faulty_macros.rs:42:1 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ + +note: trace_macro + --> $DIR/trace_faulty_macros.rs:36:13 + | +LL | let a = pat_macro!(); + | ^^^^^^^^^^^^ + | + = note: expanding `pat_macro! { }` + = note: to `pat_macro ! (A { a : a, b : 0, c : _, .. }) ;` + = note: expanding `pat_macro! { A { a : a, b : 0, c : _, .. } }` + = note: to `A { a: a, b: 0, c: _, .. }` + +error: aborting due to 4 previous errors From 470e16372fb5ff0f2c35948ada4d0fd832401cb4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 23 Mar 2020 01:31:03 +0100 Subject: [PATCH 38/38] pacify missing sysroot spans issue --- src/test/ui/parser/issue-62894.rs | 5 +++++ src/test/ui/parser/issue-62894.stderr | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/ui/parser/issue-62894.rs b/src/test/ui/parser/issue-62894.rs index b9c0bf834ddb2..e38b7b6508937 100644 --- a/src/test/ui/parser/issue-62894.rs +++ b/src/test/ui/parser/issue-62894.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + // Regression test for #62894, shouldn't crash. // error-pattern: this file contains an unclosed delimiter // error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn` diff --git a/src/test/ui/parser/issue-62894.stderr b/src/test/ui/parser/issue-62894.stderr index 73e3552e3ec7a..4a1d7e275bed8 100644 --- a/src/test/ui/parser/issue-62894.stderr +++ b/src/test/ui/parser/issue-62894.stderr @@ -1,5 +1,5 @@ error: this file contains an unclosed delimiter - --> $DIR/issue-62894.rs:7:14 + --> $DIR/issue-62894.rs:12:14 | LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! | - - - unclosed delimiter @@ -11,7 +11,7 @@ LL | fn main() {} | ^ error: this file contains an unclosed delimiter - --> $DIR/issue-62894.rs:7:14 + --> $DIR/issue-62894.rs:12:14 | LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! | - - - unclosed delimiter @@ -23,7 +23,7 @@ LL | fn main() {} | ^ error: this file contains an unclosed delimiter - --> $DIR/issue-62894.rs:7:14 + --> $DIR/issue-62894.rs:12:14 | LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! | - - - unclosed delimiter @@ -35,7 +35,7 @@ LL | fn main() {} | ^ error: expected one of `(`, `[`, or `{`, found keyword `fn` - --> $DIR/issue-62894.rs:7:1 + --> $DIR/issue-62894.rs:12:1 | LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! | - expected one of `(`, `[`, or `{`