Rollup merge of #120270 - compiler-errors:randos, r=lcnr

A bunch of random modifications

r? oli-obk

Kitchen sink of changes that I didn't know where to put elsewhere. Documentation tweaks mostly, but also removing some unreachable code and simplifying the pretty printing for closures/coroutines.
This commit is contained in:
León Orell Valerian Liehr 2024-01-23 21:19:56 +01:00 committed by GitHub
commit 3b1c2eb44c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 59 additions and 93 deletions

View File

@ -12,7 +12,9 @@
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum AutoderefKind { pub enum AutoderefKind {
/// A true pointer type, such as `&T` and `*mut T`.
Builtin, Builtin,
/// A type which must dispatch to a `Deref` implementation.
Overloaded, Overloaded,
} }
@ -83,6 +85,7 @@ fn next(&mut self) -> Option<Self::Item> {
(AutoderefKind::Builtin, ty) (AutoderefKind::Builtin, ty)
} }
} else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) { } else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
// The overloaded deref check already normalizes the pointee type.
(AutoderefKind::Overloaded, ty) (AutoderefKind::Overloaded, ty)
} else { } else {
return None; return None;

View File

@ -254,7 +254,7 @@ fn compare_method_predicate_entailment<'tcx>(
// checks. For the comparison to be valid, we need to // checks. For the comparison to be valid, we need to
// normalize the associated types in the impl/trait methods // normalize the associated types in the impl/trait methods
// first. However, because function types bind regions, just // first. However, because function types bind regions, just
// calling `normalize_associated_types_in` would have no effect on // calling `FnCtxt::normalize` would have no effect on
// any associated types appearing in the fn arguments or return // any associated types appearing in the fn arguments or return
// type. // type.

View File

@ -746,11 +746,13 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_args); let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_args);
debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty); debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
// We can't use normalize_associated_types_in as it will pollute the // We can't use `FnCtxt::normalize` as it will pollute the
// fcx's fulfillment context after this probe is over. // fcx's fulfillment context after this probe is over.
//
// Note: we only normalize `xform_self_ty` here since the normalization // Note: we only normalize `xform_self_ty` here since the normalization
// of the return type can lead to inference results that prohibit // of the return type can lead to inference results that prohibit
// valid candidates from being found, see issue #85671 // valid candidates from being found, see issue #85671
//
// FIXME Postponing the normalization of the return type likely only hides a deeper bug, // FIXME Postponing the normalization of the return type likely only hides a deeper bug,
// which might be caused by the `param_env` itself. The clauses of the `param_env` // which might be caused by the `param_env` itself. The clauses of the `param_env`
// maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized, // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,

View File

@ -804,17 +804,12 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
} }
} else { } else {
p!(print_def_path(did, args)); p!(print_def_path(did, args));
p!(" upvar_tys=("); p!(
if !args.as_coroutine().is_valid() { " upvar_tys=",
p!("unavailable"); print(args.as_coroutine().tupled_upvars_ty()),
} else { " witness=",
self.comma_sep(args.as_coroutine().upvar_tys().iter())?; print(args.as_coroutine().witness())
} );
p!(")");
if args.as_coroutine().is_valid() {
p!(" ", print(args.as_coroutine().witness()));
}
} }
p!("}}") p!("}}")
@ -868,19 +863,14 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
} }
} else { } else {
p!(print_def_path(did, args)); p!(print_def_path(did, args));
if !args.as_closure().is_valid() { p!(
p!(" closure_args=(unavailable)"); " closure_kind_ty=",
p!(write(" args={}", args.print_as_list())); print(args.as_closure().kind_ty()),
} else { " closure_sig_as_fn_ptr_ty=",
p!(" closure_kind_ty=", print(args.as_closure().kind_ty())); print(args.as_closure().sig_as_fn_ptr_ty()),
p!( " upvar_tys=",
" closure_sig_as_fn_ptr_ty=", print(args.as_closure().tupled_upvars_ty())
print(args.as_closure().sig_as_fn_ptr_ty()) );
);
p!(" upvar_tys=(");
self.comma_sep(args.as_closure().upvar_tys().iter())?;
p!(")");
}
} }
p!("}}"); p!("}}");
} }

