mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 15:11:30 +00:00
Auto merge of #101212 - eholk:dyn-star, r=compiler-errors
Initial implementation of dyn* This PR adds extremely basic and incomplete support for [dyn*](https://smallcultfollowing.com/babysteps//blog/2022/03/29/dyn-can-we-make-dyn-sized/). The goal is to get something in tree behind a flag to make collaboration easier, and also to make sure the implementation so far is not unreasonable. This PR does quite a few things: * Introduce `dyn_star` feature flag * Adds parsing for `dyn* Trait` types * Defines `dyn* Trait` as a sized type * Adds support for explicit casts, like `42usize as dyn* Debug` * Including const evaluation of such casts * Adds codegen for drop glue so things are cleaned up properly when a `dyn* Trait` object goes out of scope * Adds codegen for method calls, at least for methods that take `&self` Quite a bit is still missing, but this gives us a starting point. Note that this is never intended to become stable surface syntax for Rust, but rather `dyn*` is planned to be used as an implementation detail for async functions in dyn traits. Joint work with `@nikomatsakis` and `@compiler-errors.` r? `@bjorn3`
This commit is contained in:
commit
f6a07d1d36
3 changed files with 9 additions and 6 deletions
|
@ -2,7 +2,7 @@ use rustc_hir::Expr;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::{cast::CastKind, Ty};
|
use rustc_middle::ty::{cast::CastKind, Ty};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use rustc_typeck::check::{cast::CastCheck, FnCtxt, Inherited};
|
use rustc_typeck::check::{cast::{self, CastCheckResult}, FnCtxt, Inherited};
|
||||||
|
|
||||||
// check if the component types of the transmuted collection and the result have different ABI,
|
// check if the component types of the transmuted collection and the result have different ABI,
|
||||||
// size or alignment
|
// size or alignment
|
||||||
|
@ -53,7 +53,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
|
||||||
"Newly created FnCtxt contained errors"
|
"Newly created FnCtxt contained errors"
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Ok(check) = CastCheck::new(
|
if let CastCheckResult::Deferred(check) = cast::check_cast(
|
||||||
&fn_ctxt, e, from_ty, to_ty,
|
&fn_ctxt, e, from_ty, to_ty,
|
||||||
// We won't show any error to the user, so we don't care what the span is here.
|
// We won't show any error to the user, so we don't care what the span is here.
|
||||||
DUMMY_SP, DUMMY_SP,
|
DUMMY_SP, DUMMY_SP,
|
||||||
|
|
|
@ -82,7 +82,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
|
||||||
ty::FnPtr(..) => {
|
ty::FnPtr(..) => {
|
||||||
return Err((span, "function pointers in const fn are unstable".into()));
|
return Err((span, "function pointers in const fn are unstable".into()));
|
||||||
},
|
},
|
||||||
ty::Dynamic(preds, _) => {
|
ty::Dynamic(preds, _, _) => {
|
||||||
for pred in preds.iter() {
|
for pred in preds.iter() {
|
||||||
match pred.skip_binder() {
|
match pred.skip_binder() {
|
||||||
ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {
|
ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {
|
||||||
|
@ -161,6 +161,10 @@ fn check_rvalue<'tcx>(
|
||||||
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
|
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
|
||||||
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
||||||
},
|
},
|
||||||
|
Rvalue::Cast(CastKind::DynStar, _, _) => {
|
||||||
|
// FIXME(dyn-star)
|
||||||
|
unimplemented!()
|
||||||
|
},
|
||||||
// binops are fine on integers
|
// binops are fine on integers
|
||||||
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
|
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
|
||||||
check_operand(tcx, lhs, span, body)?;
|
check_operand(tcx, lhs, span, body)?;
|
||||||
|
@ -221,7 +225,6 @@ fn check_statement<'tcx>(
|
||||||
check_operand(tcx, src, span, body)?;
|
check_operand(tcx, src, span, body)?;
|
||||||
check_operand(tcx, count, span, body)
|
check_operand(tcx, count, span, body)
|
||||||
},
|
},
|
||||||
|
|
||||||
// These are all NOPs
|
// These are all NOPs
|
||||||
StatementKind::StorageLive(_)
|
StatementKind::StorageLive(_)
|
||||||
| StatementKind::StorageDead(_)
|
| StatementKind::StorageDead(_)
|
||||||
|
|
|
@ -201,7 +201,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
ty::Dynamic(binder, _) => {
|
ty::Dynamic(binder, _, _) => {
|
||||||
for predicate in binder.iter() {
|
for predicate in binder.iter() {
|
||||||
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
|
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
|
||||||
if cx.tcx.has_attr(trait_ref.def_id, sym::must_use) {
|
if cx.tcx.has_attr(trait_ref.def_id, sym::must_use) {
|
||||||
|
@ -579,7 +579,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
|
||||||
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs), Some(id))),
|
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs), Some(id))),
|
||||||
ty::Opaque(id, _) => sig_from_bounds(cx, ty, cx.tcx.item_bounds(id), cx.tcx.opt_parent(id)),
|
ty::Opaque(id, _) => sig_from_bounds(cx, ty, cx.tcx.item_bounds(id), cx.tcx.opt_parent(id)),
|
||||||
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
|
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
|
||||||
ty::Dynamic(bounds, _) => {
|
ty::Dynamic(bounds, _, _) => {
|
||||||
let lang_items = cx.tcx.lang_items();
|
let lang_items = cx.tcx.lang_items();
|
||||||
match bounds.principal() {
|
match bounds.principal() {
|
||||||
Some(bound)
|
Some(bound)
|
||||||
|
|
Loading…
Reference in a new issue