From e179d5dad21001a04e82ae08fb186f101b361c25 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 10 Aug 2023 21:42:56 +0000 Subject: [PATCH] Don't allow consts with unconstrained lifetimes in their types --- .../rustc_hir_analysis/src/impl_wf_check.rs | 6 +++--- .../assoc-const-unconstrained-lifetime.rs | 8 ++++++++ .../assoc-const-unconstrained-lifetime.stderr | 9 +++++++++ tests/ui/nll/trait-associated-constant.rs | 2 +- tests/ui/nll/trait-associated-constant.stderr | 19 +++---------------- 5 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 tests/ui/consts/assoc-const-unconstrained-lifetime.rs create mode 100644 tests/ui/consts/assoc-const-unconstrained-lifetime.stderr diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 4f705eaf10aac..b669cb8a07a82 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -94,21 +94,21 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) &mut input_parameters, ); - // Disallow unconstrained lifetimes, but only if they appear in assoc types. + // Disallow unconstrained lifetimes, but only if they appear in assoc types or consts. let lifetimes_in_associated_types: FxHashSet<_> = tcx .associated_item_def_ids(impl_def_id) .iter() .flat_map(|def_id| { let item = tcx.associated_item(def_id); match item.kind { - ty::AssocKind::Type => { + ty::AssocKind::Type | ty::AssocKind::Const => { if item.defaultness(tcx).has_value() { cgp::parameters_for(&tcx.type_of(def_id).instantiate_identity(), true) } else { vec![] } } - ty::AssocKind::Fn | ty::AssocKind::Const => vec![], + ty::AssocKind::Fn => vec![], } }) .collect(); diff --git a/tests/ui/consts/assoc-const-unconstrained-lifetime.rs b/tests/ui/consts/assoc-const-unconstrained-lifetime.rs new file mode 100644 index 0000000000000..f3897c67dd168 --- /dev/null +++ b/tests/ui/consts/assoc-const-unconstrained-lifetime.rs @@ -0,0 +1,8 @@ +struct Foo; + +impl<'a> Foo { + const CONST: &'a str = ""; + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates +} + +fn main() {} diff --git a/tests/ui/consts/assoc-const-unconstrained-lifetime.stderr b/tests/ui/consts/assoc-const-unconstrained-lifetime.stderr new file mode 100644 index 0000000000000..cbb9a39f258f3 --- /dev/null +++ b/tests/ui/consts/assoc-const-unconstrained-lifetime.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/assoc-const-unconstrained-lifetime.rs:3:6 + | +LL | impl<'a> Foo { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/nll/trait-associated-constant.rs b/tests/ui/nll/trait-associated-constant.rs index e13ae80f918b2..b9c6a29756aa3 100644 --- a/tests/ui/nll/trait-associated-constant.rs +++ b/tests/ui/nll/trait-associated-constant.rs @@ -19,7 +19,7 @@ struct FailStruct { } impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { const AC: Option<&'c str> = None; - //~^ ERROR: const not compatible with trait + //~^ ERROR: the lifetime parameter `'c` is not constrained by the impl trait, self type, or predicates } struct OKStruct2 { } diff --git a/tests/ui/nll/trait-associated-constant.stderr b/tests/ui/nll/trait-associated-constant.stderr index cf1c52ba7cc43..1f2c4c6c50c96 100644 --- a/tests/ui/nll/trait-associated-constant.stderr +++ b/tests/ui/nll/trait-associated-constant.stderr @@ -1,22 +1,9 @@ -error[E0308]: const not compatible with trait - --> $DIR/trait-associated-constant.rs:21:5 - | -LL | const AC: Option<&'c str> = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected enum `Option<&'b str>` - found enum `Option<&'c str>` -note: the lifetime `'c` as defined here... +error[E0207]: the lifetime parameter `'c` is not constrained by the impl trait, self type, or predicates --> $DIR/trait-associated-constant.rs:20:18 | LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { - | ^^ -note: ...does not necessarily outlive the lifetime `'b` as defined here - --> $DIR/trait-associated-constant.rs:20:14 - | -LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { - | ^^ + | ^^ unconstrained lifetime parameter error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0207`.