Auto merge of #121491 - matthiaskrgr:rollup-wkzqawy, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #121434 (Fix #121208 fallout) - #121471 (When encountering `<&T as Clone>::clone(x)` because `T: Clone`, suggest `#[derive(Clone)]`) - #121476 (remove `llvm.assertions=true` in compiler profile) - #121479 (fix generalizer unsoundness) - #121480 (Fix more #121208 fallout) - #121482 (Allow for a missing `adt_def` in `NamePrivacyVisitor`.) - #121484 (coverage: Use variable name `this` in `CoverageGraph::from_mir`) - #121487 (Explicitly call `emit_stashed_diagnostics`.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
52cea084bd
34 changed files with 377 additions and 133 deletions
|
@ -1636,7 +1636,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
if let Some(old_def_id) = self.orig_opt_local_def_id(param) {
|
if let Some(old_def_id) = self.orig_opt_local_def_id(param) {
|
||||||
old_def_id
|
old_def_id
|
||||||
} else {
|
} else {
|
||||||
self.dcx().span_bug(lifetime.ident.span, "no def-id for fresh lifetime");
|
self.dcx()
|
||||||
|
.span_delayed_bug(lifetime.ident.span, "no def-id for fresh lifetime");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,11 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
// `handle_opaque_type` cannot handle subtyping, so to support subtyping
|
// `handle_opaque_type` cannot handle subtyping, so to support subtyping
|
||||||
// we instead eagerly generalize here. This is a bit of a mess but will go
|
// we instead eagerly generalize here. This is a bit of a mess but will go
|
||||||
// away once we're using the new solver.
|
// away once we're using the new solver.
|
||||||
let mut enable_subtyping = |ty, ty_is_expected| {
|
//
|
||||||
|
// Given `opaque rel B`, we create a new infer var `ty_vid` constrain it
|
||||||
|
// by using `ty_vid rel B` and then finally and end by equating `ty_vid` to
|
||||||
|
// the opaque.
|
||||||
|
let mut enable_subtyping = |ty, opaque_is_expected| {
|
||||||
let ty_vid = infcx.next_ty_var_id_in_universe(
|
let ty_vid = infcx.next_ty_var_id_in_universe(
|
||||||
TypeVariableOrigin {
|
TypeVariableOrigin {
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
|
@ -132,7 +136,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
ty::UniverseIndex::ROOT,
|
ty::UniverseIndex::ROOT,
|
||||||
);
|
);
|
||||||
|
|
||||||
let variance = if ty_is_expected {
|
let variance = if opaque_is_expected {
|
||||||
self.ambient_variance
|
self.ambient_variance
|
||||||
} else {
|
} else {
|
||||||
self.ambient_variance.xform(ty::Contravariant)
|
self.ambient_variance.xform(ty::Contravariant)
|
||||||
|
@ -140,7 +144,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
|
|
||||||
self.type_checker.infcx.instantiate_ty_var(
|
self.type_checker.infcx.instantiate_ty_var(
|
||||||
self,
|
self,
|
||||||
ty_is_expected,
|
opaque_is_expected,
|
||||||
ty_vid,
|
ty_vid,
|
||||||
variance,
|
variance,
|
||||||
ty,
|
ty,
|
||||||
|
@ -149,8 +153,8 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let (a, b) = match (a.kind(), b.kind()) {
|
let (a, b) = match (a.kind(), b.kind()) {
|
||||||
(&ty::Alias(ty::Opaque, ..), _) => (a, enable_subtyping(b, false)?),
|
(&ty::Alias(ty::Opaque, ..), _) => (a, enable_subtyping(b, true)?),
|
||||||
(_, &ty::Alias(ty::Opaque, ..)) => (enable_subtyping(a, true)?, b),
|
(_, &ty::Alias(ty::Opaque, ..)) => (enable_subtyping(a, false)?, b),
|
||||||
_ => unreachable!(
|
_ => unreachable!(
|
||||||
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
|
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
|
||||||
),
|
),
|
||||||
|
|
|
@ -154,10 +154,8 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
||||||
trait_m_sig.inputs_and_output,
|
trait_m_sig.inputs_and_output,
|
||||||
));
|
));
|
||||||
if !ocx.select_all_or_error().is_empty() {
|
if !ocx.select_all_or_error().is_empty() {
|
||||||
// This code path is not reached in any tests, but may be reachable. If
|
tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)");
|
||||||
// this is triggered, it should be converted to `delayed_bug` and the
|
return;
|
||||||
// triggering case turned into a test.
|
|
||||||
tcx.dcx().bug("encountered errors when checking RPITIT refinement (selection)");
|
|
||||||
}
|
}
|
||||||
let outlives_env = OutlivesEnvironment::with_bounds(
|
let outlives_env = OutlivesEnvironment::with_bounds(
|
||||||
param_env,
|
param_env,
|
||||||
|
@ -165,10 +163,8 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
||||||
);
|
);
|
||||||
let errors = infcx.resolve_regions(&outlives_env);
|
let errors = infcx.resolve_regions(&outlives_env);
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
// This code path is not reached in any tests, but may be reachable. If
|
tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (regions)");
|
||||||
// this is triggered, it should be converted to `delayed_bug` and the
|
return;
|
||||||
// triggering case turned into a test.
|
|
||||||
tcx.dcx().bug("encountered errors when checking RPITIT refinement (regions)");
|
|
||||||
}
|
}
|
||||||
// Resolve any lifetime variables that may have been introduced during normalization.
|
// Resolve any lifetime variables that may have been introduced during normalization.
|
||||||
let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else {
|
let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else {
|
||||||
|
|
|
@ -315,7 +315,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
|
|
||||||
if is_host_effect {
|
if is_host_effect {
|
||||||
if let Some(idx) = host_effect_index {
|
if let Some(idx) = host_effect_index {
|
||||||
tcx.dcx().span_bug(
|
tcx.dcx().span_delayed_bug(
|
||||||
param.span,
|
param.span,
|
||||||
format!("parent also has host effect param? index: {idx}, def: {def_id:?}"),
|
format!("parent also has host effect param? index: {idx}, def: {def_id:?}"),
|
||||||
);
|
);
|
||||||
|
|
|
@ -77,8 +77,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// coercions from ! to `expected`.
|
// coercions from ! to `expected`.
|
||||||
if ty.is_never() {
|
if ty.is_never() {
|
||||||
if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
|
if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
|
||||||
self.dcx()
|
let reported = self.dcx().span_delayed_bug(
|
||||||
.span_bug(expr.span, "expression with never type wound up being adjusted");
|
expr.span,
|
||||||
|
"expression with never type wound up being adjusted",
|
||||||
|
);
|
||||||
|
return Ty::new_error(self.tcx(), reported);
|
||||||
}
|
}
|
||||||
|
|
||||||
let adj_ty = self.next_ty_var(TypeVariableOrigin {
|
let adj_ty = self.next_ty_var(TypeVariableOrigin {
|
||||||
|
|
|
@ -582,7 +582,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Tuple(args) => Ok(args.len()),
|
ty::Tuple(args) => Ok(args.len()),
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx().dcx().span_bug(span, "tuple pattern not applied to a tuple");
|
self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple");
|
||||||
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
/// This is *not* expected to be used anywhere except for an implementation of
|
/// This is *not* expected to be used anywhere except for an implementation of
|
||||||
/// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
|
/// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
|
||||||
/// other usecases (i.e. setting the value of a type var).
|
/// other usecases (i.e. setting the value of a type var).
|
||||||
#[instrument(level = "debug", skip(self, relation, target_is_expected))]
|
#[instrument(level = "debug", skip(self, relation))]
|
||||||
pub fn instantiate_ty_var<R: ObligationEmittingRelation<'tcx>>(
|
pub fn instantiate_ty_var<R: ObligationEmittingRelation<'tcx>>(
|
||||||
&self,
|
&self,
|
||||||
relation: &mut R,
|
relation: &mut R,
|
||||||
target_is_expected: bool,
|
target_is_expected: bool,
|
||||||
target_vid: ty::TyVid,
|
target_vid: ty::TyVid,
|
||||||
ambient_variance: ty::Variance,
|
instantiation_variance: ty::Variance,
|
||||||
source_ty: Ty<'tcx>,
|
source_ty: Ty<'tcx>,
|
||||||
) -> RelateResult<'tcx, ()> {
|
) -> RelateResult<'tcx, ()> {
|
||||||
debug_assert!(self.inner.borrow_mut().type_variables().probe(target_vid).is_unknown());
|
debug_assert!(self.inner.borrow_mut().type_variables().probe(target_vid).is_unknown());
|
||||||
|
@ -46,7 +46,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
//
|
//
|
||||||
// We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
|
// We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
|
||||||
let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } =
|
let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } =
|
||||||
self.generalize(relation.span(), target_vid, ambient_variance, source_ty)?;
|
self.generalize(relation.span(), target_vid, instantiation_variance, source_ty)?;
|
||||||
|
|
||||||
// Constrain `b_vid` to the generalized type `generalized_ty`.
|
// Constrain `b_vid` to the generalized type `generalized_ty`.
|
||||||
if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
|
if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
|
||||||
|
@ -73,7 +73,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
// the alias can be normalized to something which does not
|
// the alias can be normalized to something which does not
|
||||||
// mention `?0`.
|
// mention `?0`.
|
||||||
if self.next_trait_solver() {
|
if self.next_trait_solver() {
|
||||||
let (lhs, rhs, direction) = match ambient_variance {
|
let (lhs, rhs, direction) = match instantiation_variance {
|
||||||
ty::Variance::Invariant => {
|
ty::Variance::Invariant => {
|
||||||
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
|
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
|
||||||
}
|
}
|
||||||
|
@ -106,22 +106,28 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// HACK: make sure that we `a_is_expected` continues to be
|
// NOTE: The `instantiation_variance` is not the same variance as
|
||||||
// correct when relating the generalized type with the source.
|
// used by the relation. When instantiating `b`, `target_is_expected`
|
||||||
|
// is flipped and the `instantion_variance` is also flipped. To
|
||||||
|
// constrain the `generalized_ty` while using the original relation,
|
||||||
|
// we therefore only have to flip the arguments.
|
||||||
|
//
|
||||||
|
// ```ignore (not code)
|
||||||
|
// ?a rel B
|
||||||
|
// instantiate_ty_var(?a, B) # expected and variance not flipped
|
||||||
|
// B' rel B
|
||||||
|
// ```
|
||||||
|
// or
|
||||||
|
// ```ignore (not code)
|
||||||
|
// A rel ?b
|
||||||
|
// instantiate_ty_var(?b, A) # expected and variance flipped
|
||||||
|
// A rel A'
|
||||||
|
// ```
|
||||||
if target_is_expected == relation.a_is_expected() {
|
if target_is_expected == relation.a_is_expected() {
|
||||||
relation.relate_with_variance(
|
relation.relate(generalized_ty, source_ty)?;
|
||||||
ambient_variance,
|
|
||||||
ty::VarianceDiagInfo::default(),
|
|
||||||
generalized_ty,
|
|
||||||
source_ty,
|
|
||||||
)?;
|
|
||||||
} else {
|
} else {
|
||||||
relation.relate_with_variance(
|
debug!("flip relation");
|
||||||
ambient_variance.xform(ty::Contravariant),
|
relation.relate(source_ty, generalized_ty)?;
|
||||||
ty::VarianceDiagInfo::default(),
|
|
||||||
source_ty,
|
|
||||||
generalized_ty,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -429,6 +429,7 @@ lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name
|
||||||
lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing
|
lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing
|
||||||
.suggestion = remove this redundant call
|
.suggestion = remove this redundant call
|
||||||
.note = the type `{$orig_ty}` does not implement `{$trait_}`, so calling `{$method}` on `&{$orig_ty}` copies the reference, which does not do anything and can be removed
|
.note = the type `{$orig_ty}` does not implement `{$trait_}`, so calling `{$method}` on `&{$orig_ty}` copies the reference, which does not do anything and can be removed
|
||||||
|
.derive_suggestion = if you meant to clone `{$orig_ty}`, implement `Clone` for it
|
||||||
|
|
||||||
lint_only_cast_u8_to_char = only `u8` can be cast into `char`
|
lint_only_cast_u8_to_char = only `u8` can be cast into `char`
|
||||||
.suggestion = use a `char` literal instead
|
.suggestion = use a `char` literal instead
|
||||||
|
|
|
@ -1314,6 +1314,12 @@ pub struct NoopMethodCallDiag<'a> {
|
||||||
pub trait_: Symbol,
|
pub trait_: Symbol,
|
||||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||||
pub label: Span,
|
pub label: Span,
|
||||||
|
#[suggestion(
|
||||||
|
lint_derive_suggestion,
|
||||||
|
code = "#[derive(Clone)]\n",
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub suggest_derive: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
|
|
|
@ -121,10 +121,20 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
||||||
let orig_ty = expr_ty.peel_refs();
|
let orig_ty = expr_ty.peel_refs();
|
||||||
|
|
||||||
if receiver_ty == expr_ty {
|
if receiver_ty == expr_ty {
|
||||||
|
let suggest_derive = match orig_ty.kind() {
|
||||||
|
ty::Adt(def, _) => Some(cx.tcx.def_span(def.did()).shrink_to_lo()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
cx.emit_span_lint(
|
cx.emit_span_lint(
|
||||||
NOOP_METHOD_CALL,
|
NOOP_METHOD_CALL,
|
||||||
span,
|
span,
|
||||||
NoopMethodCallDiag { method: call.ident.name, orig_ty, trait_, label: span },
|
NoopMethodCallDiag {
|
||||||
|
method: call.ident.name,
|
||||||
|
orig_ty,
|
||||||
|
trait_,
|
||||||
|
label: span,
|
||||||
|
suggest_derive,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
match name {
|
match name {
|
||||||
|
|
|
@ -52,19 +52,18 @@ impl CoverageGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut basic_coverage_blocks =
|
let mut this = Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None };
|
||||||
Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None };
|
|
||||||
let dominators = dominators::dominators(&basic_coverage_blocks);
|
this.dominators = Some(dominators::dominators(&this));
|
||||||
basic_coverage_blocks.dominators = Some(dominators);
|
|
||||||
|
|
||||||
// The coverage graph's entry-point node (bcb0) always starts with bb0,
|
// The coverage graph's entry-point node (bcb0) always starts with bb0,
|
||||||
// which never has predecessors. Any other blocks merged into bcb0 can't
|
// which never has predecessors. Any other blocks merged into bcb0 can't
|
||||||
// have multiple (coverage-relevant) predecessors, so bcb0 always has
|
// have multiple (coverage-relevant) predecessors, so bcb0 always has
|
||||||
// zero in-edges.
|
// zero in-edges.
|
||||||
assert!(basic_coverage_blocks[START_BCB].leader_bb() == mir::START_BLOCK);
|
assert!(this[START_BCB].leader_bb() == mir::START_BLOCK);
|
||||||
assert!(basic_coverage_blocks.predecessors[START_BCB].is_empty());
|
assert!(this.predecessors[START_BCB].is_empty());
|
||||||
|
|
||||||
basic_coverage_blocks
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_basic_coverage_blocks(
|
fn compute_basic_coverage_blocks(
|
||||||
|
|
|
@ -988,7 +988,10 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
||||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||||
if let hir::ExprKind::Struct(qpath, fields, ref base) = expr.kind {
|
if let hir::ExprKind::Struct(qpath, fields, ref base) = expr.kind {
|
||||||
let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
|
let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
|
||||||
let adt = self.typeck_results().expr_ty(expr).ty_adt_def().unwrap();
|
let Some(adt) = self.typeck_results().expr_ty(expr).ty_adt_def() else {
|
||||||
|
self.tcx.dcx().span_delayed_bug(expr.span, "no adt_def for expression");
|
||||||
|
return;
|
||||||
|
};
|
||||||
let variant = adt.variant_of_res(res);
|
let variant = adt.variant_of_res(res);
|
||||||
if let Some(base) = *base {
|
if let Some(base) = *base {
|
||||||
// If the expression uses FRU we need to make sure all the unmentioned fields
|
// If the expression uses FRU we need to make sure all the unmentioned fields
|
||||||
|
|
|
@ -172,9 +172,7 @@ fn do_normalize_predicates<'tcx>(
|
||||||
// the normalized predicates.
|
// the normalized predicates.
|
||||||
let errors = infcx.resolve_regions(&outlives_env);
|
let errors = infcx.resolve_regions(&outlives_env);
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
// @lcnr: Let's still ICE here for now. I want a test case
|
tcx.dcx().span_delayed_bug(
|
||||||
// for that.
|
|
||||||
tcx.dcx().span_bug(
|
|
||||||
span,
|
span,
|
||||||
format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"),
|
format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"),
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,9 +19,9 @@ lto = "off"
|
||||||
frame-pointers = true
|
frame-pointers = true
|
||||||
|
|
||||||
[llvm]
|
[llvm]
|
||||||
# This enables debug-assertions in LLVM,
|
# Having this set to true disrupts compiler development workflows for people who use `llvm.download-ci-llvm = true`
|
||||||
# catching logic errors in codegen much earlier in the process.
|
# because we don't provide ci-llvm on the `rustc-alt-builds` server. Therefore, it is kept off by default.
|
||||||
assertions = true
|
assertions = false
|
||||||
# Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation)
|
# Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation)
|
||||||
enable-warnings = true
|
enable-warnings = true
|
||||||
# Will download LLVM from CI if available on your platform.
|
# Will download LLVM from CI if available on your platform.
|
||||||
|
|
|
@ -163,13 +163,21 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> {
|
fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> {
|
||||||
let mut parser = AssertUnwindSafe(&mut self.parser);
|
let mut parser = AssertUnwindSafe(&mut self.parser);
|
||||||
|
|
||||||
match catch_unwind(move || parser.parse_crate_mod()) {
|
// rustfmt doesn't use `run_compiler` like other tools, so it must emit
|
||||||
Ok(Ok(k)) => Ok(k),
|
// any stashed diagnostics itself, otherwise the `DiagCtxt` will assert
|
||||||
Ok(Err(db)) => {
|
// when dropped. The final result here combines the parsing result and
|
||||||
|
// the `emit_stashed_diagnostics` result.
|
||||||
|
let parse_res = catch_unwind(move || parser.parse_crate_mod());
|
||||||
|
let stashed_res = self.parser.dcx().emit_stashed_diagnostics();
|
||||||
|
let err = Err(ParserError::ParsePanicError);
|
||||||
|
match (parse_res, stashed_res) {
|
||||||
|
(Ok(Ok(k)), None) => Ok(k),
|
||||||
|
(Ok(Ok(_)), Some(_guar)) => err,
|
||||||
|
(Ok(Err(db)), _) => {
|
||||||
db.emit();
|
db.emit();
|
||||||
Err(ParserError::ParseError)
|
err
|
||||||
}
|
}
|
||||||
Err(_) => Err(ParserError::ParsePanicError),
|
(Err(_), _) => err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,3 +55,10 @@ fn crate_parsing_errors_on_unclosed_delims() {
|
||||||
let filename = "tests/parser/unclosed-delims/issue_4466.rs";
|
let filename = "tests/parser/unclosed-delims/issue_4466.rs";
|
||||||
assert_parser_error(filename);
|
assert_parser_error(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn crate_parsing_stashed_diag() {
|
||||||
|
// See also https://github.com/rust-lang/rust/issues/121450
|
||||||
|
let filename = "tests/parser/stashed-diag.rs";
|
||||||
|
assert_parser_error(filename);
|
||||||
|
}
|
||||||
|
|
3
src/tools/rustfmt/tests/parser/stashed-diag.rs
Normal file
3
src/tools/rustfmt/tests/parser/stashed-diag.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#![u={static N;}]
|
||||||
|
|
||||||
|
fn main() {}
|
18
tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
Normal file
18
tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
pub trait Iterable {
|
||||||
|
type Item<'a>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn iter(&self) -> impl Iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I: 'a + Iterable> Iterable for &'a I {
|
||||||
|
type Item = u32;
|
||||||
|
//~^ ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration
|
||||||
|
|
||||||
|
fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
|
||||||
|
//~^ ERROR binding for associated type `Item` references lifetime `'missing`
|
||||||
|
//~| ERROR `()` is not an iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
30
tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
Normal file
30
tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
error[E0582]: binding for associated type `Item` references lifetime `'missing`, which does not appear in the trait input types
|
||||||
|
--> $DIR/span-bug-issue-121457.rs:13:51
|
||||||
|
|
|
||||||
|
LL | fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
|
||||||
|
--> $DIR/span-bug-issue-121457.rs:10:14
|
||||||
|
|
|
||||||
|
LL | type Item<'a>
|
||||||
|
| ---- lifetimes in impl do not match this type in trait
|
||||||
|
LL | where
|
||||||
|
LL | Self: 'a;
|
||||||
|
| -- this bound might be missing in the impl
|
||||||
|
...
|
||||||
|
LL | type Item = u32;
|
||||||
|
| ^ lifetimes do not match type in trait
|
||||||
|
|
||||||
|
error[E0277]: `()` is not an iterator
|
||||||
|
--> $DIR/span-bug-issue-121457.rs:13:23
|
||||||
|
|
|
||||||
|
LL | fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
|
||||||
|
|
|
||||||
|
= help: the trait `Iterator` is not implemented for `()`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0195, E0277, E0582.
|
||||||
|
For more information about an error, try `rustc --explain E0195`.
|
|
@ -1,64 +0,0 @@
|
||||||
//@ check-pass
|
|
||||||
//@ run-rustfix
|
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
struct PlainType<T>(T);
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct CloneType<T>(T);
|
|
||||||
|
|
||||||
fn check(mut encoded: &[u8]) {
|
|
||||||
let _ = &mut encoded;
|
|
||||||
//~^ WARN call to `.clone()` on a reference in this situation does nothing
|
|
||||||
let _ = &encoded;
|
|
||||||
//~^ WARN call to `.clone()` on a reference in this situation does nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let non_clone_type_ref = &PlainType(1u32);
|
|
||||||
let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref;
|
|
||||||
//~^ WARN call to `.clone()` on a reference in this situation does nothing
|
|
||||||
|
|
||||||
let clone_type_ref = &CloneType(1u32);
|
|
||||||
let clone_type_ref_clone: CloneType<u32> = clone_type_ref.clone();
|
|
||||||
|
|
||||||
|
|
||||||
let non_deref_type = &PlainType(1u32);
|
|
||||||
let non_deref_type_deref: &PlainType<u32> = non_deref_type;
|
|
||||||
//~^ WARN call to `.deref()` on a reference in this situation does nothing
|
|
||||||
|
|
||||||
let non_borrow_type = &PlainType(1u32);
|
|
||||||
let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type;
|
|
||||||
//~^ WARN call to `.borrow()` on a reference in this situation does nothing
|
|
||||||
|
|
||||||
// Borrowing a &&T does not warn since it has collapsed the double reference
|
|
||||||
let non_borrow_type = &&PlainType(1u32);
|
|
||||||
let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generic<T>(non_clone_type: &PlainType<T>) {
|
|
||||||
non_clone_type;
|
|
||||||
//~^ WARN call to `.clone()` on a reference in this situation does nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
fn non_generic(non_clone_type: &PlainType<u32>) {
|
|
||||||
non_clone_type;
|
|
||||||
//~^ WARN call to `.clone()` on a reference in this situation does nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DiagnosticClone;
|
|
||||||
impl Clone for DiagnosticClone {
|
|
||||||
#[rustc_diagnostic_item = "other_clone"]
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
DiagnosticClone
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_other_diagnostic_item(x: DiagnosticClone) {
|
|
||||||
x.clone();
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ run-rustfix
|
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: call to `.clone()` on a reference in this situation does nothing
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:16:25
|
--> $DIR/noop-method-call.rs:15:25
|
||||||
|
|
|
|
||||||
LL | let _ = &mut encoded.clone();
|
LL | let _ = &mut encoded.clone();
|
||||||
| ^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^ help: remove this redundant call
|
||||||
|
@ -8,7 +8,7 @@ LL | let _ = &mut encoded.clone();
|
||||||
= note: `#[warn(noop_method_call)]` on by default
|
= note: `#[warn(noop_method_call)]` on by default
|
||||||
|
|
||||||
warning: call to `.clone()` on a reference in this situation does nothing
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:18:21
|
--> $DIR/noop-method-call.rs:17:21
|
||||||
|
|
|
|
||||||
LL | let _ = &encoded.clone();
|
LL | let _ = &encoded.clone();
|
||||||
| ^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^ help: remove this redundant call
|
||||||
|
@ -16,44 +16,94 @@ LL | let _ = &encoded.clone();
|
||||||
= note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed
|
= note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed
|
||||||
|
|
||||||
warning: call to `.clone()` on a reference in this situation does nothing
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:24:71
|
--> $DIR/noop-method-call.rs:23:71
|
||||||
|
|
|
|
||||||
LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
|
LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
|
||||||
| ^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
||||||
|
help: remove this redundant call
|
||||||
|
|
|
||||||
|
LL - let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
|
||||||
|
LL + let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref;
|
||||||
|
|
|
||||||
|
help: if you meant to clone `PlainType<u32>`, implement `Clone` for it
|
||||||
|
|
|
||||||
|
LL + #[derive(Clone)]
|
||||||
|
LL | struct PlainType<T>(T);
|
||||||
|
|
|
||||||
|
|
||||||
warning: call to `.deref()` on a reference in this situation does nothing
|
warning: call to `.deref()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:32:63
|
--> $DIR/noop-method-call.rs:31:63
|
||||||
|
|
|
|
||||||
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
||||||
| ^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the type `PlainType<u32>` does not implement `Deref`, so calling `deref` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
= note: the type `PlainType<u32>` does not implement `Deref`, so calling `deref` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
||||||
|
help: remove this redundant call
|
||||||
|
|
|
||||||
|
LL - let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
||||||
|
LL + let non_deref_type_deref: &PlainType<u32> = non_deref_type;
|
||||||
|
|
|
||||||
|
help: if you meant to clone `PlainType<u32>`, implement `Clone` for it
|
||||||
|
|
|
||||||
|
LL + #[derive(Clone)]
|
||||||
|
LL | struct PlainType<T>(T);
|
||||||
|
|
|
||||||
|
|
||||||
warning: call to `.borrow()` on a reference in this situation does nothing
|
warning: call to `.borrow()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:36:66
|
--> $DIR/noop-method-call.rs:35:66
|
||||||
|
|
|
|
||||||
LL | let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
LL | let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
||||||
| ^^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the type `PlainType<u32>` does not implement `Borrow`, so calling `borrow` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
= note: the type `PlainType<u32>` does not implement `Borrow`, so calling `borrow` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
||||||
|
help: remove this redundant call
|
||||||
|
|
|
||||||
|
LL - let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
||||||
|
LL + let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type;
|
||||||
|
|
|
||||||
|
help: if you meant to clone `PlainType<u32>`, implement `Clone` for it
|
||||||
|
|
|
||||||
|
LL + #[derive(Clone)]
|
||||||
|
LL | struct PlainType<T>(T);
|
||||||
|
|
|
||||||
|
|
||||||
warning: call to `.clone()` on a reference in this situation does nothing
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:45:19
|
--> $DIR/noop-method-call.rs:44:19
|
||||||
|
|
|
|
||||||
LL | non_clone_type.clone();
|
LL | non_clone_type.clone();
|
||||||
| ^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the type `PlainType<T>` does not implement `Clone`, so calling `clone` on `&PlainType<T>` copies the reference, which does not do anything and can be removed
|
= note: the type `PlainType<T>` does not implement `Clone`, so calling `clone` on `&PlainType<T>` copies the reference, which does not do anything and can be removed
|
||||||
|
help: remove this redundant call
|
||||||
|
|
|
||||||
|
LL - non_clone_type.clone();
|
||||||
|
LL + non_clone_type;
|
||||||
|
|
|
||||||
|
help: if you meant to clone `PlainType<T>`, implement `Clone` for it
|
||||||
|
|
|
||||||
|
LL + #[derive(Clone)]
|
||||||
|
LL | struct PlainType<T>(T);
|
||||||
|
|
|
||||||
|
|
||||||
warning: call to `.clone()` on a reference in this situation does nothing
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:50:19
|
--> $DIR/noop-method-call.rs:49:19
|
||||||
|
|
|
|
||||||
LL | non_clone_type.clone();
|
LL | non_clone_type.clone();
|
||||||
| ^^^^^^^^ help: remove this redundant call
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
|
||||||
|
help: remove this redundant call
|
||||||
|
|
|
||||||
|
LL - non_clone_type.clone();
|
||||||
|
LL + non_clone_type;
|
||||||
|
|
|
||||||
|
help: if you meant to clone `PlainType<u32>`, implement `Clone` for it
|
||||||
|
|
|
||||||
|
LL + #[derive(Clone)]
|
||||||
|
LL | struct PlainType<T>(T);
|
||||||
|
|
|
||||||
|
|
||||||
warning: 7 warnings emitted
|
warning: 7 warnings emitted
|
||||||
|
|
||||||
|
|
4
tests/ui/lowering/span-bug-issue-121431.rs
Normal file
4
tests/ui/lowering/span-bug-issue-121431.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fn bug<T>() -> impl CallbackMarker< Item = [(); { |_: &mut ()| 3; 4 }] > {}
|
||||||
|
//~^ ERROR cannot find trait `CallbackMarker` in this scope
|
||||||
|
|
||||||
|
fn main() {}
|
9
tests/ui/lowering/span-bug-issue-121431.stderr
Normal file
9
tests/ui/lowering/span-bug-issue-121431.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0405]: cannot find trait `CallbackMarker` in this scope
|
||||||
|
--> $DIR/span-bug-issue-121431.rs:1:21
|
||||||
|
|
|
||||||
|
LL | fn bug<T>() -> impl CallbackMarker< Item = [(); { |_: &mut ()| 3; 4 }] > {}
|
||||||
|
| ^^^^^^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0405`.
|
15
tests/ui/never_type/span-bug-issue-121445.rs
Normal file
15
tests/ui/never_type/span-bug-issue-121445.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#![feature(never_type)]
|
||||||
|
|
||||||
|
fn test2() {
|
||||||
|
let x: !;
|
||||||
|
let c2 = SingleVariant::Points(0)
|
||||||
|
| match x { //~ ERROR no implementation for `SingleVariant | ()`
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SingleVariant {
|
||||||
|
Points(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
22
tests/ui/never_type/span-bug-issue-121445.stderr
Normal file
22
tests/ui/never_type/span-bug-issue-121445.stderr
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
error[E0369]: no implementation for `SingleVariant | ()`
|
||||||
|
--> $DIR/span-bug-issue-121445.rs:6:9
|
||||||
|
|
|
||||||
|
LL | let c2 = SingleVariant::Points(0)
|
||||||
|
| ------------------------ SingleVariant
|
||||||
|
LL | | match x {
|
||||||
|
| _________^_-
|
||||||
|
LL | | _ => (),
|
||||||
|
LL | | };
|
||||||
|
| |_________- ()
|
||||||
|
|
|
||||||
|
note: an implementation of `BitOr<()>` might be missing for `SingleVariant`
|
||||||
|
--> $DIR/span-bug-issue-121445.rs:11:1
|
||||||
|
|
|
||||||
|
LL | enum SingleVariant {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ must implement `BitOr<()>`
|
||||||
|
note: the trait `BitOr` must be implemented
|
||||||
|
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0369`.
|
6
tests/ui/privacy/unreachable-issue-121455.rs
Normal file
6
tests/ui/privacy/unreachable-issue-121455.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn test(s: &Self::Id) {
|
||||||
|
//~^ ERROR failed to resolve: `Self` is only available in impls, traits, and type definitions
|
||||||
|
match &s[0..3] {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
9
tests/ui/privacy/unreachable-issue-121455.stderr
Normal file
9
tests/ui/privacy/unreachable-issue-121455.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
|
||||||
|
--> $DIR/unreachable-issue-121455.rs:1:13
|
||||||
|
|
|
||||||
|
LL | fn test(s: &Self::Id) {
|
||||||
|
| ^^^^ `Self` is only available in impls, traits, and type definitions
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0433`.
|
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(effects)]
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
trait T {}
|
||||||
|
|
||||||
|
impl const dyn T {
|
||||||
|
//~^ ERROR inherent impls cannot be `const`
|
||||||
|
//~| ERROR the const parameter `host` is not constrained by the impl trait, self type, or
|
||||||
|
pub const fn new() -> std::sync::Mutex<dyn T> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error: inherent impls cannot be `const`
|
||||||
|
--> $DIR/span-bug-issue-121418.rs:7:12
|
||||||
|
|
|
||||||
|
LL | impl const dyn T {
|
||||||
|
| ----- ^^^^^ inherent impl for this type
|
||||||
|
| |
|
||||||
|
| `const` because of this
|
||||||
|
|
|
||||||
|
= note: only trait implementations may be annotated with `const`
|
||||||
|
|
||||||
|
error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
|
||||||
|
--> $DIR/span-bug-issue-121418.rs:7:6
|
||||||
|
|
|
||||||
|
LL | impl const dyn T {
|
||||||
|
| ^^^^^ 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
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0207`.
|
15
tests/ui/traits/span-bug-issue-121414.rs
Normal file
15
tests/ui/traits/span-bug-issue-121414.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
trait Bar {
|
||||||
|
type Type;
|
||||||
|
}
|
||||||
|
struct Foo<'a>(&'a ());
|
||||||
|
impl<'a> Bar for Foo<'f> { //~ ERROR undeclared lifetime
|
||||||
|
type Type = u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test() //~ ERROR implementation of `Bar` is not general enough
|
||||||
|
where
|
||||||
|
for<'a> <Foo<'a> as Bar>::Type: Sized,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
20
tests/ui/traits/span-bug-issue-121414.stderr
Normal file
20
tests/ui/traits/span-bug-issue-121414.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0261]: use of undeclared lifetime name `'f`
|
||||||
|
--> $DIR/span-bug-issue-121414.rs:5:22
|
||||||
|
|
|
||||||
|
LL | impl<'a> Bar for Foo<'f> {
|
||||||
|
| - ^^ undeclared lifetime
|
||||||
|
| |
|
||||||
|
| help: consider introducing lifetime `'f` here: `'f,`
|
||||||
|
|
||||||
|
error: implementation of `Bar` is not general enough
|
||||||
|
--> $DIR/span-bug-issue-121414.rs:9:4
|
||||||
|
|
|
||||||
|
LL | fn test()
|
||||||
|
| ^^^^ implementation of `Bar` is not general enough
|
||||||
|
|
|
||||||
|
= note: `Bar` would have to be implemented for the type `Foo<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but `Bar` is actually implemented for the type `Foo<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0261`.
|
15
tests/ui/typeck/span-bug-issue-121410.rs
Normal file
15
tests/ui/typeck/span-bug-issue-121410.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
fn test_missing_unsafe_warning_on_repr_packed() {
|
||||||
|
struct Foo {
|
||||||
|
x: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let foo = Foo { x: String::new() };
|
||||||
|
|
||||||
|
let c = || {
|
||||||
|
let (_, t2) = foo.x; //~ ERROR mismatched types
|
||||||
|
};
|
||||||
|
|
||||||
|
c();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
tests/ui/typeck/span-bug-issue-121410.stderr
Normal file
14
tests/ui/typeck/span-bug-issue-121410.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/span-bug-issue-121410.rs:9:13
|
||||||
|
|
|
||||||
|
LL | let (_, t2) = foo.x;
|
||||||
|
| ^^^^^^^ ----- this expression has type `String`
|
||||||
|
| |
|
||||||
|
| expected `String`, found `(_, _)`
|
||||||
|
|
|
||||||
|
= note: expected struct `String`
|
||||||
|
found tuple `(_, _)`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue