Skip to main content

rustc_trait_selection/error_reporting/infer/nice_region_error/
named_anon_conflict.rs

1//! Error Reporting for Anonymous Region Lifetime Errors
2//! where one region is named and the other is anonymous.
3
4use rustc_errors::Diag;
5use rustc_middle::ty;
6use tracing::debug;
7
8use crate::diagnostics::ExplicitLifetimeRequired;
9use crate::error_reporting::infer::nice_region_error::NiceRegionError;
10use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
11
12impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
13    /// When given a `ConcreteFailure` for a function with parameters containing a named region and
14    /// an anonymous region, emit an descriptive diagnostic error.
15    pub(super) fn try_report_named_anon_conflict(&self) -> Option<Diag<'tcx>> {
16        let (span, sub, sup) = self.regions()?;
17
18        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs:18",
                        "rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs"),
                        ::tracing_core::__macro_support::Option::Some(18u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("try_report_named_anon_conflict(sub={0:?}, sup={1:?}, error={2:?})",
                                                    sub, sup, self.error) as &dyn Value))])
            });
    } else { ; }
};debug!(
19            "try_report_named_anon_conflict(sub={:?}, sup={:?}, error={:?})",
20            sub, sup, self.error,
21        );
22
23        // Determine whether the sub and sup consist of one named region ('a)
24        // and one anonymous (elided) region. If so, find the parameter arg
25        // where the anonymous region appears (there must always be one; we
26        // only introduced anonymous regions in parameters) as well as a
27        // version new_ty of its type where the anonymous region is replaced
28        // with the named one.
29        let (named, anon, anon_param_info, region_info) = if sub.is_named(self.tcx())
30            && let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sup)
31            && let Some(anon_param_info) = self.find_param_with_region(sup, sub)
32        {
33            (sub, sup, anon_param_info, region_info)
34        } else if sup.is_named(self.tcx())
35            && let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sub)
36            && let Some(anon_param_info) = self.find_param_with_region(sub, sup)
37        {
38            (sup, sub, anon_param_info, region_info)
39        } else {
40            return None; // inapplicable
41        };
42
43        // Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
44        // and can steer users down the wrong path.
45        if named.is_static() {
46            return None;
47        }
48
49        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs:49",
                        "rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs"),
                        ::tracing_core::__macro_support::Option::Some(49u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("try_report_named_anon_conflict: named = {0:?}",
                                                    named) as &dyn Value))])
            });
    } else { ; }
};debug!("try_report_named_anon_conflict: named = {:?}", named);
50        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs:50",
                        "rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs"),
                        ::tracing_core::__macro_support::Option::Some(50u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("try_report_named_anon_conflict: anon_param_info = {0:?}",
                                                    anon_param_info) as &dyn Value))])
            });
    } else { ; }
};debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info);
51        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs:51",
                        "rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs"),
                        ::tracing_core::__macro_support::Option::Some(51u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("try_report_named_anon_conflict: region_info = {0:?}",
                                                    region_info) as &dyn Value))])
            });
    } else { ; }
};debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
52
53        let param = anon_param_info.param;
54        let new_ty = anon_param_info.param_ty;
55        let new_ty_span = anon_param_info.param_ty_span;
56        let is_first = anon_param_info.is_first;
57        let scope_def_id = region_info.scope;
58        let is_impl_item = region_info.is_impl_item;
59
60        if anon_param_info.kind.is_named(self.tcx()) {
61            /* not an anonymous region */
62            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs:62",
                        "rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs"),
                        ::tracing_core::__macro_support::Option::Some(62u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("try_report_named_anon_conflict: not an anonymous region")
                                            as &dyn Value))])
            });
    } else { ; }
};debug!("try_report_named_anon_conflict: not an anonymous region");
63            return None;
64        }
65
66        if is_impl_item {
67            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs:67",
                        "rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs"),
                        ::tracing_core::__macro_support::Option::Some(67u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::named_anon_conflict"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("try_report_named_anon_conflict: impl item, bail out")
                                            as &dyn Value))])
            });
    } else { ; }
};debug!("try_report_named_anon_conflict: impl item, bail out");
68            return None;
69        }
70
71        if find_anon_type(self.tcx(), self.generic_param_scope, anon).is_some()
72            && self.is_self_anon(is_first, scope_def_id)
73        {
74            return None;
75        }
76        let orig_ty = anon_param_info.orig_param_ty;
77        // Don't suggest naming the outer lifetime when it already appears in the pointee
78        // (e.g. `&'a mut Buffer<'a>`); point at borrow splitting instead.
79        let suggestion_would_alias_lifetime =
80            if let ty::Ref(_, orig_inner_ty, ty::Mutability::Mut) = orig_ty.kind() {
81                self.tcx().any_free_region_meets(orig_inner_ty, |r| r == named)
82            } else {
83                false
84            };
85
86        let named = named.to_string();
87        let new_ty_span = if suggestion_would_alias_lifetime { None } else { Some(new_ty_span) };
88        let err = match param.pat.simple_ident() {
89            Some(simple_ident) => ExplicitLifetimeRequired::WithIdent {
90                span,
91                simple_ident,
92                named,
93                new_ty_span,
94                new_ty,
95                link_nomicon: suggestion_would_alias_lifetime,
96            },
97            None => ExplicitLifetimeRequired::WithParamType {
98                span,
99                named,
100                new_ty_span,
101                new_ty,
102                link_nomicon: suggestion_would_alias_lifetime,
103            },
104        };
105        Some(self.tcx().sess.dcx().create_err(err))
106    }
107}