Skip to content

Commit

Permalink
Auto merge of #97783 - matthiaskrgr:rollup-14t9htt, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #90905 (Add empty impl blocks if they have documentation)
 - #97683 (Fail gracefully when encountering an HRTB in APIT. )
 - #97721 (Do `suggest_await_before_try` with infer variables in self, and clean up binders)
 - #97752 (typo: `-Zcodegen-backend=llvm -Cpasses=list` should work now)
 - #97759 (Suggest adding `{}` for `'label: non_block_expr`)
 - #97764 (use strict provenance APIs)
 - #97765 (Restore a test that was intended to test `as` cast to ptr)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 6, 2022
2 parents 6609c67 + 1258fa9 commit e70c60d
Show file tree
Hide file tree
Showing 23 changed files with 419 additions and 82 deletions.
8 changes: 1 addition & 7 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,13 +1055,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
}

if cg_flags.iter().any(|x| *x == "passes=list") {
let backend_name = debug_flags.iter().find_map(|x| {
if x.starts_with("codegen-backend=") {
Some(&x["codegen-backends=".len()..])
} else {
None
}
});
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
get_codegen_backend(&None, backend_name).print_passes();
return None;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ impl<'hir> WherePredicate<'hir> {
}
}

#[derive(Debug, HashStable_Generic, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
pub enum PredicateOrigin {
WhereClause,
GenericParam,
Expand Down
64 changes: 62 additions & 2 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ use rustc_ast::tokenstream::Spacing;
use rustc_ast::util::classify;
use rustc_ast::util::literal::LitError;
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
use rustc_ast::visit::Visitor;
use rustc_ast::StmtKind;
use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp, DUMMY_NODE_ID};
use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
use rustc_ast_pretty::pprust;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
use rustc_session::lint::BuiltinLintDiagnostics;
Expand Down Expand Up @@ -1548,9 +1551,66 @@ impl<'a> Parser<'a> {
Ok(self.mk_expr_err(lo))
} else {
let msg = "expected `while`, `for`, `loop` or `{` after a label";
self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();

let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, msg);

// Continue as an expression in an effort to recover on `'label: non_block_expr`.
self.parse_expr()
let expr = self.parse_expr().map(|expr| {
let span = expr.span;

let found_labeled_breaks = {
struct FindLabeledBreaksVisitor(bool);

impl<'ast> Visitor<'ast> for FindLabeledBreaksVisitor {
fn visit_expr_post(&mut self, ex: &'ast Expr) {
if let ExprKind::Break(Some(_label), _) = ex.kind {
self.0 = true;
}
}
}

let mut vis = FindLabeledBreaksVisitor(false);
vis.visit_expr(&expr);
vis.0
};

// Suggestion involves adding a (as of time of writing this, unstable) labeled block.
//
// If there are no breaks that may use this label, suggest removing the label and
// recover to the unmodified expression.
if !found_labeled_breaks {
let msg = "consider removing the label";
err.span_suggestion_verbose(
lo.until(span),
msg,
"",
Applicability::MachineApplicable,
);

return expr;
}

let sugg_msg = "consider enclosing expression in a block";
let suggestions = vec![
(span.shrink_to_lo(), "{ ".to_owned()),
(span.shrink_to_hi(), " }".to_owned()),
];

err.multipart_suggestion_verbose(
sugg_msg,
suggestions,
Applicability::MachineApplicable,
);

// Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to supress future errors about `break 'label`.
let stmt = self.mk_stmt(span, StmtKind::Expr(expr));
let blk = self.mk_block(vec![stmt], BlockCheckMode::Default, span);
self.mk_expr(span, ExprKind::Block(blk, label), ThinVec::new())
});

err.emit();
expr
}?;

if !ate_colon && consume_colon {
Expand Down
71 changes: 64 additions & 7 deletions compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ enum Scope<'a> {
/// In some cases not allowing late bounds allows us to avoid ICEs.
/// This is almost ways set to true.
allow_late_bound: bool,

/// If this binder comes from a where clause, specify how it was created.
/// This is used to diagnose inaccessible lifetimes in APIT:
/// ```ignore (illustrative)
/// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
/// ```
where_bound_origin: Option<hir::PredicateOrigin>,
},

