Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
515395b
Expose debug scope of statement and terminator in rustc_public
hkalbasi Jun 24, 2026
e919f70
Bump POSIX spec links to the 2024 edition
schneems Jun 27, 2026
81a3c75
fix
bb1yd Jun 3, 2026
a813343
consider subtyping when checking if an infer var is sized
WaffleLapkin Jun 12, 2026
3bd15a6
fixup docs
WaffleLapkin Jun 17, 2026
6dc2620
rustc_target: Add ARMv8-M related target features
taiki-e Jul 4, 2026
b570ebd
Weaken guarantee for `From<legacy::RangeInclusive> for RangeInclusive`
theemathas Jul 4, 2026
c9ad0e5
Emit a suggestion to cast the never type into a concrete type when it…
Muhtasim-Rasheed Jul 5, 2026
1920371
Disable `RangeInclusive`'s `From` test when unwinding isn't available.
theemathas Jul 5, 2026
711ec67
enable eager param_env norm in new solver
lcnr May 26, 2026
4463c0f
remove unnecessary code
lcnr May 26, 2026
81ffc41
entirely ignore region errors in normalize_predicates
lcnr May 27, 2026
22d9d00
Move `std::io::SeekFrom` to `core::io`
bushrat011899 May 21, 2026
83de834
Move `std::io::Seek` to `core::io`
bushrat011899 May 21, 2026
a3f9abd
Fix documentation links to `Seek`
bushrat011899 May 22, 2026
6a69276
Add documentation to `stream_len_default`
bushrat011899 Jul 3, 2026
cae0245
Add `std::io::cursor::WriteThroughCursor`
bushrat011899 May 12, 2026
e7408fb
Fix rustdoc ICE on deprecated note in inlined re-export chain
TaKO8Ki Jul 6, 2026
9c85540
Fix typo for link on nto-qnx.md
jonathanpallant Jul 6, 2026
a7fac4d
Rollup merge of #156976 - lcnr:eagerly-normalize-env, r=jackh726
JonathanBrouwer Jul 6, 2026
dc5cd65
Rollup merge of #158537 - bushrat011899:std_io_write_through_cursor, …
JonathanBrouwer Jul 6, 2026
083f754
Rollup merge of #158540 - bushrat011899:core_io_seek, r=clarfonthey
JonathanBrouwer Jul 6, 2026
1d5fe4c
Rollup merge of #157820 - WaffleLapkin:sized-infer-sub, r=lcnr
JonathanBrouwer Jul 6, 2026
bd2ee38
Rollup merge of #158505 - schneems:schneems/bump-posix-edition, r=Dar…
JonathanBrouwer Jul 6, 2026
9f49140
Rollup merge of #158853 - ferrocene:fix-nto-qnx-typo, r=chenyukang
JonathanBrouwer Jul 6, 2026
baf02d2
Rollup merge of #157466 - bb1yd:issue-147889, r=davidtwco
JonathanBrouwer Jul 6, 2026
1c30ae0
Rollup merge of #157966 - Muhtasim-Rasheed:issue-157923-suggestion-ca…
JonathanBrouwer Jul 6, 2026
2ff23c3
Rollup merge of #158381 - hkalbasi:main, r=makai410
JonathanBrouwer Jul 6, 2026
a6356ed
Rollup merge of #158405 - taiki-e:armv8m-target-feature, r=davidtwco
JonathanBrouwer Jul 6, 2026
3ffc2ad
Rollup merge of #158770 - theemathas:range-inclusive-from, r=JohnTitor
JonathanBrouwer Jul 6, 2026
68dfc1d
Rollup merge of #158820 - TaKO8Ki:fix-deprecated-note-reexport-chain,…
JonathanBrouwer Jul 6, 2026
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
19 changes: 7 additions & 12 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,26 +239,21 @@ fn compare_method_predicate_entailment<'tcx>(
let hybrid_preds = hybrid_preds.into_iter().map(Unnormalized::skip_norm_wip);
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
// FIXME(-Zhigher-ranked-assumptions): The `hybrid_preds`
// NOTE(-Zhigher-ranked-assumptions): The `hybrid_preds`
// should be well-formed. However, using them may result in
// region errors as we currently don't track placeholder
// assumptions.
//
// To avoid being backwards incompatible with the old solver,
// we also eagerly normalize the where-bounds in the new solver
// here while ignoring region constraints. This means we can then
// use where-bounds whose normalization results in placeholder
// errors further down without getting any errors.
// We eagerly normalize the where-clauses here while ignoring
// region constraints. This means we can then use where-bounds
// whose normalization results in placeholder errors further
// down without getting any errors.
//
// It should be sound to do so as the only region errors here
// This should be sound to do so as the only region errors here
// should be due to missing implied bounds.
//
// cc trait-system-refactor-initiative/issues/166.
let param_env = if tcx.next_trait_solver_globally() {
traits::deeply_normalize_param_env_ignoring_regions(tcx, param_env, normalize_cause)
} else {
traits::normalize_param_env_or_error(tcx, param_env, normalize_cause)
};
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
debug!(caller_bounds=?param_env.caller_bounds());

