Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f825271

Browse files
Rollup merge of #123625 - oli-obk:private_fnctxt, r=fee1-dead
Stop exporting `TypeckRootCtxt` and `FnCtxt`. While they have many convenient APIs, it is better to expose dedicated functions for them noticed in #122213
2 parents 5c3559d + a9edbfd commit f825271

File tree

9 files changed

+57
-63
lines changed

9 files changed

+57
-63
lines changed

‎compiler/rustc_hir_typeck/src/cast.rs‎

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,19 @@ use rustc_middle::mir::Mutability;
4040
use rustc_middle::ty::adjustment::AllowTwoPhase;
4141
use rustc_middle::ty::cast::{CastKind, CastTy};
4242
use rustc_middle::ty::error::TypeError;
43+
use rustc_middle::ty::TyCtxt;
4344
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
4445
use rustc_session::lint;
4546
use rustc_span::def_id::{DefId, LOCAL_CRATE};
4647
use rustc_span::symbol::sym;
4748
use rustc_span::Span;
49+
use rustc_span::DUMMY_SP;
4850
use rustc_trait_selection::infer::InferCtxtExt;
4951

5052
/// Reifies a cast check to be checked once we have full type information for
5153
/// a function context.
5254
#[derive(Debug)]
53-
pub struct CastCheck<'tcx> {
55+
pub(crate) struct CastCheck<'tcx> {
5456
/// The expression whose value is being casted
5557
expr: &'tcx hir::Expr<'tcx>,
5658
/// The source type for the cast expression
@@ -60,8 +62,6 @@ pub struct CastCheck<'tcx> {
6062
cast_ty: Ty<'tcx>,
6163
cast_span: Span,
6264
span: Span,
63-
/// whether the cast is made in a const context or not.
64-
pub constness: hir::Constness,
6565
}
6666

6767
/// The kind of pointer and associated metadata (thin, length or vtable) - we
@@ -194,18 +194,45 @@ fn make_invalid_casting_error<'a, 'tcx>(
194194
)
195195
}
196196

197+
/// If a cast from `from_ty` to `to_ty` is valid, returns a `Some` containing the kind
198+
/// of the cast.
199+
///
200+
/// This is a helper used from clippy.
201+
pub fn check_cast<'tcx>(
202+
tcx: TyCtxt<'tcx>,
203+
param_env: ty::ParamEnv<'tcx>,
204+
e: &'tcx hir::Expr<'tcx>,
205+
from_ty: Ty<'tcx>,
206+
to_ty: Ty<'tcx>,
207+
) -> Option<CastKind> {
208+
let hir_id = e.hir_id;
209+
let local_def_id = hir_id.owner.def_id;
210+
211+
let root_ctxt = crate::TypeckRootCtxt::new(tcx, local_def_id);
212+
let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, local_def_id);
213+
214+
if let Ok(check) = CastCheck::new(
215+
&fn_ctxt, e, from_ty, to_ty,
216+
// We won't show any errors to the user, so the span is irrelevant here.
217+
DUMMY_SP, DUMMY_SP,
218+
) {
219+
check.do_check(&fn_ctxt).ok()
220+
} else {
221+
None
222+
}
223+
}
224+
197225
impl<'a, 'tcx> CastCheck<'tcx> {
198-
pub fn new(
226+
pub(crate) fn new(
199227
fcx: &FnCtxt<'a, 'tcx>,
200228
expr: &'tcx hir::Expr<'tcx>,
201229
expr_ty: Ty<'tcx>,
202230
cast_ty: Ty<'tcx>,
203231
cast_span: Span,
204232
span: Span,
205-
constness: hir::Constness,
206233
) -> Result<CastCheck<'tcx>, ErrorGuaranteed> {
207234
let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span);
208-
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, constness };
235+
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span };
209236

210237
// For better error messages, check for some obviously unsized
211238
// cases now. We do a more thorough check at the end, once
@@ -644,7 +671,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
644671
/// Checks a cast, and report an error if one exists. In some cases, this
645672
/// can return Ok and create type errors in the fcx rather than returning
646673
/// directly. coercion-cast is handled in check instead of here.
647-
pubfn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
674+
fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
648675
use rustc_middle::ty::cast::CastTy::*;
649676
use rustc_middle::ty::cast::IntTy::*;
650677

‎compiler/rustc_hir_typeck/src/coercion.rs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13181318
}
13191319
}
13201320

1321+
/// Check whether `ty` can be coerced to `output_ty`.
1322+
/// Used from clippy.
1323+
pub fn can_coerce<'tcx>(
1324+
tcx: TyCtxt<'tcx>,
1325+
param_env: ty::ParamEnv<'tcx>,
1326+
body_id: LocalDefId,
1327+
ty: Ty<'tcx>,
1328+
output_ty: Ty<'tcx>,
1329+
) -> bool {
1330+
let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id);
1331+
let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id);
1332+
fn_ctxt.can_coerce(ty, output_ty)
1333+
}
1334+
13211335
/// CoerceMany encapsulates the pattern you should use when you have
13221336
/// many expressions that are all getting coerced to a common
13231337
/// type. This arises, for example, when you have a match (the result