/// Lifetimes introduced by a fn are scoped to the call-site for that fn,
Expand Down Expand Up @@ -277,17 +284,19 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
opaque_type_parent,
scope_type,
hir_id,
s: _,
allow_late_bound,
where_bound_origin,
s: _,
} => f
.debug_struct("Binder")
.field("lifetimes", lifetimes)
.field("next_early_index", next_early_index)
.field("opaque_type_parent", opaque_type_parent)
.field("scope_type", scope_type)
.field("hir_id", hir_id)
.field("s", &"..")
.field("allow_late_bound", allow_late_bound)
.field("where_bound_origin", where_bound_origin)
.field("s", &"..")
.finish(),
Scope::Body { id, s: _ } => {
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
Expand Down Expand Up @@ -638,6 +647,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
where_bound_origin: None,
};
self.with(scope, move |this| intravisit::walk_fn(this, fk, fd, b, s, hir_id));
}
Expand Down Expand Up @@ -753,6 +763,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal,
s: ROOT_SCOPE,
allow_late_bound: false,
where_bound_origin: None,
};
self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
Expand Down Expand Up @@ -818,6 +829,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
where_bound_origin: None,
};
self.with(scope, |this| {
// a bare fn has no bounds, so everything
Expand Down Expand Up @@ -1006,6 +1018,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: false,
where_bound_origin: None,
};
this.with(scope, |this| {
this.visit_generics(generics);
Expand All @@ -1026,6 +1039,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: false,
where_bound_origin: None,
};
self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
Expand Down Expand Up @@ -1084,6 +1098,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
allow_late_bound: false,
where_bound_origin: None,
};
self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
Expand Down Expand Up @@ -1151,6 +1166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
where_bound_origin: None,
};
self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
Expand Down Expand Up @@ -1266,6 +1282,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
ref bounded_ty,
bounds,
ref bound_generic_params,
origin,
..
}) => {
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
Expand Down Expand Up @@ -1296,6 +1313,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
where_bound_origin: Some(origin),
};
this.with(scope, |this| {
this.visit_ty(&bounded_ty);
Expand Down Expand Up @@ -1368,6 +1386,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type,
allow_late_bound: true,
where_bound_origin: None,
};
self.with(scope, |this| {
intravisit::walk_param_bound(this, bound);
Expand Down Expand Up @@ -1420,6 +1439,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
opaque_type_parent: false,
scope_type,
allow_late_bound: true,
where_bound_origin: None,
};
self.with(scope, |this| {
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
Expand Down Expand Up @@ -1680,6 +1700,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
opaque_type_parent: true,
scope_type: BinderScopeType::Normal,
allow_late_bound: true,
where_bound_origin: None,
};
self.with(scope, walk);
}
Expand Down Expand Up @@ -1783,12 +1804,48 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}

self.insert_lifetime(lifetime_ref, def);
} else {
self.tcx.sess.delay_span_bug(
lifetime_ref.span,
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
);
return;
}

// We may fail to resolve higher-ranked lifetimes that are mentionned by APIT.
// AST-based resolution does not care for impl-trait desugaring, which are the
// responibility of lowering. This may create a mismatch between the resolution
// AST found (`region_def_id`) which points to HRTB, and what HIR allows.
// ```
// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
// ```
//
// In such case, walk back the binders to diagnose it properly.
let mut scope = self.scope;
loop {
match *scope {
Scope::Binder {
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
} => {
let mut err = self.tcx.sess.struct_span_err(
lifetime_ref.span,
"`impl Trait` can only mention lifetimes bound at the fn or impl level",
);
err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
err.emit();
return;
}
Scope::Root => break,
Scope::Binder { s, .. }
| Scope::Body { s, .. }
| Scope::Elision { s, .. }
| Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. }
| Scope::TraitRefBoundary { s, .. } => {
scope = s;
}
}
}

self.tcx.sess.delay_span_bug(
lifetime_ref.span,
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
);
}

fn visit_segment_args(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{

use crate::autoderef::Autoderef;
use crate::infer::InferCtxt;
use crate::traits::normalize_projection_type;
use crate::traits::normalize_to;

use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack;
Expand Down Expand Up @@ -2706,55 +2706,43 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);

let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());

// Do not check on infer_types to avoid panic in evaluate_obligation.
if self_ty.has_infer_types() {
return;
}
let self_ty = self.tcx.erase_regions(self_ty);

let impls_future = self.type_implements_trait(
future_trait,
self_ty.skip_binder(),
self.tcx.erase_late_bound_regions(self_ty),
ty::List::empty(),
obligation.param_env,
);
if !impls_future.must_apply_modulo_regions() {
return;
}

let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
// `<T as Future>::Output`
let projection_ty = ty::ProjectionTy {
// `T`
substs: self.tcx.mk_substs_trait(
trait_pred.self_ty().skip_binder(),
&self.fresh_substs_for_item(span, item_def_id)[1..],
),
// `Future::Output`
item_def_id,
};

let mut selcx = SelectionContext::new(self);

let mut obligations = vec![];
let normalized_ty = normalize_projection_type(
&mut selcx,
let projection_ty = trait_pred.map_bound(|trait_pred| {
self.tcx.mk_projection(
item_def_id,
// Future::Output has no substs
self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]),
)
});
let projection_ty = normalize_to(
&mut SelectionContext::new(self),
obligation.param_env,
projection_ty,
obligation.cause.clone(),
0,
&mut obligations,
projection_ty,
&mut vec![],
);

debug!(
"suggest_await_before_try: normalized_projection_type {:?}",
self.resolve_vars_if_possible(normalized_ty)
self.resolve_vars_if_possible(projection_ty)
);
let try_obligation = self.mk_trait_obligation_with_new_self_ty(
obligation.param_env,
trait_pred.map_bound(|trait_pred| (trait_pred, normalized_ty.ty().unwrap())),
trait_pred.map_bound(|trait_pred| (trait_pred, projection_ty.skip_binder())),
);
debug!("suggest_await_before_try: try_trait_obligation {:?}", try_obligation);
if self.predicate_may_hold(&try_obligation)
&& impls_future.must_apply_modulo_regions()
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
&& snippet.ends_with('?')
{
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ pub const fn null<T>() -> *const T {
#[rustc_diagnostic_item = "ptr_null"]
#[cfg(not(bootstrap))]
pub const fn null<T: ?Sized + Thin>() -> *const T {
from_raw_parts(0 as *const (), ())
from_raw_parts(invalid(0), ())
}

/// Creates a null mutable raw pointer.
Expand Down Expand Up @@ -709,7 +709,7 @@ where
#[rustc_diagnostic_item = "ptr_null_mut"]
#[cfg(not(bootstrap))]
pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
from_raw_parts_mut(0 as *mut (), ())
from_raw_parts_mut(invalid_mut(0), ())
}

/// Forms a raw slice from a pointer and a length.
Expand Down
Loading

0 comments on commit e70c60d

Please sign in to comment.