let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use rustc_trait_selection::traits;
use tracing::{debug, instrument, trace};

use super::{CoroutineTypes, Expectation, FnCtxt, check_fn};
use crate::fn_ctxt::UseSubtyping;

/// What signature do we *expect* the closure to have from context?
#[derive(Debug, Clone, TypeFoldable, TypeVisitable)]
Expand Down Expand Up @@ -317,7 +318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates(
Ty::new_var(self.tcx, self.root_var(vid)),
closure_kind,
self.obligations_for_self_ty(vid)
self.obligations_for_self_ty(vid, UseSubtyping::No)
.into_iter()
.map(|obl| (obl.predicate, obl.cause.span)),
),
Expand Down Expand Up @@ -587,7 +588,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// FIXME: We may want to elaborate here, though I assume this will be exceedingly rare.
let mut return_ty = None;
for bound in self.obligations_for_self_ty(return_vid) {
for bound in self.obligations_for_self_ty(return_vid, UseSubtyping::No) {
if let Some(ret_projection) = bound.predicate.as_projection_clause()
&& let Some(ret_projection) = ret_projection.no_bound_vars()
&& self.tcx.is_lang_item(ret_projection.def_id(), LangItem::FutureOutput)
Expand Down Expand Up @@ -987,9 +988,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let output_ty = match *ret_ty.kind() {
ty::Infer(ty::TyVar(ret_vid)) => {
self.obligations_for_self_ty(ret_vid).into_iter().find_map(|obligation| {
get_future_output(obligation.predicate, obligation.cause.span)
})?
self.obligations_for_self_ty(ret_vid, UseSubtyping::No).into_iter().find_map(
|obligation| get_future_output(obligation.predicate, obligation.cause.span),
)?
}
ty::Alias(_, ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
return Some(Ty::new_error_with_message(
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,14 +755,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

pub(crate) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
let sized_did = self.tcx.lang_items().sized_trait();
self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| {
match obligation.predicate.kind().skip_binder() {

// NB: `T: Sized` implies that all subtypes and all supertypes of `T` are also sized,
// so it's valid to use subtyping here. (subtyping has to preserve layout and
// `T <: U => &T <: &U`, so subtyping can't change sizedness)
self.obligations_for_self_ty(self_ty, super::UseSubtyping::Yes).into_iter().any(
|obligation| match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
Some(data.def_id()) == sized_did
}
_ => false,
}
})
},
)
}

pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec<Ty<'tcx>> {
Expand Down
59 changes: 46 additions & 13 deletions compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,38 @@ use tracing::{debug, instrument, trace};

use crate::FnCtxt;

/// Whatever to use subtyping or not when inspecting obligations
#[derive(Debug, Copy, Clone)]
pub(crate) enum UseSubtyping {
/// Do **not** use subtyping. [`FnCtxt::obligations_for_self_ty`] will only return obligations
/// where the self type is known to be equal to the provided vid.
No,

/// Use subtyping. [`FnCtxt::obligations_for_self_ty`] will return obligations
/// where the self type is related to the provided vid via subtyping.
///
/// Using this requires extra care, as traits holding for a subtype or a supertype, does not
/// necessarily imply that they hold for the respective supertype or subtype.
Yes,
}

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Returns a list of all obligations whose self type has been unified
/// with the unconstrained type `self_ty`.
#[instrument(skip(self), level = "debug")]
pub(crate) fn obligations_for_self_ty(&self, self_ty: ty::TyVid) -> PredicateObligations<'tcx> {
pub(crate) fn obligations_for_self_ty(
&self,
self_ty: ty::TyVid,
subtyping: UseSubtyping,
) -> PredicateObligations<'tcx> {
if self.next_trait_solver() {
self.obligations_for_self_ty_next(self_ty)
self.obligations_for_self_ty_next(self_ty, subtyping)
} else {
let ty_var_root = self.root_var(self_ty);
let mut obligations = self.fulfillment_cx.borrow().pending_obligations();
trace!("pending_obligations = {:#?}", obligations);
obligations
.retain(|obligation| self.predicate_has_self_ty(obligation.predicate, ty_var_root));
obligations.retain(|obligation| {
self.predicate_has_self_ty(obligation.predicate, self_ty, subtyping)
});
obligations
}
}
Expand All @@ -35,14 +54,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
predicate: ty::Predicate<'tcx>,
expected_vid: ty::TyVid,
subtyping: UseSubtyping,
) -> bool {
match predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
self.type_matches_expected_vid(data.self_ty(), expected_vid)
self.type_matches_expected_vid(data.self_ty(), expected_vid, subtyping)
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
if data.projection_term.kind.is_trait_projection() {
self.type_matches_expected_vid(data.self_ty(), expected_vid)
self.type_matches_expected_vid(data.self_ty(), expected_vid, subtyping)
} else {
false
}
Expand All @@ -64,21 +84,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

#[instrument(level = "debug", skip(self), ret)]
fn type_matches_expected_vid(&self, ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
fn type_matches_expected_vid(
&self,
ty: Ty<'tcx>,
expected_vid: ty::TyVid,
subtyping: UseSubtyping,
) -> bool {
let ty = self.shallow_resolve(ty);
debug!(?ty);

match *ty.kind() {
ty::Infer(ty::TyVar(found_vid)) => {
self.root_var(expected_vid) == self.root_var(found_vid)
}
ty::Infer(ty::TyVar(found_vid)) => match subtyping {
UseSubtyping::No => self.root_var(expected_vid) == self.root_var(found_vid),
UseSubtyping::Yes => {
self.sub_unification_table_root_var(expected_vid)
== self.sub_unification_table_root_var(found_vid)
}
},
_ => false,
}
}

pub(crate) fn obligations_for_self_ty_next(
&self,
self_ty: ty::TyVid,
subtyping: UseSubtyping,
) -> PredicateObligations<'tcx> {
// We only look at obligations which may reference the self type.
// This lookup uses the `sub_root` instead of the inference variable
Expand All @@ -93,13 +123,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.borrow()
.pending_obligations_potentially_referencing_sub_root(&self.infcx, sub_root_var);
debug!(?obligations);

let mut obligations_for_self_ty = PredicateObligations::new();
for obligation in obligations {
let mut visitor = NestedObligationsForSelfTy {
fcx: self,
self_ty,
obligations_for_self_ty: &mut obligations_for_self_ty,
root_cause: &obligation.cause,
subtyping,
};

let goal = obligation.as_goal();
Expand Down Expand Up @@ -182,6 +214,7 @@ struct NestedObligationsForSelfTy<'a, 'tcx> {
self_ty: ty::TyVid,
root_cause: &'a ObligationCause<'tcx>,
obligations_for_self_ty: &'a mut PredicateObligations<'tcx>,
subtyping: UseSubtyping,
}

impl<'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'_, 'tcx> {
Expand Down Expand Up @@ -209,15 +242,15 @@ impl<'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'_, 'tcx> {
.orig_values()
.iter()
.filter_map(|arg| arg.as_type())
.any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty))
.any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty, self.subtyping))
{
debug!(goal = ?inspect_goal.goal(), "goal does not mention self type");
return;
}

