Skip to content

Commit

Permalink
Merge check_mod_impl_wf and check_mod_type_wf
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Feb 15, 2024
1 parent e13cc67 commit ade1cd7
Show file tree
Hide file tree
Showing 57 changed files with 699 additions and 246 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
let header = tcx.impl_trait_header(def_id);
let is_auto = header
.is_some_and(|header| tcx.trait_is_auto(header.skip_binder().trait_ref.def_id));

crate::impl_wf_check::check_impl_wf(tcx, def_id)?;
let mut res = Ok(());
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
Expand Down
22 changes: 7 additions & 15 deletions compiler/rustc_hir_analysis/src/impl_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ use min_specialization::check_min_specialization;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
use rustc_middle::query::Providers;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::{ErrorGuaranteed, Span, Symbol};

Expand Down Expand Up @@ -51,23 +50,16 @@ mod min_specialization;
/// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
/// // ^ 'a is unused and appears in assoc type, error
/// ```
fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) -> Result<(), ErrorGuaranteed> {
pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let min_specialization = tcx.features().min_specialization;
let module = tcx.hir_module_items(module_def_id);
let mut res = Ok(());
for id in module.items() {
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
res = res.and(enforce_impl_params_are_constrained(tcx, id.owner_id.def_id));
if min_specialization {
res = res.and(check_min_specialization(tcx, id.owner_id.def_id));
}
}
debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }));
res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
if min_specialization {
res = res.and(check_min_specialization(tcx, impl_def_id));
}
res
}

pub fn provide(providers: &mut Providers) {
*providers = Providers { check_mod_impl_wf, ..*providers };
res
}

fn enforce_impl_params_are_constrained(
Expand Down
16 changes: 4 additions & 12 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ pub fn provide(providers: &mut Providers) {
check_unused::provide(providers);
variance::provide(providers);
outlives::provide(providers);
impl_wf_check::provide(providers);
hir_wf_check::provide(providers);
}

Expand All @@ -170,29 +169,22 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
}

tcx.sess.time("coherence_checking", || {
// Check impls constrain their parameters
let res =
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
tcx.hir().par_for_each_module(|module| {
let _ = tcx.ensure().check_mod_type_wf(module);
});

for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
let _ = tcx.ensure().coherent_trait(trait_def_id);
}
// these queries are executed for side-effects (error reporting):
let _ = tcx.ensure().crate_inherent_impls(());
let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
res
})?;
});

if tcx.features().rustc_attrs {
tcx.sess.time("variance_testing", || variance::test::test_variance(tcx))?;
}

tcx.sess.time("wf_checking", || {
tcx.hir().par_for_each_module(|module| {
let _ = tcx.ensure().check_mod_type_wf(module);
})
});

if tcx.features().rustc_attrs {
collect::test_opaque_hidden_types(tcx)?;
}
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -964,11 +964,6 @@ rustc_queries! {
desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
}

query check_mod_impl_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
ensure_forwards_result_if_red
}

query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
ensure_forwards_result_if_red
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2598,10 +2598,18 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let span = *entry.get();
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
self.report_error(param.ident.span, err);
if let GenericParamKind::Lifetime = param.kind {
// Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_param(param.id, LifetimeRes::Error);
}
let rib = match param.kind {
GenericParamKind::Lifetime => {
// Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_param(param.id, LifetimeRes::Error);
continue;
}
GenericParamKind::Type { .. } => &mut function_type_rib,
GenericParamKind::Const { .. } => &mut function_value_rib,
};