View File

@ -242,9 +242,15 @@ pub struct ClosureArgs<'tcx> {
/// Struct returned by `split()`. /// Struct returned by `split()`.
pub struct ClosureArgsParts<'tcx> { pub struct ClosureArgsParts<'tcx> {
/// This is the args of the typeck root.
pub parent_args: &'tcx [GenericArg<'tcx>], pub parent_args: &'tcx [GenericArg<'tcx>],
/// Represents the maximum calling capability of the closure.
pub closure_kind_ty: Ty<'tcx>, pub closure_kind_ty: Ty<'tcx>,
/// Captures the closure's signature. This closure signature is "tupled", and
/// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`.
pub closure_sig_as_fn_ptr_ty: Ty<'tcx>, pub closure_sig_as_fn_ptr_ty: Ty<'tcx>,
/// The upvars captured by the closure. Remains an inference variable
/// until the upvar analysis, which happens late in HIR typeck.
pub tupled_upvars_ty: Ty<'tcx>, pub tupled_upvars_ty: Ty<'tcx>,
} }
@ -277,15 +283,6 @@ fn split(self) -> ClosureArgsParts<'tcx> {
} }
} }
/// Returns `true` only if enough of the synthetic types are known to
/// allow using all of the methods on `ClosureArgs` without panicking.
///
/// Used primarily by `ty::print::pretty` to be able to handle closure
/// types that haven't had their synthetic types substituted in.
pub fn is_valid(self) -> bool {
self.args.len() >= 3 && matches!(self.split().tupled_upvars_ty.kind(), Tuple(_))
}
/// Returns the substitutions of the closure's parent. /// Returns the substitutions of the closure's parent.
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
self.split().parent_args self.split().parent_args
@ -296,9 +293,9 @@ pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
/// empty iterator is returned. /// empty iterator is returned.
#[inline] #[inline]
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> { pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
match self.tupled_upvars_ty().kind() { match *self.tupled_upvars_ty().kind() {
TyKind::Error(_) => ty::List::empty(), TyKind::Error(_) => ty::List::empty(),
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(), TyKind::Tuple(tys) => tys,
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
} }
@ -337,10 +334,9 @@ pub fn kind(self) -> ty::ClosureKind {
/// Extracts the signature from the closure. /// Extracts the signature from the closure.
pub fn sig(self) -> ty::PolyFnSig<'tcx> { pub fn sig(self) -> ty::PolyFnSig<'tcx> {
let ty = self.sig_as_fn_ptr_ty(); match *self.sig_as_fn_ptr_ty().kind() {
match ty.kind() { ty::FnPtr(sig) => sig,
ty::FnPtr(sig) => *sig, ty => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"),
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
} }
} }
@ -356,11 +352,17 @@ pub struct CoroutineArgs<'tcx> {
} }
pub struct CoroutineArgsParts<'tcx> { pub struct CoroutineArgsParts<'tcx> {
/// This is the args of the typeck root.
pub parent_args: &'tcx [GenericArg<'tcx>], pub parent_args: &'tcx [GenericArg<'tcx>],
pub resume_ty: Ty<'tcx>, pub resume_ty: Ty<'tcx>,
pub yield_ty: Ty<'tcx>, pub yield_ty: Ty<'tcx>,
pub return_ty: Ty<'tcx>, pub return_ty: Ty<'tcx>,
/// The interior type of the coroutine.
/// Represents all types that are stored in locals
/// in the coroutine's body.
pub witness: Ty<'tcx>, pub witness: Ty<'tcx>,
/// The upvars captured by the closure. Remains an inference variable
/// until the upvar analysis, which happens late in HIR typeck.
pub tupled_upvars_ty: Ty<'tcx>, pub tupled_upvars_ty: Ty<'tcx>,
} }
@ -397,15 +399,6 @@ fn split(self) -> CoroutineArgsParts<'tcx> {
} }
} }
/// Returns `true` only if enough of the synthetic types are known to
/// allow using all of the methods on `CoroutineArgs` without panicking.
///
/// Used primarily by `ty::print::pretty` to be able to handle coroutine
/// types that haven't had their synthetic types substituted in.
pub fn is_valid(self) -> bool {
self.args.len() >= 5 && matches!(self.split().tupled_upvars_ty.kind(), Tuple(_))
}
/// Returns the substitutions of the coroutine's parent. /// Returns the substitutions of the coroutine's parent.
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
self.split().parent_args self.split().parent_args
@ -425,9 +418,9 @@ pub fn witness(self) -> Ty<'tcx> {
/// empty iterator is returned. /// empty iterator is returned.
#[inline] #[inline]
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> { pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
match self.tupled_upvars_ty().kind() { match *self.tupled_upvars_ty().kind() {
TyKind::Error(_) => ty::List::empty(), TyKind::Error(_) => ty::List::empty(),
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(), TyKind::Tuple(tys) => tys,
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
} }

View File

@ -1,7 +1,7 @@
//! Computes a normalizes-to (projection) goal for inherent associated types, //! Computes a normalizes-to (projection) goal for inherent associated types,
//! `#![feature(lazy_type_alias)]` and `#![feature(type_alias_impl_trait)]`. //! `#![feature(lazy_type_alias)]` and `#![feature(type_alias_impl_trait)]`.
//! //!
//! Since a weak alias is not ambiguous, this just computes the `type_of` of //! Since a weak alias is never ambiguous, this just computes the `type_of` of
//! the alias and registers the where-clauses of the type alias. //! the alias and registers the where-clauses of the type alias.
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult}; use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult};
use rustc_middle::ty; use rustc_middle::ty;

