Skip to content

Commit 36714a9

Browse files
committed
Auto merge of #158864 - JonathanBrouwer:rollup-re2xAGf, r=JonathanBrouwer
Rollup of 12 pull requests Successful merges: - #156976 (enable eager `param_env` norm in new solver) - #158537 (Add `std::io::cursor::WriteThroughCursor`) - #158540 (Move `std::io::Seek` to `core::io`) - #157820 (consider subtyping when checking if an infer var is sized) - #158505 (Update POSIX edition links) - #158853 (Fix typo for link on nto-qnx.md) - #157466 (Better error message when bare type in impl parameter list) - #157966 (Emit a suggestion to cast the never type into a concrete type when it fails to satisfy an `impl Trait` bound) - #158381 (Expose debug scope of statement and terminator in rustc_public) - #158405 (rustc_target: Add ARMv8-M related target features) - #158770 (Weaken guarantee for `From<legacy::RangeInclusive> for RangeInclusive`) - #158820 (Fix rustdoc ICE on deprecated note in inlined re-export chain)
2 parents 3c00c96 + 68dfc1d commit 36714a9

73 files changed

Lines changed: 1143 additions & 725 deletions

File tree

Some content is hidden

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

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -239,26 +239,21 @@ fn compare_method_predicate_entailment<'tcx>(
239239
let hybrid_preds = hybrid_preds.into_iter().map(Unnormalized::skip_norm_wip);
240240
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
241241
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
242-
// FIXME(-Zhigher-ranked-assumptions): The `hybrid_preds`
242+
// NOTE(-Zhigher-ranked-assumptions): The `hybrid_preds`
243243
// should be well-formed. However, using them may result in
244244
// region errors as we currently don't track placeholder
245245
// assumptions.
246246
//
247-
// To avoid being backwards incompatible with the old solver,
248-
// we also eagerly normalize the where-bounds in the new solver
249-
// here while ignoring region constraints. This means we can then
250-
// use where-bounds whose normalization results in placeholder
251-
// errors further down without getting any errors.
247+
// We eagerly normalize the where-clauses here while ignoring
248+
// region constraints. This means we can then use where-bounds
249+
// whose normalization results in placeholder errors further
250+
// down without getting any errors.
252251
//
253-
// It should be sound to do so as the only region errors here
252+
// This should be sound to do so as the only region errors here
254253
// should be due to missing implied bounds.
255254
//
256255
// cc trait-system-refactor-initiative/issues/166.
257-
let param_env = if tcx.next_trait_solver_globally() {
258-
traits::deeply_normalize_param_env_ignoring_regions(tcx, param_env, normalize_cause)
259-
} else {
260-
traits::normalize_param_env_or_error(tcx, param_env, normalize_cause)
261-
};
256+
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
262257
debug!(caller_bounds=?param_env.caller_bounds());
263258

264259
let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_trait_selection::traits;
2323
use tracing::{debug, instrument, trace};
2424

2525
use super::{CoroutineTypes, Expectation, FnCtxt, check_fn};
26+
use crate::fn_ctxt::UseSubtyping;
2627

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

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

