Auto merge of #94692 - matthiaskrgr:rollup-64p7ya7, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #94636 (Check extra function arg exprs even if the fn is not C-variadic) - #94676 (Remove unnecessary `..` patterns) - #94681 (CTFE engine: expose misc_cast to Miri) - #94684 (Fix rustdoc for GATs with with anonymous bound regions) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
297273c45b
@ -2064,17 +2064,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
)),
|
||||
_ => None,
|
||||
});
|
||||
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
|
||||
itctx
|
||||
{
|
||||
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes } = itctx {
|
||||
capturable_lifetimes.extend(lt_def_names.clone());
|
||||
}
|
||||
|
||||
let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow());
|
||||
|
||||
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
|
||||
itctx
|
||||
{
|
||||
if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes } = itctx {
|
||||
for param in lt_def_names {
|
||||
capturable_lifetimes.remove(¶m);
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn misc_cast(
|
||||
pub fn misc_cast(
|
||||
&self,
|
||||
src: &ImmTy<'tcx, M::PointerTag>,
|
||||
cast_ty: Ty<'tcx>,
|
||||
@ -139,7 +139,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
|
||||
assert!(src.layout.is_zst());
|
||||
let discr_layout = self.layout_of(discr.ty)?;
|
||||
return Ok(self.cast_from_scalar(discr.val, discr_layout, cast_ty).into());
|
||||
return Ok(self.cast_from_int_like(discr.val, discr_layout, cast_ty).into());
|
||||
}
|
||||
}
|
||||
Variants::Multiple { .. } => {}
|
||||
@ -169,17 +169,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
// # The remaining source values are scalar.
|
||||
// # The remaining source values are scalar and "int-like".
|
||||
|
||||
// For all remaining casts, we either
|
||||
// (a) cast a raw ptr to usize, or
|
||||
// (b) cast from an integer-like (including bool, char, enums).
|
||||
// In both cases we want the bits.
|
||||
let bits = src.to_scalar()?.to_bits(src.layout.size)?;
|
||||
Ok(self.cast_from_scalar(bits, src.layout, cast_ty).into())
|
||||
Ok(self.cast_from_int_like(bits, src.layout, cast_ty).into())
|
||||
}
|
||||
|
||||
pub(super) fn cast_from_scalar(
|
||||
fn cast_from_int_like(
|
||||
&self,
|
||||
v: u128, // raw bits (there is no ScalarTy so we separate data+layout)
|
||||
src_layout: TyAndLayout<'tcx>,
|
||||
|
@ -681,18 +681,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let tag_val = self.read_immediate(&self.operand_field(op, tag_field)?)?;
|
||||
assert_eq!(tag_layout.size, tag_val.layout.size);
|
||||
assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed());
|
||||
let tag_val = tag_val.to_scalar()?;
|
||||
trace!("tag value: {:?}", tag_val);
|
||||
trace!("tag value: {}", tag_val);
|
||||
|
||||
// Figure out which discriminant and variant this corresponds to.
|
||||
Ok(match *tag_encoding {
|
||||
TagEncoding::Direct => {
|
||||
// Generate a specific error if `tag_val` is not an integer.
|
||||
// (`tag_bits` itself is only used for error messages below.)
|
||||
let tag_bits = tag_val
|
||||
.to_scalar()?
|
||||
.try_to_int()
|
||||
.map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))?
|
||||
.assert_bits(tag_layout.size);
|
||||
// Cast bits from tag layout to discriminant layout.
|
||||
let discr_val = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty);
|
||||
// After the checks we did above, this cannot fail.
|
||||
let discr_val =
|
||||
self.misc_cast(&tag_val, discr_layout.ty).unwrap().to_scalar().unwrap();
|
||||
let discr_bits = discr_val.assert_bits(discr_layout.size);
|
||||
// Convert discriminant to variant index, and catch invalid discriminants.
|
||||
let index = match *op.layout.ty.kind() {
|
||||
@ -712,6 +716,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
(discr_val, index.0)
|
||||
}
|
||||
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
|
||||
let tag_val = tag_val.to_scalar()?;
|
||||
// Compute the variant this niche value/"tag" corresponds to. With niche layout,
|
||||
// discriminant (encoded in niche/tag) and variant index are the same.
|
||||
let variants_start = niche_variants.start().as_u32();
|
||||
|
@ -660,7 +660,7 @@ pub fn write_allocations<'tcx>(
|
||||
}
|
||||
fn alloc_ids_from_const(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
|
||||
match val {
|
||||
ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _size)) => {
|
||||
ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _)) => {
|
||||
Either::Left(Either::Left(std::iter::once(ptr.provenance)))
|
||||
}
|
||||
ConstValue::Scalar(interpret::Scalar::Int { .. }) => {
|
||||
|
@ -852,7 +852,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> {
|
||||
self.visit(self.ev.tcx.type_of(param.def_id));
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Const { has_default, .. } => {
|
||||
GenericParamDefKind::Const { has_default } => {
|
||||
self.visit(self.ev.tcx.type_of(param.def_id));
|
||||
if has_default {
|
||||
self.visit(self.ev.tcx.const_param_default(param.def_id));
|
||||
|
@ -405,7 +405,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
hir::Node::Item(hir::Item {
|
||||
kind:
|
||||
hir::ItemKind::Trait(_, _, generics, _, _)
|
||||
hir::ItemKind::Trait(_, _, generics, ..)
|
||||
| hir::ItemKind::Impl(hir::Impl { generics, .. }),
|
||||
..
|
||||
}) if projection.is_some() => {
|
||||
|
@ -1403,7 +1403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.fcx.var_for_def(self.span, param)
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Const { has_default, .. } => {
|
||||
GenericParamDefKind::Const { has_default } => {
|
||||
if !infer_args && has_default {
|
||||
tcx.const_param_default(param.def_id)
|
||||
.subst_spanned(tcx, substs.unwrap(), Some(self.span))
|
||||
|
@ -281,6 +281,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.demand_suptype(provided_arg.span, formal_input_ty, coerced_ty);
|
||||
};
|
||||
|
||||
let minimum_input_count = formal_input_tys.len();
|
||||
|
||||
// Check the arguments.
|
||||
// We do this in a pretty awful way: first we type-check any arguments
|
||||
// that are not closures, then we type-check the closures. This is so
|
||||
@ -303,7 +305,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
let minimum_input_count = formal_input_tys.len();
|
||||
for (idx, arg) in provided_args.iter().enumerate() {
|
||||
// Warn only for the first loop (the "no closures" one).
|
||||
// Closure arguments themselves can't be diverging, but
|
||||
@ -456,17 +457,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.emit();
|
||||
}
|
||||
|
||||
// We also need to make sure we at least write the ty of the other
|
||||
// arguments which we skipped above.
|
||||
if c_variadic {
|
||||
fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
|
||||
use crate::structured_errors::MissingCastForVariadicArg;
|
||||
for arg in provided_args.iter().skip(minimum_input_count) {
|
||||
let arg_ty = self.check_expr(&arg);
|
||||
|
||||
MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
|
||||
}
|
||||
if c_variadic {
|
||||
// We also need to make sure we at least write the ty of the other
|
||||
// arguments which we skipped above, either because they were additional
|
||||
// c_variadic args, or because we had an argument count mismatch.
|
||||
fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
|
||||
use crate::structured_errors::MissingCastForVariadicArg;
|
||||
|
||||
for arg in provided_args.iter().skip(expected_arg_count) {
|
||||
let arg_ty = self.check_expr(&arg);
|
||||
MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
|
||||
}
|
||||
|
||||
// There are a few types which get autopromoted when passed via varargs
|
||||
// in C but we just error out instead and require explicit casts.
|
||||
|
@ -402,16 +402,7 @@ fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>)
|
||||
PathSegment {
|
||||
name: item.name,
|
||||
args: GenericArgs::AngleBracketed {
|
||||
args: ty.substs[generics.parent_count..]
|
||||
.iter()
|
||||
.map(|ty| match ty.unpack() {
|
||||
ty::subst::GenericArgKind::Lifetime(lt) => {
|
||||
GenericArg::Lifetime(lt.clean(cx).unwrap())
|
||||
}
|
||||
ty::subst::GenericArgKind::Type(ty) => GenericArg::Type(ty.clean(cx)),
|
||||
ty::subst::GenericArgKind::Const(c) => GenericArg::Const(Box::new(c.clean(cx))),
|
||||
})
|
||||
.collect(),
|
||||
args: substs_to_args(cx, &ty.substs[generics.parent_count..], false),
|
||||
bindings: Default::default(),
|
||||
},
|
||||
}
|
||||
@ -451,7 +442,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
|
||||
},
|
||||
)
|
||||
}
|
||||
ty::GenericParamDefKind::Const { has_default, .. } => (
|
||||
ty::GenericParamDefKind::Const { has_default } => (
|
||||
self.name,
|
||||
GenericParamDefKind::Const {
|
||||
did: self.def_id,
|
||||
@ -1379,11 +1370,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>
|
||||
});
|
||||
if let Some(lt) = lifetime.cloned() {
|
||||
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
||||
let cleaned = if !lt.is_elided() {
|
||||
lt.clean(cx)
|
||||
} else {
|
||||
self::types::Lifetime::elided()
|
||||
};
|
||||
let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() };
|
||||
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
|
||||
}
|
||||
indices.lifetimes += 1;
|
||||
|
@ -77,16 +77,12 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
|
||||
Crate { module, primitives, external_traits: cx.external_traits.clone() }
|
||||
}
|
||||
|
||||
fn external_generic_args(
|
||||
crate fn substs_to_args(
|
||||
cx: &mut DocContext<'_>,
|
||||
did: DefId,
|
||||
has_self: bool,
|
||||
bindings: Vec<TypeBinding>,
|
||||
substs: SubstsRef<'_>,
|
||||
) -> GenericArgs {
|
||||
let mut skip_self = has_self;
|
||||
let mut ty_kind = None;
|
||||
let args: Vec<_> = substs
|
||||
substs: &[ty::subst::GenericArg<'_>],
|
||||
mut skip_first: bool,
|
||||
) -> Vec<GenericArg> {
|
||||
substs
|
||||
.iter()
|
||||
.filter_map(|kind| match kind.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => match *lt {
|
||||
@ -95,23 +91,32 @@ fn external_generic_args(
|
||||
}
|
||||
_ => lt.clean(cx).map(GenericArg::Lifetime),
|
||||
},
|
||||
GenericArgKind::Type(_) if skip_self => {
|
||||
skip_self = false;
|
||||
GenericArgKind::Type(_) if skip_first => {
|
||||
skip_first = false;
|
||||
None
|
||||
}
|
||||
GenericArgKind::Type(ty) => {
|
||||
ty_kind = Some(ty.kind());
|
||||
Some(GenericArg::Type(ty.clean(cx)))
|
||||
}
|
||||
GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
|
||||
GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))),
|
||||
})
|
||||
.collect();
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn external_generic_args(
|
||||
cx: &mut DocContext<'_>,
|
||||
did: DefId,
|
||||
has_self: bool,
|
||||
bindings: Vec<TypeBinding>,
|
||||
substs: SubstsRef<'_>,
|
||||
) -> GenericArgs {
|
||||
let args = substs_to_args(cx, &substs, has_self);
|
||||
|
||||
if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
|
||||
let inputs = match ty_kind.unwrap() {
|
||||
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
|
||||
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
|
||||
};
|
||||
let inputs =
|
||||
// The trait's first substitution is the one after self, if there is one.
|
||||
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
|
||||
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
|
||||
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
|
||||
};
|
||||
let output = None;
|
||||
// FIXME(#20299) return type comes from a projection now
|
||||
// match types[1].kind {
|
||||
|
13
src/test/rustdoc/generic-associated-types/issue-94683.rs
Normal file
13
src/test/rustdoc/generic-associated-types/issue-94683.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![crate_name = "foo"]
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
pub trait Trait {
|
||||
type Gat<'a>;
|
||||
}
|
||||
|
||||
// Make sure that the elided lifetime shows up
|
||||
|
||||
// @has foo/type.T.html
|
||||
// @has - "pub type T = "
|
||||
// @has - "<'_>"
|
||||
pub type T = fn(&<() as Trait>::Gat<'_>);
|
6
src/test/ui/tuple/wrong_argument_ice-4.rs
Normal file
6
src/test/ui/tuple/wrong_argument_ice-4.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
(|| {})(|| {
|
||||
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
|
||||
let b = 1;
|
||||
});
|
||||
}
|
15
src/test/ui/tuple/wrong_argument_ice-4.stderr
Normal file
15
src/test/ui/tuple/wrong_argument_ice-4.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0057]: this function takes 0 arguments but 1 argument was supplied
|
||||
--> $DIR/wrong_argument_ice-4.rs:2:5
|
||||
|
|
||||
LL | (|| {})(|| {
|
||||
| _____^^^^^^^_-
|
||||
| | |
|
||||
| | expected 0 arguments
|
||||
LL | |
|
||||
LL | | let b = 1;
|
||||
LL | | });
|
||||
| |_____- supplied 1 argument
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0057`.
|
Loading…
x
Reference in New Issue
Block a user