‎compiler/rustc_hir_typeck/src/expr.rs‎

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,15 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13901390
} else {
13911391
// Defer other checks until we're done type checking.
13921392
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1393-
match cast::CastCheck::new(
1394-
self,
1395-
e,
1396-
t_expr,
1397-
t_cast,
1398-
t.span,
1399-
expr.span,
1400-
hir::Constness::NotConst,
1401-
) {
1393+
match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
14021394
Ok(cast_check) => {
14031395
debug!(
14041396
"check_expr_cast: deferring cast from {:?} to {:?}: {:?}",

‎compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use std::ops::Deref;
3838
///
3939
/// [`ItemCtxt`]: rustc_hir_analysis::collect::ItemCtxt
4040
/// [`InferCtxt`]: infer::InferCtxt
41-
pub struct FnCtxt<'a, 'tcx> {
41+
pub(crate) struct FnCtxt<'a, 'tcx> {
4242
pub(super) body_id: LocalDefId,
4343

4444
/// The parameter environment used for proving trait obligations

‎compiler/rustc_hir_typeck/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ mod typeck_root_ctxt;
4242
mod upvar;
4343
mod writeback;
4444

45-
pub use fn_ctxt::FnCtxt;
46-
pub use typeck_root_ctxt::TypeckRootCtxt;
45+
pub use coercion::can_coerce;
46+
use fn_ctxt::FnCtxt;
47+
use typeck_root_ctxt::TypeckRootCtxt;
4748

4849
use crate::check::check_fn;
4950
use crate::coercion::DynamicCoerceMany;

‎compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use std::ops::Deref;
2727
/// `bar()` will each have their own `FnCtxt`, but they will
2828
/// share the inference context, will process obligations together,
2929
/// can access each other's local types (scoping permitted), etc.
30-
pub struct TypeckRootCtxt<'tcx> {
30+
pub(crate) struct TypeckRootCtxt<'tcx> {
3131
pub(super) infcx: InferCtxt<'tcx>,
3232

3333
pub(super) typeck_results: RefCell<ty::TypeckResults<'tcx>>,

‎src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_errors::Applicability;
1212
use rustc_hir::def::{DefKind, Res};
1313
use rustc_hir::def_id::DefId;
1414
use rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
15-
use rustc_hir_typeck::{FnCtxt, TypeckRootCtxt};
1615
use rustc_infer::infer::TyCtxtInferExt;
1716
use rustc_lint::LateContext;
1817
use rustc_middle::mir::Mutability;
@@ -437,9 +436,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
437436
Node::Item(item) => {
438437
if let ItemKind::Fn(_, _, body_id) = &item.kind
439438
&& let output_ty = return_ty(cx, item.owner_id)
440-
&& let root_ctxt = TypeckRootCtxt::new(cx.tcx, item.owner_id.def_id)
441-
&& let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, item.owner_id.def_id)
442-
&& fn_ctxt.can_coerce(ty, output_ty)
439+
&& rustc_hir_typeck::can_coerce(cx.tcx, cx.param_env, item.owner_id.def_id, ty, output_ty)
443440
{
444441
if has_lifetime(output_ty) && has_lifetime(ty) {
445442
return false;

‎src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::utils::check_cast;
1+
use rustc_hir_typeck::cast::check_cast;
22
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
33
use clippy_utils::diagnostics::span_lint_and_sugg;
44
use clippy_utils::sugg::Sugg;
@@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(
2222
) -> bool {
2323
use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};
2424
let mut app = Applicability::MachineApplicable;
25-
let mut sugg = match check_cast(cx, e, from_ty, to_ty) {
25+
let mut sugg = match check_cast(cx.tcx, cx.param_env, e, from_ty, to_ty) {
2626
Some(FnPtrAddrCast | PtrAddrCast) if const_context => return false,
2727
Some(PtrPtrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) => {
2828
Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app)
Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
use rustc_hir as hir;
2-
use rustc_hir::Expr;
3-
use rustc_hir_typeck::{cast, FnCtxt, TypeckRootCtxt};
41
use rustc_lint::LateContext;
5-
use rustc_middle::ty::cast::CastKind;
62
use rustc_middle::ty::Ty;
7-
use rustc_span::DUMMY_SP;
83

94
// check if the component types of the transmuted collection and the result have different ABI,
105
// size or alignment
@@ -20,35 +15,3 @@ pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx
2015
false
2116
}
2217
}
23-
24-
/// If a cast from `from_ty` to `to_ty` is valid, returns an Ok containing the kind of
25-
/// the cast. In certain cases, including some invalid casts from array references
26-
/// to pointers, this may cause additional errors to be emitted and/or ICE error
27-
/// messages. This function will panic if that occurs.
28-
pub(super) fn check_cast<'tcx>(
29-
cx: &LateContext<'tcx>,
30-
e: &'tcx Expr<'_>,
31-
from_ty: Ty<'tcx>,
32-
to_ty: Ty<'tcx>,
33-
) -> Option<CastKind> {
34-
let hir_id = e.hir_id;
35-
let local_def_id = hir_id.owner.def_id;
36-
37-
let root_ctxt = TypeckRootCtxt::new(cx.tcx, local_def_id);
38-
let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, local_def_id);
39-
40-
if let Ok(check) = cast::CastCheck::new(
41-
&fn_ctxt,
42-
e,
43-
from_ty,
44-
to_ty,
45-
// We won't show any error to the user, so we don't care what the span is here.
46-
DUMMY_SP,
47-
DUMMY_SP,
48-
hir::Constness::NotConst,
49-
) {
50-
check.do_check(&fn_ctxt).ok()
51-
} else {
52-
None
53-
}
54-
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /