|
3 | 3 |
|
4 | 4 | use rustc_data_structures::fx::FxHashSet; |
5 | 5 | use rustc_errors::struct_span_err; |
6 | | -use rustc_errors::ErrorGuaranteed; |
| 6 | +use rustc_errors::{Diagnostic, ErrorGuaranteed}; |
7 | 7 | use rustc_hir as hir; |
8 | 8 | use rustc_infer::infer::TyCtxtInferExt; |
9 | 9 | use rustc_middle::ty::subst::GenericArgKind; |
@@ -107,6 +107,7 @@ fn do_orphan_check_impl<'tcx>( |
107 | 107 | Err(err) => emit_orphan_check_error( |
108 | 108 | tcx, |
109 | 109 | sp, |
| 110 | + item.span, |
110 | 111 | tr.path.span, |
111 | 112 | trait_ref.self_ty(), |
112 | 113 | impl_.self_ty.span, |
@@ -207,6 +208,7 @@ fn do_orphan_check_impl<'tcx>( |
207 | 208 | fn emit_orphan_check_error<'tcx>( |
208 | 209 | tcx: TyCtxt<'tcx>, |
209 | 210 | sp: Span, |
| 211 | + full_impl_span: Span, |
210 | 212 | trait_span: Span, |
211 | 213 | self_ty: Ty<'tcx>, |
212 | 214 | self_ty_span: Span, |
@@ -247,8 +249,20 @@ fn emit_orphan_check_error<'tcx>( |
247 | 249 | ty::Slice(_) => (this, " because slices are always foreign"), |
248 | 250 | ty::Array(..) => (this, " because arrays are always foreign"), |
249 | 251 | ty::Tuple(..) => (this, " because tuples are always foreign"), |
| 252 | + ty::RawPtr(ptr_ty) => { |
| 253 | + emit_newtype_suggestion_for_raw_ptr( |
| 254 | + full_impl_span, |
| 255 | + self_ty, |
| 256 | + self_ty_span, |
| 257 | + ptr_ty, |
| 258 | + &mut err, |
| 259 | + ); |
| 260 | + |
| 261 | + (format!("`{}`", ty), " because raw pointers are always foreign") |
| 262 | + } |
250 | 263 | _ => (format!("`{}`", ty), ""), |
251 | 264 | }; |
| 265 | + |
252 | 266 | let msg = format!("{} is not defined in the current crate{}", ty, postfix); |
253 | 267 | if *is_target_ty { |
254 | 268 | // Point at `D<A>` in `impl<A, B> for C<B> in D<A>` |
@@ -330,6 +344,27 @@ fn emit_orphan_check_error<'tcx>( |
330 | 344 | }) |
331 | 345 | } |
332 | 346 |
|
| 347 | +fn emit_newtype_suggestion_for_raw_ptr( |
| 348 | + full_impl_span: Span, |
| 349 | + self_ty: Ty<'_>, |
| 350 | + self_ty_span: Span, |
| 351 | + ptr_ty: &ty::TypeAndMut<'_>, |
| 352 | + diag: &mut Diagnostic, |
| 353 | +) { |
| 354 | + if !self_ty.needs_subst() { |
| 355 | + let mut_key = if ptr_ty.mutbl == rustc_middle::mir::Mutability::Mut { "mut " } else { "" }; |
| 356 | + let msg_sugg = "consider introducing a new wrapper type".to_owned(); |
| 357 | + let sugg = vec![ |
| 358 | + ( |
| 359 | + full_impl_span.shrink_to_lo(), |
| 360 | + format!("struct WrapperType(*{}{});\n\n", mut_key, ptr_ty.ty), |
| 361 | + ), |
| 362 | + (self_ty_span, "WrapperType".to_owned()), |
| 363 | + ]; |
| 364 | + diag.multipart_suggestion(msg_sugg, sugg, rustc_errors::Applicability::MaybeIncorrect); |
| 365 | + } |
| 366 | +} |
| 367 | + |
333 | 368 | /// Lint impls of auto traits if they are likely to have |
334 | 369 | /// unsound or surprising effects on auto impls. |
335 | 370 | fn lint_auto_trait_impl<'tcx>( |
|
0 commit comments