Skip to content

Commit f005c74

Browse files
committed
Auto merge of rust-lang#133561 - GuillaumeGomez:rollup-g4upmv4, r=GuillaumeGomez
Rollup of 12 pull requests Successful merges: - rust-lang#129409 (Expand std::os::unix::fs::chown() doc with a warning) - rust-lang#133320 (Add release notes for Rust 1.83.0) - rust-lang#133368 (Delay a bug when encountering an impl with unconstrained generics in `codegen_select`) - rust-lang#133428 (Actually use placeholder regions for trait method late bound regions in `collect_return_position_impl_trait_in_trait_tys`) - rust-lang#133512 (Add `as_array` and `as_mut_array` conversion methods to slices.) - rust-lang#133519 (Check `xform_ret_ty` for WF in the new solver to improve method winnowing) - rust-lang#133520 (Structurally resolve before applying projection in borrowck) - rust-lang#133534 (extend group-forbid-always-trumps-cli test) - rust-lang#133537 ([rustdoc] Fix new clippy lints) - rust-lang#133543 ([AIX] create shim for lgammaf_r) - rust-lang#133547 (rustc_span: Replace a `HashMap<_, ()>` with `HashSet`) - rust-lang#133550 (print generated doc paths) r? `@ghost` `@rustbot` modify labels: rollup
2 parents eddb717 + ed913fe commit f005c74

File tree

86 files changed

+1023
-440
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1023
-440
lines changed

RELEASES.md

+233-1
Large diffs are not rendered by default.

compiler/rustc_borrowck/src/type_check/canonical.rs

+36
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::Span;
99
use rustc_span::def_id::DefId;
10+
use rustc_trait_selection::solve::NoSolution;
1011
use rustc_trait_selection::traits::ObligationCause;
1112
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1213
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
@@ -177,6 +178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
177178
if self.infcx.next_trait_solver() {
178179
let body = self.body;
179180
let param_env = self.infcx.param_env;
181+
// FIXME: Make this into a real type op?
180182
self.fully_perform_op(
181183
location.to_locations(),
182184
ConstraintCategory::Boring,
@@ -213,6 +215,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
213215
}
214216
}
215217

