Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 12 pull requests #133561

Merged
merged 33 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a9ecd0f
Expand std::os::unix::fs::chown() doc with a warning
grinapo Aug 22, 2024
3408dc1
Update chown help with a link and adding cap warning
grinapo Aug 22, 2024
451c8cd
Remove one stray space.
grinapo Nov 14, 2024
7426066
Add release notes for Rust 1.83.0
cuviper Nov 22, 2024
c14f0a1
Update relnotes from suggestions and issues sync
cuviper Nov 22, 2024
3b8c0cc
Reorder lang relnotes
cuviper Nov 22, 2024
d3d3342
Add an empty line to fix markdown quoting
cuviper Nov 22, 2024
c31a097
aix: create shim for lgammaf_r
mustartt Nov 22, 2024
c7195c4
Change `$float` to `{float}` in relnotes
cuviper Nov 22, 2024
46cd0c5
Also change an older `$integer` to `{integer}`
cuviper Nov 23, 2024
50fb40a
Delay a bug when encountering an impl with unconstrained generics in …
compiler-errors Nov 23, 2024
15dff27
Actually use placeholder regions for trait method late bound regions …
compiler-errors Nov 24, 2024
4b8ca28
Add '<[T]>::as_array', '<[T]>::as_mut_array', '<*const [T]>::as_array…
bjoernager Nov 26, 2024
527b606
fmt
mustartt Nov 27, 2024
e37ac2a
rustc_span: Replace a `HashMap<_, ()>` with `HashSet`
cuviper Nov 27, 2024
e11cfeb
print generated doc paths
onur-ozkan Nov 27, 2024
26c7774
Structurally resolve before applying projection in borrowck
compiler-errors Nov 27, 2024
4120fdb
Check xform_ret_ty for WF in the new solver to improve method winnowing
compiler-errors Nov 27, 2024
37d3c61
extend group-forbid-always-trumps-cli test
RalfJung Nov 27, 2024
871cfc9
Further simplifications
compiler-errors Nov 24, 2024
f0c301f
Fix new clippy lints
GuillaumeGomez Nov 27, 2024
10193a3
Rollup merge of #129409 - grinapo:patch-1, r=Amanieu
GuillaumeGomez Nov 28, 2024
09734ac
Rollup merge of #133320 - cuviper:relnotes-1.83.0, r=cuviper
GuillaumeGomez Nov 28, 2024
acf48fc
Rollup merge of #133368 - compiler-errors:codegen-select-unconstraine…
GuillaumeGomez Nov 28, 2024
3e095e8
Rollup merge of #133428 - compiler-errors:rpitit-unsound, r=lcnr
GuillaumeGomez Nov 28, 2024
b1c33f4
Rollup merge of #133512 - bjoernager:slice-as-array, r=Amanieu
GuillaumeGomez Nov 28, 2024
06815d0
Rollup merge of #133519 - compiler-errors:xform-ret-wf, r=lcnr
GuillaumeGomez Nov 28, 2024
b46ed71
Rollup merge of #133520 - compiler-errors:structurally-resolve-mir-bo…
GuillaumeGomez Nov 28, 2024
7e2f261
Rollup merge of #133534 - RalfJung:cli-lint-flags, r=Nadrieril
GuillaumeGomez Nov 28, 2024
0cad2dc
Rollup merge of #133537 - GuillaumeGomez:fix-clippy-lints, r=Guillaum…
GuillaumeGomez Nov 28, 2024
82d4eae
Rollup merge of #133543 - mustartt:aix-lgammaf_r-shim, r=cuviper
GuillaumeGomez Nov 28, 2024
63a6e9c
Rollup merge of #133547 - cuviper:span-set-entry, r=jieyouxu
GuillaumeGomez Nov 28, 2024
ed913fe
Rollup merge of #133550 - onur-ozkan:doc-log, r=jieyouxu
GuillaumeGomez Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
234 changes: 233 additions & 1 deletion RELEASES.md

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_trait_selection::solve::NoSolution;
use rustc_trait_selection::traits::ObligationCause;
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
Expand Down Expand Up @@ -177,6 +178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if self.infcx.next_trait_solver() {
let body = self.body;
let param_env = self.infcx.param_env;
// FIXME: Make this into a real type op?
self.fully_perform_op(
location.to_locations(),
ConstraintCategory::Boring,
Expand Down Expand Up @@ -213,6 +215,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}

#[instrument(skip(self), level = "debug")]
pub(super) fn structurally_resolve(
&mut self,
ty: Ty<'tcx>,
location: impl NormalizeLocation,
) -> Ty<'tcx> {
if self.infcx.next_trait_solver() {
let body = self.body;
let param_env = self.infcx.param_env;
// FIXME: Make this into a real type op?
self.fully_perform_op(
location.to_locations(),
ConstraintCategory::Boring,
CustomTypeOp::new(
|ocx| {
ocx.structurally_normalize(
&ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),
),
param_env,
ty,
)
.map_err(|_| NoSolution)
},
"normalizing struct tail",
),
)
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar))
} else {
self.normalize(ty, location)
}
}