988989
let output_ty = match *ret_ty.kind() {
989990
ty::Infer(ty::TyVar(ret_vid)) => {
990-
self.obligations_for_self_ty(ret_vid).into_iter().find_map(|obligation| {
991-
get_future_output(obligation.predicate, obligation.cause.span)
992-
})?
991+
self.obligations_for_self_ty(ret_vid, UseSubtyping::No).into_iter().find_map(
992+
|obligation| get_future_output(obligation.predicate, obligation.cause.span),
993+
)?
993994
}
994995
ty::Alias(_, ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
995996
return Some(Ty::new_error_with_message(

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,14 +755,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
755755

756756
pub(crate) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
757757
let sized_did = self.tcx.lang_items().sized_trait();
758-
self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| {
759-
match obligation.predicate.kind().skip_binder() {
758+
759+
// NB: `T: Sized` implies that all subtypes and all supertypes of `T` are also sized,
760+
// so it's valid to use subtyping here. (subtyping has to preserve layout and
761+
// `T <: U => &T <: &U`, so subtyping can't change sizedness)
762+
self.obligations_for_self_ty(self_ty, super::UseSubtyping::Yes).into_iter().any(
763+
|obligation| match obligation.predicate.kind().skip_binder() {
760764
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
761765
Some(data.def_id()) == sized_did
762766
}
763767
_ => false,
764-
}
765-
})
768+
},
769+
)
766770
}
767771

768772
pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec<Ty<'tcx>> {

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,38 @@ use tracing::{debug, instrument, trace};
1313

1414
use crate::FnCtxt;
1515

16+
/// Whatever to use subtyping or not when inspecting obligations
17+
#[derive(Debug, Copy, Clone)]
18+
pub(crate) enum UseSubtyping {
19+
/// Do **not** use subtyping. [`FnCtxt::obligations_for_self_ty`] will only return obligations
20+
/// where the self type is known to be equal to the provided vid.
21+
No,
22+
23+
/// Use subtyping. [`FnCtxt::obligations_for_self_ty`] will return obligations
24+
/// where the self type is related to the provided vid via subtyping.
25+
///
26+
/// Using this requires extra care, as traits holding for a subtype or a supertype, does not
27+
/// necessarily imply that they hold for the respective supertype or subtype.
28+
Yes,
29+
}
30+
1631
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1732
/// Returns a list of all obligations whose self type has been unified
1833
/// with the unconstrained type `self_ty`.
1934
#[instrument(skip(self), level = "debug")]
20-
pub(crate) fn obligations_for_self_ty(&self, self_ty: ty::TyVid) -> PredicateObligations<'tcx> {
35+
pub(crate) fn obligations_for_self_ty(
36+
&self,
37+
self_ty: ty::TyVid,
38+
subtyping: UseSubtyping,
39+
) -> PredicateObligations<'tcx> {
2140
if self.next_trait_solver() {
22-
self.obligations_for_self_ty_next(self_ty)
41+
self.obligations_for_self_ty_next(self_ty, subtyping)
2342
} else {
24-
let ty_var_root = self.root_var(self_ty);
2543
let mut obligations = self.fulfillment_cx.borrow().pending_obligations();
2644
trace!("pending_obligations = {:#?}", obligations);
27-
obligations
28-
.retain(|obligation| self.predicate_has_self_ty(obligation.predicate, ty_var_root));
45+
obligations.retain(|obligation| {
46+
self.predicate_has_self_ty(obligation.predicate, self_ty, subtyping)
47+
});
2948
obligations
3049
}
3150
}
@@ -35,14 +54,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3554
&self,
3655
predicate: ty::Predicate<'tcx>,
3756
expected_vid: ty::TyVid,
57+
subtyping: UseSubtyping,
3858
) -> bool {
3959
match predicate.kind().skip_binder() {
4060
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
41-
self.type_matches_expected_vid(data.self_ty(), expected_vid)
61+
self.type_matches_expected_vid(data.self_ty(), expected_vid, subtyping)
4262
}
4363
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
4464
if data.projection_term.kind.is_trait_projection() {
45-
self.type_matches_expected_vid(data.self_ty(), expected_vid)
65+
self.type_matches_expected_vid(data.self_ty(), expected_vid, subtyping)
4666
} else {
4767
false
4868
}
@@ -64,21 +84,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6484
}
6585

