Auto merge of #136905 - matthiaskrgr:rollup-8zwcgta, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #135549 (Document some safety constraints and use more safe wrappers) - #135965 (In "specify type" suggestion, skip type params that are already known) - #136193 (Implement pattern type ffi checks) - #136646 (Add a TyPat in the AST to reuse the generic arg lowering logic) - #136874 (Change the issue number for `likely_unlikely` and `cold_path`) - #136884 (Lower fn items as ZST valtrees and delay a bug) - #136885 (i686-linux-android: increase CPU baseline to Pentium 4 (without an actual change) - #136891 (Check sig for errors before checking for unconstrained anonymous lifetime) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
33d92df3e6
57 changed files with 739 additions and 557 deletions
|
@ -18,6 +18,8 @@ use rustc_middle::ty::{
|
|||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
|
||||
};
|
||||
use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym};
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
use tracing::{debug, instrument, warn};
|
||||
|
||||
use super::nice_region_error::placeholder_error::Highlighted;
|
||||
|
@ -155,27 +157,92 @@ impl UnderspecifiedArgKind {
|
|||
}
|
||||
}
|
||||
|
||||
struct ClosureEraser<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
struct ClosureEraser<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
|
||||
impl<'a, 'tcx> ClosureEraser<'a, 'tcx> {
|
||||
fn new_infer(&mut self) -> Ty<'tcx> {
|
||||
self.infcx.next_ty_var(DUMMY_SP)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'a, 'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.kind() {
|
||||
ty::Closure(_, args) => {
|
||||
// For a closure type, we turn it into a function pointer so that it gets rendered
|
||||
// as `fn(args) -> Ret`.
|
||||
let closure_sig = args.as_closure().sig();
|
||||
Ty::new_fn_ptr(
|
||||
self.tcx,
|
||||
self.tcx.signature_unclosure(closure_sig, hir::Safety::Safe),
|
||||
self.cx(),
|
||||
self.cx().signature_unclosure(closure_sig, hir::Safety::Safe),
|
||||
)
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
ty::Adt(_, args) if !args.iter().any(|a| a.has_infer()) => {
|
||||
// We have a type that doesn't have any inference variables, so we replace
|
||||
// the whole thing with `_`. The type system already knows about this type in
|
||||
// its entirety and it is redundant to specify it for the user. The user only
|
||||
// needs to specify the type parameters that we *couldn't* figure out.
|
||||
self.new_infer()
|
||||
}
|
||||
ty::Adt(def, args) => {
|
||||
let generics = self.cx().generics_of(def.did());
|
||||
let generics: Vec<bool> = generics
|
||||
.own_params
|
||||
.iter()
|
||||
.map(|param| param.default_value(self.cx()).is_some())
|
||||
.collect();
|
||||
let ty = Ty::new_adt(
|
||||
self.cx(),
|
||||
*def,
|
||||
self.cx().mk_args_from_iter(generics.into_iter().zip(args.iter()).map(
|
||||
|(has_default, arg)| {
|
||||
if arg.has_infer() {
|
||||
// This param has an unsubstituted type variable, meaning that this
|
||||
// type has a (potentially deeply nested) type parameter from the
|
||||
// corresponding type's definition. We have explicitly asked this
|
||||
// type to not be hidden. In either case, we keep the type and don't
|
||||
// substitute with `_` just yet.
|
||||
arg.fold_with(self)
|
||||
} else if has_default {
|
||||
// We have a type param that has a default type, like the allocator
|
||||
// in Vec. We decided to show `Vec` itself, because it hasn't yet
|
||||
// been replaced by an `_` `Infer`, but we want to ensure that the
|
||||
// type parameter with default types does *not* get replaced with
|
||||
// `_` because then we'd end up with `Vec<_, _>`, instead of
|
||||
// `Vec<_>`.
|
||||
arg
|
||||
} else if let GenericArgKind::Type(_) = arg.kind() {
|
||||
// We don't replace lifetime or const params, only type params.
|
||||
self.new_infer().into()
|
||||
} else {
|
||||
arg.fold_with(self)
|
||||
}
|
||||
},
|
||||
)),
|
||||
);
|
||||
ty
|
||||
}
|
||||
_ if ty.has_infer() => {
|
||||
// This type has a (potentially nested) type parameter that we couldn't figure out.
|
||||
// We will print this depth of type, so at least the type name and at least one of
|
||||
// its type parameters.
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
// We don't have an unknown type parameter anywhere, replace with `_`.
|
||||
_ => self.new_infer(),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
// Avoid accidentally erasing the type of the const.
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
|
||||
|
@ -219,9 +286,9 @@ fn ty_to_string<'tcx>(
|
|||
) -> String {
|
||||
let mut printer = fmt_printer(infcx, Namespace::TypeNS);
|
||||
let ty = infcx.resolve_vars_if_possible(ty);
|
||||
// We use `fn` ptr syntax for closures, but this only works when the closure
|
||||
// does not capture anything.
|
||||
let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx });
|
||||
// We use `fn` ptr syntax for closures, but this only works when the closure does not capture
|
||||
// anything. We also remove all type parameters that are fully known to the type system.
|
||||
let ty = ty.fold_with(&mut ClosureEraser { infcx });
|
||||
|
||||
match (ty.kind(), called_method_def_id) {
|
||||
// We don't want the regular output for `fn`s because it includes its path in
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue