From 58ae4a9a5388d9c2c5e4ac435ea69a2b456ab008 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 May 2020 12:13:27 +0200 Subject: [PATCH 1/4] 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 071f0422c6dd897bc61891f96d4448df44d8069f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 28 May 2020 22:12:31 +0300 Subject: [PATCH 2/4] linker: Add a linker rerun hack for gcc versions not supporting -static-pie --- src/librustc_codegen_ssa/back/link.rs | 65 +++++++++++++++++--- src/librustc_target/spec/tests/tests_impl.rs | 5 ++ 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 9a7c4907754b0..b322e9a8fef1c 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -12,7 +12,7 @@ use rustc_session::utils::NativeLibKind; /// need out of the shared crate context before we get rid of it. use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; -use rustc_target::spec::crt_objects::CrtObjectsFallback; +use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor}; use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel}; @@ -25,16 +25,10 @@ use crate::{looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FIL use cc::windows_registry; use tempfile::{Builder as TempFileBuilder, TempDir}; -use std::ascii; -use std::char; -use std::env; use std::ffi::OsString; -use std::fmt; -use std::fs; -use std::io; use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; -use std::str; +use std::{ascii, char, env, fmt, fs, io, mem, str}; pub fn remove(sess: &Session, path: &Path) { if let Err(e) = fs::remove_file(path) { @@ -543,6 +537,61 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( continue; } + // Detect '-static-pie' used with an older version of gcc or clang not supporting it. + // Fallback from '-static-pie' to '-static' in that case. + if sess.target.target.options.linker_is_gnu + && flavor != LinkerFlavor::Ld + && (out.contains("unrecognized command line option") + || out.contains("unknown argument")) + && (out.contains("-static-pie") || out.contains("--no-dynamic-linker")) + && cmd.get_args().iter().any(|e| e.to_string_lossy() == "-static-pie") + { + info!("linker output: {:?}", out); + warn!( + "Linker does not support -static-pie command line option. Retrying with -static instead." + ); + // Mirror `add_(pre,post)_link_objects` to replace CRT objects. + let fallback = crt_objects_fallback(sess, crate_type); + let opts = &sess.target.target.options; + let pre_objects = + if fallback { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects }; + let post_objects = + if fallback { &opts.post_link_objects_fallback } else { &opts.post_link_objects }; + let get_objects = |objects: &CrtObjects, kind| { + objects + .get(&kind) + .iter() + .copied() + .flatten() + .map(|obj| get_object_file_path(sess, obj).into_os_string()) + .collect::>() + }; + let pre_objects_static_pie = get_objects(pre_objects, LinkOutputKind::StaticPicExe); + let post_objects_static_pie = get_objects(post_objects, LinkOutputKind::StaticPicExe); + let mut pre_objects_static = get_objects(pre_objects, LinkOutputKind::StaticNoPicExe); + let mut post_objects_static = get_objects(post_objects, LinkOutputKind::StaticNoPicExe); + // Assume that we know insertion positions for the replacement arguments from replaced + // arguments, which is true for all supported targets. + assert!(pre_objects_static.is_empty() || !pre_objects_static_pie.is_empty()); + assert!(post_objects_static.is_empty() || !post_objects_static_pie.is_empty()); + for arg in cmd.take_args() { + if arg.to_string_lossy() == "-static-pie" { + // Replace the output kind. + cmd.arg("-static"); + } else if pre_objects_static_pie.contains(&arg) { + // Replace the pre-link objects (replace the first and remove the rest). + cmd.args(mem::take(&mut pre_objects_static)); + } else if post_objects_static_pie.contains(&arg) { + // Replace the post-link objects (replace the first and remove the rest). + cmd.args(mem::take(&mut post_objects_static)); + } else { + cmd.arg(arg); + } + } + info!("{:?}", &cmd); + continue; + } + // Here's a terribly awful hack that really shouldn't be present in any // compiler. Here an environment variable is supported to automatically // retry the linker invocation if the linker looks like it segfaulted. diff --git a/src/librustc_target/spec/tests/tests_impl.rs b/src/librustc_target/spec/tests/tests_impl.rs index 4cf186bdd7c1a..fb3f912ffde1a 100644 --- a/src/librustc_target/spec/tests/tests_impl.rs +++ b/src/librustc_target/spec/tests/tests_impl.rs @@ -39,5 +39,10 @@ impl Target { assert_eq!(self.options.lld_flavor, LldFlavor::Link); } } + assert!( + (self.options.pre_link_objects_fallback.is_empty() + && self.options.post_link_objects_fallback.is_empty()) + || self.options.crt_objects_fallback.is_some() + ); } } From eaa57cfb712e0e61bbc61d2309c0fa708f4f297b Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 23 May 2020 11:11:20 -0700 Subject: [PATCH 3/4] `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/4] 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(), )); }