Skip to content

Commit

Permalink
Auto merge of #95526 - Dylan-DPC:rollup-0ikl5l5, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #91416 (Specialize infinite-type "insert some indirection" suggestion for Option)
 - #95384 (Update target_has_atomic documentation for stabilization)
 - #95517 (small rustc_borrowck cleanup)
 - #95520 (Fix typos in core::ptr docs)
 - #95523 (remove unused field from `infcx`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 31, 2022
2 parents bd1a869 + 1074c81 commit 0677edc
Show file tree
Hide file tree
Showing 27 changed files with 282 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
let constraint_sets: Vec<_> = unnormalized_input_output_tys
.flat_map(|ty| {
debug!("build: input_or_output={:?}", ty);
// We add implied bounds from both the unnormalized and normalized ty
// See issue #87748
// We only add implied bounds for the normalized type as the unnormalized
// type may not actually get checked by the caller.
//
// Can otherwise be unsound, see #91068.
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1899,7 +1899,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ObligationCause::new(
span,
self.tcx().hir().local_def_id_to_hir_id(def_id),
traits::ObligationCauseCode::RepeatVec(is_const_fn),
traits::ObligationCauseCode::RepeatElementCopy {
is_const_fn,
},
),
self.param_env,
ty::Binder::dummy(ty::TraitRef::new(
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Self {
tcx: self.tcx.clone(),
defining_use_anchor: self.defining_use_anchor.clone(),
reveal_defining_opaque_types: self.reveal_defining_opaque_types.clone(),
in_progress_typeck_results: self.in_progress_typeck_results.clone(),
inner: self.inner.clone(),
skip_leak_check: self.skip_leak_check.clone(),
Expand Down
27 changes: 2 additions & 25 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,6 @@ pub struct InferCtxt<'a, 'tcx> {
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
pub defining_use_anchor: Option<LocalDefId>,

/// Used by WF-checking to not have to figure out hidden types itself, but
/// to just invoke type_of to get the already computed hidden type from typeck.
pub reveal_defining_opaque_types: bool,

/// During type-checking/inference of a body, `in_progress_typeck_results`
/// contains a reference to the typeck results being built up, which are
/// used for reading closure kinds/signatures as they are inferred,
Expand Down Expand Up @@ -569,7 +565,6 @@ pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
defining_use_anchor: Option<LocalDefId>,
reveal_defining_opaque_types: bool,
}

pub trait TyCtxtInferExt<'tcx> {
Expand All @@ -578,12 +573,7 @@ pub trait TyCtxtInferExt<'tcx> {

impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
InferCtxtBuilder {
tcx: self,
defining_use_anchor: None,
fresh_typeck_results: None,
reveal_defining_opaque_types: false,
}
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
}
}

Expand All @@ -607,13 +597,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
self
}

/// WF-checking doesn't need to recompute opaque types and can instead use
/// the type_of query to get them from typeck.
pub fn reveal_defining_opaque_types(mut self) -> Self {
self.reveal_defining_opaque_types = true;
self
}

/// Given a canonical value `C` as a starting point, create an
/// inference context that contains each of the bound values
/// within instantiated as a fresh variable. The `f` closure is
Expand All @@ -638,17 +621,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
}

pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
let InferCtxtBuilder {
tcx,
defining_use_anchor,
reveal_defining_opaque_types,
ref fresh_typeck_results,
} = *self;
let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self;
let in_progress_typeck_results = fresh_typeck_results.as_ref();
f(InferCtxt {
tcx,
defining_use_anchor,
reveal_defining_opaque_types,
in_progress_typeck_results,
inner: RefCell::new(InferCtxtInner::new()),
lexical_region_resolutions: RefCell::new(None),
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,12 @@ pub enum ObligationCauseCode<'tcx> {
SizedBoxType,
/// Inline asm operand type must be `Sized`.
InlineAsmSized,
/// `[T, ..n]` implies that `T` must be `Copy`.
/// If the function in the array repeat expression is a `const fn`,
/// display a help message suggesting to move the function call to a
/// new `const` item while saying that `T` doesn't implement `Copy`.
RepeatVec(bool),
/// `[expr; N]` requires `type_of(expr): Copy`.
RepeatElementCopy {
/// If element is a `const fn` we display a help message suggesting to move the
/// function call to a new `const` item while saying that `T` doesn't implement `Copy`.
is_const_fn: bool,
},

/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
FieldSized {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let kind = match pat.kind {
hir::PatKind::Wild => PatKind::Wild,

hir::PatKind::Lit(ref value) => self.lower_lit(value),
hir::PatKind::Lit(value) => self.lower_lit(value),

hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref());
Expand Down
59 changes: 48 additions & 11 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2285,10 +2285,10 @@ impl<'v> Visitor<'v> for FindTypeParam {
}
}

pub fn recursive_type_with_infinite_size_error(
tcx: TyCtxt<'_>,
pub fn recursive_type_with_infinite_size_error<'tcx>(
tcx: TyCtxt<'tcx>,
type_def_id: DefId,
spans: Vec<Span>,
spans: Vec<(Span, Option<hir::HirId>)>,
) {
assert!(type_def_id.is_local());
let span = tcx.hir().span_if_local(type_def_id).unwrap();
Expand All @@ -2297,24 +2297,33 @@ pub fn recursive_type_with_infinite_size_error(
let mut err =
struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", path);
err.span_label(span, "recursive type has infinite size");
for &span in &spans {
for &(span, _) in &spans {
err.span_label(span, "recursive without indirection");
}
let msg = format!(
"insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable",
path,
);
if spans.len() <= 4 {
// FIXME(compiler-errors): This suggestion might be erroneous if Box is shadowed
err.multipart_suggestion(
&msg,
spans
.iter()
.flat_map(|&span| {
[
(span.shrink_to_lo(), "Box<".to_string()),
(span.shrink_to_hi(), ">".to_string()),
]
.into_iter()
.into_iter()
.flat_map(|(span, field_id)| {
if let Some(generic_span) = get_option_generic_from_field_id(tcx, field_id) {
// If we match an `Option` and can grab the span of the Option's generic, then
// suggest boxing the generic arg for a non-null niche optimization.
vec![
(generic_span.shrink_to_lo(), "Box<".to_string()),
(generic_span.shrink_to_hi(), ">".to_string()),
]
} else {
vec![
(span.shrink_to_lo(), "Box<".to_string()),
(span.shrink_to_hi(), ">".to_string()),
]
}
})
.collect(),
Applicability::HasPlaceholders,
Expand All @@ -2325,6 +2334,34 @@ pub fn recursive_type_with_infinite_size_error(
err.emit();
}

/// Extract the span for the generic type `T` of `Option<T>` in a field definition
fn get_option_generic_from_field_id(tcx: TyCtxt<'_>, field_id: Option<hir::HirId>) -> Option<Span> {
let node = tcx.hir().find(field_id?);

// Expect a field from our field_id
let Some(hir::Node::Field(field_def)) = node
else { bug!("Expected HirId corresponding to FieldDef, found: {:?}", node) };

// Match a type that is a simple QPath with no Self
let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = &field_def.ty.kind
else { return None };

// Check if the path we're checking resolves to Option
let hir::def::Res::Def(_, did) = path.res
else { return None };

// Bail if this path doesn't describe `::core::option::Option`
if !tcx.is_diagnostic_item(sym::Option, did) {
return None;
}

// Match a single generic arg in the 0th path segment
let generic_arg = path.segments.last()?.args?.args.get(0)?;

// Take the span out of the type, if it's a type
if let hir::GenericArg::Type(generic_ty) = generic_arg { Some(generic_ty.span) } else { None }
}

/// Summarizes information
#[derive(Clone)]
pub enum ArgKind {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1988,7 +1988,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ObligationCauseCode::Coercion { source: _, target } => {
err.note(&format!("required by cast to type `{}`", self.ty_to_string(target)));
}
ObligationCauseCode::RepeatVec(is_const_fn) => {
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
err.note(
"the `Copy` trait is required because the repeated element will be copied",
);
Expand Down
Loading

0 comments on commit 0677edc

Please sign in to comment.