Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Version 1.90 (2025-09-18)
==========================
Version 1.90.0 (2025-09-18)
===========================

<a id="1.90-Language"></a>

Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block

ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect

ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list

ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions
.label = `extern "{$abi}"` because of this
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ impl<'a> AstValidator<'a> {

match fn_ctxt {
FnCtxt::Foreign => return,
FnCtxt::Free => match sig.header.ext {
FnCtxt::Free | FnCtxt::Assoc(_) => match sig.header.ext {
Extern::Implicit(_) => {
if !matches!(sig.header.safety, Safety::Unsafe(_)) {
self.dcx().emit_err(errors::CVariadicMustBeUnsafe {
Expand Down Expand Up @@ -726,11 +726,6 @@ impl<'a> AstValidator<'a> {
self.dcx().emit_err(err);
}
},
FnCtxt::Assoc(_) => {
// For now, C variable argument lists are unsupported in associated functions.
let err = errors::CVariadicAssociatedFunction { span: variadic_param.span };
self.dcx().emit_err(err);
}
}
}

Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,6 @@ pub(crate) struct ExternItemAscii {
pub block: Span,
}

#[derive(Diagnostic)]
#[diag(ast_passes_c_variadic_associated_function)]
pub(crate) struct CVariadicAssociatedFunction {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(ast_passes_c_variadic_no_extern)]
#[help]
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_borrowck/src/handle_placeholders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,9 @@ impl RegionTracker {
}
}

/// Determine if the tracked universes of the two SCCs are compatible.
pub(crate) fn universe_compatible_with(&self, other: Self) -> bool {
// HACK: We first check whether we can name the highest existential universe
// of `other`. This only exists to avoid errors in case that scc already
// depends on a placeholder it cannot name itself.
self.max_nameable_universe().can_name(other.max_nameable_universe())
|| other.reachable_placeholders.can_be_named_by(self.max_nameable_universe())
/// Determine if we can name all the placeholders in `other`.
pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool {
other.reachable_placeholders.can_be_named_by(self.max_nameable_universe.0)
}

/// If this SCC reaches a placeholder it can't name, return it.
Expand Down
20 changes: 15 additions & 5 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,11 +571,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}

/// Returns `true` if all the elements in the value of `scc_b` are nameable
/// Returns `true` if all the placeholders in the value of `scc_b` are nameable
/// in `scc_a`. Used during constraint propagation, and only once
/// the value of `scc_b` has been computed.
fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool {
self.scc_annotations[scc_a].universe_compatible_with(self.scc_annotations[scc_b])
fn can_name_all_placeholders(
&self,
scc_a: ConstraintSccIndex,
scc_b: ConstraintSccIndex,
) -> bool {
self.scc_annotations[scc_a].can_name_all_placeholders(self.scc_annotations[scc_b])
}

/// Once regions have been propagated, this method is used to see
Expand Down Expand Up @@ -964,16 +968,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return true;
}

let fr_static = self.universal_regions().fr_static;

// If we are checking that `'sup: 'sub`, and `'sub` contains
// some placeholder that `'sup` cannot name, then this is only
// true if `'sup` outlives static.
if !self.universe_compatible(sub_region_scc, sup_region_scc) {
//
// Avoid infinite recursion if `sub_region` is already `'static`
if sub_region != fr_static
&& !self.can_name_all_placeholders(sup_region_scc, sub_region_scc)
{
debug!(
"sub universe `{sub_region_scc:?}` is not nameable \
by super `{sup_region_scc:?}`, promoting to static",
);

return self.eval_outlives(sup_region, self.universal_regions().fr_static);
return self.eval_outlives(sup_region, fr_static);
}

// Both the `sub_region` and `sup_region` consist of the union
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
location: impl NormalizeLocation,
) -> Ty<'tcx> {
let tcx = self.tcx();
let body = self.body;

let cause = ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),
);

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(
Expand All @@ -241,10 +247,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|ocx| {
let structurally_normalize = |ty| {
ocx.structurally_normalize_ty(
&ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),
),
&cause,
param_env,
ty,
)
Expand All @@ -253,6 +256,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

let tail = tcx.struct_tail_raw(
ty,
&cause,
structurally_normalize,
|| {},
);
Expand All @@ -265,7 +269,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
} else {
let mut normalize = |ty| self.normalize(ty, location);
let tail = tcx.struct_tail_raw(ty, &mut normalize, || {});
let tail = tcx.struct_tail_raw(ty, &cause, &mut normalize, || {});
normalize(tail)
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_abi::{BackendRepr, FieldIdx, VariantIdx};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::layout::{LayoutCx, TyAndLayout};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
Expand Down Expand Up @@ -196,6 +197,7 @@ fn reconstruct_place_meta<'tcx>(
// Traverse the type, and update `last_valtree` as we go.
let tail = tcx.struct_tail_raw(
layout.ty,
&ObligationCause::dummy(),
|ty| ty,
|| {
let branches = last_valtree.unwrap_branch();
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_hir_typeck/src/expectation.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;

Expand Down Expand Up @@ -74,8 +75,14 @@ impl<'a, 'tcx> Expectation<'tcx> {
/// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
/// for examples of where this comes up,.
pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
let span = match ty.kind() {
ty::Adt(adt_def, _) => fcx.tcx.def_span(adt_def.did()),
_ => fcx.tcx.def_span(fcx.body_id),
};
let cause = ObligationCause::misc(span, fcx.body_id);

// FIXME: This is not right, even in the old solver...
match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}).kind() {
match fcx.tcx.struct_tail_raw(ty, &cause, |ty| ty, || {}).kind() {
ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
_ => ExpectHasType(ty),
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !ty.references_error() {
let tail = self.tcx.struct_tail_raw(
ty,
&self.misc(span),
|ty| {
if self.next_trait_solver() {
self.try_structurally_resolve_type(span, ty)
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ pub enum TypeMismatchReason {
#[diag(middle_recursion_limit_reached)]
#[help]
pub(crate) struct RecursionLimitReached<'tcx> {
#[primary_span]
pub span: Span,
pub ty: Ty<'tcx>,
pub suggested_limit: rustc_hir::limit::Limit,
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,9 @@ impl DynCompatibilityViolation {
DynCompatibilityViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
format!("method `{name}` is `async`").into()
}
DynCompatibilityViolation::Method(name, MethodViolationCode::CVariadic, _) => {
format!("method `{name}` is C-variadic").into()
}
DynCompatibilityViolation::Method(
name,
MethodViolationCode::WhereClauseReferencesSelf,
Expand Down Expand Up @@ -977,6 +980,9 @@ pub enum MethodViolationCode {
/// e.g., `fn foo<A>()`
Generic,

/// e.g., `fn (mut ap: ...)`
CVariadic,

/// the method's receiver (`self` argument) can't be dispatched on
UndispatchableReceiver(Option<Span>),
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use {rustc_abi as abi, rustc_hir as hir};

use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::query::TyCtxtAt;
use crate::traits::ObligationCause;
use crate::ty::normalize_erasing_regions::NormalizationError;
use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt};

Expand Down Expand Up @@ -384,6 +385,7 @@ impl<'tcx> SizeSkeleton<'tcx> {

let tail = tcx.struct_tail_raw(
pointee,
&ObligationCause::dummy(),
|ty| match tcx.try_normalize_erasing_regions(typing_env, ty) {
Ok(ty) => ty,
Err(e) => Ty::new_error_with_message(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use ty::util::IntTypeExt;

use super::GenericParamDefKind;
use crate::infer::canonical::Canonical;
use crate::traits::ObligationCause;
use crate::ty::InferTy::*;
use crate::ty::{
self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv,
Expand Down Expand Up @@ -1638,7 +1639,7 @@ impl<'tcx> Ty<'tcx> {
tcx: TyCtxt<'tcx>,
normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
) -> Result<Ty<'tcx>, Ty<'tcx>> {
let tail = tcx.struct_tail_raw(self, normalize, || {});
let tail = tcx.struct_tail_raw(self, &ObligationCause::dummy(), normalize, || {});
match tail.kind() {
// Sized types
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
Expand Down
17 changes: 13 additions & 4 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::TypingEnv;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir;
use crate::query::Providers;
use crate::traits::ObligationCause;
use crate::ty::layout::{FloatExt, IntegerExt};
use crate::ty::{
self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
Expand Down Expand Up @@ -216,7 +217,12 @@ impl<'tcx> TyCtxt<'tcx> {
typing_env: ty::TypingEnv<'tcx>,
) -> Ty<'tcx> {
let tcx = self;
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {})
tcx.struct_tail_raw(
ty,
&ObligationCause::dummy(),
|ty| tcx.normalize_erasing_regions(typing_env, ty),
|| {},
)
}

/// Returns true if a type has metadata.
Expand Down Expand Up @@ -248,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn struct_tail_raw(
self,
mut ty: Ty<'tcx>,
cause: &ObligationCause<'tcx>,
mut normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
// This is currently used to allow us to walk a ValTree
// in lockstep with the type in order to get the ValTree branch that
Expand All @@ -261,9 +268,11 @@ impl<'tcx> TyCtxt<'tcx> {
Limit(0) => Limit(2),
limit => limit * 2,
};
let reported = self
.dcx()
.emit_err(crate::error::RecursionLimitReached { ty, suggested_limit });
let reported = self.dcx().emit_err(crate::error::RecursionLimitReached {
span: cause.span,
ty,
suggested_limit,
});
return Ty::new_error(self, reported);
}
match *ty.kind() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,9 @@ fn virtual_call_violations_for_method<'tcx>(
if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
errors.push(code);
}
if sig.skip_binder().c_variadic {
errors.push(MethodViolationCode::CVariadic);
}

// We can't monomorphize things like `fn foo<A>(...)`.
let own_counts = tcx.generics_of(method.def_id).own_counts();
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
Some(LangItem::PointeeTrait) => {
let tail = selcx.tcx().struct_tail_raw(
self_ty,
&obligation.cause,
|ty| {
// We throw away any obligations we get from this, since we normalize
// and confirm these obligations once again during confirmation
Expand Down
46 changes: 24 additions & 22 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_hashes::Hash64;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::layout::{
FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout,
};
Expand Down Expand Up @@ -390,30 +391,31 @@ fn layout_of_uncached<'tcx>(

let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]);
let metadata_ty =
match tcx.try_normalize_erasing_regions(cx.typing_env, pointee_metadata) {
Ok(metadata_ty) => metadata_ty,
Err(mut err) => {
// Usually `<Ty as Pointee>::Metadata` can't be normalized because
// its struct tail cannot be normalized either, so try to get a
// more descriptive layout error here, which will lead to less confusing
// diagnostics.
//
// We use the raw struct tail function here to get the first tail
// that is an alias, which is likely the cause of the normalization
// error.
match tcx.try_normalize_erasing_regions(
cx.typing_env,
tcx.struct_tail_raw(pointee, |ty| ty, || {}),
) {
Ok(_) => {}
Err(better_err) => {
err = better_err;
}
let metadata_ty = match tcx
.try_normalize_erasing_regions(cx.typing_env, pointee_metadata)
{
Ok(metadata_ty) => metadata_ty,
Err(mut err) => {
// Usually `<Ty as Pointee>::Metadata` can't be normalized because
// its struct tail cannot be normalized either, so try to get a
// more descriptive layout error here, which will lead to less confusing
// diagnostics.
//
// We use the raw struct tail function here to get the first tail
// that is an alias, which is likely the cause of the normalization
// error.
match tcx.try_normalize_erasing_regions(
cx.typing_env,
tcx.struct_tail_raw(pointee, &ObligationCause::dummy(), |ty| ty, || {}),
) {
Ok(_) => {}
Err(better_err) => {
err = better_err;
}
return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
}
};
return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
}
};

let metadata_layout = cx.layout_of(metadata_ty)?;
// If the metadata is a 1-zst, then the pointer is thin.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId)

let tail = tcx.struct_tail_raw(
tcx.type_of(impl_def_id).instantiate_identity(),
&cause,
|ty| {
ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| {
Ty::new_error_with_message(
Expand Down
Loading
Loading