218+
#[instrument(skip(self), level = "debug")]
219+
pub(super) fn structurally_resolve(
220+
&mut self,
221+
ty: Ty<'tcx>,
222+
location: impl NormalizeLocation,
223+
) -> Ty<'tcx> {
224+
if self.infcx.next_trait_solver() {
225+
let body = self.body;
226+
let param_env = self.infcx.param_env;
227+
// FIXME: Make this into a real type op?
228+
self.fully_perform_op(
229+
location.to_locations(),
230+
ConstraintCategory::Boring,
231+
CustomTypeOp::new(
232+
|ocx| {
233+
ocx.structurally_normalize(
234+
&ObligationCause::misc(
235+
location.to_locations().span(body),
236+
body.source.def_id().expect_local(),
237+
),
238+
param_env,
239+
ty,
240+
)
241+
.map_err(|_| NoSolution)
242+
},
243+
"normalizing struct tail",
244+
),
245+
)
246+
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar))
247+
} else {
248+
self.normalize(ty, location)
249+
}
250+
}
251+
216252
#[instrument(skip(self), level = "debug")]
217253
pub(super) fn ascribe_user_type(
218254
&mut self,

compiler/rustc_borrowck/src/type_check/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10641064
let tcx = self.infcx.tcx;
10651065

10661066
for proj in &user_ty.projs {
1067-
if let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() {
1067+
if !self.infcx.next_trait_solver()
1068+
&& let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind()
1069+
{
10681070
// There is nothing that we can compare here if we go through an opaque type.
10691071
// We're always in its defining scope as we can otherwise not project through
10701072
// it, so we're constraining it anyways.
@@ -1075,7 +1077,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10751077
proj,
10761078
|this, field, ()| {
10771079
let ty = this.field_ty(tcx, field);
1078-
self.normalize(ty, locations)
1080+
self.structurally_resolve(ty, locations)
10791081
},
10801082
|_, _| unreachable!(),
10811083
);

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+21-27
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
523523
let impl_sig = ocx.normalize(
524524
&misc_cause,
525525
param_env,
526-
tcx.liberate_late_bound_regions(
527-
impl_m.def_id,
526+
infcx.instantiate_binder_with_fresh_vars(
527+
return_span,
528+
infer::HigherRankedType,
528529
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
529530
),
530531
);
@@ -536,10 +537,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
536537
// them with inference variables.
537538
// We will use these inference variables to collect the hidden types of RPITITs.
538539
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id);
539-
let unnormalized_trait_sig = infcx
540-
.instantiate_binder_with_fresh_vars(
541-
return_span,
542-
infer::HigherRankedType,
540+
let unnormalized_trait_sig = tcx
541+
.liberate_late_bound_regions(
542+
impl_m.def_id,
543543
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
544544
)
545545
.fold_with(&mut collector);
@@ -702,8 +702,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
702702

703703
let mut remapped_types = DefIdMap::default();
704704
for (def_id, (ty, args)) in collected_types {
705-
match infcx.fully_resolve((ty, args)) {
706-
Ok((ty, args)) => {
705+
match infcx.fully_resolve(ty) {
706+
Ok(ty) => {
707707
// `ty` contains free regions that we created earlier while liberating the
708708
// trait fn signature. However, projection normalization expects `ty` to
709709
// contains `def_id`'s early-bound regions.
@@ -883,33 +883,27 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
883883
self.tcx
884884
}
885885

886-
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
887-
if let ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = *t.kind() {
888-
let mut mapped_args = Vec::with_capacity(args.len());
889-
for (arg, v) in std::iter::zip(args, self.tcx.variances_of(def_id)) {
890-
mapped_args.push(match (arg.unpack(), v) {
891-
// Skip uncaptured opaque args
892-
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
893-
_ => arg.try_fold_with(self)?,
894-
});
895-
}
896-
Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_args(&mapped_args)))
897-
} else {
898-
t.try_super_fold_with(self)
899-
}
900-
}
901-
902886
fn try_fold_region(
903887
&mut self,
904888
region: ty::Region<'tcx>,
905889
) -> Result<ty::Region<'tcx>, Self::Error> {
906890
match region.kind() {
907-
// Remap late-bound regions from the function.
891+
// Never remap bound regions or `'static`
892+
ty::ReBound(..) | ty::ReStatic | ty::ReError(_) => return Ok(region),
893+
// We always remap liberated late-bound regions from the function.
908894
ty::ReLateParam(_) => {}
909895
// Remap early-bound regions as long as they don't come from the `impl` itself,
910896
// in which case we don't really need to renumber them.
911-
ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
912-
_ => return Ok(region),
897+
ty::ReEarlyParam(ebr) => {
898+
if ebr.index as usize >= self.num_impl_args {
899+
// Remap
900+
} else {
901+
return Ok(region);
902+
}
903+
}
904+
ty::ReVar(_) | ty::RePlaceholder(_) | ty::ReErased => unreachable!(
905+
"should not have leaked vars or placeholders into hidden type of RPITIT"
906+
),
913907
}
914908

915909
let e = if let Some(id_region) = self.map.get(&region) {

compiler/rustc_hir_typeck/src/method/probe.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,28 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16421642
}
16431643
}
16441644

1645+
// FIXME(-Znext-solver): See the linked issue below.
1646+
// <https://github.com/rust-lang/trait-system-refactor-initiative/issues/134>
1647+
//
1648+
// In the new solver, check the well-formedness of the return type.
1649+
// This emulates, in a way, the predicates that fall out of
1650+
// normalizing the return type in the old solver.
1651+
//
1652+
// We alternatively could check the predicates of the method itself hold,
1653+
// but we intentionally do not do this in the old solver b/c of cycles,
1654+
// and doing it in the new solver would be stronger. This should be fixed
1655+
// in the future, since it likely leads to much better method winnowing.
1656+
if let Some(xform_ret_ty) = xform_ret_ty
1657+
&& self.infcx.next_trait_solver()
1658+
{
1659+
ocx.register_obligation(traits::Obligation::new(
1660+
self.tcx,
1661+
cause.clone(),
1662+
self.param_env,
1663+
ty::ClauseKind::WellFormed(xform_ret_ty.into()),
1664+
));
1665+
}
1666+
16451667
// Evaluate those obligations to see if they might possibly hold.
16461668
for error in ocx.select_where_possible() {
16471669
result = ProbeResult::NoMatch;

compiler/rustc_span/src/hygiene.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
use std::cell::RefCell;
2828
use std::collections::hash_map::Entry;
29+
use std::collections::hash_set::Entry as SetEntry;
2930
use std::fmt;
3031
use std::hash::Hash;
3132

@@ -1270,7 +1271,7 @@ pub struct HygieneDecodeContext {
12701271
inner: Lock<HygieneDecodeContextInner>,
12711272

12721273
/// A set of serialized `SyntaxContext` ids that are currently being decoded on each thread.
1273-
local_in_progress: WorkerLocal<RefCell<FxHashMap<u32, ()>>>,
1274+
local_in_progress: WorkerLocal<RefCell<FxHashSet<u32>>>,
12741275
}
12751276

12761277
/// Register an expansion which has been decoded from the on-disk-cache for the local crate.
@@ -1364,14 +1365,14 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
13641365
match inner.decoding.entry(raw_id) {
13651366
Entry::Occupied(ctxt_entry) => {
13661367
match context.local_in_progress.borrow_mut().entry(raw_id) {
1367-
Entry::Occupied(..) => {
1368+
SetEntry::Occupied(..) => {
13681369
// We're decoding this already on the current thread. Return here
13691370
// and let the function higher up the stack finish decoding to handle
13701371
// recursive cases.
13711372
return *ctxt_entry.get();
13721373
}
1373-
Entry::Vacant(entry) => {
1374-
entry.insert(());
1374+
SetEntry::Vacant(entry) => {
1375+
entry.insert();
13751376

13761377
// Some other thread is current decoding this. Race with it.
13771378
*ctxt_entry.get()
@@ -1380,7 +1381,7 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
13801381
}
13811382
Entry::Vacant(entry) => {
13821383
// We are the first thread to start decoding. Mark the current thread as being progress.
1383-
context.local_in_progress.borrow_mut().insert(raw_id, ());
1384+
context.local_in_progress.borrow_mut().insert(raw_id);
13841385

13851386
// Allocate and store SyntaxContext id *before* calling the decoder function,
13861387
// as the SyntaxContextData may reference itself.

compiler/rustc_span/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#![feature(array_windows)]
2323
#![feature(cfg_match)]
2424
#![feature(core_io_borrowed_buf)]
25+
#![feature(hash_set_entry)]
2526
#![feature(if_let_guard)]
2627
#![feature(let_chains)]
2728
#![feature(min_specialization)]

compiler/rustc_traits/src/codegen.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,21 @@ pub(crate) fn codegen_select_candidate<'tcx>(
7474
}
7575

7676
let impl_source = infcx.resolve_vars_if_possible(impl_source);
77-
let impl_source = infcx.tcx.erase_regions(impl_source);
78-
if impl_source.has_infer() {
79-
// Unused lifetimes on an impl get replaced with inference vars, but never resolved,
80-
// causing the return value of a query to contain inference vars. We do not have a concept
81-
// for this and will in fact ICE in stable hashing of the return value. So bail out instead.
82-
infcx.tcx.dcx().has_errors().unwrap();
77+
let impl_source = tcx.erase_regions(impl_source);
78+
if impl_source.has_non_region_infer() {
79+
// Unused generic types or consts on an impl get replaced with inference vars,
80+
// but never resolved, causing the return value of a query to contain inference
81+
// vars. We do not have a concept for this and will in fact ICE in stable hashing
82+
// of the return value. So bail out instead.
83+
match impl_source {
84+
ImplSource::UserDefined(impl_) => {
85+
tcx.dcx().span_delayed_bug(
86+
tcx.def_span(impl_.impl_def_id),
87+
"this impl has unconstrained generic parameters",
88+
);
89+
}
90+
_ => unreachable!(),
91+
}
8392
return Err(CodegenObligationError::FulfillmentError);
8493
}
8594

library/core/src/array/mod.rs

+4-16
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ impl<T, const N: usize> BorrowMut<[T]> for [T; N] {
214214
}
215215
}
216216

217-
/// Tries to create an array `[T; N]` by copying from a slice `&[T]`. Succeeds if
218-
/// `slice.len() == N`.
217+
/// Tries to create an array `[T; N]` by copying from a slice `&[T]`.
218+
/// Succeeds if `slice.len() == N`.
219219
///
220220
/// ```
221221
/// let bytes: [u8; 3] = [1, 0, 2];
@@ -282,13 +282,7 @@ impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
282282

283283
#[inline]
284284
fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> {
285-
if slice.len() == N {
286-
let ptr = slice.as_ptr() as *const [T; N];
287-
// SAFETY: ok because we just checked that the length fits
288-
unsafe { Ok(&*ptr) }
289-
} else {
290-
Err(TryFromSliceError(()))
291-
}
285+
slice.as_array().ok_or(TryFromSliceError(()))
292286
}
293287
}
294288

@@ -310,13 +304,7 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
310304

311305
#[inline]
312306
fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> {
313-
if slice.len() == N {
314-
let ptr = slice.as_mut_ptr() as *mut [T; N];
315-
// SAFETY: ok because we just checked that the length fits
316-
unsafe { Ok(&mut *ptr) }
317-
} else {
318-
Err(TryFromSliceError(()))
319-
}
307+
slice.as_mut_array().ok_or(TryFromSliceError(()))
320308
}
321309
}
322310

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
#![feature(ptr_alignment_type)]
145145
#![feature(ptr_metadata)]
146146
#![feature(set_ptr_value)]
147+
#![feature(slice_as_array)]
147148
#![feature(slice_as_chunks)]
148149
#![feature(slice_ptr_get)]
149150
#![feature(str_internals)]

library/core/src/ptr/const_ptr.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,22 @@ impl<T> *const [T] {
15261526
self as *const T
15271527
}
15281528

1529+
/// Gets a raw pointer to the underlying array.
1530+
///
1531+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1532+
#[unstable(feature = "slice_as_array", issue = "133508")]
1533+
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
1534+
#[inline]
1535+
#[must_use]
1536+
pub const fn as_array<const N: usize>(self) -> Option<*const [T; N]> {
1537+
if self.len() == N {
1538+
let me = self.as_ptr() as *const [T; N];
1539+
Some(me)
1540+
} else {
1541+
None
1542+
}
1543+
}
1544+
15291545
/// Returns a raw pointer to an element or subslice, without doing bounds
15301546
/// checking.
15311547
///

library/core/src/ptr/mut_ptr.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,22 @@ impl<T> *mut [T] {
17601760
self.len() == 0
17611761
}
17621762

1763+
/// Gets a raw, mutable pointer to the underlying array.
1764+
///
1765+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1766+
#[unstable(feature = "slice_as_array", issue = "133508")]
1767+
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
1768+
#[inline]
1769+
#[must_use]
1770+
pub const fn as_mut_array<const N: usize>(self) -> Option<*mut [T; N]> {
1771+
if self.len() == N {
1772+
let me = self.as_mut_ptr() as *mut [T; N];
1773+
Some(me)
1774+
} else {
1775+
None
1776+
}
1777+
}
1778+
17631779
/// Divides one mutable raw slice into two at an index.
17641780
///
17651781
/// The first will contain all indices from `[0, mid)` (excluding

0 commit comments

Comments
 (0)