Skip to content

Commit 0677edc

Browse files
committed
Auto merge of #95526 - Dylan-DPC:rollup-0ikl5l5, r=Dylan-DPC
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
2 parents bd1a869 + 1074c81 commit 0677edc

File tree

27 files changed

+282
-114
lines changed

27 files changed

+282
-114
lines changed

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
253253
let constraint_sets: Vec<_> = unnormalized_input_output_tys
254254
.flat_map(|ty| {
255255
debug!("build: input_or_output={:?}", ty);
256-
// We add implied bounds from both the unnormalized and normalized ty
257-
// See issue #87748
256+
// We only add implied bounds for the normalized type as the unnormalized
257+
// type may not actually get checked by the caller.
258+
//
259+
// Can otherwise be unsound, see #91068.
258260
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
259261
.param_env
260262
.and(type_op::normalize::Normalize::new(ty))

compiler/rustc_borrowck/src/type_check/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1899,7 +1899,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18991899
ObligationCause::new(
19001900
span,
19011901
self.tcx().hir().local_def_id_to_hir_id(def_id),
1902-
traits::ObligationCauseCode::RepeatVec(is_const_fn),
1902+
traits::ObligationCauseCode::RepeatElementCopy {
1903+
is_const_fn,
1904+
},
19031905
),
19041906
self.param_env,
19051907
ty::Binder::dummy(ty::TraitRef::new(

compiler/rustc_infer/src/infer/at.rs

-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
6565
Self {
6666
tcx: self.tcx.clone(),
6767
defining_use_anchor: self.defining_use_anchor.clone(),
68-
reveal_defining_opaque_types: self.reveal_defining_opaque_types.clone(),
6968
in_progress_typeck_results: self.in_progress_typeck_results.clone(),
7069
inner: self.inner.clone(),
7170
skip_leak_check: self.skip_leak_check.clone(),

compiler/rustc_infer/src/infer/mod.rs

+2-25
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,6 @@ pub struct InferCtxt<'a, 'tcx> {
290290
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
291291
pub defining_use_anchor: Option<LocalDefId>,
292292

293-
/// Used by WF-checking to not have to figure out hidden types itself, but
294-
/// to just invoke type_of to get the already computed hidden type from typeck.
295-
pub reveal_defining_opaque_types: bool,
296-
297293
/// During type-checking/inference of a body, `in_progress_typeck_results`
298294
/// contains a reference to the typeck results being built up, which are
299295
/// used for reading closure kinds/signatures as they are inferred,
@@ -569,7 +565,6 @@ pub struct InferCtxtBuilder<'tcx> {
569565
tcx: TyCtxt<'tcx>,
570566
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
571567
defining_use_anchor: Option<LocalDefId>,
572-
reveal_defining_opaque_types: bool,
573568
}
574569

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

579574
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
580575
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
581-
InferCtxtBuilder {
582-
tcx: self,
583-
defining_use_anchor: None,
584-
fresh_typeck_results: None,
585-
reveal_defining_opaque_types: false,
586-
}
576+
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
587577
}
588578
}
589579

@@ -607,13 +597,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
607597
self
608598
}
609599

610-
/// WF-checking doesn't need to recompute opaque types and can instead use
611-
/// the type_of query to get them from typeck.
612-
pub fn reveal_defining_opaque_types(mut self) -> Self {
613-
self.reveal_defining_opaque_types = true;
614-
self
615-
}
616-
617600
/// Given a canonical value `C` as a starting point, create an
618601
/// inference context that contains each of the bound values
619602
/// within instantiated as a fresh variable. The `f` closure is
@@ -638,17 +621,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
638621
}
639622

640623
pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
641-
let InferCtxtBuilder {
642-
tcx,
643-
defining_use_anchor,
644-
reveal_defining_opaque_types,
645-
ref fresh_typeck_results,
646-
} = *self;
624+
let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self;
647625
let in_progress_typeck_results = fresh_typeck_results.as_ref();
648626
f(InferCtxt {
649627
tcx,
650628
defining_use_anchor,
651-
reveal_defining_opaque_types,
652629
in_progress_typeck_results,
653630
inner: RefCell::new(InferCtxtInner::new()),
654631
lexical_region_resolutions: RefCell::new(None),

compiler/rustc_middle/src/traits/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,12 @@ pub enum ObligationCauseCode<'tcx> {
236236
SizedBoxType,
237237
/// Inline asm operand type must be `Sized`.
238238
InlineAsmSized,
239-
/// `[T, ..n]` implies that `T` must be `Copy`.
240-
/// If the function in the array repeat expression is a `const fn`,
241-
/// display a help message suggesting to move the function call to a
242-
/// new `const` item while saying that `T` doesn't implement `Copy`.
243-
RepeatVec(bool),
239+
/// `[expr; N]` requires `type_of(expr): Copy`.
240+
RepeatElementCopy {
241+
/// If element is a `const fn` we display a help message suggesting to move the
242+
/// function call to a new `const` item while saying that `T` doesn't implement `Copy`.
243+
is_const_fn: bool,
244+
},
244245

245246
/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
246247
FieldSized {

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
198198
let kind = match pat.kind {
199199
hir::PatKind::Wild => PatKind::Wild,
200200

201-
hir::PatKind::Lit(ref value) => self.lower_lit(value),
201+
hir::PatKind::Lit(value) => self.lower_lit(value),
202202

203203
hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
204204
let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref());

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+48-11
Original file line numberDiff line numberDiff line change
@@ -2285,10 +2285,10 @@ impl<'v> Visitor<'v> for FindTypeParam {
22852285
}
22862286
}
22872287

2288-
pub fn recursive_type_with_infinite_size_error(
2289-
tcx: TyCtxt<'_>,
2288+
pub fn recursive_type_with_infinite_size_error<'tcx>(
2289+
tcx: TyCtxt<'tcx>,
22902290
type_def_id: DefId,
2291-
spans: Vec<Span>,
2291+
spans: Vec<(Span, Option<hir::HirId>)>,
22922292
) {
22932293
assert!(type_def_id.is_local());
22942294
let span = tcx.hir().span_if_local(type_def_id).unwrap();
@@ -2297,24 +2297,33 @@ pub fn recursive_type_with_infinite_size_error(
22972297
let mut err =
22982298
struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", path);
22992299
err.span_label(span, "recursive type has infinite size");
2300-
for &span in &spans {
2300+
for &(span, _) in &spans {
23012301
err.span_label(span, "recursive without indirection");
23022302
}
23032303
let msg = format!(
23042304
"insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable",
23052305
path,
23062306
);
23072307
if spans.len() <= 4 {
2308+
// FIXME(compiler-errors): This suggestion might be erroneous if Box is shadowed
23082309
err.multipart_suggestion(
23092310
&msg,
23102311
spans
2311-
.iter()
2312-
.flat_map(|&span| {
2313-
[
2314-
(span.shrink_to_lo(), "Box<".to_string()),
2315-
(span.shrink_to_hi(), ">".to_string()),
2316-
]
2317-
.into_iter()
2312+
.into_iter()
2313+
.flat_map(|(span, field_id)| {
2314+
if let Some(generic_span) = get_option_generic_from_field_id(tcx, field_id) {
2315+
// If we match an `Option` and can grab the span of the Option's generic, then
2316+
// suggest boxing the generic arg for a non-null niche optimization.
2317+
vec![
2318+
(generic_span.shrink_to_lo(), "Box<".to_string()),
2319+
(generic_span.shrink_to_hi(), ">".to_string()),
2320+
]
2321+
} else {
2322+
vec![
2323+
(span.shrink_to_lo(), "Box<".to_string()),
2324+
(span.shrink_to_hi(), ">".to_string()),
2325+
]
2326+
}
23182327
})
23192328
.collect(),
23202329
Applicability::HasPlaceholders,
@@ -2325,6 +2334,34 @@ pub fn recursive_type_with_infinite_size_error(
23252334
err.emit();
23262335
}
23272336

2337+
/// Extract the span for the generic type `T` of `Option<T>` in a field definition
2338+
fn get_option_generic_from_field_id(tcx: TyCtxt<'_>, field_id: Option<hir::HirId>) -> Option<Span> {
2339+
let node = tcx.hir().find(field_id?);
2340+
2341+
// Expect a field from our field_id
2342+
let Some(hir::Node::Field(field_def)) = node
2343+
else { bug!("Expected HirId corresponding to FieldDef, found: {:?}", node) };
2344+
2345+
// Match a type that is a simple QPath with no Self
2346+
let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = &field_def.ty.kind
2347+
else { return None };
2348+
2349+
// Check if the path we're checking resolves to Option
2350+
let hir::def::Res::Def(_, did) = path.res
2351+
else { return None };
2352+
2353+
// Bail if this path doesn't describe `::core::option::Option`
2354+
if !tcx.is_diagnostic_item(sym::Option, did) {
2355+
return None;
2356+
}
2357+
2358+
// Match a single generic arg in the 0th path segment
2359+
let generic_arg = path.segments.last()?.args?.args.get(0)?;
2360+
2361+
// Take the span out of the type, if it's a type
2362+
if let hir::GenericArg::Type(generic_ty) = generic_arg { Some(generic_ty.span) } else { None }
2363+
}
2364+
23282365
/// Summarizes information
23292366
#[derive(Clone)]
23302367
pub enum ArgKind {

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1988,7 +1988,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
19881988
ObligationCauseCode::Coercion { source: _, target } => {
19891989
err.note(&format!("required by cast to type `{}`", self.ty_to_string(target)));
19901990
}
1991-
ObligationCauseCode::RepeatVec(is_const_fn) => {
1991+
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
19921992
err.note(
19931993
"the `Copy` trait is required because the repeated element will be copied",
19941994
);

0 commit comments

Comments
 (0)