diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/free_regions.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/mod.rs | 88 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/wfcheck.rs | 54 |
5 files changed, 81 insertions, 66 deletions
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 62c17e6a10f..1dfaae7a150 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -6,7 +6,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] -#![feature(const_cstr_unchecked)] #![feature(crate_visibility_modifier)] #![feature(extern_types)] #![feature(in_band_lifetimes)] diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index 4814b65e320..e93cdf79421 100644 --- a/compiler/rustc_infer/src/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Lift, Region, TyCtxt}; /// /// This stuff is a bit convoluted and should be refactored, but as we /// transition to NLL, it'll all go away anyhow. -pub struct RegionRelations<'a, 'tcx> { +pub(crate) struct RegionRelations<'a, 'tcx> { pub tcx: TyCtxt<'tcx>, /// The context used for debug messages diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 85ee6d2cdc2..a5ec84a4f14 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -28,7 +28,7 @@ use std::fmt; /// assuming such values can be found. It returns the final values of /// all the variables as well as a set of errors that must be reported. #[instrument(level = "debug", skip(region_rels, var_infos, data))] -pub fn resolve<'tcx>( +pub(crate) fn resolve<'tcx>( region_rels: &RegionRelations<'_, 'tcx>, var_infos: VarInfos, data: RegionConstraintData<'tcx>, diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 752183365d6..aad8dd2119f 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -414,34 +414,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { arg: &GenericArg<'_>, ) -> subst::GenericArg<'tcx> { let tcx = self.astconv.tcx(); + + let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| { + if has_default { + tcx.check_optional_stability( + param.def_id, + Some(arg.id()), + arg.span(), + None, + |_, _| { + // Default generic parameters may not be marked + // with stability attributes, i.e. when the + // default parameter was defined at the same time + // as the rest of the type. As such, we ignore missing + // stability attributes. + }, + ) + } + if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) { + self.inferred_params.push(ty.span); + tcx.ty_error().into() + } else { + self.astconv.ast_ty_to_ty(ty).into() + } + }; + match (¶m.kind, arg) { (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { self.astconv.ast_region_to_region(lt, Some(param)).into() } (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => { - if has_default { - tcx.check_optional_stability( - param.def_id, - Some(arg.id()), - arg.span(), - None, - |_, _| { - // Default generic parameters may not be marked - // with stability attributes, i.e. when the - // default parameter was defined at the same time - // as the rest of the type. As such, we ignore missing - // stability attributes. - }, - ) - } - if let (hir::TyKind::Infer, false) = - (&ty.kind, self.astconv.allow_ty_infer()) - { - self.inferred_params.push(ty.span); - tcx.ty_error().into() - } else { - self.astconv.ast_ty_to_ty(ty).into() - } + handle_ty_args(has_default, ty) + } + (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => { + handle_ty_args(has_default, &inf.to_ty()) } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { ty::Const::from_opt_const_arg_anon_const( @@ -453,41 +459,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) .into() } - (&GenericParamDefKind::Const { has_default }, hir::GenericArg::Infer(inf)) => { - if has_default { - tcx.const_param_default(param.def_id).into() - } else if self.astconv.allow_ty_infer() { - // FIXME(const_generics): Actually infer parameter here? - todo!() - } else { - self.inferred_params.push(inf.span); - tcx.ty_error().into() - } - } - ( - &GenericParamDefKind::Type { has_default, .. }, - hir::GenericArg::Infer(inf), - ) => { - if has_default { - tcx.check_optional_stability( - param.def_id, - Some(arg.id()), - arg.span(), - None, - |_, _| { - // Default generic parameters may not be marked - // with stability attributes, i.e. when the - // default parameter was defined at the same time - // as the rest of the type. As such, we ignore missing - // stability attributes. - }, - ); - } + (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { + let ty = tcx.at(self.span).type_of(param.def_id); if self.astconv.allow_ty_infer() { - self.astconv.ast_ty_to_ty(&inf.to_ty()).into() + self.astconv.ct_infer(ty, Some(param), inf.span).into() } else { self.inferred_params.push(inf.span); - tcx.ty_error().into() + tcx.const_error(ty).into() } } _ => unreachable!(), diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 3fd3284d8b1..1404bc27167 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -426,22 +426,48 @@ fn check_gat_where_clauses( } } - // If there are any missing clauses, emit an error - let mut clauses = clauses.unwrap_or_default(); + // If there are any clauses that aren't provable, emit an error + let clauses = clauses.unwrap_or_default(); debug!(?clauses); if !clauses.is_empty() { - let written_predicates: ty::GenericPredicates<'_> = - tcx.explicit_predicates_of(trait_item.def_id); + let param_env = tcx.param_env(trait_item.def_id); + let mut clauses: Vec<_> = clauses - .drain_filter(|clause| !written_predicates.predicates.iter().any(|p| &p.0 == clause)) + .into_iter() + .filter(|clause| match clause.kind().skip_binder() { + ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { + !region_known_to_outlive( + tcx, + trait_item.hir_id(), + param_env, + &FxHashSet::default(), + a, + b, + ) + } + ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => { + !ty_known_to_outlive( + tcx, + trait_item.hir_id(), + param_env, + &FxHashSet::default(), + a, + b, + ) + } + _ => bug!("Unexpected PredicateKind"), + }) .map(|clause| format!("{}", clause)) .collect(); + // We sort so that order is predictable clauses.sort(); + if !clauses.is_empty() { + let plural = if clauses.len() > 1 { "s" } else { "" }; let mut err = tcx.sess.struct_span_err( trait_item.span, - &format!("Missing required bounds on {}", trait_item.ident), + &format!("missing required bound{} on `{}`", plural, trait_item.ident), ); let suggestion = format!( @@ -455,11 +481,22 @@ fn check_gat_where_clauses( ); err.span_suggestion( trait_item.generics.where_clause.tail_span_for_suggestion(), - "add the required where clauses", + &format!("add the required where clause{}", plural), suggestion, Applicability::MachineApplicable, ); + let bound = if clauses.len() > 1 { "these bounds are" } else { "this bound is" }; + err.note(&format!( + "{} currently required to ensure that impls have maximum flexibility", + bound + )); + err.note( + "we are soliciting feedback, see issue #87479 \ + <https://github.com/rust-lang/rust/issues/87479> \ + for more information", + ); + err.emit() } } @@ -541,7 +578,8 @@ fn region_known_to_outlive<'tcx>( }); use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate; - (&infcx).push_sub_region_constraint(origin, region_a, region_b); + // `region_a: region_b` -> `region_b <= region_a` + (&infcx).push_sub_region_constraint(origin, region_b, region_a); let errors = infcx.resolve_regions( id.expect_owner().to_def_id(), |