self.r.record_partial_res(param.id, PartialRes::new(Res::Err));
rib.bindings.insert(ident, Res::Err);
continue;
}
Entry::Vacant(entry) => {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_traits/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
use rustc_middle::traits::CodegenObligationError;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::{
ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
Expand Down Expand Up @@ -72,6 +72,10 @@ pub fn codegen_select_candidate<'tcx>(

let impl_source = infcx.resolve_vars_if_possible(impl_source);
let impl_source = infcx.tcx.erase_regions(impl_source);
if impl_source.has_infer() {
infcx.tcx.dcx().has_errors().unwrap();
return Err(CodegenObligationError::FulfillmentError);
}

Ok(&*tcx.arena.alloc(impl_source))
}
38 changes: 19 additions & 19 deletions tests/ui/associated-types/issue-38821.stderr
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
--> $DIR/issue-38821.rs:23:17
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
|
LL | impl<T: NotNull> IntoNullable for T {
| ------- ^^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting the associated type
|
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
| +++++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
--> $DIR/issue-38821.rs:40:1
|
Expand Down Expand Up @@ -129,6 +110,25 @@ LL | impl<T: NotNull> IntoNullable for T {
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
--> $DIR/issue-38821.rs:23:17
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
|
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
--> $DIR/issue-38821.rs:9:18
|
LL | impl<T: NotNull> IntoNullable for T {
| ------- ^^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting the associated type
|
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
| +++++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
--> $DIR/issue-38821.rs:23:17
|
Expand Down
48 changes: 24 additions & 24 deletions tests/ui/coherence/coherence-orphan.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,6 @@ LL | impl TheTrait<usize> for isize { }
|
= note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
--> $DIR/coherence-orphan.rs:20:1
|
LL | impl !Send for Vec<isize> { }
| ^^^^^^^^^^^^^^^----------
| | |
| | `Vec` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead

warning: cross-crate traits with a default impl, like `Send`, should not be specialized
--> $DIR/coherence-orphan.rs:20:1
|
LL | impl !Send for Vec<isize> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this will change its meaning in a future release!
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
= note: `isize` is not a generic parameter
note: try using the same sequence of generic parameters as the struct definition
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
= note: `#[warn(suspicious_auto_trait_impls)]` on by default

error[E0046]: not all trait items implemented, missing: `the_fn`
--> $DIR/coherence-orphan.rs:10:1
|
Expand All @@ -58,6 +34,30 @@ LL | impl TheTrait<isize> for TheType { }
|
= help: implement the missing item: `fn the_fn(&self) { todo!() }`

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
--> $DIR/coherence-orphan.rs:20:1
|
LL | impl !Send for Vec<isize> { }
| ^^^^^^^^^^^^^^^----------
| | |
| | `Vec` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead

warning: cross-crate traits with a default impl, like `Send`, should not be specialized
--> $DIR/coherence-orphan.rs:20:1
|
LL | impl !Send for Vec<isize> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this will change its meaning in a future release!
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
= note: `isize` is not a generic parameter
note: try using the same sequence of generic parameters as the struct definition
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
= note: `#[warn(suspicious_auto_trait_impls)]` on by default

error: aborting due to 5 previous errors; 1 warning emitted

Some errors have detailed explanations: E0046, E0117.
Expand Down
26 changes: 23 additions & 3 deletions tests/ui/const-generics/issues/issue-68366.full.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
error: `Option<usize>` is forbidden as the type of a const generic parameter
--> $DIR/issue-68366.rs:9:25
|
LL | struct Collatz<const N: Option<usize>>;
| ^^^^^^^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`
= help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:11:7
--> $DIR/issue-68366.rs:12:7
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^^^^^^^^^^^^^^ unconstrained const parameter
Expand All @@ -8,14 +17,25 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
= note: proving the result of expressions other than the parameter are unique is not supported

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:17:6
--> $DIR/issue-68366.rs:19:6
|
LL | impl<const N: usize> Foo {}
| ^^^^^^^^^^^^^^ unconstrained const parameter
|
= note: expressions using a const parameter must map each value to a distinct output value
= note: proving the result of expressions other than the parameter are unique is not supported

error: aborting due to 2 previous errors
error: overly complex generic constant
--> $DIR/issue-68366.rs:12:31
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^-------^
| |
| struct/enum construction is not supported in generic constants
|
= help: consider moving this anonymous constant into a `const` function
= note: this operation may be supported in the future

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0207`.
17 changes: 13 additions & 4 deletions tests/ui/const-generics/issues/issue-68366.min.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
error: generic parameters may not be used in const operations
--> $DIR/issue-68366.rs:11:37
--> $DIR/issue-68366.rs:12:37
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^ cannot perform const operation using `N`
|
= help: const parameters may only be used as standalone arguments, i.e. `N`
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: `Option<usize>` is forbidden as the type of a const generic parameter
--> $DIR/issue-68366.rs:9:25
|
LL | struct Collatz<const N: Option<usize>>;
| ^^^^^^^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`
= help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:11:7
--> $DIR/issue-68366.rs:12:7
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^^^^^^^^^^^^^^ unconstrained const parameter
Expand All @@ -17,14 +26,14 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
= note: proving the result of expressions other than the parameter are unique is not supported

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:17:6
--> $DIR/issue-68366.rs:19:6
|
LL | impl<const N: usize> Foo {}
| ^^^^^^^^^^^^^^ unconstrained const parameter
|
= note: expressions using a const parameter must map each value to a distinct output value
= note: proving the result of expressions other than the parameter are unique is not supported

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0207`.
2 changes: 2 additions & 0 deletions tests/ui/const-generics/issues/issue-68366.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
#![cfg_attr(full, allow(incomplete_features))]

struct Collatz<const N: Option<usize>>;
//~^ ERROR: `Option<usize>` is forbidden

impl <const N: usize> Collatz<{Some(N)}> {}
//~^ ERROR the const parameter
//[min]~^^ generic parameters may not be used in const operations
//[full]~^^^ ERROR overly complex

struct Foo;

Expand Down
1 change: 0 additions & 1 deletion tests/ui/duplicate/duplicate-type-parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ trait Qux<T,T> {}

impl<T,T> Qux<T,T> for Option<T> {}
//~^ ERROR the name `T` is already used
//~^^ ERROR the type parameter `T` is not constrained

fn main() {
}
11 changes: 2 additions & 9 deletions tests/ui/duplicate/duplicate-type-parameter.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@ LL | impl<T,T> Qux<T,T> for Option<T> {}
| |
| first use of `T`

error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> $DIR/duplicate-type-parameter.rs:24:8
|
LL | impl<T,T> Qux<T,T> for Option<T> {}
| ^ unconstrained type parameter

error: aborting due to 8 previous errors
error: aborting due to 7 previous errors

Some errors have detailed explanations: E0207, E0403.
For more information about an error, try `rustc --explain E0207`.
For more information about this error, try `rustc --explain E0403`.
Loading

0 comments on commit ade1cd7

Please sign in to comment.