Skip to content

Commit

Permalink
use the correct ParamEnv when checking future's output type (#13863)
Browse files Browse the repository at this point in the history
Fixes #13862

`missing_headers::check` is sometimes called from outside of a body
(specifically, from `check_attributes`, where the LateContext's ParamEnv
is not yet properly initialized for that item). Using that empty
ParamEnv for trait solving things from within the body can then lead to
various ICEs, like the linked issue where we have a const generic
parameter `DMA_INST` without a `ConstArgHasType` bound in the ParamEnv
so the const parameter has no type, which is normally not supposed to
happen.

We have the item's DefId so we can just get its ParamEnv/TypingEnv from
there, and using that one for trait solving should be safe.

changelog: none
  • Loading branch information
dswij authored Dec 29, 2024
2 parents aef4772 + 15ab2ff commit c8ba3e1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
11 changes: 9 additions & 2 deletions clippy_lints/src/doc/missing_headers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{DocHeaders, MISSING_ERRORS_DOC, MISSING_PANICS_DOC, MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC};
use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::ty::{implements_trait_with_env, is_type_diagnostic_item};
use clippy_utils::{is_doc_hidden, return_ty};
use rustc_hir::{BodyId, FnSig, OwnerId, Safety};
use rustc_lint::LateContext;
Expand Down Expand Up @@ -70,7 +70,14 @@ pub fn check(
&& let typeck = cx.tcx.typeck_body(body_id)
&& let body = cx.tcx.hir().body(body_id)
&& let ret_ty = typeck.expr_ty(body.value)
&& implements_trait(cx, ret_ty, future, &[])
&& implements_trait_with_env(
cx.tcx,
ty::TypingEnv::non_body_analysis(cx.tcx, owner_id.def_id),
ret_ty,
future,
Some(owner_id.def_id.to_def_id()),
&[],
)
&& let ty::Coroutine(_, subs) = ret_ty.kind()
&& is_type_diagnostic_item(cx, subs.as_coroutine().return_ty(), sym::Result)
{
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/crashes/ice-13862.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![crate_type = "lib"]
#![no_std]

use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};

pub struct S<const N: u8>;

impl<const N: u8> Future for S<N> {
type Output = ();
fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
todo!()
}
}

pub fn f<const N: u8>() -> S<N> {
S
}

0 comments on commit c8ba3e1

Please sign in to comment.