Skip to content

Commit db5704f

Browse files
committed
Auto merge of #129024 - matthiaskrgr:rollup-uj1pd0x, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #128712 (Normalize struct tail properly for `dyn` ptr-to-ptr casting in new solver) - #128912 (Store `do_not_recommend`-ness in impl header) - #129000 (bootstrap: clear miri ui-test deps when miri sysroot gets rebuilt) - #129013 (Remove unused script from run-make tests) - #129017 (Replace `std::fmt:FormatterFn` with `std::fmt::from_fn`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 91376f4 + 522d436 commit db5704f

File tree

27 files changed

+174
-94
lines changed

27 files changed

+174
-94
lines changed

Diff for: compiler/rustc_borrowck/src/type_check/canonical.rs

+47
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::mir::ConstraintCategory;
77
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
88
use rustc_span::def_id::DefId;
99
use rustc_span::Span;
10+
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1011
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
1112
use rustc_trait_selection::traits::ObligationCause;
1213

@@ -165,6 +166,52 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
165166
result.unwrap_or(value)
166167
}
167168

169+
#[instrument(skip(self), level = "debug")]
170+
pub(super) fn struct_tail(
171+
&mut self,
172+
ty: Ty<'tcx>,
173+
location: impl NormalizeLocation,
174+
) -> Ty<'tcx> {
175+
let tcx = self.tcx();
176+
if self.infcx.next_trait_solver() {
177+
let body = self.body;
178+
let param_env = self.param_env;
179+
self.fully_perform_op(
180+
location.to_locations(),
181+
ConstraintCategory::Boring,
182+
CustomTypeOp::new(
183+
|ocx| {
184+
let structurally_normalize = |ty| {
185+
ocx.structurally_normalize(
186+
&ObligationCause::misc(
187+
location.to_locations().span(body),
188+
body.source.def_id().expect_local(),
189+
),
190+
param_env,
191+
ty,
192+
)
193+
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
194+
};
195+
196+
let tail = tcx.struct_tail_raw(
197+
ty,
198+
structurally_normalize,
199+
|| {},
200+
);
201+
202+
Ok(tail)
203+
},
204+
"normalizing struct tail",
205+
),
206+
)
207+
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
208+
} else {
209+
let mut normalize = |ty| self.normalize(ty, location);
210+
let tail = tcx.struct_tail_raw(ty, &mut normalize, || {});
211+
normalize(tail)
212+
}
213+
}
214+
168215
#[instrument(skip(self), level = "debug")]
169216
pub(super) fn ascribe_user_type(
170217
&mut self,

Diff for: compiler/rustc_borrowck/src/type_check/mod.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -2329,17 +2329,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23292329
let cast_ty_to = CastTy::from_ty(*ty);
23302330
match (cast_ty_from, cast_ty_to) {
23312331
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
2332-
let mut normalize = |t| self.normalize(t, location);
2333-
2334-
// N.B. `struct_tail_with_normalize` only "structurally resolves"
2335-
// the type. It is not fully normalized, so we have to normalize it
2336-
// afterwards.
2337-
let src_tail =
2338-
tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ());
2339-
let src_tail = normalize(src_tail);
2340-
let dst_tail =
2341-
tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ());
2342-
let dst_tail = normalize(dst_tail);
2332+
let src_tail = self.struct_tail(src.ty, location);
2333+
let dst_tail = self.struct_tail(dst.ty, location);
23432334

23442335
// This checks (lifetime part of) vtable validity for pointer casts,
23452336
// which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).

Diff for: compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ pub(super) fn op_to_const<'tcx>(
226226
let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs
227227
debug_assert!(
228228
matches!(
229-
ecx.tcx.struct_tail_without_normalization(pointee_ty).kind(),
229+
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.param_env).kind(),
230230
ty::Str | ty::Slice(..),
231231
),
232232
"`ConstValue::Slice` is for slice-tailed types only, but got {}",

Diff for: compiler/rustc_const_eval/src/const_eval/valtrees.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ fn reconstruct_place_meta<'tcx>(
195195