6686
#[instrument(level = "debug", skip(self), ret)]
67-
fn type_matches_expected_vid(&self, ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
87+
fn type_matches_expected_vid(
88+
&self,
89+
ty: Ty<'tcx>,
90+
expected_vid: ty::TyVid,
91+
subtyping: UseSubtyping,
92+
) -> bool {
6893
let ty = self.shallow_resolve(ty);
6994
debug!(?ty);
7095

7196
match *ty.kind() {
72-
ty::Infer(ty::TyVar(found_vid)) => {
73-
self.root_var(expected_vid) == self.root_var(found_vid)
74-
}
97+
ty::Infer(ty::TyVar(found_vid)) => match subtyping {
98+
UseSubtyping::No => self.root_var(expected_vid) == self.root_var(found_vid),
99+
UseSubtyping::Yes => {
100+
self.sub_unification_table_root_var(expected_vid)
101+
== self.sub_unification_table_root_var(found_vid)
102+
}
103+
},
75104
_ => false,
76105
}
77106
}
78107

79108
pub(crate) fn obligations_for_self_ty_next(
80109
&self,
81110
self_ty: ty::TyVid,
111+
subtyping: UseSubtyping,
82112
) -> PredicateObligations<'tcx> {
83113
// We only look at obligations which may reference the self type.
84114
// This lookup uses the `sub_root` instead of the inference variable
@@ -93,13 +123,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
93123
.borrow()
94124
.pending_obligations_potentially_referencing_sub_root(&self.infcx, sub_root_var);
95125
debug!(?obligations);
126+
96127
let mut obligations_for_self_ty = PredicateObligations::new();
97128
for obligation in obligations {
98129
let mut visitor = NestedObligationsForSelfTy {
99130
fcx: self,
100131
self_ty,
101132
obligations_for_self_ty: &mut obligations_for_self_ty,
102133
root_cause: &obligation.cause,
134+
subtyping,
103135
};
104136

105137
let goal = obligation.as_goal();
@@ -182,6 +214,7 @@ struct NestedObligationsForSelfTy<'a, 'tcx> {
182214
self_ty: ty::TyVid,
183215
root_cause: &'a ObligationCause<'tcx>,
184216
obligations_for_self_ty: &'a mut PredicateObligations<'tcx>,
217+
subtyping: UseSubtyping,
185218
}
186219

187220
impl<'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'_, 'tcx> {
@@ -209,15 +242,15 @@ impl<'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'_, 'tcx> {
209242
.orig_values()
210243
.iter()
211244
.filter_map(|arg| arg.as_type())
212-
.any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty))
245+
.any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty, self.subtyping))
213246
{
214247
debug!(goal = ?inspect_goal.goal(), "goal does not mention self type");
215248
return;
216249
}
217250