View File

@ -232,32 +232,12 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
Ok::<_, NoSolution>(()) Ok::<_, NoSolution>(())
})?, })?,
ty::Closure(_, args) => { ty::Closure(_, args) => rustc_data_structures::stack::ensure_sufficient_stack(|| {
if !args.as_closure().is_valid() { for ty in args.as_closure().upvar_tys() {
// By the time this code runs, all type variables ought to dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, ty, constraints)?;
// be fully resolved.
tcx.dcx().span_delayed_bug(
span,
format!("upvar_tys for closure not found. Expected capture information for closure {ty}",),
);
return Err(NoSolution);
} }
Ok::<_, NoSolution>(())
rustc_data_structures::stack::ensure_sufficient_stack(|| { })?,
for ty in args.as_closure().upvar_tys() {
dtorck_constraint_for_ty_inner(
tcx,
param_env,
span,
depth + 1,
ty,
constraints,
)?;
}
Ok::<_, NoSolution>(())
})?
}
ty::Coroutine(_, args) => { ty::Coroutine(_, args) => {
// rust-lang/rust#49918: types can be constructed, stored // rust-lang/rust#49918: types can be constructed, stored
@ -283,15 +263,6 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
// derived from lifetimes attached to the upvars and resume // derived from lifetimes attached to the upvars and resume
// argument, and we *do* incorporate those here. // argument, and we *do* incorporate those here.
let args = args.as_coroutine(); let args = args.as_coroutine();
if !args.is_valid() {
// By the time this code runs, all type variables ought to
// be fully resolved.
tcx.dcx().span_delayed_bug(
span,
format!("upvar_tys for coroutine not found. Expected capture information for coroutine {ty}",),
);
return Err(NoSolution);
}
// While we conservatively assume that all coroutines require drop // While we conservatively assume that all coroutines require drop
// to avoid query cycles during MIR building, we can check the actual // to avoid query cycles during MIR building, we can check the actual

View File

@ -141,6 +141,13 @@ fn fully_perform(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
span: Span, span: Span,
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> { ) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
// In the new trait solver, query type ops are performed locally. This
// is because query type ops currently use the old canonicalizer, and
// that doesn't preserve things like opaques which have been registered
// during MIR typeck. Even after the old canonicalizer is gone, it's
// probably worthwhile just keeping this run-locally logic, since we
// probably don't gain much from caching here given the new solver does
// caching internally.
if infcx.next_trait_solver() { if infcx.next_trait_solver() {
return Ok(scrape_region_constraints( return Ok(scrape_region_constraints(
infcx, infcx,

View File

@ -9,7 +9,7 @@ LL | let c1 : () = c;
| expected due to this | expected due to this
| |
= note: expected unit type `()` = note: expected unit type `()`
found closure `{mod1::f<T>::{closure#0} closure_args=(unavailable) args=[T, ?8t, extern "rust-call" fn(()), ?7t]}` found closure `{mod1::f<T>::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}`
help: use parentheses to call this closure help: use parentheses to call this closure
| |
LL | let c1 : () = c(); LL | let c1 : () = c();

View File

@ -9,7 +9,7 @@ LL | let c1 : () = c;
| expected due to this | expected due to this
| |
= note: expected unit type `()` = note: expected unit type `()`
found closure `{f<T>::{closure#0} closure_args=(unavailable) args=[T, ?8t, extern "rust-call" fn(()), ?7t]}` found closure `{f<T>::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}`
help: use parentheses to call this closure help: use parentheses to call this closure
| |
LL | let c1 : () = c(); LL | let c1 : () = c();

View File

@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
| expected due to this | expected due to this
| |
= note: expected fn pointer `fn(u8) -> u8` = note: expected fn pointer `fn(u8) -> u8`
found closure `{main::{closure#0} closure_args=(unavailable) args=[i8, extern "rust-call" fn((u8,)) -> u8, ?4t]}` found closure `{main::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn((u8,)) -> u8 upvar_tys=?4t}`
note: closures can only be coerced to `fn` types if they do not capture any variables note: closures can only be coerced to `fn` types if they do not capture any variables
--> $DIR/closure-print-verbose.rs:10:39 --> $DIR/closure-print-verbose.rs:10:39
| |

View File

@ -4,7 +4,7 @@ error: coroutine cannot be shared between threads safely
LL | assert_sync(|| { LL | assert_sync(|| {
| ^^^^^^^^^^^ coroutine is not `Sync` | ^^^^^^^^^^^ coroutine is not `Sync`
| |
= help: within `{main::{closure#0} upvar_tys=() {main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync` = help: within `{main::{closure#0} upvar_tys=() witness={main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
note: coroutine is not `Sync` as this value is used across a yield note: coroutine is not `Sync` as this value is used across a yield
--> $DIR/coroutine-print-verbose-2.rs:20:9 --> $DIR/coroutine-print-verbose-2.rs:20:9
| |
@ -24,7 +24,7 @@ error: coroutine cannot be sent between threads safely
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ coroutine is not `Send` | ^^^^^^^^^^^ coroutine is not `Send`
| |
= help: within `{main::{closure#1} upvar_tys=() {main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend` = help: within `{main::{closure#1} upvar_tys=() witness={main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
note: coroutine is not `Send` as this value is used across a yield note: coroutine is not `Send` as this value is used across a yield
--> $DIR/coroutine-print-verbose-2.rs:27:9 --> $DIR/coroutine-print-verbose-2.rs:27:9
| |

View File

@ -12,7 +12,7 @@ LL | | };
| |_____^ expected `()`, found coroutine | |_____^ expected `()`, found coroutine
| |
= note: expected unit type `()` = note: expected unit type `()`
found coroutine `{main::{closure#0} upvar_tys=(unavailable)}` found coroutine `{main::{closure#0} upvar_tys=?4t witness=?6t}`
error: aborting due to 1 previous error error: aborting due to 1 previous error