Skip to content

Rollup of 7 pull requests #73062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/libcore/time.rs
Original file line number Diff line number Diff line change
@@ -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 }
2 changes: 2 additions & 0 deletions src/librustc_expand/expand.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}

8 changes: 7 additions & 1 deletion src/librustc_expand/proc_macro_server.rs
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
@@ -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())
};

1 change: 1 addition & 0 deletions src/librustc_interface/tests.rs
Original file line number Diff line number Diff line change
@@ -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));
8 changes: 2 additions & 6 deletions src/librustc_middle/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -724,10 +724,6 @@ impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
///
/// Trait references also appear in object types like `Foo<U>`, 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> {
@@ -765,8 +761,8 @@ impl<'tcx> TraitRef<'tcx> {
pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;

impl<'tcx> PolyTraitRef<'tcx> {
pub fn self_ty(&self) -> Ty<'tcx> {
self.skip_binder().self_ty()
pub fn self_ty(&self) -> Binder<Ty<'tcx>> {
self.map_bound_ref(|tr| tr.self_ty())
}

pub fn def_id(&self) -> DefId {
69 changes: 43 additions & 26 deletions src/librustc_mir/transform/generator.rs
Original file line number Diff line number Diff line change
@@ -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<Ty<'tcx>>,
interior: Ty<'tcx>,
always_live_locals: &storage::AlwaysLiveLocals,
movable: bool,
body: &mut Body<'tcx>,
) -> (
FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
GeneratorLayout<'tcx>,
IndexVec<BasicBlock, Option<BitSet<Local>>>,
retained: &BitSet<Local>,
) {
// 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<Ty<'tcx>>,
interior: Ty<'tcx>,
always_live_locals: &storage::AlwaysLiveLocals,
movable: bool,
body: &mut Body<'tcx>,
) -> (
FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
GeneratorLayout<'tcx>,
IndexVec<BasicBlock, Option<BitSet<Local>>>,
) {
// 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::<GeneratorSavedLocal, _>::new();
8 changes: 5 additions & 3 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
}
10 changes: 7 additions & 3 deletions src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
2 changes: 2 additions & 0 deletions src/librustc_session/options.rs
Original file line number Diff line number Diff line change
@@ -996,6 +996,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"make the current crate share its generic instantiations"),
show_span: Option<String> = (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)"),
32 changes: 21 additions & 11 deletions src/librustc_trait_selection/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -290,7 +290,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 \
@@ -340,7 +340,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()
),
);
}
}
@@ -353,7 +356,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(),
)
};

@@ -643,7 +646,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),
@@ -1360,11 +1366,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());
@@ -1435,7 +1445,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() {
@@ -1564,7 +1574,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;
24 changes: 17 additions & 7 deletions src/librustc_trait_selection/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
@@ -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<ty::TraitRef<'tcx>>,
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<ty::TraitRef<'tcx>>,
) {
let is_empty_tuple =
|ty: ty::Binder<Ty<'_>>| 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={:?}",
@@ -1917,7 +1927,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,
));
@@ -1933,7 +1943,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`
Loading