11use rustc_data_structures:: fx:: FxHashSet ;
2- use rustc_middle:: lint:: LintExpectation ;
2+ use rustc_hir:: find_attr;
3+ use rustc_middle:: lint:: { LintExpectation , ShallowLintLevelMap } ;
34use rustc_middle:: query:: Providers ;
45use rustc_middle:: ty:: TyCtxt ;
56use rustc_session:: lint:: LintExpectationId ;
@@ -20,10 +21,10 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
2021 for owner in krate. owners ( ) {
2122 // Deduplicate expectations
2223 let mut inner_expectations = Vec :: new ( ) ;
23- let lints = tcx. shallow_lint_levels_on ( owner) ;
24+ let lints: & ShallowLintLevelMap = tcx. shallow_lint_levels_on ( owner) ;
2425 for expectation in & lints. expectations {
25- let canonicalized = canonicalize_id ( & expectation. 0 ) ;
26- if !inner_expectations. iter ( ) . any ( |( id, _) | canonicalize_id ( id) == canonicalized) {
26+ let canonicalized = canonicalize_id ( tcx , & expectation. 0 ) ;
27+ if !inner_expectations. iter ( ) . any ( |( id, _) | canonicalize_id ( tcx , id) == canonicalized) {
2728 inner_expectations. push ( expectation. clone ( ) ) ;
2829 }
2930 }
@@ -33,10 +34,16 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
3334 expectations
3435}
3536
36- fn canonicalize_id ( expect_id : & LintExpectationId ) -> ( rustc_span:: AttrId , u16 ) {
37+ fn canonicalize_id ( tcx : TyCtxt < ' _ > , expect_id : & LintExpectationId ) -> ( rustc_span:: AttrId , u16 ) {
3738 match * expect_id {
38- LintExpectationId :: Unstable { attr_id, lint_index, .. } => ( attr_id, lint_index) ,
39- LintExpectationId :: Stable { attr_id, lint_index, .. } => ( attr_id, lint_index) ,
39+ LintExpectationId :: Unstable { attr_id, lint_index } => ( attr_id, lint_index) ,
40+ LintExpectationId :: Stable { hir_id, attr_index, lint_index } => {
41+ // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok.
42+ let attrs = find_attr ! ( tcx, hir_id, LintAttributes ( lints) => lints) . unwrap ( ) ;
43+ let attr_id = attrs[ attr_index as usize ] . attr_id . attr_id ;
44+
45+ ( attr_id, lint_index)
46+ }
4047 }
4148}
4249
@@ -46,15 +53,15 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
4653
4754 // Turn a `LintExpectationId` into a `(AttrId, lint_index)` pair.
4855 let fulfilled_expectations: FxHashSet < _ > =
49- fulfilled_expectations. iter ( ) . map ( canonicalize_id) . collect ( ) ;
56+ fulfilled_expectations. iter ( ) . map ( |id| canonicalize_id ( tcx , id ) ) . collect ( ) ;
5057
5158 for ( expect_id, expectation) in lint_expectations {
5259 // This check will always be true, since `lint_expectations` only holds stable ids
5360 let LintExpectationId :: Stable { hir_id, .. } = expect_id else {
5461 unreachable ! ( "at this stage all `LintExpectationId`s are stable" ) ;
5562 } ;
5663
57- let expect_id = canonicalize_id ( expect_id) ;
64+ let expect_id = canonicalize_id ( tcx , expect_id) ;
5865
5966 if !fulfilled_expectations. contains ( & expect_id)
6067 && tool_filter. is_none_or ( |filter| expectation. lint_tool == Some ( filter) )
0 commit comments