From dab5c4480011fadde4302ae356e0a631154d7f08 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 19 Feb 2022 00:48:31 +0100 Subject: [PATCH 1/7] rustc_trait_selection: adopt let else in more places --- .../src/traits/auto_trait.rs | 7 ++-- .../src/traits/coherence.rs | 17 ++++----- .../src/traits/error_reporting/mod.rs | 35 ++++++++---------- .../src/traits/error_reporting/suggestions.rs | 37 +++++++------------ .../rustc_trait_selection/src/traits/mod.rs | 27 +++++--------- .../src/traits/object_safety.rs | 7 +--- .../src/traits/project.rs | 5 +-- .../src/traits/select/candidate_assembly.rs | 16 +++----- .../src/traits/select/confirmation.rs | 20 ++++------ .../src/traits/specialize/mod.rs | 21 +++++------ 10 files changed, 75 insertions(+), 117 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 5fe7b62f45418..c9398d746d721 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -148,7 +148,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // traits::project will see that 'T: SomeTrait' is in our ParamEnv, allowing // SelectionContext to return it back to us. - let (new_env, user_env) = match self.evaluate_predicates( + let Some((new_env, user_env)) = self.evaluate_predicates( &infcx, trait_did, ty, @@ -156,9 +156,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { orig_env, &mut fresh_preds, false, - ) { - Some(e) => e, - None => return AutoTraitResult::NegativeImpl, + ) else { + return AutoTraitResult::NegativeImpl; }; let (full_env, full_user_env) = self diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index b2aa72e0e6741..d9854c6f91482 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -335,18 +335,15 @@ fn negative_impl<'cx, 'tcx>( impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs); // do the impls unify? If not, not disjoint. - let more_obligations = match infcx + let Ok(InferOk { obligations: more_obligations, .. }) = infcx .at(&ObligationCause::dummy(), impl1_env) .eq(impl1_trait_ref, impl2_trait_ref) - { - Ok(InferOk { obligations, .. }) => obligations, - Err(_) => { - debug!( - "explicit_disjoint: {:?} does not unify with {:?}", - impl1_trait_ref, impl2_trait_ref - ); - return false; - } + else { + debug!( + "explicit_disjoint: {:?} does not unify with {:?}", + impl1_trait_ref, impl2_trait_ref + ); + return false; }; let opt_failing_obligation = obligations diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f22b4e8d072a8..e345d0fc52213 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -801,9 +801,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() { - Some(ty) => ty, - None => return, + let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else { + return; }; let found_did = match *found_trait_ty.kind() { @@ -2115,26 +2114,24 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'tcx>, obligation: &PredicateObligation<'tcx>, ) { - let (pred, item_def_id, span) = match ( + let ( + ty::PredicateKind::Trait(pred), + &ObligationCauseCode::BindingObligation(item_def_id, span), + ) = ( obligation.predicate.kind().skip_binder(), obligation.cause.code().peel_derives(), - ) { - ( - ty::PredicateKind::Trait(pred), - &ObligationCauseCode::BindingObligation(item_def_id, span), - ) => (pred, item_def_id, span), - _ => return, + ) else { + return; }; debug!( "suggest_unsized_bound_if_applicable: pred={:?} item_def_id={:?} span={:?}", pred, item_def_id, span ); - let node = match ( + let (Some(node), true) = ( self.tcx.hir().get_if_local(item_def_id), Some(pred.def_id()) == self.tcx.lang_items().sized_trait(), - ) { - (Some(node), true) => node, - _ => return, + ) else { + return; }; self.maybe_suggest_unsized_generics(err, span, node); } @@ -2145,9 +2142,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { span: Span, node: Node<'hir>, ) { - let generics = match node.generics() { - Some(generics) => generics, - None => return, + let Some(generics) = node.generics() else { + return; }; let sized_trait = self.tcx.lang_items().sized_trait(); debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params); @@ -2160,9 +2156,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { .iter() .all(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait) }); - let param = match param { - Some(param) => param, - _ => return, + let Some(param) = param else { + return; }; let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id(); let preds = generics.where_clause.predicates.iter(); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 6d1b6e5ac84d4..4c15bb888e0e9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -513,9 +513,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { | ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_pred, _ => trait_pred, }; - let real_ty = match real_trait_pred.self_ty().no_bound_vars() { - Some(ty) => ty, - None => return, + let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else { + return; }; if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { @@ -593,9 +592,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { - let self_ty = match trait_pred.self_ty().no_bound_vars() { - None => return, - Some(ty) => ty, + let Some(self_ty) = trait_pred.self_ty().no_bound_vars() else { + return; }; let (def_id, output_ty, callable) = match *self_ty.kind() { @@ -607,9 +605,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // `mk_trait_obligation_with_new_self_ty` only works for types with no escaping bound // variables, so bail out if we have any. - let output_ty = match output_ty.no_bound_vars() { - Some(ty) => ty, - None => return, + let Some(output_ty) = output_ty.no_bound_vars() else { + return; }; let new_obligation = @@ -631,9 +628,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .. })) => { err.span_label(*span, "consider calling this closure"); - let name = match self.get_closure_name(def_id, err, &msg) { - Some(name) => name, - None => return, + let Some(name) = self.get_closure_name(def_id, err, &msg) else { + return; }; let args = decl.inputs.iter().map(|_| "_").collect::>().join(", "); let sugg = format!("({})", args); @@ -830,9 +826,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - let mut suggested_ty = match trait_pred.self_ty().no_bound_vars() { - Some(ty) => ty, - None => return, + let Some(mut suggested_ty) = trait_pred.self_ty().no_bound_vars() else { + return; }; for refs_remaining in 0..refs_number { @@ -1050,9 +1045,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option { let hir = self.tcx.hir(); let parent_node = hir.get_parent_node(obligation.cause.body_id); - let sig = match hir.find(parent_node) { - Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) => sig, - _ => return None, + let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = hir.find(parent_node) else { + return None; }; if let hir::FnRetTy::Return(ret_ty) = sig.decl.output { Some(ret_ty.span) } else { None } @@ -1502,11 +1496,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Only continue if a generator was found. debug!(?generator, ?trait_ref, ?target_ty, "maybe_note_obligation_cause_for_async_await"); - let (generator_did, trait_ref, target_ty) = match (generator, trait_ref, target_ty) { - (Some(generator_did), Some(trait_ref), Some(target_ty)) => { - (generator_did, trait_ref, target_ty) - } - _ => return false, + let (Some(generator_did), Some(trait_ref), Some(target_ty)) = (generator, trait_ref, target_ty) else { + return false; }; let span = self.tcx.def_span(generator_did); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 2927e64f705fe..3e095dceb21e1 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -340,19 +340,16 @@ pub fn normalize_param_env_or_error<'tcx>( "normalize_param_env_or_error: predicates=(non-outlives={:?}, outlives={:?})", predicates, outlives_predicates ); - let non_outlives_predicates = match do_normalize_predicates( + let Ok(non_outlives_predicates) = do_normalize_predicates( tcx, region_context, cause.clone(), elaborated_env, predicates, - ) { - Ok(predicates) => predicates, + ) else { // An unnormalized env is better than nothing. - Err(ErrorReported) => { - debug!("normalize_param_env_or_error: errored resolving non-outlives predicates"); - return elaborated_env; - } + debug!("normalize_param_env_or_error: errored resolving non-outlives predicates"); + return elaborated_env; }; debug!("normalize_param_env_or_error: non-outlives predicates={:?}", non_outlives_predicates); @@ -367,19 +364,16 @@ pub fn normalize_param_env_or_error<'tcx>( unnormalized_env.reveal(), unnormalized_env.constness(), ); - let outlives_predicates = match do_normalize_predicates( + let Ok(outlives_predicates) = do_normalize_predicates( tcx, region_context, cause, outlives_env, outlives_predicates, - ) { - Ok(predicates) => predicates, + ) else { // An unnormalized env is better than nothing. - Err(ErrorReported) => { - debug!("normalize_param_env_or_error: errored resolving outlives predicates"); - return elaborated_env; - } + debug!("normalize_param_env_or_error: errored resolving outlives predicates"); + return elaborated_env; }; debug!("normalize_param_env_or_error: outlives predicates={:?}", outlives_predicates); @@ -834,9 +828,8 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( selcx.select(&obligation).unwrap() }); - let implsrc_traitcasting = match implsrc { - Some(ImplSource::TraitUpcasting(data)) => data, - _ => bug!(), + let Some(ImplSource::TraitUpcasting(implsrc_traitcasting)) = implsrc else { + bug!(); }; implsrc_traitcasting.vtable_vptr_slot diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 7818053218dec..6cceec8621304 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -322,11 +322,8 @@ fn trait_has_sized_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { } fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - let sized_def_id = match tcx.lang_items().sized_trait() { - Some(def_id) => def_id, - None => { - return false; /* No Sized trait, can't require it! */ - } + let Some(sized_def_id) = tcx.lang_items().sized_trait() else { + return false; /* No Sized trait, can't require it! */ }; // Search for a predicate like `Self : Sized` amongst the trait bounds. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 5f338664c9a98..7907b71da6f8d 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1832,9 +1832,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); let param_env = obligation.param_env; - let assoc_ty = match assoc_def(selcx, impl_def_id, assoc_item_id) { - Ok(assoc_ty) => assoc_ty, - Err(ErrorReported) => return Progress { term: tcx.ty_error().into(), obligations: nested }, + let Ok(assoc_ty) = assoc_def(selcx, impl_def_id, assoc_item_id) else { + return Progress { term: tcx.ty_error().into(), obligations: nested }; }; if !assoc_ty.item.defaultness.has_value() { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index db86041f6180b..3d93e526cbc8e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -436,11 +436,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) { - Some(k) => k, - None => { - return; - } + let Some(kind) = self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) else { + return; }; // Okay to skip binder because the substs on closure types never @@ -763,12 +760,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // T: Trait // so it seems ok if we (conservatively) fail to accept that `Unsize` // obligation above. Should be possible to extend this in the future. - let source = match obligation.self_ty().no_bound_vars() { - Some(t) => t, - None => { - // Don't add any candidates if there are bound regions. - return; - } + let Some(source) = obligation.self_ty().no_bound_vars() else { + // Don't add any candidates if there are bound regions. + return; }; let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 84bc7cdff2890..e1d84dac8aeb2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -272,9 +272,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else { bug!("unexpected builtin trait {:?}", trait_def) }; - let nested = match conditions { - BuiltinImplConditions::Where(nested) => nested, - _ => bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation), + let BuiltinImplConditions::Where(nested) = conditions else { + bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation); }; let cause = obligation.derived_cause(BuiltinDerivedObligation); @@ -421,9 +420,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let trait_predicate = self.infcx.replace_bound_vars_with_placeholders(obligation.predicate); let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty()); let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref); - let data = match *self_ty.kind() { - ty::Dynamic(data, ..) => data, - _ => span_bug!(obligation.cause.span, "object candidate with non-object"), + let ty::Dynamic(data, ..) = *self_ty.kind() else { + span_bug!(obligation.cause.span, "object candidate with non-object"); }; let object_trait_ref = data.principal().unwrap_or_else(|| { @@ -608,9 +606,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // touch bound regions, they just capture the in-scope // type/region parameters. let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); - let (generator_def_id, substs) = match *self_ty.kind() { - ty::Generator(id, substs, _) => (id, substs), - _ => bug!("closure candidate for non-closure {:?}", obligation), + let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else { + bug!("closure candidate for non-closure {:?}", obligation); }; debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate"); @@ -652,9 +649,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // touch bound regions, they just capture the in-scope // type/region parameters. let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); - let (closure_def_id, substs) = match *self_ty.kind() { - ty::Closure(id, substs) => (id, substs), - _ => bug!("closure candidate for non-closure {:?}", obligation), + let ty::Closure(closure_def_id, substs) = *self_ty.kind() else { + bug!("closure candidate for non-closure {:?}", obligation); }; let obligation_predicate = obligation.predicate; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 38a6220082ff6..f02f7a20ecbeb 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -192,18 +192,15 @@ fn fulfill_implication<'a, 'tcx>( impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs); // do the impls unify? If not, no specialization. - let more_obligations = - match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) - { - Ok(InferOk { obligations, .. }) => obligations, - Err(_) => { - debug!( - "fulfill_implication: {:?} does not unify with {:?}", - source_trait_ref, target_trait_ref - ); - return Err(()); - } - }; + let Ok(InferOk { obligations: more_obligations, .. }) = + infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) + else { + debug!( + "fulfill_implication: {:?} does not unify with {:?}", + source_trait_ref, target_trait_ref + ); + return Err(()); + }; // attempt to prove all of the predicates for impl2 given those for impl1 // (which are packed up in penv) From 261765fe8ba7dbe28d33ed4f92609e5d468064d6 Mon Sep 17 00:00:00 2001 From: lightning1141 Date: Fri, 25 Feb 2022 19:35:03 +0800 Subject: [PATCH 2/7] Fix show error message when literal overflows in match patterns --- compiler/rustc_mir_build/src/thir/constant.rs | 8 +++++++- src/test/ui/issues/issue-94239.rs | 8 ++++++++ src/test/ui/issues/issue-94239.stderr | 11 +++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-94239.rs create mode 100644 src/test/ui/issues/issue-94239.stderr diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 72c0985a63c33..a94c2b9f5f7d4 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -17,7 +17,13 @@ crate fn lit_to_const<'tcx>( let param_ty = ParamEnv::reveal_all().and(ty); let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); - let result = width.truncate(n); + let result = match &ty.kind() { + ty::Uint(_) => { + let max_value = width.unsigned_int_max(); + if n >= max_value { max_value } else { width.truncate(n) } + } + _ => width.truncate(n), + }; trace!("trunc result: {}", result); Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) }; diff --git a/src/test/ui/issues/issue-94239.rs b/src/test/ui/issues/issue-94239.rs new file mode 100644 index 0000000000000..58ebba6764cef --- /dev/null +++ b/src/test/ui/issues/issue-94239.rs @@ -0,0 +1,8 @@ +pub const fn test_match_range(len: usize) -> usize { + match len { + 10000000000000000000..=99999999999999999999 => 0, //~ ERROR literal out of range for `usize` + _ => unreachable!(), + } +} + +fn main() {} diff --git a/src/test/ui/issues/issue-94239.stderr b/src/test/ui/issues/issue-94239.stderr new file mode 100644 index 0000000000000..f847d45949baf --- /dev/null +++ b/src/test/ui/issues/issue-94239.stderr @@ -0,0 +1,11 @@ +error: literal out of range for `usize` + --> $DIR/issue-94239.rs:3:32 + | +LL | 10000000000000000000..=99999999999999999999 => 0, + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[deny(overflowing_literals)]` on by default + = note: the literal `99999999999999999999` does not fit into the type `usize` whose range is `0..=18446744073709551615` + +error: aborting due to previous error + From 5b58c6feb87face0118bd36b61f58d137dd625e7 Mon Sep 17 00:00:00 2001 From: lightning1141 Date: Fri, 25 Feb 2022 21:12:04 +0800 Subject: [PATCH 3/7] fix E0081 error message due to lit_to_const behavior change --- src/test/ui/error-codes/E0081.rs | 6 +++--- src/test/ui/error-codes/E0081.stderr | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/ui/error-codes/E0081.rs b/src/test/ui/error-codes/E0081.rs index 255e05ced19f7..6f15b9d2ef95c 100644 --- a/src/test/ui/error-codes/E0081.rs +++ b/src/test/ui/error-codes/E0081.rs @@ -10,10 +10,10 @@ enum Enum { #[repr(u8)] enum EnumOverflowRepr { P = 257, - //~^ NOTE first use of `1` (overflowed from `257`) + //~^ NOTE first use of `255` (overflowed from `257`) X = 513, - //~^ ERROR discriminant value `1` already exists - //~| NOTE enum already has `1` (overflowed from `513`) + //~^ ERROR discriminant value `255` already exists + //~| NOTE enum already has `255` (overflowed from `513`) } fn main() { diff --git a/src/test/ui/error-codes/E0081.stderr b/src/test/ui/error-codes/E0081.stderr index 9b279bb0214c6..68bb0f407b82f 100644 --- a/src/test/ui/error-codes/E0081.stderr +++ b/src/test/ui/error-codes/E0081.stderr @@ -7,14 +7,14 @@ LL | LL | X = 3, | ^ enum already has `3` -error[E0081]: discriminant value `1` already exists +error[E0081]: discriminant value `255` already exists --> $DIR/E0081.rs:14:9 | LL | P = 257, - | --- first use of `1` (overflowed from `257`) + | --- first use of `255` (overflowed from `257`) LL | LL | X = 513, - | ^^^ enum already has `1` (overflowed from `513`) + | ^^^ enum already has `255` (overflowed from `513`) error: aborting due to 2 previous errors From b0c4db35942cfaa860d2d60b468af8734a34674d Mon Sep 17 00:00:00 2001 From: lightning1141 Date: Fri, 25 Feb 2022 21:57:09 +0800 Subject: [PATCH 4/7] Fix ci test issue-94239.rs --- src/test/ui/issues/issue-94239.rs | 4 ++-- src/test/ui/issues/issue-94239.stderr | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/issues/issue-94239.rs b/src/test/ui/issues/issue-94239.rs index 58ebba6764cef..a09ae32aa74d6 100644 --- a/src/test/ui/issues/issue-94239.rs +++ b/src/test/ui/issues/issue-94239.rs @@ -1,6 +1,6 @@ -pub const fn test_match_range(len: usize) -> usize { +pub const fn test_match_range(len: u64) -> u64 { match len { - 10000000000000000000..=99999999999999999999 => 0, //~ ERROR literal out of range for `usize` + 10000000000000000000..=99999999999999999999 => 0, //~ ERROR literal out of range for `u64` _ => unreachable!(), } } diff --git a/src/test/ui/issues/issue-94239.stderr b/src/test/ui/issues/issue-94239.stderr index f847d45949baf..057fbfec64f9b 100644 --- a/src/test/ui/issues/issue-94239.stderr +++ b/src/test/ui/issues/issue-94239.stderr @@ -1,11 +1,11 @@ -error: literal out of range for `usize` +error: literal out of range for `u64` --> $DIR/issue-94239.rs:3:32 | LL | 10000000000000000000..=99999999999999999999 => 0, | ^^^^^^^^^^^^^^^^^^^^ | = note: `#[deny(overflowing_literals)]` on by default - = note: the literal `99999999999999999999` does not fit into the type `usize` whose range is `0..=18446744073709551615` + = note: the literal `99999999999999999999` does not fit into the type `u64` whose range is `0..=18446744073709551615` error: aborting due to previous error From 2bf56b9aa7f92f665c40ddbe8259417de84bb142 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Sat, 26 Feb 2022 11:32:07 +0100 Subject: [PATCH 5/7] Document that pre-expansion lint passes are deprecated --- compiler/rustc_lint/src/context.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 0582a4e01bfeb..ad9a16fb39ae2 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -166,7 +166,12 @@ impl LintStore { self.early_passes.push(Box::new(pass)); } - /// Used by clippy. + /// This lint pass is softly deprecated. It misses expanded code and has caused a few + /// errors in the past. Currently, it is only used in Clippy. New implementations + /// should avoid using this interface, as it might be removed in the future. + /// + /// * See [rust#69838](https://github.com/rust-lang/rust/pull/69838) + /// * See [rust-clippy#5518](https://github.com/rust-lang/rust-clippy/pull/5518) pub fn register_pre_expansion_pass( &mut self, pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, From 915740c392e0147a5afa6f6fd0e2c303c066ac34 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 26 Feb 2022 16:58:21 +0100 Subject: [PATCH 6/7] Add test for #79465 to prevent regression --- src/test/rustdoc-ui/issue-79465.rs | 3 +++ src/test/rustdoc-ui/issue-79465.stderr | 15 +++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/rustdoc-ui/issue-79465.rs create mode 100644 src/test/rustdoc-ui/issue-79465.stderr diff --git a/src/test/rustdoc-ui/issue-79465.rs b/src/test/rustdoc-ui/issue-79465.rs new file mode 100644 index 0000000000000..f1a77982fb523 --- /dev/null +++ b/src/test/rustdoc-ui/issue-79465.rs @@ -0,0 +1,3 @@ +pub fn f1(x: T::A) {} +//~^ ERROR +//~^^ ERROR diff --git a/src/test/rustdoc-ui/issue-79465.stderr b/src/test/rustdoc-ui/issue-79465.stderr new file mode 100644 index 0000000000000..489cc14420a4c --- /dev/null +++ b/src/test/rustdoc-ui/issue-79465.stderr @@ -0,0 +1,15 @@ +error[E0220]: associated type `A` not found for `T` + --> $DIR/issue-79465.rs:1:20 + | +LL | pub fn f1(x: T::A) {} + | ^ associated type `A` not found + +error[E0220]: associated type `A` not found for `T` + --> $DIR/issue-79465.rs:1:20 + | +LL | pub fn f1(x: T::A) {} + | ^ associated type `A` not found + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0220`. From ef5601b321660f53bc93d30477308074174521c2 Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 26 Feb 2022 13:45:36 -0300 Subject: [PATCH 7/7] 2 - Make more use of let_chains Continuation of #94376. cc #53667 --- compiler/rustc_ast/src/attr/mod.rs | 11 ++--- compiler/rustc_ast/src/lib.rs | 5 +- compiler/rustc_ast/src/token.rs | 20 +++----- compiler/rustc_ast/src/tokenstream.rs | 68 +++++++++++++------------- compiler/rustc_ast/src/util/literal.rs | 8 +-- 5 files changed, 53 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index b94b8c8721693..550c66e3d3b20 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -75,12 +75,11 @@ impl NestedMetaItem { pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> { self.meta_item().and_then(|meta_item| { meta_item.meta_item_list().and_then(|meta_item_list| { - if meta_item_list.len() == 1 { - if let Some(ident) = meta_item.ident() { - if let Some(lit) = meta_item_list[0].literal() { - return Some((ident.name, lit)); - } - } + if meta_item_list.len() == 1 + && let Some(ident) = meta_item.ident() + && let Some(lit) = meta_item_list[0].literal() + { + return Some((ident.name, lit)); } None }) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 21183121e15a0..538bfc2129017 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -12,11 +12,12 @@ #![feature(crate_visibility_modifier)] #![feature(if_let_guard)] #![feature(label_break_value)] -#![feature(nll)] +#![feature(let_chains)] #![feature(min_specialization)] -#![recursion_limit = "256"] +#![feature(nll)] #![feature(slice_internals)] #![feature(stmt_expr_attributes)] +#![recursion_limit = "256"] #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index db066d7c6a519..c367573de8a94 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -504,10 +504,8 @@ impl Token { /// Returns `true` if the token is an interpolated path. fn is_path(&self) -> bool { - if let Interpolated(ref nt) = self.kind { - if let NtPath(..) = **nt { - return true; - } + if let Interpolated(ref nt) = self.kind && let NtPath(..) = **nt { + return true; } false } @@ -516,10 +514,10 @@ impl Token { /// That is, is this a pre-parsed expression dropped into the token stream /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { - if let Interpolated(ref nt) = self.kind { - if let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt { - return true; - } + if let Interpolated(ref nt) = self.kind + && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt + { + return true; } false @@ -527,10 +525,8 @@ impl Token { // Is the token an interpolated block (`$b:block`)? pub fn is_whole_block(&self) -> bool { - if let Interpolated(ref nt) = self.kind { - if let NtBlock(..) = **nt { - return true; - } + if let Interpolated(ref nt) = self.kind && let NtBlock(..) = **nt { + return true; } false } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 2174378a560d3..a67e7b1215b28 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -497,42 +497,40 @@ impl TokenStreamBuilder { // If `self` is not empty and the last tree within the last stream is a // token tree marked with `Joint`... - if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut() { - if let Some((TokenTree::Token(last_token), Spacing::Joint)) = last_stream_lrc.last() { - // ...and `stream` is not empty and the first tree within it is - // a token tree... - let TokenStream(ref mut stream_lrc) = stream; - if let Some((TokenTree::Token(token), spacing)) = stream_lrc.first() { - // ...and the two tokens can be glued together... - if let Some(glued_tok) = last_token.glue(&token) { - // ...then do so, by overwriting the last token - // tree in `self` and removing the first token tree - // from `stream`. This requires using `make_mut()` - // on the last stream in `self` and on `stream`, - // and in practice this doesn't cause cloning 99.9% - // of the time. - - // Overwrite the last token tree with the merged - // token. - let last_vec_mut = Lrc::make_mut(last_stream_lrc); - *last_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing); - - // Remove the first token tree from `stream`. (This - // is almost always the only tree in `stream`.) - let stream_vec_mut = Lrc::make_mut(stream_lrc); - stream_vec_mut.remove(0); - - // Don't push `stream` if it's empty -- that could - // block subsequent token gluing, by getting - // between two token trees that should be glued - // together. - if !stream.is_empty() { - self.0.push(stream); - } - return; - } - } + if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut() + && let Some((TokenTree::Token(last_token), Spacing::Joint)) = last_stream_lrc.last() + // ...and `stream` is not empty and the first tree within it is + // a token tree... + && let TokenStream(ref mut stream_lrc) = stream + && let Some((TokenTree::Token(token), spacing)) = stream_lrc.first() + // ...and the two tokens can be glued together... + && let Some(glued_tok) = last_token.glue(&token) + { + // ...then do so, by overwriting the last token + // tree in `self` and removing the first token tree + // from `stream`. This requires using `make_mut()` + // on the last stream in `self` and on `stream`, + // and in practice this doesn't cause cloning 99.9% + // of the time. + + // Overwrite the last token tree with the merged + // token. + let last_vec_mut = Lrc::make_mut(last_stream_lrc); + *last_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing); + + // Remove the first token tree from `stream`. (This + // is almost always the only tree in `stream`.) + let stream_vec_mut = Lrc::make_mut(stream_lrc); + stream_vec_mut.remove(0); + + // Don't push `stream` if it's empty -- that could + // block subsequent token gluing, by getting + // between two token trees that should be glued + // together. + if !stream.is_empty() { + self.0.push(stream); } + return; } self.0.push(stream); } diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 224afbd553fb8..231dd72af2c7d 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -222,10 +222,10 @@ impl Lit { } token::Literal(lit) => lit, token::Interpolated(ref nt) => { - if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { - if let ast::ExprKind::Lit(lit) = &expr.kind { - return Ok(lit.clone()); - } + if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt + && let ast::ExprKind::Lit(lit) = &expr.kind + { + return Ok(lit.clone()); } return Err(LitError::NotLiteral); }