#[instrument(skip(self), level = "debug")]
pub(super) fn ascribe_user_type(
&mut self,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let tcx = self.infcx.tcx;

for proj in &user_ty.projs {
if let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() {
if !self.infcx.next_trait_solver()
&& let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind()
{
// There is nothing that we can compare here if we go through an opaque type.
// We're always in its defining scope as we can otherwise not project through
// it, so we're constraining it anyways.
Expand All @@ -1075,7 +1077,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
proj,
|this, field, ()| {
let ty = this.field_ty(tcx, field);
self.normalize(ty, locations)
self.structurally_resolve(ty, locations)
},
|_, _| unreachable!(),
);
Expand Down
48 changes: 21 additions & 27 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_sig = ocx.normalize(
&misc_cause,
param_env,
tcx.liberate_late_bound_regions(
impl_m.def_id,
infcx.instantiate_binder_with_fresh_vars(
return_span,
infer::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
),
);
Expand All @@ -536,10 +537,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// them with inference variables.
// We will use these inference variables to collect the hidden types of RPITITs.
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id);
let unnormalized_trait_sig = infcx
.instantiate_binder_with_fresh_vars(
return_span,
infer::HigherRankedType,
let unnormalized_trait_sig = tcx
.liberate_late_bound_regions(
impl_m.def_id,
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
)
.fold_with(&mut collector);
Expand Down Expand Up @@ -702,8 +702,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(

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

fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
if let ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = *t.kind() {
let mut mapped_args = Vec::with_capacity(args.len());
for (arg, v) in std::iter::zip(args, self.tcx.variances_of(def_id)) {
mapped_args.push(match (arg.unpack(), v) {
// Skip uncaptured opaque args
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
_ => arg.try_fold_with(self)?,
});
}
Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_args(&mapped_args)))
} else {
t.try_super_fold_with(self)
}
}

fn try_fold_region(
&mut self,
region: ty::Region<'tcx>,
) -> Result<ty::Region<'tcx>, Self::Error> {
match region.kind() {
// Remap late-bound regions from the function.
// Never remap bound regions or `'static`
ty::ReBound(..) | ty::ReStatic | ty::ReError(_) => return Ok(region),
// We always remap liberated late-bound regions from the function.
ty::ReLateParam(_) => {}
// Remap early-bound regions as long as they don't come from the `impl` itself,
// in which case we don't really need to renumber them.
ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
_ => return Ok(region),
ty::ReEarlyParam(ebr) => {
if ebr.index as usize >= self.num_impl_args {
// Remap
} else {
return Ok(region);
}
}
ty::ReVar(_) | ty::RePlaceholder(_) | ty::ReErased => unreachable!(
"should not have leaked vars or placeholders into hidden type of RPITIT"
),
}

let e = if let Some(id_region) = self.map.get(&region) {
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1642,6 +1642,28 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}

// FIXME(-Znext-solver): See the linked issue below.
// <https://github.com/rust-lang/trait-system-refactor-initiative/issues/134>
//
// In the new solver, check the well-formedness of the return type.
// This emulates, in a way, the predicates that fall out of
// normalizing the return type in the old solver.
//
// We alternatively could check the predicates of the method itself hold,
// but we intentionally do not do this in the old solver b/c of cycles,
// and doing it in the new solver would be stronger. This should be fixed
// in the future, since it likely leads to much better method winnowing.
if let Some(xform_ret_ty) = xform_ret_ty
&& self.infcx.next_trait_solver()
{
ocx.register_obligation(traits::Obligation::new(
self.tcx,
cause.clone(),
self.param_env,
ty::ClauseKind::WellFormed(xform_ret_ty.into()),
));
}

// Evaluate those obligations to see if they might possibly hold.
for error in ocx.select_where_possible() {
result = ProbeResult::NoMatch;
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_span/src/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::collections::hash_set::Entry as SetEntry;
use std::fmt;
use std::hash::Hash;

Expand Down Expand Up @@ -1270,7 +1271,7 @@ pub struct HygieneDecodeContext {
inner: Lock<HygieneDecodeContextInner>,

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

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

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

// Allocate and store SyntaxContext id *before* calling the decoder function,
// as the SyntaxContextData may reference itself.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#![feature(array_windows)]
#![feature(cfg_match)]
#![feature(core_io_borrowed_buf)]
#![feature(hash_set_entry)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(min_specialization)]
Expand Down
21 changes: 15 additions & 6 deletions compiler/rustc_traits/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,21 @@ pub(crate) fn codegen_select_candidate<'tcx>(
}

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

Expand Down
20 changes: 4 additions & 16 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ impl<T, const N: usize> BorrowMut<[T]> for [T; N] {
}
}

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

#[inline]
fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> {
if slice.len() == N {
let ptr = slice.as_ptr() as *const [T; N];
// SAFETY: ok because we just checked that the length fits
unsafe { Ok(&*ptr) }
} else {
Err(TryFromSliceError(()))
}
slice.as_array().ok_or(TryFromSliceError(()))
}
}

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

#[inline]
fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> {
if slice.len() == N {
let ptr = slice.as_mut_ptr() as *mut [T; N];
// SAFETY: ok because we just checked that the length fits
unsafe { Ok(&mut *ptr) }
} else {
Err(TryFromSliceError(()))
}
slice.as_mut_array().ok_or(TryFromSliceError(()))
}
}

Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
#![feature(ptr_alignment_type)]
#![feature(ptr_metadata)]
#![feature(set_ptr_value)]
#![feature(slice_as_array)]
#![feature(slice_as_chunks)]
#![feature(slice_ptr_get)]
#![feature(str_internals)]
Expand Down
16 changes: 16 additions & 0 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1526,6 +1526,22 @@ impl<T> *const [T] {
self as *const T
}

/// Gets a raw pointer to the underlying array.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
#[inline]
#[must_use]
pub const fn as_array<const N: usize>(self) -> Option<*const [T; N]> {
if self.len() == N {
let me = self.as_ptr() as *const [T; N];
Some(me)
} else {
None
}
}

/// Returns a raw pointer to an element or subslice, without doing bounds
/// checking.
///
Expand Down
16 changes: 16 additions & 0 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,22 @@ impl<T> *mut [T] {
self.len() == 0
}

/// Gets a raw, mutable pointer to the underlying array.
///
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
#[unstable(feature = "slice_as_array", issue = "133508")]
#[rustc_const_unstable(feature = "slice_as_array", issue = "133508")]
#[inline]
#[must_use]
pub const fn as_mut_array<const N: usize>(self) -> Option<*mut [T; N]> {
if self.len() == N {
let me = self.as_mut_ptr() as *mut [T; N];
Some(me)
} else {
None
}
}

/// Divides one mutable raw slice into two at an index.
///
/// The first will contain all indices from `[0, mid)` (excluding
Expand Down
Loading
Loading