mkHsForAllTy exp tvs ctxt     ty
  = HsForAllTy exp extra   (mkHsQTvs tvs) cleanCtxt        ty
  where -- Separate the extra-constraints wildcard when present
        (cleanCtxt, extra)
          | (L l HsWildcardTy) <- ignoreParens (last (unLoc ctxt)) = (init `fmap` ctxt, Just l)
          | otherwise = (ctxt, Nothing)
        ignoreParens (L _ (HsParTy ty)) = ty
        ignoreParens ty                 = ty


-- |When a sigtype is parsed, the type found is wrapped in an Implicit
-- HsForAllTy via mkImplicitHsForAllTy, to ensure that a signature always has a
-- forall at the outer level. For Api Annotations this nested structure is
-- important to ensure that all `forall` and `.` locations are retained.  From
-- the renamer onwards this structure is flattened, to ease the renaming and
-- type checking process.
mkHsForAllTy exp tvs ctxt     ty
  = HsForAllTy exp extra   (mkHsQTvs tvs) cleanCtxt        ty
  where -- Separate the extra-constraints wildcard when present
        (cleanCtxt, extra)
          | (L l HsWildcardTy) <- ignoreParens (last (unLoc ctxt)) = (init `fmap` ctxt, Just l)
          | otherwise = (ctxt, Nothing)
        ignoreParens (L _ (HsParTy ty)) = ty
        ignoreParens ty                 = ty


-- |When a sigtype is parsed, the type found is wrapped in an Implicit
-- HsForAllTy via mkImplicitHsForAllTy, to ensure that a signature always has a
-- forall at the outer level. For Api Annotations this nested structure is
-- important to ensure that all `forall` and `.` locations are retained.  From
-- the renamer onwards this structure is flattened, to ease the renaming and
-- type checking process.
mkHsForAllTy exp tvs ctxt     ty
  = HsForAllTy exp extra   (mkHsQTvs tvs) cleanCtxt        ty
  where -- Separate the extra-constraints wildcard when present
        (cleanCtxt, extra)
          | (L l HsWildcardTy) <- ignoreParens (last (unLoc ctxt)) = (init `fmap` ctxt, Just l)
          | otherwise = (ctxt, Nothing)
        ignoreParens (L _ (HsParTy ty)) = ty
        ignoreParens ty                 = ty


-- |When a sigtype is parsed, the type found is wrapped in an Implicit
-- HsForAllTy via mkImplicitHsForAllTy, to ensure that a signature always has a
-- forall at the outer level. For Api Annotations this nested structure is
-- important to ensure that all `forall` and `.` locations are retained.  From
-- the renamer onwards this structure is flattened, to ease the renaming and
-- type checking process.