mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Random type checker changes
This commit is contained in:
parent
021861aea8
commit
5fc39e0796
@ -12,7 +12,9 @@ use rustc_trait_selection::traits::StructurallyNormalizeExt;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum AutoderefKind {
|
||||
/// A true pointer type, such as `&T` and `*mut T`.
|
||||
Builtin,
|
||||
/// A type which must dispatch to a `Deref` implementation.
|
||||
Overloaded,
|
||||
}
|
||||
|
||||
@ -83,6 +85,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
|
||||
(AutoderefKind::Builtin, 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)
|
||||
} else {
|
||||
return None;
|
||||
|
@ -254,7 +254,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
// checks. For the comparison to be valid, we need to
|
||||
// normalize the associated types in the impl/trait methods
|
||||
// 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
|
||||
// type.
|
||||
|
||||
|
@ -746,11 +746,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
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);
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Note: we only normalize `xform_self_ty` here since the normalization
|
||||
// of the return type can lead to inference results that prohibit
|
||||
// valid candidates from being found, see issue #85671
|
||||
//
|
||||
// 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`
|
||||
// maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
|
||||
|
@ -804,17 +804,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, args));
|
||||
p!(" upvar_tys=(");
|
||||
if !args.as_coroutine().is_valid() {
|
||||
p!("unavailable");
|
||||
} else {
|
||||
self.comma_sep(args.as_coroutine().upvar_tys().iter())?;
|
||||
}
|
||||
p!(")");
|
||||
|
||||
if args.as_coroutine().is_valid() {
|
||||
p!(" ", print(args.as_coroutine().witness()));
|
||||
}
|
||||
p!(
|
||||
" upvar_tys=",
|
||||
print(args.as_coroutine().tupled_upvars_ty()),
|
||||
" witness=",
|
||||
print(args.as_coroutine().witness())
|
||||
);
|
||||
}
|
||||
|
||||
p!("}}")
|
||||
@ -868,19 +863,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, args));
|
||||
if !args.as_closure().is_valid() {
|
||||
p!(" closure_args=(unavailable)");
|
||||
p!(write(" args={}", args.print_as_list()));
|
||||
} else {
|
||||
p!(" closure_kind_ty=", print(args.as_closure().kind_ty()));
|
||||
p!(
|
||||
" closure_sig_as_fn_ptr_ty=",
|
||||
print(args.as_closure().sig_as_fn_ptr_ty())
|
||||
);
|
||||
p!(" upvar_tys=(");
|
||||
self.comma_sep(args.as_closure().upvar_tys().iter())?;
|
||||
p!(")");
|
||||
}
|
||||
p!(
|
||||
" closure_kind_ty=",
|
||||
print(args.as_closure().kind_ty()),
|
||||
" closure_sig_as_fn_ptr_ty=",
|
||||
print(args.as_closure().sig_as_fn_ptr_ty()),
|
||||
" upvar_tys=",
|
||||
print(args.as_closure().tupled_upvars_ty())
|
||||
);
|
||||
}
|
||||
p!("}}");
|
||||
}
|
||||
|
@ -242,9 +242,15 @@ pub struct ClosureArgs<'tcx> {
|
||||
|
||||
/// Struct returned by `split()`.
|
||||
pub struct ClosureArgsParts<'tcx> {
|
||||
/// This is the args of the typeck root.
|
||||
pub parent_args: &'tcx [GenericArg<'tcx>],
|
||||
/// Represents the maximum calling capability of the closure.
|
||||
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>,
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
@ -277,15 +283,6 @@ impl<'tcx> ClosureArgs<'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.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
@ -296,9 +293,9 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
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::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Tuple(tys) => tys,
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
@ -337,10 +334,9 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
|
||||
/// Extracts the signature from the closure.
|
||||
pub fn sig(self) -> ty::PolyFnSig<'tcx> {
|
||||
let ty = self.sig_as_fn_ptr_ty();
|
||||
match ty.kind() {
|
||||
ty::FnPtr(sig) => *sig,
|
||||
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
|
||||
match *self.sig_as_fn_ptr_ty().kind() {
|
||||
ty::FnPtr(sig) => sig,
|
||||
ty => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,11 +352,17 @@ pub struct CoroutineArgs<'tcx> {
|
||||
}
|
||||
|
||||
pub struct CoroutineArgsParts<'tcx> {
|
||||
/// This is the args of the typeck root.
|
||||
pub parent_args: &'tcx [GenericArg<'tcx>],
|
||||
pub resume_ty: Ty<'tcx>,
|
||||
pub yield_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>,
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
@ -397,15 +399,6 @@ impl<'tcx> CoroutineArgs<'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.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
@ -425,9 +418,9 @@ impl<'tcx> CoroutineArgs<'tcx> {
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
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::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Tuple(tys) => tys,
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Computes a normalizes-to (projection) goal for inherent associated types,
|
||||
//! `#![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.
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult};
|
||||
use rustc_middle::ty;
|
||||
|
@ -232,32 +232,12 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::Closure(_, args) => {
|
||||
if !args.as_closure().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 closure not found. Expected capture information for closure {ty}",),
|
||||
);
|
||||
return Err(NoSolution);
|
||||
ty::Closure(_, args) => 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)?;
|
||||
}
|
||||
|
||||
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>(())
|
||||
})?
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
// 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
|
||||
// argument, and we *do* incorporate those here.
|
||||
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
|
||||
// to avoid query cycles during MIR building, we can check the actual
|
||||
|
@ -141,6 +141,13 @@ where
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
span: Span,
|
||||
) -> 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() {
|
||||
return Ok(scrape_region_constraints(
|
||||
infcx,
|
||||
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
||||
| expected due to this
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | let c1 : () = c();
|
||||
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
||||
| expected due to this
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | let c1 : () = c();
|
||||
|
@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
|
||||
| expected due to this
|
||||
|
|
||||
= 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
|
||||
--> $DIR/closure-print-verbose.rs:10:39
|
||||
|
|
||||
|
@ -4,7 +4,7 @@ error: coroutine cannot be shared between threads safely
|
||||
LL | assert_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
|
||||
--> $DIR/coroutine-print-verbose-2.rs:20:9
|
||||
|
|
||||
@ -24,7 +24,7 @@ error: coroutine cannot be sent between threads safely
|
||||
LL | assert_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
|
||||
--> $DIR/coroutine-print-verbose-2.rs:27:9
|
||||
|
|
||||
|
@ -12,7 +12,7 @@ LL | | };
|
||||
| |_____^ expected `()`, found coroutine
|
||||
|
|
||||
= 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user