196196
let mut last_valtree = valtree;
197197
// Traverse the type, and update `last_valtree` as we go.
198-
let tail = tcx.struct_tail_with_normalize(
198+
let tail = tcx.struct_tail_raw(
199199
layout.ty,
200200
|ty| ty,
201201
|| {

Diff for: compiler/rustc_hir_analysis/src/collect.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1700,6 +1700,8 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
17001700
trait_ref: ty::EarlyBinder::bind(trait_ref),
17011701
safety: impl_.safety,
17021702
polarity: polarity_of_impl(tcx, def_id, impl_, item.span),
1703+
do_not_recommend: tcx.features().do_not_recommend
1704+
&& tcx.has_attrs_with_path(def_id, &[sym::diagnostic, sym::do_not_recommend]),
17031705
}
17041706
})
17051707
}

Diff for: compiler/rustc_hir_typeck/src/cast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9797
return Ok(Some(PointerKind::Thin));
9898
}
9999

100+
let t = self.try_structurally_resolve_type(span, t);
101+
100102
Ok(match *t.kind() {
101103
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
102104
ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty)),

Diff for: compiler/rustc_hir_typeck/src/expectation.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ impl<'a, 'tcx> Expectation<'tcx> {
7070
/// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
7171
/// for examples of where this comes up,.
7272
pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
73-
match fcx.tcx.struct_tail_without_normalization(ty).kind() {
73+
// FIXME: This is not right, even in the old solver...
74+
match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}).kind() {
7475
ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
7576
_ => ExpectHasType(ty),
7677
}

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
404404
code: traits::ObligationCauseCode<'tcx>,
405405
) {
406406
if !ty.references_error() {
407-
let tail = self.tcx.struct_tail_with_normalize(
407+
let tail = self.tcx.struct_tail_raw(
408408
ty,
409409
|ty| {
410410
if self.next_trait_solver() {

Diff for: compiler/rustc_middle/src/ty/context.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3176,6 +3176,12 @@ impl<'tcx> TyCtxt<'tcx> {
31763176
pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
31773177
self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
31783178
}
3179+
3180+
/// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
3181+
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3182+
matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true })
3183+
&& self.impl_trait_header(def_id).is_some_and(|header| header.do_not_recommend)
3184+
}
31793185
}
31803186

31813187
/// Parameter attributes that can only be determined by examining the body of a function instead

Diff for: compiler/rustc_middle/src/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
362362
ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
363363
let non_zero = !ty.is_unsafe_ptr();
364364

365-
let tail = tcx.struct_tail_with_normalize(
365+
let tail = tcx.struct_tail_raw(
366366
pointee,
367367
|ty| match tcx.try_normalize_erasing_regions(param_env, ty) {
368368
Ok(ty) => ty,

Diff for: compiler/rustc_middle/src/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ pub struct ImplTraitHeader<'tcx> {
262262
pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
263263
pub polarity: ImplPolarity,
264264
pub safety: hir::Safety,
265+
pub do_not_recommend: bool,
265266
}
266267

267268
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]

Diff for: compiler/rustc_middle/src/ty/sty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ impl<'tcx> Ty<'tcx> {
15901590
tcx: TyCtxt<'tcx>,
15911591
normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
15921592
) -> Result<Ty<'tcx>, Ty<'tcx>> {
1593-
let tail = tcx.struct_tail_with_normalize(self, normalize, || {});
1593+
let tail = tcx.struct_tail_raw(self, normalize, || {});
15941594
match tail.kind() {
15951595
// Sized types
15961596
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
@@ -1614,10 +1614,10 @@ impl<'tcx> Ty<'tcx> {
16141614
| ty::Foreign(..)
16151615
// `dyn*` has metadata = ().
16161616
| ty::Dynamic(_, _, ty::DynStar)
1617-
// If returned by `struct_tail_with_normalize` this is a unit struct
1617+
// If returned by `struct_tail_raw` this is a unit struct
16181618
// without any fields, or not a struct, and therefore is Sized.
16191619
| ty::Adt(..)
1620-
// If returned by `struct_tail_with_normalize` this is the empty tuple,
1620+
// If returned by `struct_tail_raw` this is the empty tuple,
16211621
// a.k.a. unit type, which is Sized
16221622
| ty::Tuple(..) => Ok(tcx.types.unit),
16231623

Diff for: compiler/rustc_middle/src/ty/util.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,6 @@ impl<'tcx> TyCtxt<'tcx> {
171171
}
172172
}
173173

174-
/// Attempts to returns the deeply last field of nested structures, but
175-
/// does not apply any normalization in its search. Returns the same type
176-
/// if input `ty` is not a structure at all.
177-
pub fn struct_tail_without_normalization(self, ty: Ty<'tcx>) -> Ty<'tcx> {
178-
let tcx = self;
179-
tcx.struct_tail_with_normalize(ty, |ty| ty, || {})
180-
}
181-
182174
/// Returns the deeply last field of nested structures, or the same type if
183175
/// not a structure at all. Corresponds to the only possible unsized field,
184176
/// and its type can be used to determine unsizing strategy.
@@ -188,20 +180,22 @@ impl<'tcx> TyCtxt<'tcx> {
188180
/// normalization attempt may cause compiler bugs.
189181
pub fn struct_tail_for_codegen(self, ty: Ty<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
190182
let tcx = self;
191-
tcx.struct_tail_with_normalize(ty, |ty| tcx.normalize_erasing_regions(param_env, ty), || {})
183+
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(param_env, ty), || {})
192184
}
193185

194186
/// Returns the deeply last field of nested structures, or the same type if
195187
/// not a structure at all. Corresponds to the only possible unsized field,
196188
/// and its type can be used to determine unsizing strategy.
197189
///
198190
/// This is parameterized over the normalization strategy (i.e. how to
199-
/// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
200-
/// function to indicate no normalization should take place.
191+
/// handle `<T as Trait>::Assoc` and `impl Trait`). You almost certainly do
192+
/// **NOT** want to pass the identity function here, unless you know what
193+
/// you're doing, or you're within normalization code itself and will handle
194+
/// an unnormalized tail recursively.
201195
///
202196
/// See also `struct_tail_for_codegen`, which is suitable for use
203197
/// during codegen.
204-
pub fn struct_tail_with_normalize(
198+
pub fn struct_tail_raw(
205199
self,
206200
mut ty: Ty<'tcx>,
207201
mut normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
@@ -281,7 +275,7 @@ impl<'tcx> TyCtxt<'tcx> {
281275
param_env: ty::ParamEnv<'tcx>,
282276
) -> (Ty<'tcx>, Ty<'tcx>) {
283277
let tcx = self;
284-
tcx.struct_lockstep_tails_with_normalize(source, target, |ty| {
278+
tcx.struct_lockstep_tails_raw(source, target, |ty| {
285279
tcx.normalize_erasing_regions(param_env, ty)
286280
})
287281
}
@@ -294,7 +288,7 @@ impl<'tcx> TyCtxt<'tcx> {
294288
///
295289
/// See also `struct_lockstep_tails_for_codegen`, which is suitable for use
296290
/// during codegen.
297-
pub fn struct_lockstep_tails_with_normalize(
291+
pub fn struct_lockstep_tails_raw(
298292
self,
299293
source: Ty<'tcx>,
300294
target: Ty<'tcx>,

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -687,10 +687,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
687687
let mut applied_do_not_recommend = false;
688688
loop {
689689
if let ObligationCauseCode::ImplDerived(ref c) = base_cause {
690-
if self.tcx.has_attrs_with_path(
691-
c.impl_or_alias_def_id,
692-
&[sym::diagnostic, sym::do_not_recommend],
693-
) {
690+
if self.tcx.do_not_recommend_impl(c.impl_or_alias_def_id) {
694691
let code = (*c.derived.parent_code).clone();
695692
obligation.cause.map_code(|_| code);
696693
obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx);
@@ -1629,11 +1626,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
16291626
.tcx
16301627
.all_impls(def_id)
16311628
// ignore `do_not_recommend` items
1632-
.filter(|def_id| {
1633-
!self
1634-
.tcx
1635-
.has_attrs_with_path(*def_id, &[sym::diagnostic, sym::do_not_recommend])
1636-
})
1629+
.filter(|def_id| !self.tcx.do_not_recommend_impl(*def_id))
16371630
// Ignore automatically derived impls and `!Trait` impls.
16381631
.filter_map(|def_id| self.tcx.impl_trait_header(def_id))
16391632
.filter_map(|header| {
@@ -1903,12 +1896,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
19031896
let impl_candidates = impl_candidates
19041897
.into_iter()
19051898
.cloned()
1906-
.filter(|cand| {
1907-
!self.tcx.has_attrs_with_path(
1908-
cand.impl_def_id,
1909-
&[sym::diagnostic, sym::do_not_recommend],
1910-
)
1911-
})
1899+
.filter(|cand| !self.tcx.do_not_recommend_impl(cand.impl_def_id))
19121900
.collect::<Vec<_>>();
19131901

19141902
let def_id = trait_ref.def_id();

Diff for: compiler/rustc_trait_selection/src/solve/fulfill.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_middle::bug;
1313
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1414
use rustc_middle::ty::{self, TyCtxt};
1515
use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as _};
16-
use rustc_span::symbol::sym;
1716

1817
use super::delegate::SolverDelegate;
1918
use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
@@ -440,10 +439,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
440439
source: CandidateSource::Impl(impl_def_id),
441440
result: _,
442441
} = candidate.kind()
443-
&& goal
444-
.infcx()
445-
.tcx
446-
.has_attrs_with_path(impl_def_id, &[sym::diagnostic, sym::do_not_recommend])
442+
&& goal.infcx().tcx.do_not_recommend_impl(impl_def_id)
447443
{
448444
return ControlFlow::Break(self.obligation.clone());
449445
}

Diff for: compiler/rustc_trait_selection/src/traits/project.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
11101110
| ty::Error(_) => false,
11111111
}
11121112
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::PointeeTrait) {
1113-
let tail = selcx.tcx().struct_tail_with_normalize(
1113+
let tail = selcx.tcx().struct_tail_raw(
11141114
self_ty,
11151115
|ty| {
11161116
// We throw away any obligations we get from this, since we normalize
@@ -1149,10 +1149,10 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
11491149
| ty::Never
11501150
// Extern types have unit metadata, according to RFC 2850
11511151
| ty::Foreign(_)
1152-
// If returned by `struct_tail_without_normalization` this is a unit struct
1152+
// If returned by `struct_tail` this is a unit struct
11531153
// without any fields, or not a struct, and therefore is Sized.
11541154
| ty::Adt(..)
1155-
// If returned by `struct_tail_without_normalization` this is the empty tuple.
1155+
// If returned by `struct_tail` this is the empty tuple.
11561156
| ty::Tuple(..)
11571157
// Integers and floats are always Sized, and so have unit type metadata.
11581158
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,

Diff for: compiler/rustc_ty_utils/src/layout.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,13 @@ fn layout_of_uncached<'tcx>(
219219
// its struct tail cannot be normalized either, so try to get a
220220
// more descriptive layout error here, which will lead to less confusing
221221
// diagnostics.
222+
//
223+
// We use the raw struct tail function here to get the first tail
224+
// that is an alias, which is likely the cause of the normalization
225+
// error.
222226
match tcx.try_normalize_erasing_regions(
223227
param_env,
224-
tcx.struct_tail_without_normalization(pointee),
228+
tcx.struct_tail_raw(pointee, |ty| ty, || {}),
225229
) {
226230
Ok(_) => {}
227231
Err(better_err) => {

Diff for: library/alloc/src/fmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ pub use core::fmt::Alignment;
581581
#[stable(feature = "rust1", since = "1.0.0")]
582582
pub use core::fmt::Error;
583583
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
584-
pub use core::fmt::FormatterFn;
584+
pub use core::fmt::{from_fn, FromFn};
585585
#[stable(feature = "rust1", since = "1.0.0")]
586586
pub use core::fmt::{write, Arguments};
587587
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)