Skip to content

Commit 61b879c

Browse files
committed
Some additional cleanup
1 parent 65318da commit 61b879c

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

src/librustc_typeck/check/mod.rs

+48-1
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ pub struct Inherited<'a, 'tcx> {
256256
/// not clear.
257257
implicit_region_bound: Option<ty::Region<'tcx>>,
258258

259+
/// Maps each expression with a generic path
260+
/// (e.g. `foo::<u8>()` to `InferredPath` containing
261+
/// additional information used by `NeverCompatHandler`.
262+
///
263+
/// Each entry in this map is gradually filled in during typecheck,
264+
/// as the information we need is not available all at once.
259265
inferred_paths: RefCell<FxHashMap<hir::HirId, InferredPath<'tcx>>>,
260266

261267
body_id: Option<hir::BodyId>,
@@ -623,11 +629,45 @@ pub struct FnCtxt<'a, 'tcx> {
623629
inh: &'a Inherited<'a, 'tcx>,
624630
}
625631

632+
/// Stores additional data about a generic path
633+
/// containing inference variables (e.g. `my_method::<_, u8>(bar)`).
634+
/// This is used by `NeverCompatHandler` to inspect
635+
/// all method calls that contain inference variables.
636+
///
637+
/// This struct is a little strange, in that its data
638+
/// is filled in from two different places in typecheck.
639+
/// Thw two `Option` fields are written by `check_argument_types`
640+
/// and `instantiate_value_path`, since neither method
641+
/// has all of the information it needs.
626642
#[derive(Clone, Debug)]
627643
struct InferredPath<'tcx> {
644+
/// The span of the corresponding expression.
628645
span: Span,
646+
/// The type of this path. For method calls,
647+
/// this is a `ty::FnDef`
629648
ty: Option<Ty<'tcx>>,
649+
/// The types of the arguments (*not* generic substs)
650+
/// provided to this path, if it represents a method
651+
/// call. For example, `foo(true, 25)` would have
652+
/// types `[bool, i32]`. If this path does not
653+
/// correspond to a method, then this will be `None`
654+
///
655+
/// This is a `Cow` rather than a `Vec` or slice
656+
/// to accommodate `check_argument_types`, which may
657+
/// be called with either an interned slice or a Vec.
658+
/// A `Cow` lets us avoid unecessary interning
659+
/// and Vec construction, since we just need to iterate
660+
/// over this
630661
args: Option<Cow<'tcx, [Ty<'tcx>]>>,
662+
/// The unresolved inference variables for each
663+
/// generic substs. Each entry in the outer vec
664+
/// corresponds to a generic substs in the function.
665+
///
666+
/// For example, suppose we have the function
667+
/// `fn foo<T, V> (){ ... }`.
668+
///
669+
/// The method call `foo::<MyStruct<_#0t, #1t>, true>>()`
670+
/// will have an `unresolved_vars` of `[[_#0t, _#1t], []]`
631671
unresolved_vars: Vec<Vec<Ty<'tcx>>>,
632672
}
633673

@@ -3757,6 +3797,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37573797
) {
37583798
let fn_inputs = fn_inputs.into();
37593799
debug!("check_argument_types: storing arguments for expr {:?}", expr);
3800+
// We now have the arguments types available for this msthod call,
3801+
// so store them in the `inferred_paths` entry for this method call.
3802+
// We set `ty` as `None` if we are the first to access the entry
3803+
// for this method, and leave it untouched otherwise.
37603804
match self.inferred_paths.borrow_mut().entry(expr.hir_id) {
37613805
Entry::Vacant(e) => {
37623806
debug!("check_argument_types: making new entry for types {:?}", fn_inputs);
@@ -3769,7 +3813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37693813
}
37703814
Entry::Occupied(mut e) => {
37713815
debug!(
3772-
"check_argument_types: modifiying exsting entry {:?} with types {:?}",
3816+
"check_argument_types: modifying existing {:?} with types {:?}",
37733817
e.get(),
37743818
fn_inputs
37753819
);
@@ -5473,6 +5517,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
54735517
match parent {
54745518
Node::Expr(hir::Expr { span: p_span, kind: ExprKind::Call(..), .. })
54755519
| Node::Expr(hir::Expr { span: p_span, kind: ExprKind::MethodCall(..), .. }) => {
5520+
// Fill in the type for our parent expression. This might not be
5521+
// a method call - if it is, the argumetns will be filled in by
5522+
// `check_argument_types`
54765523
match self.inferred_paths.borrow_mut().entry(parent_id) {
54775524
Entry::Vacant(e) => {
54785525
debug!("instantiate_value_path: inserting new path");

src/librustc_typeck/check/never_compat.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,13 @@ fn find_questionable_call<'a, 'tcx>(
203203

204204
let ty = ty.unwrap_or_else(|| bug!("Missing ty in path: {:?}", path));
205205

206-
/// Check that this InferredPath actually corresponds to a method
207-
/// invocation. Currently, type-checking resolves generic paths
208-
/// (e.g. `Box::<_>::new` separately from determining that a method call
209-
/// is occuring). We use this check to skip over `InferredPaths` for
210-
/// non-method-calls (e.g. struct constructors).
206+
// Check that this InferredPath actually corresponds to a method
207+
// invocation. Currently, type-checking resolves generic paths
208+
// (e.g. `Box::<_>::new` separately from determining that a method call
209+
// is occurring). We use this check to skip over `InferredPaths` for
210+
// non-method-calls (e.g. struct constructors).
211211
if let ty::FnDef(_, substs) = ty.kind {
212212
debug!("find_questionable_call: Got substs: {:?}", substs);
213-
let mut args_inhabited = true;
214213

215214
// See if we can find any arguments that are definitely uninhabited.
216215
// If we can, we're done - the method call is dead, so fallback
@@ -221,7 +220,10 @@ fn find_questionable_call<'a, 'tcx>(
221220
// We use `conservative_is_privately_uninhabited` so that we only
222221
// bail out if we're certain that a type is uninhabited.
223222
if resolved_arg.conservative_is_privately_uninhabited(tcx) {
224-
debug!("find_questionable_call: bailing out due to uninhabited arg: {:?}", resolved_arg);
223+
debug!(
224+
"find_questionable_call: bailing out due to uninhabited arg: {:?}",
225+
resolved_arg
226+
);
225227
return None;
226228
} else {
227229
debug!("find_questionable_call: Arg is inhabited: {:?}", resolved_arg);
@@ -236,7 +238,7 @@ fn find_questionable_call<'a, 'tcx>(
236238
// Using a broader check for uninhabitedness ensures that we lint
237239
// whenever the subst is uninhabted, regardless of whether or not
238240
// the user code could know this.
239-
if tcx.is_ty_uninhabited_from_any_module(resolved_subst){
241+
if tcx.is_ty_uninhabited_from_any_module(resolved_subst) {
240242
debug!("find_questionable_call: Subst is uninhabited: {:?}", resolved_subst);
241243
if !vars.is_empty() {
242244
debug!("find_questionable_call: Found fallback vars: {:?}", vars);

0 commit comments

Comments
 (0)