let tcx = self.fcx.tcx;
let goal = inspect_goal.goal();
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty, self.subtyping) {
self.obligations_for_self_ty.push(traits::Obligation::new(
tcx,
self.root_cause.clone(),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod suggestions;
use std::cell::{Cell, RefCell};
use std::ops::Deref;

pub(crate) use inspect_obligations::UseSubtyping;
use rustc_errors::DiagCtxtHandle;
use rustc_hir::attrs::{DivergingBlockBehavior, DivergingFallbackBehavior};
use rustc_hir::def_id::{DefId, LocalDefId};
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_infer/src/infer/type_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,11 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
}

/// Returns the "root" variable of `vid` in the `sub_unification_table`
/// equivalence table. All type variables that have been are related via
/// equivalence table. All type variables that have been related via
/// equality or subtyping will yield the same root variable (per the
/// union-find algorithm), so `sub_unification_table_root_var(a)
/// == sub_unification_table_root_var(b)` implies that:
/// ```text
/// exists X. (a <: X || X <: a) && (b <: X || X <: b)
/// ```
/// == sub_unification_table_root_var(b)` implies that `a` and `b` are
/// transitively related via subtyping.
pub(crate) fn sub_unification_table_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
self.sub_unification_table().find(vid).vid
}
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4660,3 +4660,33 @@ pub(crate) struct UseRegularStructSuggestion {
#[suggestion_part(code = "")]
pub semicolon: Option<Span>,
}
#[derive(Diagnostic)]
#[diag("expected type parameter, found path `{$path}`")]
pub(crate) struct FoundPathInGenerics {
#[primary_span]
pub span: Span,
pub path: String,
}
#[derive(Subdiagnostic)]
#[suggestion(
"you might have meant to bind a type parameter to a trait",
applicability = "maybe-incorrect",
code = "T: "
)]

pub(crate) struct SuggestBindTypeParameter {
#[primary_span]
pub span: Span,
}

#[derive(Subdiagnostic)]
#[suggestion(
"alternatively, you might have meant to introduce type parameter",
applicability = "maybe-incorrect",
code = "{parameters}"
)]
pub(crate) struct SuggestIntroduceTypeParameter {
#[primary_span]
pub span: Span,
pub parameters: String,
}
64 changes: 55 additions & 9 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind};
use rustc_ast::util::parser::AssocOp;
use rustc_ast::{
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode,
Block, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind,
Block, BlockCheckMode, Expr, ExprKind, GenericArg, GenericArgs, Generics, Item, ItemKind,
MgcaDisambiguation, Param, Pat, PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind,
};
use rustc_ast_pretty::pprust;
Expand All @@ -31,14 +31,16 @@ use crate::errors::{
AwaitSuggestion, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi,
ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg,
DocCommentDoesNotDocumentAnything, DocCommentOnParamType, DoubleColonInBound,
ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, GenericParamsWithoutAngleBrackets,
GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition,
InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse,
MisspelledKw, PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg,
SelfParamNotFirst, StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg,
SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator,
TernaryOperatorSuggestion, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, FoundPathInGenerics,
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait,
IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, MisspelledKw,
PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt,
SuggEscapeIdentifier, SuggRemoveComma, SuggestBindTypeParameter, SuggestIntroduceTypeParameter,
TernaryOperator, TernaryOperatorSuggestion, UnexpectedConstInGenericParam,
UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets,
UseEqInstead, WrapType,
};
use crate::exp;
use crate::parser::FnContext;
Expand Down Expand Up @@ -3164,4 +3166,48 @@ impl<'a> Parser<'a> {
}
Ok(())
}
pub(super) fn maybe_type_in_generic_parameter(&mut self, origin_error: Diag<'a>) -> Diag<'a> {
if !self.may_recover() {
return origin_error;
}
self.with_recovery(super::Recovery::Forbidden, |snapshot| {
snapshot.bump();
let lo = snapshot.token.span.shrink_to_lo();

let ty = match snapshot.parse_ty() {
Ok(t) => t,
Err(err) => {
err.cancel();
return origin_error;
}
};
let TyKind::Path(_, path) = ty.kind else {
return origin_error;
};
let Some(GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, ref args })) =
path.segments[0].args
else {
return origin_error;
};

let path_span = path.span;
let mut new_error = snapshot.dcx().create_err(FoundPathInGenerics {
span: path_span,
path: snapshot.span_to_snippet(path_span).unwrap(),
});
new_error.subdiagnostic(SuggestBindTypeParameter { span: lo });
origin_error.cancel();

let params = args
.iter()
.map(|arg| snapshot.span_to_snippet(arg.span()).unwrap())
.collect::<Vec<_>>()
.join(", ");
new_error.subdiagnostic(SuggestIntroduceTypeParameter {
span: path_span,
parameters: params,
});
new_error
})
}
}
Loading
Loading