218251
let tcx = self.fcx.tcx;
219252
let goal = inspect_goal.goal();
220-
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
253+
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty, self.subtyping) {
221254
self.obligations_for_self_ty.push(traits::Obligation::new(
222255
tcx,
223256
self.root_cause.clone(),

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod suggestions;
88
use std::cell::{Cell, RefCell};
99
use std::ops::Deref;
1010

11+
pub(crate) use inspect_obligations::UseSubtyping;
1112
use rustc_errors::DiagCtxtHandle;
1213
use rustc_hir::attrs::{DivergingBlockBehavior, DivergingFallbackBehavior};
1314
use rustc_hir::def_id::{DefId, LocalDefId};

compiler/rustc_infer/src/infer/type_variable.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,11 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
246246
}
247247

248248
/// Returns the "root" variable of `vid` in the `sub_unification_table`
249-
/// equivalence table. All type variables that have been are related via
249+
/// equivalence table. All type variables that have been related via
250250
/// equality or subtyping will yield the same root variable (per the
251251
/// union-find algorithm), so `sub_unification_table_root_var(a)
252-
/// == sub_unification_table_root_var(b)` implies that:
253-
/// ```text
254-
/// exists X. (a <: X || X <: a) && (b <: X || X <: b)
255-
/// ```
252+
/// == sub_unification_table_root_var(b)` implies that `a` and `b` are
253+
/// transitively related via subtyping.
256254
pub(crate) fn sub_unification_table_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
257255
self.sub_unification_table().find(vid).vid
258256
}

compiler/rustc_parse/src/errors.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4660,3 +4660,33 @@ pub(crate) struct UseRegularStructSuggestion {
46604660
#[suggestion_part(code = "")]
46614661
pub semicolon: Option<Span>,
46624662
}
4663+
#[derive(Diagnostic)]
4664+
#[diag("expected type parameter, found path `{$path}`")]
4665+
pub(crate) struct FoundPathInGenerics {
4666+
#[primary_span]
4667+
pub span: Span,
4668+
pub path: String,
4669+
}
4670+
#[derive(Subdiagnostic)]
4671+
#[suggestion(
4672+
"you might have meant to bind a type parameter to a trait",
4673+
applicability = "maybe-incorrect",
4674+
code = "T: "
4675+
)]
4676+
4677+
pub(crate) struct SuggestBindTypeParameter {
4678+
#[primary_span]
4679+
pub span: Span,
4680+
}
4681+
4682+
#[derive(Subdiagnostic)]
4683+
#[suggestion(
4684+
"alternatively, you might have meant to introduce type parameter",
4685+
applicability = "maybe-incorrect",
4686+
code = "{parameters}"
4687+
)]
4688+
pub(crate) struct SuggestIntroduceTypeParameter {
4689+
#[primary_span]
4690+
pub span: Span,
4691+
pub parameters: String,
4692+
}

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind};
66
use rustc_ast::util::parser::AssocOp;
77
use rustc_ast::{
88
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode,
9-
Block, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind,
9+
Block, BlockCheckMode, Expr, ExprKind, GenericArg, GenericArgs, Generics, Item, ItemKind,
1010
MgcaDisambiguation, Param, Pat, PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind,
1111
};
1212
use rustc_ast_pretty::pprust;
@@ -31,14 +31,16 @@ use crate::errors::{
3131
AwaitSuggestion, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi,
3232
ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg,
3333
DocCommentDoesNotDocumentAnything, DocCommentOnParamType, DoubleColonInBound,
34-
ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, GenericParamsWithoutAngleBrackets,
35-
GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition,
36-
InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse,
37-
MisspelledKw, PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg,
38-
SelfParamNotFirst, StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg,
39-
SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator,
40-
TernaryOperatorSuggestion, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
41-
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
34+
ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, FoundPathInGenerics,
35+
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
36+
HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait,
37+
IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, MisspelledKw,
38+
PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
39+
StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt,
40+
SuggEscapeIdentifier, SuggRemoveComma, SuggestBindTypeParameter, SuggestIntroduceTypeParameter,
41+
TernaryOperator, TernaryOperatorSuggestion, UnexpectedConstInGenericParam,
42+
UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets,
43+
UseEqInstead, WrapType,
4244
};
4345
use crate::exp;
4446
use crate::parser::FnContext;
@@ -3164,4 +3166,48 @@ impl<'a> Parser<'a> {
31643166
}
31653167
Ok(())
31663168
}
3169+
pub(super) fn maybe_type_in_generic_parameter(&mut self, origin_error: Diag<'a>) -> Diag<'a> {
3170+
if !self.may_recover() {
3171+
return origin_error;
3172+
}
3173+
self.with_recovery(super::Recovery::Forbidden, |snapshot| {
3174+
snapshot.bump();
3175+
let lo = snapshot.token.span.shrink_to_lo();
3176+
3177+
let ty = match snapshot.parse_ty() {
3178+
Ok(t) => t,
3179+
Err(err) => {
3180+
err.cancel();
3181+
return origin_error;
3182+
}
3183+
};
3184+
let TyKind::Path(_, path) = ty.kind else {
3185+
return origin_error;
3186+
};
3187+
let Some(GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, ref args })) =
3188+
path.segments[0].args
3189+
else {
3190+
return origin_error;
3191+
};
3192+
3193+
let path_span = path.span;
3194+
let mut new_error = snapshot.dcx().create_err(FoundPathInGenerics {
3195+
span: path_span,
3196+
path: snapshot.span_to_snippet(path_span).unwrap(),
3197+
});
3198+
new_error.subdiagnostic(SuggestBindTypeParameter { span: lo });
3199+
origin_error.cancel();
3200+
3201+
let params = args
3202+
.iter()
3203+
.map(|arg| snapshot.span_to_snippet(arg.span()).unwrap())
3204+
.collect::<Vec<_>>()
3205+
.join(", ");
3206+
new_error.subdiagnostic(SuggestIntroduceTypeParameter {
3207+
span: path_span,
3208+
parameters: params,
3209+
});
3210+
new_error
3211+
})
3212+
}
31673213
}

0 commit comments

Comments
 (0)