From 58ae4a9a5388d9c2c5e4ac435ea69a2b456ab008 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 May 2020 12:13:27 +0200 Subject: [PATCH 1/9] de-promote Duration::from_secs --- src/libcore/time.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index ed1d5d46db5c4..e2ceaf80c0cda 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -152,7 +152,6 @@ impl Duration { /// ``` #[stable(feature = "duration", since = "1.3.0")] #[inline] - #[rustc_promotable] #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] pub const fn from_secs(secs: u64) -> Duration { Duration { secs, nanos: 0 } From 7242bda3dc6ad638392577fd43d1e30c3671ae74 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 30 May 2020 03:04:15 +0200 Subject: [PATCH 2/9] Be more careful around ty::Error in generators --- src/librustc_mir/transform/generator.rs | 69 +++++++++++++++---------- src/librustc_ty/needs_drop.rs | 10 +++- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 461b13c4f6382..60c040c25f97c 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -669,40 +669,33 @@ fn compute_storage_conflicts( storage_conflicts } -fn compute_layout<'tcx>( +/// Validates the typeck view of the generator against the actual set of types retained between +/// yield points. +fn sanitize_witness<'tcx>( tcx: TyCtxt<'tcx>, - source: MirSource<'tcx>, + body: &Body<'tcx>, + did: DefId, + witness: Ty<'tcx>, upvars: &Vec>, - interior: Ty<'tcx>, - always_live_locals: &storage::AlwaysLiveLocals, - movable: bool, - body: &mut Body<'tcx>, -) -> ( - FxHashMap, VariantIdx, usize)>, - GeneratorLayout<'tcx>, - IndexVec>>, + retained: &BitSet, ) { - // Use a liveness analysis to compute locals which are live across a suspension point - let LivenessInfo { - live_locals, - live_locals_at_suspension_points, - storage_conflicts, - storage_liveness, - } = locals_live_across_suspend_points(tcx, body, source, always_live_locals, movable); - - // Erase regions from the types passed in from typeck so we can compare them with - // MIR types let allowed_upvars = tcx.erase_regions(upvars); - let allowed = match interior.kind { + let allowed = match witness.kind { ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s), - _ => bug!(), + _ => { + tcx.sess.delay_span_bug( + body.span, + &format!("unexpected generator witness type {:?}", witness.kind), + ); + return; + } }; - let param_env = tcx.param_env(source.def_id()); + let param_env = tcx.param_env(did); for (local, decl) in body.local_decls.iter_enumerated() { - // Ignore locals which are internal or not live - if !live_locals.contains(local) || decl.internal { + // Ignore locals which are internal or not retained between yields. + if !retained.contains(local) || decl.internal { continue; } let decl_ty = tcx.normalize_erasing_regions(param_env, decl.ty); @@ -715,10 +708,34 @@ fn compute_layout<'tcx>( "Broken MIR: generator contains type {} in MIR, \ but typeck only knows about {}", decl.ty, - interior + witness, ); } } +} + +fn compute_layout<'tcx>( + tcx: TyCtxt<'tcx>, + source: MirSource<'tcx>, + upvars: &Vec>, + interior: Ty<'tcx>, + always_live_locals: &storage::AlwaysLiveLocals, + movable: bool, + body: &mut Body<'tcx>, +) -> ( + FxHashMap, VariantIdx, usize)>, + GeneratorLayout<'tcx>, + IndexVec>>, +) { + // Use a liveness analysis to compute locals which are live across a suspension point + let LivenessInfo { + live_locals, + live_locals_at_suspension_points, + storage_conflicts, + storage_liveness, + } = locals_live_across_suspend_points(tcx, body, source, always_live_locals, movable); + + sanitize_witness(tcx, body, source.def_id(), interior, upvars, &live_locals); // Gather live local types and their indices. let mut locals = IndexVec::::new(); diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs index 1b059fa3dbdf0..ca5477ef4a986 100644 --- a/src/librustc_ty/needs_drop.rs +++ b/src/librustc_ty/needs_drop.rs @@ -98,7 +98,7 @@ where } } - ty::Generator(_, substs, _) => { + ty::Generator(def_id, substs, _) => { let substs = substs.as_generator(); for upvar_ty in substs.upvar_tys() { queue_type(self, upvar_ty); @@ -107,7 +107,13 @@ where let witness = substs.witness(); let interior_tys = match &witness.kind { ty::GeneratorWitness(tys) => tcx.erase_late_bound_regions(tys), - _ => bug!(), + _ => { + tcx.sess.delay_span_bug( + tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP), + &format!("unexpected generator witness type {:?}", witness), + ); + return Some(Err(AlwaysRequiresDrop)); + } }; for interior_ty in interior_tys { From eaa57cfb712e0e61bbc61d2309c0fa708f4f297b Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 23 May 2020 11:11:20 -0700 Subject: [PATCH 3/9] `PolyTraitRef::self_ty` returns `Binder` --- src/librustc_middle/ty/sty.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index f4962ced6c03a..f01b9751c406b 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -765,8 +765,8 @@ impl<'tcx> TraitRef<'tcx> { pub type PolyTraitRef<'tcx> = Binder>; impl<'tcx> PolyTraitRef<'tcx> { - pub fn self_ty(&self) -> Ty<'tcx> { - self.skip_binder().self_ty() + pub fn self_ty(&self) -> Binder> { + self.map_bound_ref(|tr| tr.self_ty()) } pub fn def_id(&self) -> DefId { From b4e06b9e8899ed907a57d4ecea9dd1be6896a852 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 23 May 2020 11:12:06 -0700 Subject: [PATCH 4/9] Call `skip_binder` or `no_bound_vars` before `self_ty` --- .../traits/error_reporting/mod.rs | 32 ++++++++++++------- .../traits/error_reporting/suggestions.rs | 24 ++++++++++---- .../traits/specialize/mod.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustdoc/clean/mod.rs | 4 +-- .../clippy_lints/src/future_not_send.rs | 2 +- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index f8b33b782c017..3c9665e4c1414 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ( Some(format!( "`?` couldn't convert the error to `{}`", - trait_ref.self_ty(), + trait_ref.skip_binder().self_ty(), )), Some( "the question mark operation (`?`) implicitly performs a \ @@ -339,7 +339,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let Some(ret_span) = self.return_type_span(obligation) { err.span_label( ret_span, - &format!("expected `{}` because of this", trait_ref.self_ty()), + &format!( + "expected `{}` because of this", + trait_ref.skip_binder().self_ty() + ), ); } } @@ -352,7 +355,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { "{}the trait `{}` is not implemented for `{}`", pre_message, trait_ref.print_only_trait_path(), - trait_ref.self_ty(), + trait_ref.skip_binder().self_ty(), ) }; @@ -642,7 +645,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - let found_trait_ty = found_trait_ref.self_ty(); + let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() { + Some(ty) => ty, + None => return, + }; let found_did = match found_trait_ty.kind { ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did), @@ -1359,11 +1365,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ) { let get_trait_impl = |trait_def_id| { let mut trait_impl = None; - self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| { - if trait_impl.is_none() { - trait_impl = Some(impl_def_id); - } - }); + self.tcx.for_each_relevant_impl( + trait_def_id, + trait_ref.skip_binder().self_ty(), + |impl_def_id| { + if trait_impl.is_none() { + trait_impl = Some(impl_def_id); + } + }, + ); trait_impl }; let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); @@ -1434,7 +1444,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let mut err = match predicate.kind() { ty::PredicateKind::Trait(ref data, _) => { let trait_ref = data.to_poly_trait_ref(); - let self_ty = trait_ref.self_ty(); + let self_ty = trait_ref.skip_binder().self_ty(); debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); if predicate.references_error() { @@ -1552,7 +1562,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } ty::PredicateKind::Projection(ref data) => { let trait_ref = data.to_poly_trait_ref(self.tcx); - let self_ty = trait_ref.self_ty(); + let self_ty = trait_ref.skip_binder().self_ty(); let ty = data.skip_binder().ty; if predicate.references_error() { return; diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index cfbea9ee0f196..501cde40d245e 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -318,7 +318,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, body_id: hir::HirId, ) { - let self_ty = trait_ref.self_ty(); + let self_ty = trait_ref.skip_binder().self_ty(); let (param_ty, projection) = match &self_ty.kind { ty::Param(_) => (true, None), ty::Projection(projection) => (false, Some(projection)), @@ -524,7 +524,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_ref: &ty::Binder>, points_at_arg: bool, ) { - let self_ty = trait_ref.self_ty(); + let self_ty = match trait_ref.self_ty().no_bound_vars() { + None => return, + Some(ty) => ty, + }; + let (def_id, output_ty, callable) = match self_ty.kind { ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"), ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"), @@ -707,7 +711,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - let mut suggested_ty = trait_ref.self_ty(); + let mut suggested_ty = match trait_ref.self_ty().no_bound_vars() { + Some(ty) => ty, + None => return, + }; for refs_remaining in 0..refs_number { if let ty::Ref(_, inner_ty, _) = suggested_ty.kind { @@ -829,6 +836,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span: Span, trait_ref: &ty::Binder>, ) { + let is_empty_tuple = + |ty: ty::Binder>| ty.skip_binder().kind == ty::Tuple(ty::List::empty()); + let hir = self.tcx.hir(); let parent_node = hir.get_parent_node(obligation.cause.body_id); let node = hir.find(parent_node); @@ -840,7 +850,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let hir::ExprKind::Block(blk, _) = &body.value.kind { if sig.decl.output.span().overlaps(span) && blk.expr.is_none() - && "()" == &trait_ref.self_ty().to_string() + && is_empty_tuple(trait_ref.self_ty()) { // FIXME(estebank): When encountering a method with a trait // bound not satisfied in the return type with a body that has @@ -1271,7 +1281,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ObligationCauseCode::DerivedObligation(derived_obligation) | ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) | ObligationCauseCode::ImplDerivedObligation(derived_obligation) => { - let ty = derived_obligation.parent_trait_ref.self_ty(); + let ty = derived_obligation.parent_trait_ref.skip_binder().self_ty(); debug!( "maybe_note_obligation_cause_for_async_await: \ parent_trait_ref={:?} self_ty.kind={:?}", @@ -1911,7 +1921,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let impls_future = self.tcx.type_implements_trait(( future_trait, - self_ty, + self_ty.skip_binder(), ty::List::empty(), obligation.param_env, )); @@ -1927,7 +1937,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let projection_ty = ty::ProjectionTy { // `T` substs: self.tcx.mk_substs_trait( - trait_ref.self_ty(), + trait_ref.self_ty().skip_binder(), self.fresh_substs_for_item(span, item_def_id), ), // `Future::Output` diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs index f2b43754acaea..2b596be954267 100644 --- a/src/librustc_trait_selection/traits/specialize/mod.rs +++ b/src/librustc_trait_selection/traits/specialize/mod.rs @@ -496,7 +496,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option for (p, _) in predicates { if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() { if Some(poly_trait_ref.def_id()) == sized_trait { - types_without_default_bounds.remove(poly_trait_ref.self_ty()); + types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder()); continue; } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a8fa65a135ac2..4e76fd4ca11fb 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3812,7 +3812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, expected_vid: ty::TyVid, ) -> bool { - let self_ty = self.shallow_resolve(trait_ref.self_ty()); + let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty()); debug!( "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})", trait_ref, self_ty, expected_vid diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 371df7444b004..dd4df11b1df38 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -500,7 +500,7 @@ impl<'a> Clean for ty::PolyTraitPredicate<'a> { fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { let poly_trait_ref = self.map_bound(|pred| pred.trait_ref); WherePredicate::BoundPredicate { - ty: poly_trait_ref.self_ty().clean(cx), + ty: poly_trait_ref.skip_binder().self_ty().clean(cx), bounds: vec![poly_trait_ref.clean(cx)], } } @@ -755,7 +755,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx let mut projection = None; let param_idx = (|| { if let Some(trait_ref) = p.to_opt_poly_trait_ref() { - if let ty::Param(param) = trait_ref.self_ty().kind { + if let ty::Param(param) = trait_ref.skip_binder().self_ty().kind { return Some(param.index); } } else if let Some(outlives) = p.to_opt_type_outlives() { diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 0a02aa7533c17..17dd3cd5493e7 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend { let trait_ref = trait_pred.to_poly_trait_ref(); db.note(&*format!( "`{}` doesn't implement `{}`", - trait_ref.self_ty(), + trait_ref.skip_binder().self_ty(), trait_ref.print_only_trait_path(), )); } From b541d3da5d9f89407c7072f4a6d65872cf30a577 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 31 May 2020 16:20:50 -0400 Subject: [PATCH 5/9] Add `-Z span-debug` to allow for easier debugging of proc macros Currently, the `Debug` impl for `proc_macro::Span` just prints out the byte range. This can make debugging proc macros (either as a crate author or as a compiler developer) very frustrating, since neither the actual filename nor the `SyntaxContext` is displayed. This commit adds a perma-unstable flag `-Z span-debug`. When enabled, the `Debug` impl for `proc_macro::Span` simply forwards directly to `rustc_span::Span`. Once #72618 is merged, this will start displaying actual line numbers. While `Debug` impls are not subject to Rust's normal stability guarnatees, we probably shouldn't expose any additional information on stable until `#![feature(proc_macro_span)]` is stabilized. Otherwise, we would be providing a 'backdoor' way to access information that's supposed be behind unstable APIs. --- src/librustc_expand/expand.rs | 2 + src/librustc_expand/proc_macro_server.rs | 8 +- src/librustc_interface/passes.rs | 1 + src/librustc_interface/tests.rs | 1 + src/librustc_session/options.rs | 2 + .../proc-macro/debug/dump-debug-span-debug.rs | 41 +++++ .../debug/dump-debug-span-debug.stderr | 166 ++++++++++++++++++ 7 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/proc-macro/debug/dump-debug-span-debug.rs create mode 100644 src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 5214ca0dc7fff..4e41bd4bbfa08 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1789,6 +1789,7 @@ pub struct ExpansionConfig<'feat> { pub trace_mac: bool, pub should_test: bool, // If false, strip `#[test]` nodes pub keep_macs: bool, + pub span_debug: bool, // If true, use verbose debugging for `proc_macro::Span` } impl<'feat> ExpansionConfig<'feat> { @@ -1800,6 +1801,7 @@ impl<'feat> ExpansionConfig<'feat> { trace_mac: false, should_test: false, keep_macs: false, + span_debug: false, } } diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 36af83711f7e4..79fa091ba1808 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -352,6 +352,7 @@ pub(crate) struct Rustc<'a> { def_site: Span, call_site: Span, mixed_site: Span, + span_debug: bool, } impl<'a> Rustc<'a> { @@ -362,6 +363,7 @@ impl<'a> Rustc<'a> { def_site: cx.with_def_site_ctxt(expn_data.def_site), call_site: cx.with_call_site_ctxt(expn_data.call_site), mixed_site: cx.with_mixed_site_ctxt(expn_data.call_site), + span_debug: cx.ecfg.span_debug, } } @@ -646,7 +648,11 @@ impl server::Diagnostic for Rustc<'_> { impl server::Span for Rustc<'_> { fn debug(&mut self, span: Self::Span) -> String { - format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0) + if self.span_debug { + format!("{:?}", span) + } else { + format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0) + } } fn def_site(&mut self) -> Self::Span { self.def_site diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a01170db807f2..9a60e74d94d01 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -291,6 +291,7 @@ fn configure_and_expand_inner<'a>( recursion_limit: sess.recursion_limit(), trace_mac: sess.opts.debugging_opts.trace_macros, should_test: sess.opts.test, + span_debug: sess.opts.debugging_opts.span_debug, ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string()) }; diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index 18cbea858d47a..87647f3b0b017 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -506,6 +506,7 @@ fn test_debugging_options_tracking_hash() { untracked!(save_analysis, true); untracked!(self_profile, SwitchWithOptPath::Enabled(None)); untracked!(self_profile_events, Some(vec![String::new()])); + untracked!(span_debug, true); untracked!(span_free_formats, true); untracked!(strip, Strip::None); untracked!(terminal_width, Some(80)); diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index a38e7f063d79a..d22c6ec9d7d01 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -996,6 +996,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "make the current crate share its generic instantiations"), show_span: Option = (None, parse_opt_string, [TRACKED], "show spans for compiler debugging (expr|pat|ty)"), + span_debug: bool = (false, parse_bool, [UNTRACKED], + "forward proc_macro::Span's `Debug` impl to `Span`"), // o/w tests have closure@path span_free_formats: bool = (false, parse_bool, [UNTRACKED], "exclude spans when debug-printing compiler state (default: no)"), diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs new file mode 100644 index 0000000000000..fd34eb974c094 --- /dev/null +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs @@ -0,0 +1,41 @@ +// run-pass +// aux-build:macro-dump-debug.rs +// compile-flags: -Z span-debug + +extern crate macro_dump_debug; +use macro_dump_debug::dump_debug; + +dump_debug! { + ident // ident + r#ident // raw ident + , // alone punct + ==> // joint punct + () // empty group + [_] // nonempty group + + // unsuffixed literals + 0 + 1.0 + "S" + b"B" + r"R" + r##"R"## + br"BR" + br##"BR"## + 'C' + b'B' + + // suffixed literals + 0q + 1.0q + "S"q + b"B"q + r"R"q + r##"R"##q + br"BR"q + br##"BR"##q + 'C'q + b'B'q +} + +fn main() {} diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr new file mode 100644 index 0000000000000..163a2c9f44cad --- /dev/null +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr @@ -0,0 +1,166 @@ +TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 }], span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 }] +TokenStream [ + Ident { + ident: "ident", + span: $DIR/dump-debug-span-debug.rs:9:5: 9:10, + }, + Ident { + ident: "r#ident", + span: $DIR/dump-debug-span-debug.rs:10:5: 10:12, + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:11:5: 11:6, + }, + Punct { + ch: '=', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:12:5: 12:7, + }, + Punct { + ch: '=', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:12:5: 12:7, + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:12:7: 12:8, + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [], + span: $DIR/dump-debug-span-debug.rs:13:5: 13:7, + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "_", + span: $DIR/dump-debug-span-debug.rs:14:6: 14:7, + }, + ], + span: $DIR/dump-debug-span-debug.rs:14:5: 14:8, + }, + Literal { + kind: Integer, + symbol: "0", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:17:5: 17:6, + }, + Literal { + kind: Float, + symbol: "1.0", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:18:5: 18:8, + }, + Literal { + kind: Str, + symbol: "S", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:19:5: 19:8, + }, + Literal { + kind: ByteStr, + symbol: "B", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:20:5: 20:9, + }, + Literal { + kind: StrRaw(0), + symbol: "R", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:21:5: 21:9, + }, + Literal { + kind: StrRaw(2), + symbol: "R", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:22:5: 22:13, + }, + Literal { + kind: ByteStrRaw(0), + symbol: "BR", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:23:5: 23:11, + }, + Literal { + kind: ByteStrRaw(2), + symbol: "BR", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:24:5: 24:15, + }, + Literal { + kind: Char, + symbol: "C", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:25:5: 25:8, + }, + Literal { + kind: Byte, + symbol: "B", + suffix: None, + span: $DIR/dump-debug-span-debug.rs:26:5: 26:9, + }, + Literal { + kind: Integer, + symbol: "0", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:29:5: 29:7, + }, + Literal { + kind: Float, + symbol: "1.0", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:30:5: 30:9, + }, + Literal { + kind: Str, + symbol: "S", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:31:5: 31:9, + }, + Literal { + kind: ByteStr, + symbol: "B", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:32:5: 32:10, + }, + Literal { + kind: StrRaw(0), + symbol: "R", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:33:5: 33:10, + }, + Literal { + kind: StrRaw(2), + symbol: "R", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:34:5: 34:14, + }, + Literal { + kind: ByteStrRaw(0), + symbol: "BR", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:35:5: 35:12, + }, + Literal { + kind: ByteStrRaw(2), + symbol: "BR", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:36:5: 36:16, + }, + Literal { + kind: Char, + symbol: "C", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:37:5: 37:9, + }, + Literal { + kind: Byte, + symbol: "B", + suffix: Some("q"), + span: $DIR/dump-debug-span-debug.rs:38:5: 38:10, + }, +] From 2764e54c29d0f19242e794d5eecd00cc5470f530 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Fri, 5 Jun 2020 01:49:50 +0200 Subject: [PATCH 6/9] impl ToSocketAddrs for (String, u16) --- src/libstd/net/addr.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index b780340884e1f..25897c502ec5e 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -1000,6 +1000,14 @@ impl ToSocketAddrs for (&str, u16) { } } +#[stable(feature = "string_u16_to_socket_addrs", since = "1.46.0")] +impl ToSocketAddrs for (String, u16) { + type Iter = vec::IntoIter; + fn to_socket_addrs(&self) -> io::Result> { + (&*self.0, self.1).to_socket_addrs() + } +} + // accepts strings like 'localhost:12345' #[stable(feature = "rust1", since = "1.0.0")] impl ToSocketAddrs for str { From 84e4777ae203c0ce93faad89abf4ab1f0b006af2 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sat, 6 Jun 2020 00:38:39 +0100 Subject: [PATCH 7/9] save_analysis: fix ice in `get_expr_data` --- src/librustc_save_analysis/lib.rs | 10 +++++++--- src/test/ui/save-analysis/issue-73022.rs | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/save-analysis/issue-73022.rs diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 8c7731c18e9c4..0341b54252661 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -534,10 +534,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } } - hir::ExprKind::Struct(hir::QPath::Resolved(_, path), ..) => { + hir::ExprKind::Struct(qpath, ..) => { + let segment = match qpath { + hir::QPath::Resolved(_, path) => path.segments.last().unwrap(), + hir::QPath::TypeRelative(_, segment) => segment, + }; match self.tables.expr_ty_adjusted(&hir_node).kind { ty::Adt(def, _) if !def.is_enum() => { - let sub_span = path.segments.last().unwrap().ident.span; + let sub_span = segment.ident.span; filter!(self.span_utils, sub_span); let span = self.span_from_span(sub_span); Some(Data::RefData(Ref { @@ -580,7 +584,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } _ => { // FIXME - bug!(); + bug!("invalid expression: {:?}", expr); } } } diff --git a/src/test/ui/save-analysis/issue-73022.rs b/src/test/ui/save-analysis/issue-73022.rs new file mode 100644 index 0000000000000..9ad89a319ba3b --- /dev/null +++ b/src/test/ui/save-analysis/issue-73022.rs @@ -0,0 +1,13 @@ +// build-pass +// compile-flags: -Zsave-analysis +enum Enum2 { + Variant8 { _field: bool }, +} + +impl Enum2 { + fn new_variant8() -> Enum2 { + Self::Variant8 { _field: true } + } +} + +fn main() {} From 4d6a307f3f8090005ac2d12e49254aefeab478dd Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sat, 6 Jun 2020 00:54:28 +0100 Subject: [PATCH 8/9] save_analysis: fix panic in `write_sub_paths_truncated` --- src/librustc_save_analysis/dump_visitor.rs | 8 +++++--- src/test/ui/save-analysis/issue-73020.rs | 5 +++++ src/test/ui/save-analysis/issue-73020.stderr | 9 +++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/save-analysis/issue-73020.rs create mode 100644 src/test/ui/save-analysis/issue-73020.stderr diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index a5e61ab9ab033..0c76c9108dd56 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -210,9 +210,11 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // As write_sub_paths, but does not process the last ident in the path (assuming it // will be processed elsewhere). See note on write_sub_paths about global. fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx>) { - for seg in &path.segments[..path.segments.len() - 1] { - if let Some(data) = self.save_ctxt.get_path_segment_data(seg) { - self.dumper.dump_ref(data); + if path.segments.len() > 0 { + for seg in &path.segments[..path.segments.len() - 1] { + if let Some(data) = self.save_ctxt.get_path_segment_data(seg) { + self.dumper.dump_ref(data); + } } } } diff --git a/src/test/ui/save-analysis/issue-73020.rs b/src/test/ui/save-analysis/issue-73020.rs new file mode 100644 index 0000000000000..87ce0933681c5 --- /dev/null +++ b/src/test/ui/save-analysis/issue-73020.rs @@ -0,0 +1,5 @@ +// compile-flags: -Zsave-analysis +use {self}; //~ ERROR E0431 + +fn main () { +} diff --git a/src/test/ui/save-analysis/issue-73020.stderr b/src/test/ui/save-analysis/issue-73020.stderr new file mode 100644 index 0000000000000..5bb3aae99975c --- /dev/null +++ b/src/test/ui/save-analysis/issue-73020.stderr @@ -0,0 +1,9 @@ +error[E0431]: `self` import can only appear in an import list with a non-empty prefix + --> $DIR/issue-73020.rs:2:6 + | +LL | use {self}; + | ^^^^ can only appear in an import list with a non-empty prefix + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0431`. From 32c488f045fb9fe0fc45c6dacb9938ebc6767598 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 6 Jun 2020 15:54:07 +0200 Subject: [PATCH 9/9] remove outdated comment --- src/librustc_middle/ty/sty.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index f4962ced6c03a..32a685297122b 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -724,10 +724,6 @@ impl<'tcx> Binder<&'tcx List>> { /// /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the substitutions. -/// -/// Note that a `TraitRef` introduces a level of region binding, to -/// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>` -/// or higher-ranked object types. #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] #[derive(HashStable, TypeFoldable)] pub struct TraitRef<'tcx> {